Merge remote-tracking branch 'origin/dm-notifications-enhancements' into dm-notifications-enhancements
This commit is contained in:
commit
3795ff2420
@ -10,8 +10,8 @@ android {
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 29
|
||||
|
||||
versionCode 57
|
||||
versionName '19.0.5'
|
||||
versionCode 58
|
||||
versionName '19.1.0'
|
||||
|
||||
multiDexEnabled true
|
||||
|
||||
|
@ -12,11 +12,13 @@ import com.facebook.imagepipeline.core.ImagePipelineConfig;
|
||||
import java.net.CookieHandler;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.LocaleUtils;
|
||||
import awais.instagrabber.utils.SettingsHelper;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
import awais.instagrabber.utils.UserAgentUtils;
|
||||
import awaisomereport.CrashReporter;
|
||||
import awaisomereport.LogCollector;
|
||||
|
||||
@ -85,5 +87,15 @@ public final class InstaGrabberApplication extends Application {
|
||||
if (TextUtils.isEmpty(settingsHelper.getString(Constants.DEVICE_UUID))) {
|
||||
settingsHelper.putString(Constants.DEVICE_UUID, UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
if (settingsHelper.getInteger(Constants.BROWSER_UA_CODE) == -1) {
|
||||
int randomNum = ThreadLocalRandom.current().nextInt(0, UserAgentUtils.browsers.length);
|
||||
settingsHelper.putInteger(Constants.BROWSER_UA_CODE, randomNum);
|
||||
}
|
||||
|
||||
if (settingsHelper.getInteger(Constants.APP_UA_CODE) == -1) {
|
||||
int randomNum = ThreadLocalRandom.current().nextInt(0, UserAgentUtils.devices.length);
|
||||
settingsHelper.putInteger(Constants.APP_UA_CODE, randomNum);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package awais.instagrabber.animations;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.view.View;
|
||||
|
||||
// https://medium.com/better-programming/animated-fab-button-with-more-options-2dcf7118fff6
|
||||
|
||||
public class FabAnimation {
|
||||
public static boolean rotateFab(final View v, boolean rotate) {
|
||||
v.animate().setDuration(200)
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
}
|
||||
})
|
||||
.rotation(rotate ? 135f : 0f);
|
||||
return rotate;
|
||||
}
|
||||
|
||||
public static void showIn(final View v) {
|
||||
v.setVisibility(View.VISIBLE);
|
||||
v.setAlpha(0f);
|
||||
v.setTranslationY(v.getHeight());
|
||||
v.animate()
|
||||
.setDuration(200)
|
||||
.translationY(0)
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
}
|
||||
})
|
||||
.alpha(1f)
|
||||
.start();
|
||||
}
|
||||
|
||||
public static void showOut(final View v) {
|
||||
v.setVisibility(View.VISIBLE);
|
||||
v.setAlpha(1f);
|
||||
v.setTranslationY(0);
|
||||
v.animate()
|
||||
.setDuration(200)
|
||||
.translationY(v.getHeight())
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
v.setVisibility(View.GONE);
|
||||
super.onAnimationEnd(animation);
|
||||
}
|
||||
}).alpha(0f)
|
||||
.start();
|
||||
}
|
||||
|
||||
public static void init(final View v) {
|
||||
v.setVisibility(View.GONE);
|
||||
v.setTranslationY(v.getHeight());
|
||||
v.setAlpha(0f);
|
||||
}
|
||||
}
|
@ -35,7 +35,7 @@ public class CreateThreadAction extends AsyncTask<Void, Void, String> {
|
||||
try {
|
||||
urlConnection = (HttpURLConnection) new URL(url).openConnection();
|
||||
urlConnection.setRequestMethod("POST");
|
||||
urlConnection.setRequestProperty("User-Agent", Constants.I_USER_AGENT);
|
||||
urlConnection.setRequestProperty("User-Agent", Utils.settingsHelper.getString(Constants.APP_UA));
|
||||
urlConnection.setUseCaches(false);
|
||||
final String urlParameters = Utils.sign("{\"_csrftoken\":\"" + cookie.split("csrftoken=")[1].split(";")[0]
|
||||
+ "\",\"_uid\":\"" + CookieUtils.getUserIdFromCookie(cookie)
|
||||
|
@ -29,8 +29,9 @@ public class FeedPostFetchService implements PostFetcher.PostFetchService {
|
||||
final List<Media> feedModels = new ArrayList<>();
|
||||
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||
final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
|
||||
final String deviceUuid = settingsHelper.getString(Constants.DEVICE_UUID);
|
||||
feedModels.clear();
|
||||
feedService.fetch(csrfToken, nextCursor, new ServiceCallback<PostsFetchResponse>() {
|
||||
feedService.fetch(csrfToken, deviceUuid, nextCursor, new ServiceCallback<PostsFetchResponse>() {
|
||||
@Override
|
||||
public void onSuccess(final PostsFetchResponse result) {
|
||||
if (result == null && feedModels.size() > 0) {
|
||||
|
@ -14,6 +14,7 @@ import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.CookieUtils;
|
||||
import awais.instagrabber.utils.NetworkUtils;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
|
||||
public class GetActivityAsyncTask extends AsyncTask<String, Void, GetActivityAsyncTask.NotificationCounts> {
|
||||
private static final String TAG = "GetActivityAsyncTask";
|
||||
@ -44,7 +45,7 @@ public class GetActivityAsyncTask extends AsyncTask<String, Void, GetActivityAsy
|
||||
try {
|
||||
urlConnection = (HttpURLConnection) new URL(url).openConnection();
|
||||
urlConnection.setUseCaches(false);
|
||||
urlConnection.setRequestProperty("User-Agent", Constants.USER_AGENT);
|
||||
urlConnection.setRequestProperty("User-Agent", Utils.settingsHelper.getString(Constants.BROWSER_UA));
|
||||
urlConnection.setRequestProperty("x-csrftoken", cookie.split("csrftoken=")[1].split(";")[0]);
|
||||
urlConnection.connect();
|
||||
if (urlConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
|
||||
|
@ -76,8 +76,8 @@ public final class ProfileFetcher extends AsyncTask<Void, Void, User> {
|
||||
userJson.optBoolean("blocked_by_viewer"),
|
||||
false,
|
||||
isPrivate,
|
||||
false,
|
||||
userJson.optBoolean("restricted_by_viewer"),
|
||||
userJson.optBoolean("has_requested_viewer"),
|
||||
userJson.optBoolean("requested_by_viewer"),
|
||||
false,
|
||||
userJson.optBoolean("restricted_by_viewer"),
|
||||
false
|
||||
|
@ -14,6 +14,7 @@ import awais.instagrabber.BuildConfig;
|
||||
import awais.instagrabber.interfaces.FetchListener;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.NetworkUtils;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
|
||||
public final class UsernameFetcher extends AsyncTask<Void, Void, String> {
|
||||
private final FetchListener<String> fetchListener;
|
||||
@ -31,7 +32,7 @@ public final class UsernameFetcher extends AsyncTask<Void, Void, String> {
|
||||
|
||||
try {
|
||||
final HttpURLConnection conn = (HttpURLConnection) new URL("https://i.instagram.com/api/v1/users/" + uid + "/info/").openConnection();
|
||||
conn.setRequestProperty("User-Agent", Constants.USER_AGENT);
|
||||
conn.setRequestProperty("User-Agent", Utils.settingsHelper.getString(Constants.BROWSER_UA));
|
||||
conn.setUseCaches(true);
|
||||
|
||||
final JSONObject user;
|
||||
|
@ -64,7 +64,7 @@ public final class CommentsViewerFragment extends BottomSheetDialogFragment impl
|
||||
private LinearLayoutManager layoutManager;
|
||||
private RecyclerLazyLoader lazyLoader;
|
||||
private String shortCode;
|
||||
private long userId;
|
||||
private long authorUserId, userIdFromCookie;
|
||||
private String endCursor = null;
|
||||
private Resources resources;
|
||||
private InputMethodManager imm;
|
||||
@ -140,14 +140,13 @@ public final class CommentsViewerFragment extends BottomSheetDialogFragment impl
|
||||
Toast.makeText(context, R.string.comment_send_empty_comment, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
final long userId = CookieUtils.getUserIdFromCookie(cookie);
|
||||
if (userId == 0) return;
|
||||
if (userIdFromCookie == 0) return;
|
||||
String replyToId = null;
|
||||
final CommentModel commentModel = commentsAdapter.getSelected();
|
||||
if (commentModel != null) {
|
||||
replyToId = commentModel.getId();
|
||||
}
|
||||
mediaService.comment(postId, text.toString(), userId, replyToId, CookieUtils.getCsrfTokenFromCookie(cookie), new ServiceCallback<Boolean>() {
|
||||
mediaService.comment(postId, text.toString(), replyToId, new ServiceCallback<Boolean>() {
|
||||
@Override
|
||||
public void onSuccess(final Boolean result) {
|
||||
commentsAdapter.clearSelection();
|
||||
@ -171,7 +170,10 @@ public final class CommentsViewerFragment extends BottomSheetDialogFragment impl
|
||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
fragmentActivity = (AppCompatActivity) getActivity();
|
||||
mediaService = MediaService.getInstance();
|
||||
final String deviceUuid = Utils.settingsHelper.getString(Constants.DEVICE_UUID);
|
||||
final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
|
||||
userIdFromCookie = CookieUtils.getUserIdFromCookie(cookie);
|
||||
mediaService = MediaService.getInstance(deviceUuid, csrfToken, userIdFromCookie);
|
||||
// setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@ -231,7 +233,7 @@ public final class CommentsViewerFragment extends BottomSheetDialogFragment impl
|
||||
final CommentsViewerFragmentArgs fragmentArgs = CommentsViewerFragmentArgs.fromBundle(getArguments());
|
||||
shortCode = fragmentArgs.getShortCode();
|
||||
postId = fragmentArgs.getPostId();
|
||||
userId = fragmentArgs.getPostUserId();
|
||||
authorUserId = fragmentArgs.getPostUserId();
|
||||
// setTitle();
|
||||
binding.swipeRefreshLayout.setOnRefreshListener(this);
|
||||
binding.swipeRefreshLayout.setRefreshing(true);
|
||||
@ -289,10 +291,9 @@ public final class CommentsViewerFragment extends BottomSheetDialogFragment impl
|
||||
|
||||
String[] commentDialogList;
|
||||
|
||||
final long userIdFromCookie = CookieUtils.getUserIdFromCookie(cookie);
|
||||
if (!TextUtils.isEmpty(cookie)
|
||||
&& userIdFromCookie != 0
|
||||
&& (userIdFromCookie == commentModel.getProfileModel().getPk() || userIdFromCookie == userId)) {
|
||||
&& (userIdFromCookie == commentModel.getProfileModel().getPk() || userIdFromCookie == authorUserId)) {
|
||||
commentDialogList = new String[]{
|
||||
resources.getString(R.string.open_profile),
|
||||
resources.getString(R.string.comment_viewer_copy_comment),
|
||||
@ -324,7 +325,6 @@ public final class CommentsViewerFragment extends BottomSheetDialogFragment impl
|
||||
if (context == null) return;
|
||||
final DialogInterface.OnClickListener profileDialogListener = (dialog, which) -> {
|
||||
final User profileModel = commentModel.getProfileModel();
|
||||
final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
|
||||
switch (which) {
|
||||
case 0: // open profile
|
||||
openProfile("@" + profileModel.getUsername());
|
||||
@ -354,11 +354,8 @@ public final class CommentsViewerFragment extends BottomSheetDialogFragment impl
|
||||
}, 200);
|
||||
break;
|
||||
case 4: // like/unlike comment
|
||||
if (csrfToken == null) {
|
||||
return;
|
||||
}
|
||||
if (!commentModel.getLiked()) {
|
||||
mediaService.commentLike(commentModel.getId(), csrfToken, new ServiceCallback<Boolean>() {
|
||||
mediaService.commentLike(commentModel.getId(), new ServiceCallback<Boolean>() {
|
||||
@Override
|
||||
public void onSuccess(final Boolean result) {
|
||||
if (!result) {
|
||||
@ -376,7 +373,7 @@ public final class CommentsViewerFragment extends BottomSheetDialogFragment impl
|
||||
});
|
||||
return;
|
||||
}
|
||||
mediaService.commentUnlike(commentModel.getId(), csrfToken, new ServiceCallback<Boolean>() {
|
||||
mediaService.commentUnlike(commentModel.getId(), new ServiceCallback<Boolean>() {
|
||||
@Override
|
||||
public void onSuccess(final Boolean result) {
|
||||
if (!result) {
|
||||
@ -416,10 +413,9 @@ public final class CommentsViewerFragment extends BottomSheetDialogFragment impl
|
||||
});
|
||||
break;
|
||||
case 6: // delete comment
|
||||
final long userId = CookieUtils.getUserIdFromCookie(cookie);
|
||||
if (userId == 0) return;
|
||||
if (userIdFromCookie == 0) return;
|
||||
mediaService.deleteComment(
|
||||
postId, userId, commentModel.getId(), csrfToken,
|
||||
postId, commentModel.getId(),
|
||||
new ServiceCallback<Boolean>() {
|
||||
@Override
|
||||
public void onSuccess(final Boolean result) {
|
||||
|
@ -118,7 +118,7 @@ public final class FollowViewerFragment extends Fragment implements SwipeRefresh
|
||||
@Override
|
||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
friendshipService = FriendshipService.getInstance();
|
||||
friendshipService = FriendshipService.getInstance(null, null, 0);
|
||||
fragmentActivity = (AppCompatActivity) getActivity();
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
@ -414,10 +414,11 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
hashtagDetailsBinding.btnFollowTag.setOnClickListener(v -> {
|
||||
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||
final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
|
||||
final String ua = settingsHelper.getString(Constants.BROWSER_UA);
|
||||
if (csrfToken != null) {
|
||||
hashtagDetailsBinding.btnFollowTag.setClickable(false);
|
||||
if (!hashtagModel.getFollowing()) {
|
||||
tagsService.follow(hashtag.substring(1), csrfToken, new ServiceCallback<Boolean>() {
|
||||
tagsService.follow(ua, hashtag.substring(1), csrfToken, new ServiceCallback<Boolean>() {
|
||||
@Override
|
||||
public void onSuccess(final Boolean result) {
|
||||
hashtagDetailsBinding.btnFollowTag.setClickable(true);
|
||||
@ -445,7 +446,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
});
|
||||
return;
|
||||
}
|
||||
tagsService.unfollow(hashtag.substring(1), csrfToken, new ServiceCallback<Boolean>() {
|
||||
tagsService.unfollow(ua, hashtag.substring(1), csrfToken, new ServiceCallback<Boolean>() {
|
||||
@Override
|
||||
public void onSuccess(final Boolean result) {
|
||||
hashtagDetailsBinding.btnFollowTag.setClickable(true);
|
||||
|
@ -104,7 +104,7 @@ public final class LikesViewerFragment extends BottomSheetDialogFragment impleme
|
||||
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
|
||||
// final AppCompatActivity fragmentActivity = (AppCompatActivity) getActivity();
|
||||
mediaService = isLoggedIn ? MediaService.getInstance() : null;
|
||||
mediaService = isLoggedIn ? MediaService.getInstance(null, null, 0) : null;
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.getInstance();
|
||||
// setHasOptionsMenu(true);
|
||||
}
|
||||
|
@ -60,7 +60,6 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
|
||||
private NotificationViewModel notificationViewModel;
|
||||
private FriendshipService friendshipService;
|
||||
private MediaService mediaService;
|
||||
private long userId;
|
||||
private String csrfToken;
|
||||
private String type;
|
||||
private Context context;
|
||||
@ -133,7 +132,7 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
|
||||
break;
|
||||
case 1:
|
||||
if (model.getType() == NotificationType.REQUEST) {
|
||||
friendshipService.approve(userId, model.getUserId(), csrfToken, new ServiceCallback<FriendshipChangeResponse>() {
|
||||
friendshipService.approve(model.getUserId(), new ServiceCallback<FriendshipChangeResponse>() {
|
||||
@Override
|
||||
public void onSuccess(final FriendshipChangeResponse result) {
|
||||
onRefresh();
|
||||
@ -175,7 +174,7 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
|
||||
});
|
||||
break;
|
||||
case 2:
|
||||
friendshipService.ignore(userId, model.getUserId(), csrfToken, new ServiceCallback<FriendshipChangeResponse>() {
|
||||
friendshipService.ignore(model.getUserId(), new ServiceCallback<FriendshipChangeResponse>() {
|
||||
@Override
|
||||
public void onSuccess(final FriendshipChangeResponse result) {
|
||||
onRefresh();
|
||||
@ -218,10 +217,11 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe
|
||||
if (TextUtils.isEmpty(cookie)) {
|
||||
Toast.makeText(context, R.string.activity_notloggedin, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
friendshipService = FriendshipService.getInstance();
|
||||
mediaService = MediaService.getInstance();
|
||||
userId = CookieUtils.getUserIdFromCookie(cookie);
|
||||
mediaService = MediaService.getInstance(null, null, 0);
|
||||
final long userId = CookieUtils.getUserIdFromCookie(cookie);
|
||||
final String deviceUuid = Utils.settingsHelper.getString(Constants.DEVICE_UUID);
|
||||
csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
|
||||
friendshipService = FriendshipService.getInstance(deviceUuid, csrfToken, userId);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -465,16 +465,16 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
|
||||
binding.date.setVisibility(View.VISIBLE);
|
||||
binding.date.setText(date);
|
||||
}));
|
||||
if (viewModel.getMedia().isCommentLikesEnabled()) {
|
||||
viewModel.getLikeCount().observe(getViewLifecycleOwner(), count -> {
|
||||
final long safeCount = getSafeCount(count);
|
||||
final String likesString = getResources().getQuantityString(R.plurals.likes_count, (int) safeCount, safeCount);
|
||||
binding.likesCount.setText(likesString);
|
||||
});
|
||||
viewModel.getLikeCount().observe(getViewLifecycleOwner(), count -> {
|
||||
final long safeCount = getSafeCount(count);
|
||||
final String likesString = getResources().getQuantityString(R.plurals.likes_count, (int) safeCount, safeCount);
|
||||
binding.likesCount.setText(likesString);
|
||||
});
|
||||
if (!viewModel.getMedia().isCommentsDisabled()) {
|
||||
viewModel.getCommentCount().observe(getViewLifecycleOwner(), count -> {
|
||||
final long safeCount = getSafeCount(count);
|
||||
final String likesString = getResources().getQuantityString(R.plurals.comments_count, (int) safeCount, safeCount);
|
||||
binding.likesCount.setText(likesString);
|
||||
binding.commentsCount.setText(likesString);
|
||||
});
|
||||
}
|
||||
viewModel.getViewCount().observe(getViewLifecycleOwner(), count -> {
|
||||
@ -538,7 +538,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
|
||||
}
|
||||
|
||||
private void setupComment() {
|
||||
if (!viewModel.hasPk() || !viewModel.getMedia().isCommentLikesEnabled()) {
|
||||
if (!viewModel.hasPk() || viewModel.getMedia().isCommentsDisabled()) {
|
||||
binding.comment.setVisibility(View.GONE);
|
||||
binding.commentsCount.setVisibility(View.GONE);
|
||||
return;
|
||||
@ -577,7 +577,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
|
||||
}
|
||||
|
||||
private void setupLike() {
|
||||
final boolean likableMedia = viewModel.hasPk() && viewModel.getMedia().isCommentLikesEnabled();
|
||||
final boolean likableMedia = viewModel.hasPk() /*&& viewModel.getMedia().isCommentLikesEnabled()*/;
|
||||
if (!likableMedia) {
|
||||
binding.like.setVisibility(View.GONE);
|
||||
binding.likesCount.setVisibility(View.GONE);
|
||||
@ -1402,20 +1402,24 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
|
||||
if (media.getLocation() != null) {
|
||||
binding.location.setVisibility(View.VISIBLE);
|
||||
}
|
||||
binding.captionParent.setVisibility(View.VISIBLE);
|
||||
binding.bottomBg.setVisibility(View.VISIBLE);
|
||||
binding.likesCount.setVisibility(View.VISIBLE);
|
||||
binding.commentsCount.setVisibility(View.VISIBLE);
|
||||
binding.date.setVisibility(View.VISIBLE);
|
||||
binding.captionToggle.setVisibility(View.VISIBLE);
|
||||
if (viewModel.hasPk()) {
|
||||
binding.likesCount.setVisibility(View.VISIBLE);
|
||||
binding.date.setVisibility(View.VISIBLE);
|
||||
binding.captionParent.setVisibility(View.VISIBLE);
|
||||
binding.captionToggle.setVisibility(View.VISIBLE);
|
||||
binding.share.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (viewModel.hasPk() && !viewModel.getMedia().isCommentsDisabled()) {
|
||||
binding.comment.setVisibility(View.VISIBLE);
|
||||
binding.commentsCount.setVisibility(View.VISIBLE);
|
||||
}
|
||||
binding.download.setVisibility(View.VISIBLE);
|
||||
binding.share.setVisibility(View.VISIBLE);
|
||||
binding.comment.setVisibility(View.VISIBLE);
|
||||
final List<Integer> options = viewModel.getOptions().getValue();
|
||||
if (options != null && !options.isEmpty()) {
|
||||
binding.options.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (viewModel.isLoggedIn()) {
|
||||
if (viewModel.isLoggedIn() && viewModel.hasPk()) {
|
||||
binding.like.setVisibility(View.VISIBLE);
|
||||
binding.save.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
@ -172,6 +172,21 @@ public class DirectMessageThreadFragment extends Fragment {
|
||||
|
||||
@Override
|
||||
public void onMediaClick(final Media media) {
|
||||
if (media.isReelMedia()) {
|
||||
final String pk = media.getPk();
|
||||
try {
|
||||
final long mediaId = Long.parseLong(pk);
|
||||
final User user = media.getUser();
|
||||
if (user == null) return;
|
||||
final String username = user.getUsername();
|
||||
final NavDirections action = DirectMessageThreadFragmentDirections
|
||||
.actionThreadToStory(StoryViewerOptions.forStory(mediaId, username));
|
||||
NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(action);
|
||||
} catch (NumberFormatException e) {
|
||||
Log.e(TAG, "onMediaClick (story): ", e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
final PostViewV2Fragment.Builder builder = PostViewV2Fragment.builder(media);
|
||||
builder.build().show(getChildFragmentManager(), "post_view");
|
||||
}
|
||||
|
@ -68,6 +68,7 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
|
||||
private FragmentFeedBinding binding;
|
||||
private StoriesService storiesService;
|
||||
private boolean shouldRefresh = true;
|
||||
private final boolean isRotate = false;
|
||||
private FeedStoriesViewModel feedStoriesViewModel;
|
||||
private boolean storiesFetching;
|
||||
private ActionMode actionMode;
|
||||
@ -282,6 +283,24 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
|
||||
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
|
||||
if (!shouldRefresh) return;
|
||||
binding.feedSwipeRefreshLayout.setOnRefreshListener(this);
|
||||
/*
|
||||
FabAnimation.init(binding.fabCamera);
|
||||
FabAnimation.init(binding.fabStory);
|
||||
binding.fabAdd.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
isRotate = FabAnimation.rotateFab(v, !isRotate);
|
||||
if (isRotate) {
|
||||
FabAnimation.showIn(binding.fabCamera);
|
||||
FabAnimation.showIn(binding.fabStory);
|
||||
}
|
||||
else {
|
||||
FabAnimation.showOut(binding.fabCamera);
|
||||
FabAnimation.showOut(binding.fabStory);
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
setupFeedStories();
|
||||
setupFeed();
|
||||
shouldRefresh = false;
|
||||
|
@ -99,7 +99,6 @@ import awais.instagrabber.webservices.StoriesService;
|
||||
import static androidx.core.content.PermissionChecker.checkSelfPermission;
|
||||
import static awais.instagrabber.fragments.HashTagFragment.ARG_HASHTAG;
|
||||
import static awais.instagrabber.utils.DownloadUtils.WRITE_PERMISSION;
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||
|
||||
public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
|
||||
private static final String TAG = "ProfileFragment";
|
||||
@ -300,10 +299,15 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
@Override
|
||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
cookie = Utils.settingsHelper.getString(Constants.COOKIE);
|
||||
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
|
||||
final long userId = CookieUtils.getUserIdFromCookie(cookie);
|
||||
final String deviceUuid = Utils.settingsHelper.getString(Constants.DEVICE_UUID);
|
||||
final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
|
||||
fragmentActivity = (MainActivity) requireActivity();
|
||||
friendshipService = FriendshipService.getInstance();
|
||||
friendshipService = FriendshipService.getInstance(deviceUuid, csrfToken, userId);
|
||||
storiesService = StoriesService.getInstance();
|
||||
mediaService = MediaService.getInstance();
|
||||
mediaService = MediaService.getInstance(null, null, 0);
|
||||
accountRepository = AccountRepository.getInstance(AccountDataSource.getInstance(getContext()));
|
||||
favoriteRepository = FavoriteRepository.getInstance(FavoriteDataSource.getInstance(getContext()));
|
||||
setHasOptionsMenu(true);
|
||||
@ -313,8 +317,6 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
public View onCreateView(@NonNull final LayoutInflater inflater,
|
||||
final ViewGroup container,
|
||||
final Bundle savedInstanceState) {
|
||||
cookie = settingsHelper.getString(Constants.COOKIE);
|
||||
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
|
||||
if (root != null) {
|
||||
if (getArguments() != null) {
|
||||
final ProfileFragmentArgs fragmentArgs = ProfileFragmentArgs.fromBundle(getArguments());
|
||||
@ -380,7 +382,6 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
friendshipService.toggleRestrict(
|
||||
profileModel.getPk(),
|
||||
!profileModel.getFriendshipStatus().isRestricted(),
|
||||
CookieUtils.getCsrfTokenFromCookie(cookie),
|
||||
new ServiceCallback<FriendshipRestrictResponse>() {
|
||||
@Override
|
||||
public void onSuccess(final FriendshipRestrictResponse result) {
|
||||
@ -396,13 +397,10 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
return true;
|
||||
}
|
||||
if (item.getItemId() == R.id.block) {
|
||||
final long userIdFromCookie = CookieUtils.getUserIdFromCookie(cookie);
|
||||
if (!isLoggedIn) return false;
|
||||
if (profileModel.getFriendshipStatus().isBlocking()) {
|
||||
friendshipService.unblock(
|
||||
userIdFromCookie,
|
||||
profileModel.getPk(),
|
||||
CookieUtils.getCsrfTokenFromCookie(cookie),
|
||||
new ServiceCallback<FriendshipChangeResponse>() {
|
||||
@Override
|
||||
public void onSuccess(final FriendshipChangeResponse result) {
|
||||
@ -418,9 +416,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
return true;
|
||||
}
|
||||
friendshipService.block(
|
||||
userIdFromCookie,
|
||||
profileModel.getPk(),
|
||||
CookieUtils.getCsrfTokenFromCookie(cookie),
|
||||
new ServiceCallback<FriendshipChangeResponse>() {
|
||||
@Override
|
||||
public void onSuccess(final FriendshipChangeResponse result) {
|
||||
@ -628,9 +624,9 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
), new RepositoryCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(final Void result) {
|
||||
profileDetailsBinding.favChip.setText(R.string.added_to_favs);
|
||||
profileDetailsBinding.favChip.setText(R.string.added_to_favs_short);
|
||||
profileDetailsBinding.favChip.setChipIconResource(R.drawable.ic_star_check_24);
|
||||
showSnackbar(getString(R.string.added_to_favs));
|
||||
showSnackbar(getString(R.string.added_to_favs_short));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -894,7 +890,6 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
|
||||
private void setupCommonListeners() {
|
||||
final Context context = getContext();
|
||||
final long userIdFromCookie = CookieUtils.getUserIdFromCookie(cookie);
|
||||
profileDetailsBinding.btnFollow.setOnClickListener(v -> {
|
||||
if (profileModel.getFriendshipStatus().isFollowing() && profileModel.isPrivate()) {
|
||||
new AlertDialog.Builder(context)
|
||||
@ -902,9 +897,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
.setMessage(R.string.priv_acc_confirm)
|
||||
.setPositiveButton(R.string.confirm, (d, w) ->
|
||||
friendshipService.unfollow(
|
||||
userIdFromCookie,
|
||||
profileModel.getPk(),
|
||||
CookieUtils.getCsrfTokenFromCookie(cookie),
|
||||
new ServiceCallback<FriendshipChangeResponse>() {
|
||||
@Override
|
||||
public void onSuccess(final FriendshipChangeResponse result) {
|
||||
@ -919,11 +912,10 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
}))
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show();
|
||||
} else if (profileModel.getFriendshipStatus().isFollowing() || profileModel.getFriendshipStatus().isOutgoingRequest()) {
|
||||
}
|
||||
else if (profileModel.getFriendshipStatus().isFollowing() || profileModel.getFriendshipStatus().isOutgoingRequest()) {
|
||||
friendshipService.unfollow(
|
||||
userIdFromCookie,
|
||||
profileModel.getPk(),
|
||||
CookieUtils.getCsrfTokenFromCookie(cookie),
|
||||
new ServiceCallback<FriendshipChangeResponse>() {
|
||||
@Override
|
||||
public void onSuccess(final FriendshipChangeResponse result) {
|
||||
@ -938,9 +930,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
});
|
||||
} else {
|
||||
friendshipService.follow(
|
||||
userIdFromCookie,
|
||||
profileModel.getPk(),
|
||||
CookieUtils.getCsrfTokenFromCookie(cookie),
|
||||
new ServiceCallback<FriendshipChangeResponse>() {
|
||||
@Override
|
||||
public void onSuccess(final FriendshipChangeResponse result) {
|
||||
@ -1102,6 +1092,6 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
private boolean isReallyPrivate() {
|
||||
final long myId = CookieUtils.getUserIdFromCookie(cookie);
|
||||
final FriendshipStatus friendshipStatus = profileModel.getFriendshipStatus();
|
||||
return !friendshipStatus.isFollowedBy() && (profileModel.getPk() != myId) && profileModel.isPrivate();
|
||||
return !friendshipStatus.isFollowing() && (profileModel.getPk() != myId) && profileModel.isPrivate();
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import retrofit2.Call;
|
||||
import retrofit2.http.FieldMap;
|
||||
import retrofit2.http.FormUrlEncoded;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.Header;
|
||||
import retrofit2.http.POST;
|
||||
import retrofit2.http.Path;
|
||||
import retrofit2.http.QueryMap;
|
||||
@ -17,20 +16,17 @@ public interface FriendshipRepository {
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/api/v1/friendships/{action}/{id}/")
|
||||
Call<FriendshipChangeResponse> change(@Header("User-Agent") String userAgent,
|
||||
@Path("action") String action,
|
||||
Call<FriendshipChangeResponse> change(@Path("action") String action,
|
||||
@Path("id") long id,
|
||||
@FieldMap Map<String, String> form);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/api/v1/restrict_action/{action}/")
|
||||
Call<FriendshipRestrictResponse> toggleRestrict(@Header("User-Agent") String userAgent,
|
||||
@Path("action") String action,
|
||||
Call<FriendshipRestrictResponse> toggleRestrict(@Path("action") String action,
|
||||
@FieldMap Map<String, String> form);
|
||||
|
||||
@GET("/api/v1/friendships/{userId}/{type}/")
|
||||
Call<String> getList(@Header("User-Agent") String userAgent,
|
||||
@Path("userId") long userId,
|
||||
Call<String> getList(@Path("userId") long userId,
|
||||
@Path("type") String type, // following or followers
|
||||
@QueryMap(encoded = true) Map<String, String> queryParams);
|
||||
}
|
||||
|
@ -2,28 +2,23 @@ package awais.instagrabber.repositories;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.FieldMap;
|
||||
import retrofit2.http.FormUrlEncoded;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.Header;
|
||||
import retrofit2.http.Headers;
|
||||
import retrofit2.http.POST;
|
||||
import retrofit2.http.Query;
|
||||
|
||||
public interface NewsRepository {
|
||||
|
||||
@Headers("User-Agent: " + Constants.USER_AGENT)
|
||||
@GET("https://www.instagram.com/accounts/activity/?__a=1")
|
||||
Call<String> webInbox();
|
||||
Call<String> webInbox(@Header("User-Agent") String userAgent);
|
||||
|
||||
@Headers("User-Agent: " + Constants.I_USER_AGENT)
|
||||
@GET("/api/v1/news/inbox/")
|
||||
Call<String> appInbox(@Query(value = "mark_as_seen", encoded = true) boolean markAsSeen);
|
||||
Call<String> appInbox(@Header("User-Agent") String userAgent, @Query(value = "mark_as_seen", encoded = true) boolean markAsSeen);
|
||||
|
||||
@FormUrlEncoded
|
||||
@Headers("User-Agent: " + Constants.I_USER_AGENT)
|
||||
@POST("/api/v1/discover/ayml/")
|
||||
Call<String> getAyml(@FieldMap final Map<String, String> form);
|
||||
Call<String> getAyml(@Header("User-Agent") String userAgent, @FieldMap final Map<String, String> form);
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import retrofit2.Call;
|
||||
import retrofit2.http.FieldMap;
|
||||
import retrofit2.http.FormUrlEncoded;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.Header;
|
||||
import retrofit2.http.POST;
|
||||
import retrofit2.http.Path;
|
||||
import retrofit2.http.QueryMap;
|
||||
@ -28,12 +27,11 @@ public interface StoriesRepository {
|
||||
Call<String> fetchArchive(@QueryMap Map<String, String> queryParams);
|
||||
|
||||
@GET
|
||||
Call<String> getUserStory(@Header("User-Agent") String userAgent, @Url String url);
|
||||
Call<String> getUserStory(@Url String url);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/api/v1/media/{storyId}/{stickerId}/{action}/")
|
||||
Call<StoryStickerResponse> respondToSticker(@Header("User-Agent") String userAgent,
|
||||
@Path("storyId") String storyId,
|
||||
Call<StoryStickerResponse> respondToSticker(@Path("storyId") String storyId,
|
||||
@Path("stickerId") String stickerId,
|
||||
@Path("action") String action,
|
||||
// story_poll_vote, story_question_response, story_slider_vote, story_quiz_answer
|
||||
|
@ -19,6 +19,7 @@ public class Media implements Serializable {
|
||||
private final MediaItemType mediaType;
|
||||
private final boolean canViewerReshare;
|
||||
private final boolean commentLikesEnabled;
|
||||
private final boolean commentsDisabled;
|
||||
private final long nextMaxId;
|
||||
private final long commentCount;
|
||||
private final ImageVersions2 imageVersions2;
|
||||
@ -56,6 +57,7 @@ public class Media implements Serializable {
|
||||
final int originalHeight,
|
||||
final MediaItemType mediaType,
|
||||
final boolean commentLikesEnabled,
|
||||
final boolean commentsDisabled,
|
||||
final long nextMaxId,
|
||||
final long commentCount,
|
||||
final long likeCount,
|
||||
@ -87,6 +89,7 @@ public class Media implements Serializable {
|
||||
this.originalHeight = originalHeight;
|
||||
this.mediaType = mediaType;
|
||||
this.commentLikesEnabled = commentLikesEnabled;
|
||||
this.commentsDisabled = commentsDisabled;
|
||||
this.nextMaxId = nextMaxId;
|
||||
this.commentCount = commentCount;
|
||||
this.likeCount = likeCount;
|
||||
@ -182,6 +185,10 @@ public class Media implements Serializable {
|
||||
return commentLikesEnabled;
|
||||
}
|
||||
|
||||
public boolean isCommentsDisabled() {
|
||||
return commentsDisabled;
|
||||
}
|
||||
|
||||
public long getNextMaxId() {
|
||||
return nextMaxId;
|
||||
}
|
||||
|
@ -9,8 +9,10 @@ public final class Constants {
|
||||
public static final String APP_THEME = "app_theme_v19";
|
||||
public static final String APP_LANGUAGE = "app_language_v19";
|
||||
public static final String STORY_SORT = "story_sort";
|
||||
// int prefs
|
||||
// int prefs, do not export
|
||||
public static final String PREV_INSTALL_VERSION = "prevVersion";
|
||||
public static final String BROWSER_UA_CODE = "browser_ua_code";
|
||||
public static final String APP_UA_CODE = "app_ua_code";
|
||||
// boolean prefs
|
||||
public static final String DOWNLOAD_USER_FOLDER = "download_user_folder";
|
||||
// deprecated: public static final String BOTTOM_TOOLBAR = "bottom_toolbar";
|
||||
@ -31,6 +33,8 @@ public final class Constants {
|
||||
public static final String COOKIE = "cookie";
|
||||
public static final String SHOW_QUICK_ACCESS_DIALOG = "show_quick_dlg";
|
||||
public static final String DEVICE_UUID = "device_uuid";
|
||||
public static final String BROWSER_UA = "browser_ua";
|
||||
public static final String APP_UA = "app_ua";
|
||||
//////////////////////// EXTRAS ////////////////////////
|
||||
public static final String EXTRAS_USER = "user";
|
||||
public static final String EXTRAS_HASHTAG = "hashtag";
|
||||
@ -54,13 +58,6 @@ public final class Constants {
|
||||
// Notification ids
|
||||
public static final int ACTIVITY_NOTIFICATION_ID = 10;
|
||||
|
||||
// spoof
|
||||
public static final String USER_AGENT = "Mozilla/5.0 (Linux; Android 8.1.0; motorola one Build/OPKS28.63-18-3; wv) " +
|
||||
"AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36 " +
|
||||
"Instagram 169.1.0.29.135 Android (27/8.1.0; 320dpi; 720x1362; motorola; motorola one; deen_sprout; qcom; pt_BR; 262886998)";
|
||||
public static final String I_USER_AGENT =
|
||||
"Instagram 169.1.0.29.135 Android (27/8.1.0; 320dpi; 720x1362; motorola; motorola one; deen_sprout; qcom; pt_BR; 262886998)";
|
||||
public static final String A_USER_AGENT = "https://Barinsta.AustinHuang.me / mailto:Barinsta@AustinHuang.me";
|
||||
// see https://github.com/dilame/instagram-private-api/blob/master/src/core/constants.ts
|
||||
public static final String SUPPORTED_CAPABILITIES = "[ { \"name\": \"SUPPORTED_SDK_VERSIONS\", \"value\":" +
|
||||
" \"13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0," +
|
||||
|
@ -81,6 +81,7 @@ public class DirectItemFactory {
|
||||
height,
|
||||
isVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE,
|
||||
false,
|
||||
false,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
@ -156,6 +157,7 @@ public class DirectItemFactory {
|
||||
0,
|
||||
MediaItemType.MEDIA_TYPE_VOICE,
|
||||
false,
|
||||
false,
|
||||
-1,
|
||||
0,
|
||||
0,
|
||||
|
@ -343,6 +343,10 @@ public final class ExportImportUtils {
|
||||
jsonObject.remove(Constants.COOKIE);
|
||||
jsonObject.remove(Constants.DEVICE_UUID);
|
||||
jsonObject.remove(Constants.PREV_INSTALL_VERSION);
|
||||
jsonObject.remove(Constants.BROWSER_UA_CODE);
|
||||
jsonObject.remove(Constants.BROWSER_UA);
|
||||
jsonObject.remove(Constants.APP_UA_CODE);
|
||||
jsonObject.remove(Constants.APP_UA);
|
||||
return jsonObject;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error exporting settings", e);
|
||||
|
@ -102,6 +102,14 @@ public final class FlavorTown {
|
||||
|
||||
public static void changelogCheck(@NonNull final Context context) {
|
||||
if (settingsHelper.getInteger(Constants.PREV_INSTALL_VERSION) < BuildConfig.VERSION_CODE) {
|
||||
final String langCode = settingsHelper.getString(Constants.APP_LANGUAGE);
|
||||
final String lang = LocaleUtils.getCorrespondingLanguageCode(langCode);
|
||||
final int appUaCode = settingsHelper.getInteger(Constants.APP_UA_CODE);
|
||||
final String appUa = UserAgentUtils.generateAppUA(appUaCode, lang);
|
||||
settingsHelper.putString(Constants.APP_UA, appUa);
|
||||
final int browserUaCode = settingsHelper.getInteger(Constants.BROWSER_UA_CODE);
|
||||
final String browserUa = UserAgentUtils.generateBrowserUA(browserUaCode);
|
||||
settingsHelper.putString(Constants.BROWSER_UA, browserUa);
|
||||
Toast.makeText(context, R.string.updated, Toast.LENGTH_SHORT).show();
|
||||
settingsHelper.putInteger(Constants.PREV_INSTALL_VERSION, BuildConfig.VERSION_CODE);
|
||||
}
|
||||
|
@ -19,7 +19,11 @@ public final class LocaleUtils {
|
||||
if (baseContext instanceof ContextThemeWrapper)
|
||||
baseContext = ((ContextThemeWrapper) baseContext).getBaseContext();
|
||||
|
||||
final String lang = LocaleUtils.getCorrespondingLanguageCode(baseContext);
|
||||
if (Utils.settingsHelper == null)
|
||||
Utils.settingsHelper = new SettingsHelper(baseContext);
|
||||
|
||||
final String appLanguageSettings = Utils.settingsHelper.getString(Constants.APP_LANGUAGE);
|
||||
final String lang = TextUtils.isEmpty(appLanguageSettings) ? null : LocaleUtils.getCorrespondingLanguageCode(appLanguageSettings);
|
||||
|
||||
currentLocale = TextUtils.isEmpty(lang) ? defaultLocale :
|
||||
(lang.contains("_") ? new Locale(lang.split("_")[0], lang.split("_")[1]) : new Locale(lang));
|
||||
@ -49,13 +53,7 @@ public final class LocaleUtils {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getCorrespondingLanguageCode(final Context baseContext) {
|
||||
if (Utils.settingsHelper == null)
|
||||
Utils.settingsHelper = new SettingsHelper(baseContext);
|
||||
|
||||
final String appLanguageSettings = Utils.settingsHelper.getString(Constants.APP_LANGUAGE);
|
||||
if (TextUtils.isEmpty(appLanguageSettings)) return null;
|
||||
|
||||
public static String getCorrespondingLanguageCode(final String appLanguageSettings) {
|
||||
final int appLanguageIndex = Integer.parseInt(appLanguageSettings);
|
||||
if (appLanguageIndex == 1) return "en";
|
||||
if (appLanguageIndex == 2) return "fr";
|
||||
|
@ -857,6 +857,7 @@ public final class ResponseBodyUtils {
|
||||
height,
|
||||
mediaItemType,
|
||||
false,
|
||||
feedItem.optBoolean("comments_disabled"),
|
||||
-1,
|
||||
commentsCount,
|
||||
likesCount,
|
||||
|
@ -10,7 +10,11 @@ import androidx.appcompat.app.AppCompatDelegate;
|
||||
|
||||
import static awais.instagrabber.utils.Constants.APP_LANGUAGE;
|
||||
import static awais.instagrabber.utils.Constants.APP_THEME;
|
||||
import static awais.instagrabber.utils.Constants.APP_UA;
|
||||
import static awais.instagrabber.utils.Constants.APP_UA_CODE;
|
||||
import static awais.instagrabber.utils.Constants.AUTOPLAY_VIDEOS;
|
||||
import static awais.instagrabber.utils.Constants.BROWSER_UA;
|
||||
import static awais.instagrabber.utils.Constants.BROWSER_UA_CODE;
|
||||
import static awais.instagrabber.utils.Constants.CHECK_ACTIVITY;
|
||||
import static awais.instagrabber.utils.Constants.CHECK_UPDATES;
|
||||
import static awais.instagrabber.utils.Constants.COOKIE;
|
||||
@ -80,7 +84,7 @@ public final class SettingsHelper {
|
||||
|
||||
private int getIntegerDefault(@IntegerSettings final String key) {
|
||||
if (APP_THEME.equals(key)) return getThemeCode(true);
|
||||
if (PREV_INSTALL_VERSION.equals(key)) return -1;
|
||||
if (PREV_INSTALL_VERSION.equals(key) || APP_UA_CODE.equals(key) || BROWSER_UA_CODE.equals(key)) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -121,10 +125,11 @@ public final class SettingsHelper {
|
||||
}
|
||||
|
||||
@StringDef(
|
||||
{APP_LANGUAGE, APP_THEME, COOKIE, FOLDER_PATH, DATE_TIME_FORMAT, DATE_TIME_SELECTION, CUSTOM_DATE_TIME_FORMAT,
|
||||
DEVICE_UUID, SKIPPED_VERSION, DEFAULT_TAB, PREF_DARK_THEME, PREF_LIGHT_THEME, PREF_POSTS_LAYOUT,
|
||||
PREF_PROFILE_POSTS_LAYOUT, PREF_TOPIC_POSTS_LAYOUT, PREF_HASHTAG_POSTS_LAYOUT, PREF_LOCATION_POSTS_LAYOUT,
|
||||
PREF_LIKED_POSTS_LAYOUT, PREF_TAGGED_POSTS_LAYOUT, PREF_SAVED_POSTS_LAYOUT, STORY_SORT, PREF_EMOJI_VARIANTS, PREF_REACTIONS})
|
||||
{APP_LANGUAGE, APP_THEME, APP_UA, BROWSER_UA, COOKIE, FOLDER_PATH, DATE_TIME_FORMAT, DATE_TIME_SELECTION,
|
||||
CUSTOM_DATE_TIME_FORMAT, DEVICE_UUID, SKIPPED_VERSION, DEFAULT_TAB, PREF_DARK_THEME, PREF_LIGHT_THEME,
|
||||
PREF_POSTS_LAYOUT, PREF_PROFILE_POSTS_LAYOUT, PREF_TOPIC_POSTS_LAYOUT, PREF_HASHTAG_POSTS_LAYOUT,
|
||||
PREF_LOCATION_POSTS_LAYOUT, PREF_LIKED_POSTS_LAYOUT, PREF_TAGGED_POSTS_LAYOUT, PREF_SAVED_POSTS_LAYOUT,
|
||||
STORY_SORT, PREF_EMOJI_VARIANTS, PREF_REACTIONS})
|
||||
public @interface StringSettings {}
|
||||
|
||||
@StringDef({DOWNLOAD_USER_FOLDER, FOLDER_SAVE_TO, AUTOPLAY_VIDEOS, SHOW_QUICK_ACCESS_DIALOG, MUTED_VIDEOS,
|
||||
@ -132,6 +137,6 @@ public final class SettingsHelper {
|
||||
CHECK_UPDATES, SWAP_DATE_TIME_FORMAT_ENABLED})
|
||||
public @interface BooleanSettings {}
|
||||
|
||||
@StringDef({PREV_INSTALL_VERSION})
|
||||
@StringDef({PREV_INSTALL_VERSION, BROWSER_UA_CODE, APP_UA_CODE})
|
||||
public @interface IntegerSettings {}
|
||||
}
|
@ -30,7 +30,7 @@ public final class UpdateChecker extends AsyncTask<Void, Void, Boolean> {
|
||||
HttpURLConnection conn =
|
||||
(HttpURLConnection) new URL("https://f-droid.org/api/v1/packages/me.austinhuang.instagrabber").openConnection();
|
||||
conn.setUseCaches(false);
|
||||
conn.setRequestProperty("User-Agent", Constants.A_USER_AGENT);
|
||||
conn.setRequestProperty("User-Agent", "https://Barinsta.AustinHuang.me / mailto:Barinsta@AustinHuang.me");
|
||||
conn.connect();
|
||||
|
||||
final int responseCode = conn.getResponseCode();
|
||||
|
@ -0,0 +1,77 @@
|
||||
package awais.instagrabber.utils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class UserAgentUtils {
|
||||
|
||||
/* GraphQL user agents (which are just standard browser UA's).
|
||||
* Go to https://www.whatismybrowser.com/guides/the-latest-user-agent/ to update it
|
||||
* Windows first (Assume win64 not wow64): Chrome, Firefox, Edge
|
||||
* Then macOS: Chrome, Firefox, Safari
|
||||
*/
|
||||
public static final String[] browsers = {
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36 Edg/87.0.664.75",
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36",
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 11.1; rv:84.0) Gecko/20100101 Firefox/84.0",
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.2 Safari/605.1.15"
|
||||
};
|
||||
// use APKpure, assume x86
|
||||
private static final String igVersion = "169.3.0.30.135";
|
||||
private static final String igVersionCode = "264009054";
|
||||
// https://github.com/dilame/instagram-private-api/blob/master/src/samples/devices.json
|
||||
// presumed constant, so no need to update
|
||||
public static final String[] devices = {
|
||||
"25/7.1.1; 440dpi; 1080x1920; Xiaomi; Mi Note 3; jason; qcom",
|
||||
"23/6.0.1; 480dpi; 1080x1920; Xiaomi; Redmi Note 3; kenzo; qcom",
|
||||
"23/6.0; 480dpi; 1080x1920; Xiaomi; Redmi Note 4; nikel; mt6797",
|
||||
"24/7.0; 480dpi; 1080x1920; Xiaomi/xiaomi; Redmi Note 4; mido; qcom",
|
||||
"23/6.0; 480dpi; 1080x1920; Xiaomi; Redmi Note 4X; nikel; mt6797",
|
||||
"27/8.1.0; 440dpi; 1080x2030; Xiaomi/xiaomi; Redmi Note 5; whyred; qcom",
|
||||
"23/6.0.1; 480dpi; 1080x1920; Xiaomi; Redmi 4; markw; qcom",
|
||||
"27/8.1.0; 440dpi; 1080x2030; Xiaomi/xiaomi; Redmi 5 Plus; vince; qcom",
|
||||
"25/7.1.2; 440dpi; 1080x2030; Xiaomi/xiaomi; Redmi 5 Plus; vince; qcom",
|
||||
"26/8.0.0; 480dpi; 1080x1920; Xiaomi; MI 5; gemini; qcom",
|
||||
"27/8.1.0; 480dpi; 1080x1920; Xiaomi/xiaomi; Mi A1; tissot_sprout; qcom",
|
||||
"26/8.0.0; 480dpi; 1080x1920; Xiaomi; MI 6; sagit; qcom",
|
||||
"25/7.1.1; 440dpi; 1080x1920; Xiaomi; MI MAX 2; oxygen; qcom",
|
||||
"24/7.0; 480dpi; 1080x1920; Xiaomi; MI 5s; capricorn; qcom",
|
||||
"26/8.0.0; 480dpi; 1080x1920; samsung; SM-A520F; a5y17lte; samsungexynos7880",
|
||||
"26/8.0.0; 480dpi; 1080x2076; samsung; SM-G950F; dreamlte; samsungexynos8895",
|
||||
"26/8.0.0; 640dpi; 1440x2768; samsung; SM-G950F; dreamlte; samsungexynos8895",
|
||||
"26/8.0.0; 420dpi; 1080x2094; samsung; SM-G955F; dream2lte; samsungexynos8895",
|
||||
"26/8.0.0; 560dpi; 1440x2792; samsung; SM-G955F; dream2lte; samsungexynos8895",
|
||||
"24/7.0; 480dpi; 1080x1920; samsung; SM-A510F; a5xelte; samsungexynos7580",
|
||||
"26/8.0.0; 480dpi; 1080x1920; samsung; SM-G930F; herolte; samsungexynos8890",
|
||||
"26/8.0.0; 480dpi; 1080x1920; samsung; SM-G935F; hero2lte; samsungexynos8890",
|
||||
"26/8.0.0; 420dpi; 1080x2094; samsung; SM-G965F; star2lte; samsungexynos9810",
|
||||
"26/8.0.0; 480dpi; 1080x2076; samsung; SM-A530F; jackpotlte; samsungexynos7885",
|
||||
"24/7.0; 640dpi; 1440x2560; samsung; SM-G925F; zerolte; samsungexynos7420",
|
||||
"26/8.0.0; 420dpi; 1080x1920; samsung; SM-A720F; a7y17lte; samsungexynos7880",
|
||||
"24/7.0; 640dpi; 1440x2560; samsung; SM-G920F; zeroflte; samsungexynos7420",
|
||||
"24/7.0; 420dpi; 1080x1920; samsung; SM-J730FM; j7y17lte; samsungexynos7870",
|
||||
"26/8.0.0; 480dpi; 1080x2076; samsung; SM-G960F; starlte; samsungexynos9810",
|
||||
"26/8.0.0; 420dpi; 1080x2094; samsung; SM-N950F; greatlte; samsungexynos8895",
|
||||
"26/8.0.0; 420dpi; 1080x2094; samsung; SM-A730F; jackpot2lte; samsungexynos7885",
|
||||
"26/8.0.0; 420dpi; 1080x2094; samsung; SM-A605FN; a6plte; qcom",
|
||||
"26/8.0.0; 480dpi; 1080x1920; HUAWEI/HONOR; STF-L09; HWSTF; hi3660",
|
||||
"27/8.1.0; 480dpi; 1080x2280; HUAWEI/HONOR; COL-L29; HWCOL; kirin970",
|
||||
"26/8.0.0; 480dpi; 1080x2032; HUAWEI/HONOR; LLD-L31; HWLLD-H; hi6250",
|
||||
"26/8.0.0; 480dpi; 1080x2150; HUAWEI; ANE-LX1; HWANE; hi6250",
|
||||
"26/8.0.0; 480dpi; 1080x2032; HUAWEI; FIG-LX1; HWFIG-H; hi6250",
|
||||
"27/8.1.0; 480dpi; 1080x2150; HUAWEI/HONOR; COL-L29; HWCOL; kirin970",
|
||||
"26/8.0.0; 480dpi; 1080x2038; HUAWEI/HONOR; BND-L21; HWBND-H; hi6250",
|
||||
"23/6.0.1; 420dpi; 1080x1920; LeMobile/LeEco; Le X527; le_s2_ww; qcom"
|
||||
};
|
||||
|
||||
@NonNull
|
||||
public static String generateBrowserUA(final int code) {
|
||||
return browsers[code - 1];
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String generateAppUA(final int code, final String lang) {
|
||||
return "Instagram " + igVersion + " Android (" + devices[code] + "; " + lang + "; " + igVersionCode + ")";
|
||||
}
|
||||
}
|
@ -79,7 +79,7 @@ public class DirectSettingsViewModel extends AndroidViewModel {
|
||||
throw new IllegalArgumentException("User is not logged in!");
|
||||
}
|
||||
directMessagesService = DirectMessagesService.getInstance(csrfToken, userId, deviceUuid);
|
||||
friendshipService = FriendshipService.getInstance();
|
||||
friendshipService = FriendshipService.getInstance(deviceUuid, csrfToken, userId);
|
||||
resources = getApplication().getResources();
|
||||
}
|
||||
|
||||
@ -264,7 +264,7 @@ public class DirectSettingsViewModel extends AndroidViewModel {
|
||||
|
||||
private LiveData<Resource<Object>> blockUser(final User user) {
|
||||
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
|
||||
friendshipService.block(userId, user.getPk(), csrfToken, new ServiceCallback<FriendshipChangeResponse>() {
|
||||
friendshipService.block(user.getPk(), new ServiceCallback<FriendshipChangeResponse>() {
|
||||
@Override
|
||||
public void onSuccess(final FriendshipChangeResponse result) {
|
||||
// refresh thread
|
||||
@ -281,7 +281,7 @@ public class DirectSettingsViewModel extends AndroidViewModel {
|
||||
|
||||
private LiveData<Resource<Object>> unblockUser(final User user) {
|
||||
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
|
||||
friendshipService.unblock(userId, user.getPk(), csrfToken, new ServiceCallback<FriendshipChangeResponse>() {
|
||||
friendshipService.unblock(user.getPk(), new ServiceCallback<FriendshipChangeResponse>() {
|
||||
@Override
|
||||
public void onSuccess(final FriendshipChangeResponse result) {
|
||||
// refresh thread
|
||||
@ -298,7 +298,7 @@ public class DirectSettingsViewModel extends AndroidViewModel {
|
||||
|
||||
private LiveData<Resource<Object>> restrictUser(final User user) {
|
||||
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
|
||||
friendshipService.toggleRestrict(user.getPk(), true, csrfToken, new ServiceCallback<FriendshipRestrictResponse>() {
|
||||
friendshipService.toggleRestrict(user.getPk(), true, new ServiceCallback<FriendshipRestrictResponse>() {
|
||||
@Override
|
||||
public void onSuccess(final FriendshipRestrictResponse result) {
|
||||
// refresh thread
|
||||
@ -315,7 +315,7 @@ public class DirectSettingsViewModel extends AndroidViewModel {
|
||||
|
||||
private LiveData<Resource<Object>> unRestrictUser(final User user) {
|
||||
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
|
||||
friendshipService.toggleRestrict(user.getPk(), false, csrfToken, new ServiceCallback<FriendshipRestrictResponse>() {
|
||||
friendshipService.toggleRestrict(user.getPk(), false, new ServiceCallback<FriendshipRestrictResponse>() {
|
||||
@Override
|
||||
public void onSuccess(final FriendshipRestrictResponse result) {
|
||||
// refresh thread
|
||||
|
@ -103,7 +103,7 @@ public class DirectThreadViewModel extends AndroidViewModel {
|
||||
throw new IllegalArgumentException("User is not logged in!");
|
||||
}
|
||||
service = DirectMessagesService.getInstance(csrfToken, userId, deviceUuid);
|
||||
mediaService = MediaService.getInstance();
|
||||
mediaService = MediaService.getInstance(deviceUuid, csrfToken, userId);
|
||||
contentResolver = application.getContentResolver();
|
||||
recordingsDir = DirectoryUtils.getOutputMediaDirectory(application, "Recordings");
|
||||
this.application = application;
|
||||
@ -467,7 +467,7 @@ public class DirectThreadViewModel extends AndroidViewModel {
|
||||
.setUploadId(uploadDmVideoOptions.getUploadId())
|
||||
.setSourceType("2")
|
||||
.setVideoOptions(new UploadFinishOptions.VideoOptions().setLength(duration / 1000f));
|
||||
final Call<String> uploadFinishRequest = mediaService.uploadFinish(userId, csrfToken, uploadFinishOptions);
|
||||
final Call<String> uploadFinishRequest = mediaService.uploadFinish(uploadFinishOptions);
|
||||
uploadFinishRequest.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
@ -584,7 +584,7 @@ public class DirectThreadViewModel extends AndroidViewModel {
|
||||
final UploadFinishOptions uploadFinishOptions = new UploadFinishOptions()
|
||||
.setUploadId(uploadDmVoiceOptions.getUploadId())
|
||||
.setSourceType("4");
|
||||
final Call<String> uploadFinishRequest = mediaService.uploadFinish(userId, csrfToken, uploadFinishOptions);
|
||||
final Call<String> uploadFinishRequest = mediaService.uploadFinish(uploadFinishOptions);
|
||||
uploadFinishRequest.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
|
@ -43,16 +43,16 @@ public class PostViewV2ViewModel extends ViewModel {
|
||||
private final MutableLiveData<List<Integer>> options = new MutableLiveData<>(new ArrayList<>());
|
||||
private final MediaService mediaService;
|
||||
private final long viewerId;
|
||||
private final String csrfToken;
|
||||
private final boolean isLoggedIn;
|
||||
|
||||
private Media media;
|
||||
|
||||
public PostViewV2ViewModel() {
|
||||
mediaService = MediaService.getInstance();
|
||||
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||
final String deviceUuid = settingsHelper.getString(Constants.DEVICE_UUID);
|
||||
final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
|
||||
viewerId = CookieUtils.getUserIdFromCookie(cookie);
|
||||
csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
|
||||
mediaService = MediaService.getInstance(deviceUuid, csrfToken, viewerId);
|
||||
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
|
||||
}
|
||||
|
||||
@ -142,14 +142,14 @@ public class PostViewV2ViewModel extends ViewModel {
|
||||
public LiveData<Resource<Object>> like() {
|
||||
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
|
||||
data.postValue(Resource.loading(null));
|
||||
mediaService.like(media.getPk(), viewerId, csrfToken, getLikeUnlikeCallback(data));
|
||||
mediaService.like(media.getPk(), getLikeUnlikeCallback(data));
|
||||
return data;
|
||||
}
|
||||
|
||||
public LiveData<Resource<Object>> unlike() {
|
||||
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
|
||||
data.postValue(Resource.loading(null));
|
||||
mediaService.unlike(media.getPk(), viewerId, csrfToken, getLikeUnlikeCallback(data));
|
||||
mediaService.unlike(media.getPk(), getLikeUnlikeCallback(data));
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -196,14 +196,14 @@ public class PostViewV2ViewModel extends ViewModel {
|
||||
public LiveData<Resource<Object>> save() {
|
||||
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
|
||||
data.postValue(Resource.loading(null));
|
||||
mediaService.save(media.getPk(), viewerId, csrfToken, getSaveUnsaveCallback(data));
|
||||
mediaService.save(media.getPk(), getSaveUnsaveCallback(data));
|
||||
return data;
|
||||
}
|
||||
|
||||
public LiveData<Resource<Object>> unsave() {
|
||||
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
|
||||
data.postValue(Resource.loading(null));
|
||||
mediaService.unsave(media.getPk(), viewerId, csrfToken, getSaveUnsaveCallback(data));
|
||||
mediaService.unsave(media.getPk(), getSaveUnsaveCallback(data));
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -232,7 +232,7 @@ public class PostViewV2ViewModel extends ViewModel {
|
||||
public LiveData<Resource<Object>> updateCaption(final String caption) {
|
||||
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
|
||||
data.postValue(Resource.loading(null));
|
||||
mediaService.editCaption(media.getPk(), viewerId, caption, csrfToken, new ServiceCallback<Boolean>() {
|
||||
mediaService.editCaption(media.getPk(), caption, new ServiceCallback<Boolean>() {
|
||||
@Override
|
||||
public void onSuccess(final Boolean result) {
|
||||
if (result) {
|
||||
|
@ -25,7 +25,7 @@ public class AddCookiesInterceptor implements Interceptor {
|
||||
}
|
||||
final String userAgentHeader = "User-Agent";
|
||||
if (request.header(userAgentHeader) == null) {
|
||||
builder.addHeader(userAgentHeader, hasCookie ? Constants.I_USER_AGENT : Constants.USER_AGENT);
|
||||
builder.addHeader(userAgentHeader, Utils.settingsHelper.getString(hasCookie ? Constants.APP_UA : Constants.BROWSER_UA));
|
||||
}
|
||||
final String languageHeader = "Accept-Language";
|
||||
if (request.header(languageHeader) == null) {
|
||||
|
@ -9,7 +9,6 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
import java.util.UUID;
|
||||
|
||||
import awais.instagrabber.repositories.FeedRepository;
|
||||
@ -47,16 +46,16 @@ public class FeedService extends BaseService {
|
||||
}
|
||||
|
||||
public void fetch(final String csrfToken,
|
||||
final String deviceUuid,
|
||||
final String cursor,
|
||||
final ServiceCallback<PostsFetchResponse> callback) {
|
||||
final Map<String, String> form = new HashMap<>();
|
||||
form.put("_uuid", UUID.randomUUID().toString());
|
||||
form.put("_uuid", deviceUuid);
|
||||
form.put("_csrftoken", csrfToken);
|
||||
form.put("phone_id", UUID.randomUUID().toString());
|
||||
form.put("device_id", UUID.randomUUID().toString());
|
||||
form.put("client_session_id", UUID.randomUUID().toString());
|
||||
form.put("is_prefetch", "0");
|
||||
form.put("timezone_offset", String.valueOf(TimeZone.getDefault().getRawOffset() / 1000));
|
||||
if (!TextUtils.isEmpty(cursor)) {
|
||||
form.put("max_id", cursor);
|
||||
form.put("reason", "pagination");
|
||||
@ -110,7 +109,7 @@ public class FeedService extends BaseService {
|
||||
final List<Media> allPosts = new ArrayList<>();
|
||||
final List<Media> items = feedFetchResponse.getItems();
|
||||
for (final Media media : items) {
|
||||
if (media.isInjected() || media.getMediaType() == null) continue;
|
||||
if (media == null || media.isInjected() || (media.getMediaType() == null && media.getEndOfFeedDemarcator() == null)) continue;
|
||||
if (needNewMaxId && media.getEndOfFeedDemarcator() != null) {
|
||||
final EndOfFeedDemarcator endOfFeedDemarcator = media.getEndOfFeedDemarcator();
|
||||
final EndOfFeedGroupSet groupSet = endOfFeedDemarcator.getGroupSet();
|
||||
@ -123,7 +122,7 @@ public class FeedService extends BaseService {
|
||||
nextMaxId = group.getNextMaxId();
|
||||
final List<Media> feedItems = group.getFeedItems();
|
||||
for (final Media feedItem : feedItems) {
|
||||
if (feedItem == null || feedItem.isInjected()) continue;
|
||||
if (feedItem == null || feedItem.isInjected() || feedItem.getMediaType() == null) continue;
|
||||
allPosts.add(feedItem);
|
||||
}
|
||||
}
|
||||
|
@ -13,14 +13,13 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.Objects;
|
||||
|
||||
import awais.instagrabber.models.FollowModel;
|
||||
import awais.instagrabber.repositories.FriendshipRepository;
|
||||
import awais.instagrabber.repositories.responses.FriendshipChangeResponse;
|
||||
import awais.instagrabber.repositories.responses.FriendshipListFetchResponse;
|
||||
import awais.instagrabber.repositories.responses.FriendshipRestrictResponse;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
import retrofit2.Call;
|
||||
@ -32,61 +31,74 @@ public class FriendshipService extends BaseService {
|
||||
private static final String TAG = "FriendshipService";
|
||||
|
||||
private final FriendshipRepository repository;
|
||||
private final String deviceUuid, csrfToken;
|
||||
private final long userId;
|
||||
|
||||
private static FriendshipService instance;
|
||||
|
||||
private FriendshipService() {
|
||||
private FriendshipService(final String deviceUuid,
|
||||
final String csrfToken,
|
||||
final long userId) {
|
||||
this.deviceUuid = deviceUuid;
|
||||
this.csrfToken = csrfToken;
|
||||
this.userId = userId;
|
||||
final Retrofit retrofit = getRetrofitBuilder()
|
||||
.baseUrl("https://i.instagram.com")
|
||||
.build();
|
||||
repository = retrofit.create(FriendshipRepository.class);
|
||||
}
|
||||
|
||||
public static FriendshipService getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new FriendshipService();
|
||||
public String getCsrfToken() {
|
||||
return csrfToken;
|
||||
}
|
||||
|
||||
public String getDeviceUuid() {
|
||||
return deviceUuid;
|
||||
}
|
||||
|
||||
public long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public static FriendshipService getInstance(final String deviceUuid, final String csrfToken, final long userId) {
|
||||
if (instance == null
|
||||
|| !Objects.equals(instance.getCsrfToken(), csrfToken)
|
||||
|| !Objects.equals(instance.getDeviceUuid(), deviceUuid)
|
||||
|| !Objects.equals(instance.getUserId(), userId)) {
|
||||
instance = new FriendshipService(deviceUuid, csrfToken, userId);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void follow(final long userId,
|
||||
final long targetUserId,
|
||||
final String csrfToken,
|
||||
public void follow(final long targetUserId,
|
||||
final ServiceCallback<FriendshipChangeResponse> callback) {
|
||||
change("create", userId, targetUserId, csrfToken, callback);
|
||||
change("create", targetUserId, callback);
|
||||
}
|
||||
|
||||
public void unfollow(final long userId,
|
||||
final long targetUserId,
|
||||
final String csrfToken,
|
||||
public void unfollow(final long targetUserId,
|
||||
final ServiceCallback<FriendshipChangeResponse> callback) {
|
||||
change("destroy", userId, targetUserId, csrfToken, callback);
|
||||
change("destroy", targetUserId, callback);
|
||||
}
|
||||
|
||||
public void block(final long userId,
|
||||
final long targetUserId,
|
||||
final String csrfToken,
|
||||
public void block(final long targetUserId,
|
||||
final ServiceCallback<FriendshipChangeResponse> callback) {
|
||||
change("block", userId, targetUserId, csrfToken, callback);
|
||||
change("block", targetUserId, callback);
|
||||
}
|
||||
|
||||
public void unblock(final long userId,
|
||||
final long targetUserId,
|
||||
final String csrfToken,
|
||||
public void unblock(final long targetUserId,
|
||||
final ServiceCallback<FriendshipChangeResponse> callback) {
|
||||
change("unblock", userId, targetUserId, csrfToken, callback);
|
||||
change("unblock", targetUserId, callback);
|
||||
}
|
||||
|
||||
public void toggleRestrict(final long targetUserId,
|
||||
final boolean restrict,
|
||||
final String csrfToken,
|
||||
final ServiceCallback<FriendshipRestrictResponse> callback) {
|
||||
final Map<String, String> form = new HashMap<>(3);
|
||||
form.put("_csrftoken", csrfToken);
|
||||
form.put("_uuid", UUID.randomUUID().toString());
|
||||
form.put("_uuid", deviceUuid);
|
||||
form.put("target_user_id", String.valueOf(targetUserId));
|
||||
final String action = restrict ? "restrict" : "unrestrict";
|
||||
final Call<FriendshipRestrictResponse> request = repository.toggleRestrict(Constants.I_USER_AGENT, action, form);
|
||||
final Call<FriendshipRestrictResponse> request = repository.toggleRestrict(action, form);
|
||||
request.enqueue(new Callback<FriendshipRestrictResponse>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<FriendshipRestrictResponse> call,
|
||||
@ -106,33 +118,27 @@ public class FriendshipService extends BaseService {
|
||||
});
|
||||
}
|
||||
|
||||
public void approve(final long userId,
|
||||
final long targetUserId,
|
||||
final String csrfToken,
|
||||
public void approve(final long targetUserId,
|
||||
final ServiceCallback<FriendshipChangeResponse> callback) {
|
||||
change("approve", userId, targetUserId, csrfToken, callback);
|
||||
change("approve", targetUserId, callback);
|
||||
}
|
||||
|
||||
public void ignore(final long userId,
|
||||
final long targetUserId,
|
||||
final String csrfToken,
|
||||
public void ignore(final long targetUserId,
|
||||
final ServiceCallback<FriendshipChangeResponse> callback) {
|
||||
change("ignore", userId, targetUserId, csrfToken, callback);
|
||||
change("ignore", targetUserId, callback);
|
||||
}
|
||||
|
||||
private void change(final String action,
|
||||
final long userId,
|
||||
final long targetUserId,
|
||||
final String csrfToken,
|
||||
final ServiceCallback<FriendshipChangeResponse> callback) {
|
||||
final Map<String, Object> form = new HashMap<>(5);
|
||||
form.put("_csrftoken", csrfToken);
|
||||
form.put("_uid", userId);
|
||||
form.put("_uuid", UUID.randomUUID().toString());
|
||||
form.put("_uuid", deviceUuid);
|
||||
form.put("radio_type", "wifi-none");
|
||||
form.put("user_id", targetUserId);
|
||||
final Map<String, String> signedForm = Utils.sign(form);
|
||||
final Call<FriendshipChangeResponse> request = repository.change(Constants.I_USER_AGENT, action, targetUserId, signedForm);
|
||||
final Call<FriendshipChangeResponse> request = repository.change(action, targetUserId, signedForm);
|
||||
request.enqueue(new Callback<FriendshipChangeResponse>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<FriendshipChangeResponse> call,
|
||||
@ -158,8 +164,8 @@ public class FriendshipService extends BaseService {
|
||||
final ServiceCallback<FriendshipListFetchResponse> callback) {
|
||||
final Map<String, String> queryMap = new HashMap<>();
|
||||
if (maxId != null) queryMap.put("max_id", maxId);
|
||||
final Call<String> request = repository.getList(Constants.I_USER_AGENT,
|
||||
targetUserId,
|
||||
final Call<String> request = repository.getList(
|
||||
targetUserId,
|
||||
follower ? "followers" : "following",
|
||||
queryMap);
|
||||
request.enqueue(new Callback<String>() {
|
||||
|
@ -14,6 +14,7 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
import awais.instagrabber.repositories.MediaRepository;
|
||||
@ -34,19 +35,41 @@ public class MediaService extends BaseService {
|
||||
private static final String TAG = "MediaService";
|
||||
|
||||
private final MediaRepository repository;
|
||||
private final String deviceUuid, csrfToken;
|
||||
private final long userId;
|
||||
|
||||
private static MediaService instance;
|
||||
|
||||
private MediaService() {
|
||||
private MediaService(final String deviceUuid,
|
||||
final String csrfToken,
|
||||
final long userId) {
|
||||
this.deviceUuid = deviceUuid;
|
||||
this.csrfToken = csrfToken;
|
||||
this.userId = userId;
|
||||
final Retrofit retrofit = getRetrofitBuilder()
|
||||
.baseUrl("https://i.instagram.com")
|
||||
.build();
|
||||
repository = retrofit.create(MediaRepository.class);
|
||||
}
|
||||
|
||||
public static MediaService getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new MediaService();
|
||||
public String getCsrfToken() {
|
||||
return csrfToken;
|
||||
}
|
||||
|
||||
public String getDeviceUuid() {
|
||||
return deviceUuid;
|
||||
}
|
||||
|
||||
public long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public static MediaService getInstance(final String deviceUuid, final String csrfToken, final long userId) {
|
||||
if (instance == null
|
||||
|| !Objects.equals(instance.getCsrfToken(), csrfToken)
|
||||
|| !Objects.equals(instance.getDeviceUuid(), deviceUuid)
|
||||
|| !Objects.equals(instance.getUserId(), userId)) {
|
||||
instance = new MediaService(deviceUuid, csrfToken, userId);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
@ -78,43 +101,33 @@ public class MediaService extends BaseService {
|
||||
}
|
||||
|
||||
public void like(final String mediaId,
|
||||
final long userId,
|
||||
final String csrfToken,
|
||||
final ServiceCallback<Boolean> callback) {
|
||||
action(mediaId, userId, "like", csrfToken, callback);
|
||||
action(mediaId, "like", callback);
|
||||
}
|
||||
|
||||
public void unlike(final String mediaId,
|
||||
final long userId,
|
||||
final String csrfToken,
|
||||
final ServiceCallback<Boolean> callback) {
|
||||
action(mediaId, userId, "unlike", csrfToken, callback);
|
||||
action(mediaId, "unlike", callback);
|
||||
}
|
||||
|
||||
public void save(final String mediaId,
|
||||
final long userId,
|
||||
final String csrfToken,
|
||||
final ServiceCallback<Boolean> callback) {
|
||||
action(mediaId, userId, "save", csrfToken, callback);
|
||||
action(mediaId, "save", callback);
|
||||
}
|
||||
|
||||
public void unsave(final String mediaId,
|
||||
final long userId,
|
||||
final String csrfToken,
|
||||
final ServiceCallback<Boolean> callback) {
|
||||
action(mediaId, userId, "unsave", csrfToken, callback);
|
||||
action(mediaId, "unsave", callback);
|
||||
}
|
||||
|
||||
private void action(final String mediaId,
|
||||
final long userId,
|
||||
final String action,
|
||||
final String csrfToken,
|
||||
final ServiceCallback<Boolean> callback) {
|
||||
final Map<String, Object> form = new HashMap<>(4);
|
||||
form.put("media_id", mediaId);
|
||||
form.put("_csrftoken", csrfToken);
|
||||
form.put("_uid", userId);
|
||||
form.put("_uuid", UUID.randomUUID().toString());
|
||||
form.put("_uuid", deviceUuid);
|
||||
// form.put("radio_type", "wifi-none");
|
||||
final Map<String, String> signedForm = Utils.sign(form);
|
||||
final Call<String> request = repository.action(action, mediaId, signedForm);
|
||||
@ -149,9 +162,7 @@ public class MediaService extends BaseService {
|
||||
|
||||
public void comment(@NonNull final String mediaId,
|
||||
@NonNull final String comment,
|
||||
final long userId,
|
||||
final String replyToCommentId,
|
||||
final String csrfToken,
|
||||
@NonNull final ServiceCallback<Boolean> callback) {
|
||||
final String module = "self_comments_v2";
|
||||
final Map<String, Object> form = new HashMap<>();
|
||||
@ -159,7 +170,7 @@ public class MediaService extends BaseService {
|
||||
form.put("idempotence_token", UUID.randomUUID().toString());
|
||||
form.put("_csrftoken", csrfToken);
|
||||
form.put("_uid", userId);
|
||||
form.put("_uuid", UUID.randomUUID().toString());
|
||||
form.put("_uuid", deviceUuid);
|
||||
form.put("comment_text", comment);
|
||||
form.put("containermodule", module);
|
||||
if (!TextUtils.isEmpty(replyToCommentId)) {
|
||||
@ -194,23 +205,19 @@ public class MediaService extends BaseService {
|
||||
}
|
||||
|
||||
public void deleteComment(final String mediaId,
|
||||
final long userId,
|
||||
final String commentId,
|
||||
final String csrfToken,
|
||||
@NonNull final ServiceCallback<Boolean> callback) {
|
||||
deleteComments(mediaId, userId, Collections.singletonList(commentId), csrfToken, callback);
|
||||
deleteComments(mediaId, Collections.singletonList(commentId), callback);
|
||||
}
|
||||
|
||||
public void deleteComments(final String mediaId,
|
||||
final long userId,
|
||||
final List<String> commentIds,
|
||||
final String csrfToken,
|
||||
@NonNull final ServiceCallback<Boolean> callback) {
|
||||
final Map<String, Object> form = new HashMap<>();
|
||||
form.put("comment_ids_to_delete", TextUtils.join(",", commentIds));
|
||||
form.put("_csrftoken", csrfToken);
|
||||
form.put("_uid", userId);
|
||||
form.put("_uuid", UUID.randomUUID().toString());
|
||||
form.put("_uuid", deviceUuid);
|
||||
final Map<String, String> signedForm = Utils.sign(form);
|
||||
final Call<String> bulkDeleteRequest = repository.commentsBulkDelete(mediaId, signedForm);
|
||||
bulkDeleteRequest.enqueue(new Callback<String>() {
|
||||
@ -241,12 +248,11 @@ public class MediaService extends BaseService {
|
||||
}
|
||||
|
||||
public void commentLike(@NonNull final String commentId,
|
||||
@NonNull final String csrfToken,
|
||||
@NonNull final ServiceCallback<Boolean> callback) {
|
||||
final Map<String, Object> form = new HashMap<>();
|
||||
form.put("_csrftoken", csrfToken);
|
||||
// form.put("_uid", userId);
|
||||
// form.put("_uuid", UUID.randomUUID().toString());
|
||||
// form.put("_uuid", deviceUuid);
|
||||
final Map<String, String> signedForm = Utils.sign(form);
|
||||
final Call<String> commentLikeRequest = repository.commentLike(commentId, signedForm);
|
||||
commentLikeRequest.enqueue(new Callback<String>() {
|
||||
@ -277,12 +283,11 @@ public class MediaService extends BaseService {
|
||||
}
|
||||
|
||||
public void commentUnlike(final String commentId,
|
||||
@NonNull final String csrfToken,
|
||||
@NonNull final ServiceCallback<Boolean> callback) {
|
||||
final Map<String, Object> form = new HashMap<>();
|
||||
form.put("_csrftoken", csrfToken);
|
||||
// form.put("_uid", userId);
|
||||
// form.put("_uuid", UUID.randomUUID().toString());
|
||||
// form.put("_uuid", deviceUuid);
|
||||
final Map<String, String> signedForm = Utils.sign(form);
|
||||
final Call<String> commentUnlikeRequest = repository.commentUnlike(commentId, signedForm);
|
||||
commentUnlikeRequest.enqueue(new Callback<String>() {
|
||||
@ -313,14 +318,12 @@ public class MediaService extends BaseService {
|
||||
}
|
||||
|
||||
public void editCaption(final String postId,
|
||||
final long userId,
|
||||
final String newCaption,
|
||||
@NonNull final String csrfToken,
|
||||
@NonNull final ServiceCallback<Boolean> callback) {
|
||||
final Map<String, Object> form = new HashMap<>();
|
||||
form.put("_csrftoken", csrfToken);
|
||||
form.put("_uid", userId);
|
||||
form.put("_uuid", UUID.randomUUID().toString());
|
||||
form.put("_uuid", deviceUuid);
|
||||
form.put("igtv_feed_preview", "false");
|
||||
form.put("media_id", postId);
|
||||
form.put("caption_text", newCaption);
|
||||
@ -411,9 +414,7 @@ public class MediaService extends BaseService {
|
||||
});
|
||||
}
|
||||
|
||||
public Call<String> uploadFinish(final long userId,
|
||||
@NonNull final String csrfToken,
|
||||
@NonNull final UploadFinishOptions options) {
|
||||
public Call<String> uploadFinish(@NonNull final UploadFinishOptions options) {
|
||||
if (options.getVideoOptions() != null) {
|
||||
final UploadFinishOptions.VideoOptions videoOptions = options.getVideoOptions();
|
||||
if (videoOptions.getClips() == null) {
|
||||
@ -430,7 +431,7 @@ public class MediaService extends BaseService {
|
||||
.put("_csrftoken", csrfToken)
|
||||
.put("source_type", options.getSourceType())
|
||||
.put("_uid", String.valueOf(userId))
|
||||
.put("_uuid", UUID.randomUUID().toString())
|
||||
.put("_uuid", deviceUuid)
|
||||
.put("upload_id", options.getUploadId());
|
||||
if (options.getVideoOptions() != null) {
|
||||
formBuilder.putAll(options.getVideoOptions().getMap());
|
||||
|
@ -21,6 +21,7 @@ import awais.instagrabber.models.NotificationModel;
|
||||
import awais.instagrabber.models.enums.NotificationType;
|
||||
import awais.instagrabber.repositories.NewsRepository;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
@ -32,6 +33,7 @@ public class NewsService extends BaseService {
|
||||
private final NewsRepository repository;
|
||||
|
||||
private static NewsService instance;
|
||||
private static String browserUa, appUa;
|
||||
|
||||
private NewsService() {
|
||||
final Retrofit retrofit = getRetrofitBuilder()
|
||||
@ -44,13 +46,15 @@ public class NewsService extends BaseService {
|
||||
if (instance == null) {
|
||||
instance = new NewsService();
|
||||
}
|
||||
appUa = Utils.settingsHelper.getString(Constants.APP_UA);
|
||||
browserUa = Utils.settingsHelper.getString(Constants.BROWSER_UA);
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void fetchAppInbox(final boolean markAsSeen,
|
||||
final ServiceCallback<List<NotificationModel>> callback) {
|
||||
final List<NotificationModel> result = new ArrayList<>();
|
||||
final Call<String> request = repository.appInbox(markAsSeen);
|
||||
final Call<String> request = repository.appInbox(appUa, markAsSeen);
|
||||
request.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
@ -90,7 +94,7 @@ public class NewsService extends BaseService {
|
||||
|
||||
public void fetchWebInbox(final boolean markAsSeen,
|
||||
final ServiceCallback<List<NotificationModel>> callback) {
|
||||
final Call<String> request = repository.webInbox();
|
||||
final Call<String> request = repository.webInbox(browserUa);
|
||||
request.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
@ -181,7 +185,7 @@ public class NewsService extends BaseService {
|
||||
data.getLong("profile_id"),
|
||||
data.getString("profile_name"),
|
||||
data.getString("profile_image"),
|
||||
!data.isNull("media") ? data.getJSONArray("media").getJSONObject(0).getLong("id") : 0,
|
||||
!data.isNull("media") ? Long.valueOf(data.getJSONArray("media").getJSONObject(0).getString("id").split("_")[0]) : 0,
|
||||
!data.isNull("media") ? data.getJSONArray("media").getJSONObject(0).getString("image") : null,
|
||||
notificationType);
|
||||
}
|
||||
@ -206,7 +210,7 @@ public class NewsService extends BaseService {
|
||||
form.put("device_id", UUID.randomUUID().toString());
|
||||
form.put("module", "discover_people");
|
||||
form.put("paginate", "false");
|
||||
final Call<String> request = repository.getAyml(form);
|
||||
final Call<String> request = repository.getAyml(appUa, form);
|
||||
request.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
|
@ -325,7 +325,7 @@ public class StoriesService extends BaseService {
|
||||
public void getUserStory(final StoryViewerOptions options,
|
||||
final ServiceCallback<List<StoryModel>> callback) {
|
||||
final String url = buildUrl(options);
|
||||
final Call<String> userStoryCall = repository.getUserStory(Constants.I_USER_AGENT, url);
|
||||
final Call<String> userStoryCall = repository.getUserStory(url);
|
||||
final boolean isLoc = options.getType() == StoryViewerOptions.Type.LOCATION;
|
||||
final boolean isHashtag = options.getType() == StoryViewerOptions.Type.HASHTAG;
|
||||
final boolean isHighlight = options.getType() == StoryViewerOptions.Type.HIGHLIGHT;
|
||||
@ -400,7 +400,7 @@ public class StoriesService extends BaseService {
|
||||
form.put(arg1, arg2);
|
||||
final Map<String, String> signedForm = Utils.sign(form);
|
||||
final Call<StoryStickerResponse> request =
|
||||
repository.respondToSticker(Constants.I_USER_AGENT, storyId, stickerId, action, signedForm);
|
||||
repository.respondToSticker(storyId, stickerId, action, signedForm);
|
||||
request.enqueue(new Callback<StoryStickerResponse>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<StoryStickerResponse> call,
|
||||
|
@ -12,7 +12,6 @@ import org.json.JSONObject;
|
||||
import awais.instagrabber.repositories.TagsRepository;
|
||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||
import awais.instagrabber.repositories.responses.TagFeedResponse;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
@ -46,12 +45,11 @@ public class TagsService extends BaseService {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void follow(@NonNull final String tag,
|
||||
public void follow(@NonNull final String ua,
|
||||
@NonNull final String tag,
|
||||
@NonNull final String csrfToken,
|
||||
final ServiceCallback<Boolean> callback) {
|
||||
final Call<String> request = webRepository.follow(Constants.USER_AGENT,
|
||||
csrfToken,
|
||||
tag);
|
||||
final Call<String> request = webRepository.follow(ua, csrfToken, tag);
|
||||
request.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
@ -77,12 +75,11 @@ public class TagsService extends BaseService {
|
||||
});
|
||||
}
|
||||
|
||||
public void unfollow(@NonNull final String tag,
|
||||
public void unfollow(@NonNull final String ua,
|
||||
@NonNull final String tag,
|
||||
@NonNull final String csrfToken,
|
||||
final ServiceCallback<Boolean> callback) {
|
||||
final Call<String> request = webRepository.unfollow(Constants.USER_AGENT,
|
||||
csrfToken,
|
||||
tag);
|
||||
final Call<String> request = webRepository.unfollow(ua, csrfToken, tag);
|
||||
request.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
|
@ -72,6 +72,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="0dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:layout_margin="8dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/mute_mentions"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/title_edit_input_layout" />
|
||||
@ -98,6 +99,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="0dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:layout_margin="8dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/leave"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/mute_messages" />
|
||||
|
Loading…
Reference in New Issue
Block a user