diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f3398ac6..01838249 100755
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -132,14 +132,14 @@
-
+
+
+
-
-
+
+
+
+
-
+
+
+
-
-
+
+
+
+
-
+
+
+
-
-
+
+
+
+
-
+
+
+
-
-
+
+
+
+
-
+
+
+
-
-
+
+
+
+
new ProfileAction().execute("follow"))
.show();
- }
- else new ProfileAction().execute("follow");
+ } else new ProfileAction().execute("follow");
} else if (v == mainActivity.mainBinding.profileView.btnRestrict && isLoggedIn) {
new ProfileAction().execute("restrict");
} else if (v == mainActivity.mainBinding.profileView.btnSaved && !isSelf) {
@@ -1431,17 +1435,17 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
} else if (v == mainActivity.mainBinding.profileView.btnFollowTag) {
new ProfileAction().execute("followtag");
} else if (v == mainActivity.mainBinding.profileView.btnTagged || v == mainActivity.mainBinding.profileView.btnRestrict) {
- mainActivity.startActivity(new Intent(mainActivity, SavedViewer.class)
+ mainActivity.startActivity(new Intent(mainActivity, SavedViewerFragment.class)
.putExtra(Constants.EXTRAS_INDEX, "%" + mainActivity.profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + mainActivity.profileModel.getUsername())
);
} else if (v == mainActivity.mainBinding.profileView.btnSaved) {
- mainActivity.startActivity(new Intent(mainActivity, SavedViewer.class)
+ mainActivity.startActivity(new Intent(mainActivity, SavedViewerFragment.class)
.putExtra(Constants.EXTRAS_INDEX, "$" + mainActivity.profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + mainActivity.profileModel.getUsername())
);
} else if (v == mainActivity.mainBinding.profileView.btnLiked) {
- mainActivity.startActivity(new Intent(mainActivity, SavedViewer.class)
+ mainActivity.startActivity(new Intent(mainActivity, SavedViewerFragment.class)
.putExtra(Constants.EXTRAS_INDEX, "^" + mainActivity.profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + mainActivity.profileModel.getUsername())
);
diff --git a/app/src/main/java/awais/instagrabber/activities/MainActivity.java b/app/src/main/java/awais/instagrabber/activities/MainActivity.java
index 003feff8..673beb2c 100644
--- a/app/src/main/java/awais/instagrabber/activities/MainActivity.java
+++ b/app/src/main/java/awais/instagrabber/activities/MainActivity.java
@@ -45,7 +45,8 @@ public class MainActivity extends BaseLanguageActivity {
R.id.morePreferencesFragment,
R.id.settingsPreferencesFragment,
R.id.hashTagFragment,
- R.id.locationFragment);
+ R.id.locationFragment,
+ R.id.savedViewerFragment);
private ActivityMainBinding binding;
private LiveData currentNavControllerLiveData;
diff --git a/app/src/main/java/awais/instagrabber/activities/PostViewer.java b/app/src/main/java/awais/instagrabber/activities/PostViewer.java
index 34c2320e..0b63fa28 100755
--- a/app/src/main/java/awais/instagrabber/activities/PostViewer.java
+++ b/app/src/main/java/awais/instagrabber/activities/PostViewer.java
@@ -313,10 +313,11 @@ public final class PostViewer extends BaseLanguageActivity {
final List extends BasePostModel> itemGetterItems;
final boolean isSwipeable;
- if (postItemType == PostItemType.SAVED && SavedViewer.itemGetter != null) {
- itemGetterItems = SavedViewer.itemGetter.get(postItemType);
- isSwipeable = !(itemGetterItems.size() < 1 || postItemType == PostItemType.SAVED && isFromShare);
- } else if (postItemType != null && MainActivityBackup.itemGetter != null) {
+ // if (postItemType == PostItemType.SAVED && SavedViewerFragment.itemGetter != null) {
+ // itemGetterItems = SavedViewerFragment.itemGetter.get(postItemType);
+ // isSwipeable = !(itemGetterItems.size() < 1 || postItemType == PostItemType.SAVED && isFromShare);
+ // } else
+ if (postItemType != null && MainActivityBackup.itemGetter != null) {
itemGetterItems = MainActivityBackup.itemGetter.get(postItemType);
isSwipeable = !(itemGetterItems.size() < 1 || postItemType == PostItemType.MAIN && isFromShare);
} else {
diff --git a/app/src/main/java/awais/instagrabber/activities/ProfileViewer.java b/app/src/main/java/awais/instagrabber/activities/ProfileViewer.java
index 5dd49e18..d781d637 100755
--- a/app/src/main/java/awais/instagrabber/activities/ProfileViewer.java
+++ b/app/src/main/java/awais/instagrabber/activities/ProfileViewer.java
@@ -52,6 +52,7 @@ import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager;
import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration;
import awais.instagrabber.customviews.helpers.RecyclerLazyLoader;
import awais.instagrabber.databinding.ActivityProfileBinding;
+import awais.instagrabber.fragments.SavedViewerFragment;
import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.BasePostModel;
@@ -62,6 +63,7 @@ import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.DownloadMethod;
+import awais.instagrabber.models.enums.PostItemType;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.DataBox;
import awais.instagrabber.utils.Utils;
@@ -109,8 +111,8 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
if (autoloadPosts && hasNextPage)
currentlyExecuting = new PostsFetcher(
profileModel != null ? profileModel.getId()
- : (hashtagModel != null ? ("#" + hashtagModel.getName()) : locationModel.getId()),
- false,
+ : (hashtagModel != null ? (hashtagModel.getName()) : locationModel.getId()),
+ profileModel != null ? PostItemType.MAIN : (hashtagModel != null ? PostItemType.HASHTAG : PostItemType.LOCATION),
endCursor,
this)
.setUsername((isLocation || isHashtag) ? null : profileModel.getUsername())
@@ -247,7 +249,9 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
: (hashtagModel != null
? ("#" + hashtagModel.getName())
: locationModel.getId()),
- isHashtag,
+ profileModel != null
+ ? PostItemType.MAIN
+ : (hashtagModel != null ? PostItemType.HASHTAG : PostItemType.LOCATION),
endCursor, postsFetchListener)
.setUsername((isHashtag || isLocation) ? null : profileModel.getUsername())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
@@ -371,7 +375,7 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
return;
}
- currentlyExecuting = new PostsFetcher(userQuery, postsFetchListener)
+ currentlyExecuting = new PostsFetcher(userQuery, PostItemType.HASHTAG, null, postsFetchListener)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
profileBinding.profileView.btnFollowTag.setVisibility(View.VISIBLE);
@@ -383,7 +387,7 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
profileBinding.profileView.mainHashtagImage.setStoriesBorder();
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- if (hashtagModel.getFollowing() == true) {
+ if (hashtagModel.getFollowing()) {
profileBinding.profileView.btnFollowTag.setText(R.string.unfollow);
profileBinding.profileView.btnFollowTag.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
ProfileViewer.this, R.color.btn_purple_background)));
@@ -614,8 +618,9 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
} else {
profileBinding.profileView.swipeRefreshLayout.setRefreshing(true);
profileBinding.profileView.mainPosts.setVisibility(View.VISIBLE);
- currentlyExecuting = new PostsFetcher(profileId, postsFetchListener).setUsername(profileModel.getUsername())
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ currentlyExecuting = new PostsFetcher(profileId, PostItemType.MAIN, null, postsFetchListener)
+ .setUsername(profileModel.getUsername())
+ .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
} else {
profileBinding.profileView.mainFollowers.setClickable(false);
@@ -720,7 +725,7 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
} else {
profileBinding.profileView.swipeRefreshLayout.setRefreshing(true);
profileBinding.profileView.mainPosts.setVisibility(View.VISIBLE);
- currentlyExecuting = new PostsFetcher(profileId, postsFetchListener)
+ currentlyExecuting = new PostsFetcher(profileId, PostItemType.LOCATION, null, postsFetchListener)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
@@ -870,17 +875,17 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
} else if (v == profileBinding.profileView.btnFollowTag) {
new ProfileAction().execute("followtag");
} else if (v == profileBinding.profileView.btnTagged || (v == profileBinding.profileView.btnRestrict && !isLoggedIn)) {
- startActivity(new Intent(ProfileViewer.this, SavedViewer.class)
+ startActivity(new Intent(ProfileViewer.this, SavedViewerFragment.class)
.putExtra(Constants.EXTRAS_INDEX, "%" + profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername())
);
} else if (v == profileBinding.profileView.btnSaved) {
- startActivity(new Intent(ProfileViewer.this, SavedViewer.class)
+ startActivity(new Intent(ProfileViewer.this, SavedViewerFragment.class)
.putExtra(Constants.EXTRAS_INDEX, "$" + profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername())
);
} else if (v == profileBinding.profileView.btnLiked) {
- startActivity(new Intent(ProfileViewer.this, SavedViewer.class)
+ startActivity(new Intent(ProfileViewer.this, SavedViewerFragment.class)
.putExtra(Constants.EXTRAS_INDEX, "^" + profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername())
);
diff --git a/app/src/main/java/awais/instagrabber/activities/SavedViewer.java b/app/src/main/java/awais/instagrabber/activities/SavedViewer.java
deleted file mode 100755
index f2b8a214..00000000
--- a/app/src/main/java/awais/instagrabber/activities/SavedViewer.java
+++ /dev/null
@@ -1,288 +0,0 @@
-package awais.instagrabber.activities;
-
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.ActionMode;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-
-import androidx.activity.OnBackPressedCallback;
-import androidx.activity.OnBackPressedDispatcher;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.lifecycle.ViewModelProvider;
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import awais.instagrabber.BuildConfig;
-import awais.instagrabber.R;
-import awais.instagrabber.adapters.PostsAdapter;
-import awais.instagrabber.asyncs.PostsFetcher;
-import awais.instagrabber.asyncs.i.iLikedFetcher;
-import awais.instagrabber.customviews.PrimaryActionModeCallback;
-import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager;
-import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration;
-import awais.instagrabber.customviews.helpers.RecyclerLazyLoader;
-import awais.instagrabber.databinding.ActivitySavedBinding;
-import awais.instagrabber.fragments.main.viewmodels.PostsViewModel;
-import awais.instagrabber.interfaces.FetchListener;
-import awais.instagrabber.interfaces.ItemGetter;
-import awais.instagrabber.models.PostModel;
-import awais.instagrabber.models.enums.DownloadMethod;
-import awais.instagrabber.models.enums.PostItemType;
-import awais.instagrabber.utils.Constants;
-import awais.instagrabber.utils.Utils;
-import awaisomereport.LogCollector;
-
-import static awais.instagrabber.utils.Constants.AUTOLOAD_POSTS;
-import static awais.instagrabber.utils.Utils.logCollector;
-
-public final class SavedViewer extends BaseLanguageActivity implements SwipeRefreshLayout.OnRefreshListener {
- private static AsyncTask, ?, ?> currentlyExecuting;
- public static ItemGetter itemGetter;
- private PostsAdapter postsAdapter;
- private boolean hasNextPage, autoloadPosts;
- //private CommentModel commentModel;
- private ActivitySavedBinding savedBinding;
- private String action, username, endCursor;
- private RecyclerLazyLoader lazyLoader;
- private Resources resources;
- private ArrayList selectedItems = new ArrayList<>();
- private ActionMode actionMode;
- private PostsViewModel postsViewModel;
-
- private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
- private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(true) {
- @Override
- public void handleOnBackPressed() {
- if (postsAdapter == null) {
- remove();
- return;
- }
- postsAdapter.clearSelection();
- remove();
- }
- };
- private final PrimaryActionModeCallback multiSelectAction = new PrimaryActionModeCallback(
- R.menu.multi_select_download_menu,
- new PrimaryActionModeCallback.CallbacksHelper() {
- @Override
- public void onDestroy(final ActionMode mode) {
- onBackPressedCallback.handleOnBackPressed();
- }
-
- @Override
- public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
- if (item.getItemId() == R.id.action_download) {
- if (postsAdapter == null || username == null) {
- return false;
- }
- Utils.batchDownload(SavedViewer.this,
- username,
- DownloadMethod.DOWNLOAD_MAIN,
- postsAdapter.getSelectedModels());
- checkAndResetAction();
- return true;
- }
- return false;
- }
- });
- private final FetchListener postsFetchListener = new FetchListener() {
- @Override
- public void onResult(final PostModel[] result) {
- if (result != null) {
- final List current = postsViewModel.getList().getValue();
- final List resultList = Arrays.asList(result);
- if (current == null) {
- postsViewModel.getList().postValue(resultList);
- } else {
- final List currentCopy = new ArrayList<>(current);
- currentCopy.addAll(resultList);
- postsViewModel.getList().postValue(currentCopy);
- }
- savedBinding.mainPosts.post(() -> {
- savedBinding.mainPosts.setNestedScrollingEnabled(true);
- savedBinding.mainPosts.setVisibility(View.VISIBLE);
- });
-
- final PostModel model = result.length > 0 ? result[result.length - 1] : null;
- if (model != null) {
- endCursor = model.getEndCursor();
-
- hasNextPage = model.hasNextPage();
- if (autoloadPosts && hasNextPage && action.charAt(0) == '^')
- currentlyExecuting = new iLikedFetcher(endCursor, postsFetchListener)
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- else if (autoloadPosts && hasNextPage)
- currentlyExecuting = new PostsFetcher(action, false, endCursor, this)
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- else {
- savedBinding.swipeRefreshLayout.setRefreshing(false);
- }
- model.setPageCursor(false, null);
- }
- }
- savedBinding.swipeRefreshLayout.setRefreshing(false);
- // if (oldSize == 0) {
- // Toast.makeText(getApplicationContext(), R.string.empty_list, Toast.LENGTH_SHORT).show();
- // finish();
- // }
- }
- };
-
- @Override
- protected void onCreate(@Nullable final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- savedBinding = ActivitySavedBinding.inflate(getLayoutInflater());
- setContentView(savedBinding.getRoot());
- savedBinding.swipeRefreshLayout.setOnRefreshListener(this);
- autoloadPosts = Utils.settingsHelper.getBoolean(AUTOLOAD_POSTS);
- savedBinding.mainPosts.setNestedScrollingEnabled(false);
- final GridAutofitLayoutManager layoutManager = new GridAutofitLayoutManager(this, Utils.convertDpToPx(110));
- savedBinding.mainPosts.setLayoutManager(layoutManager);
- savedBinding.mainPosts.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(4)));
-
- final Intent intent = getIntent();
- if (intent == null || !intent.hasExtra(Constants.EXTRAS_INDEX)
- || Utils.isEmpty((action = intent.getStringExtra(Constants.EXTRAS_INDEX)))
- || !intent.hasExtra(Constants.EXTRAS_USER)
- || Utils.isEmpty((username = intent.getStringExtra(Constants.EXTRAS_USER)))) {
- Utils.errorFinish(this);
- return;
- }
-
- postsViewModel = new ViewModelProvider(this).get(PostsViewModel.class);
- postsAdapter = new PostsAdapter((postModel, position) -> {
- if (postsAdapter.isSelecting()) {
- if (actionMode == null) return;
- final String title = getString(R.string.number_selected, postsAdapter.getSelectedModels().size());
- actionMode.setTitle(title);
- return;
- }
- if (checkAndResetAction()) return;
- startActivity(new Intent(this, PostViewer.class)
- .putExtra(Constants.EXTRAS_INDEX, position)
- .putExtra(Constants.EXTRAS_POST, postModel)
- .putExtra(Constants.EXTRAS_USER, username)
- .putExtra(Constants.EXTRAS_TYPE, PostItemType.SAVED));
-
- }, (model, position) -> {
- if (!postsAdapter.isSelecting()) {
- checkAndResetAction();
- return true;
- }
- final OnBackPressedDispatcher onBackPressedDispatcher = getOnBackPressedDispatcher();
- if (onBackPressedDispatcher.hasEnabledCallbacks()) return true;
- actionMode = startActionMode(multiSelectAction);
- final String title = getString(R.string.number_selected, 1);
- actionMode.setTitle(title);
- onBackPressedDispatcher.addCallback(onBackPressedCallback);
- return true;
- });
- savedBinding.mainPosts.setAdapter(postsAdapter);
- postsViewModel.getList().observe(this, postsAdapter::submitList);
- savedBinding.swipeRefreshLayout.setRefreshing(true);
- setSupportActionBar(savedBinding.toolbar.toolbar);
- savedBinding.toolbar.toolbar.setTitle((action.charAt(0) == '$' ? R.string.saved :
- (action.charAt(0) == '%' ? R.string.tagged : R.string.liked)));
- savedBinding.toolbar.toolbar.setSubtitle(username);
-
- lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
- if (!autoloadPosts && hasNextPage) {
- savedBinding.swipeRefreshLayout.setRefreshing(true);
- stopCurrentExecutor();
-
- currentlyExecuting = action.charAt(0) == '^'
- ? new iLikedFetcher(endCursor, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
- : new PostsFetcher(action, false, endCursor, postsFetchListener)
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- endCursor = null;
- }
- });
- savedBinding.mainPosts.addOnScrollListener(lazyLoader);
-
- itemGetter = itemGetType -> {
- if (itemGetType == PostItemType.SAVED)
- return postsViewModel.getList().getValue();
- return null;
- };
-
- if (action.charAt(0) == '^')
- new iLikedFetcher(postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- else
- new PostsFetcher(action, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- @Override
- public boolean onCreateOptionsMenu(final Menu menu) {
- getMenuInflater().inflate(R.menu.saved, menu);
-
- final MenuItem downloadAction = menu.findItem(R.id.downloadAction);
- downloadAction.setVisible(false);
-
- menu.findItem(R.id.favouriteAction).setVisible(false);
-
- downloadAction.setOnMenuItemClickListener(item -> {
- if (selectedItems.size() > 0) {
- Utils.batchDownload(this, null, DownloadMethod.DOWNLOAD_SAVED, selectedItems);
- }
- return true;
- });
- return true;
- }
-
- @Override
- public void onRefresh() {
- if (lazyLoader != null) lazyLoader.resetState();
- stopCurrentExecutor();
- postsViewModel.getList().postValue(Collections.emptyList());
- selectedItems.clear();
- if (postsAdapter != null) {
- // postsAdapter.isSelecting = false;
- postsAdapter.notifyDataSetChanged();
- }
- savedBinding.swipeRefreshLayout.setRefreshing(true);
- if (action.charAt(0) == '^')
- new iLikedFetcher(postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- else
- new PostsFetcher(action, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- @Override
- public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- if (requestCode == 8020 && grantResults[0] == PackageManager.PERMISSION_GRANTED && selectedItems.size() > 0)
- Utils.batchDownload(this, null, DownloadMethod.DOWNLOAD_SAVED, selectedItems);
- }
-
- public static void stopCurrentExecutor() {
- if (currentlyExecuting != null) {
- try {
- currentlyExecuting.cancel(true);
- } catch (final Exception e) {
- if (logCollector != null)
- logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor");
- if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
- }
- }
- }
-
- private boolean checkAndResetAction() {
- final OnBackPressedDispatcher onBackPressedDispatcher = getOnBackPressedDispatcher();
- if (!onBackPressedDispatcher.hasEnabledCallbacks() || actionMode == null) {
- return false;
- }
- actionMode.finish();
- actionMode = null;
- return true;
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java
index 5861b990..97efc042 100755
--- a/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java
+++ b/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java
@@ -15,6 +15,7 @@ import awais.instagrabber.BuildConfig;
import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.enums.MediaItemType;
+import awais.instagrabber.models.enums.PostItemType;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils;
import awaisomereport.LogCollector;
@@ -26,24 +27,18 @@ import static awais.instagrabber.utils.Utils.logCollector;
public final class PostsFetcher extends AsyncTask {
private static final String TAG = "PostsFetcher";
- private boolean isLocation;
+ private final PostItemType type;
private final String endCursor;
private final String id;
private final FetchListener fetchListener;
private String username = null;
- public PostsFetcher(final String id, final FetchListener fetchListener) {
- this.id = id;
- this.endCursor = "";
- this.fetchListener = fetchListener;
- }
-
public PostsFetcher(final String id,
- final boolean isLocation,
+ final PostItemType type,
final String endCursor,
final FetchListener fetchListener) {
this.id = id;
- this.isLocation = isLocation;
+ this.type = type;
this.endCursor = endCursor == null ? "" : endCursor;
this.fetchListener = fetchListener;
}
@@ -55,27 +50,32 @@ public final class PostsFetcher extends AsyncTask {
@Override
protected PostModel[] doInBackground(final Void... voids) {
- final boolean isHashTag = id.charAt(0) == '#';
- final boolean isSaved = id.charAt(0) == '$';
- final boolean isTagged = id.charAt(0) == '%';
+ // final boolean isHashTag = id.charAt(0) == '#';
+ // final boolean isSaved = id.charAt(0) == '$';
+ // final boolean isTagged = id.charAt(0) == '%';
// final boolean isLocation = id.contains("/");
final String url;
- if (isHashTag)
- url = "https://www.instagram.com/graphql/query/?query_hash=9b498c08113f1e09617a1703c22b2f32&variables=" +
- "{\"tag_name\":\"" + id.substring(1).toLowerCase() + "\",\"first\":150,\"after\":\"" + endCursor + "\"}";
- else if (isLocation)
- url = "https://www.instagram.com/graphql/query/?query_hash=36bd0f2bf5911908de389b8ceaa3be6d&variables=" +
- "{\"id\":\"" + id + "\",\"first\":150,\"after\":\"" + endCursor + "\"}";
- else if (isSaved)
- url = "https://www.instagram.com/graphql/query/?query_hash=8c86fed24fa03a8a2eea2a70a80c7b6b&variables=" +
- "{\"id\":\"" + id.substring(1) + "\",\"first\":150,\"after\":\"" + endCursor + "\"}";
- else if (isTagged)
- url = "https://www.instagram.com/graphql/query/?query_hash=ff260833edf142911047af6024eb634a&variables=" +
- "{\"id\":\"" + id.substring(1) + "\",\"first\":150,\"after\":\"" + endCursor + "\"}";
- else
- url = "https://www.instagram.com/graphql/query/?query_id=17880160963012870&id=" + id + "&first=50&after=" + endCursor;
-
+ switch (type) {
+ case HASHTAG:
+ url = "https://www.instagram.com/graphql/query/?query_hash=9b498c08113f1e09617a1703c22b2f32&variables=" +
+ "{\"tag_name\":\"" + id.toLowerCase() + "\",\"first\":150,\"after\":\"" + endCursor + "\"}";
+ break;
+ case LOCATION:
+ url = "https://www.instagram.com/graphql/query/?query_hash=36bd0f2bf5911908de389b8ceaa3be6d&variables=" +
+ "{\"id\":\"" + id + "\",\"first\":150,\"after\":\"" + endCursor + "\"}";
+ break;
+ case SAVED:
+ url = "https://www.instagram.com/graphql/query/?query_hash=8c86fed24fa03a8a2eea2a70a80c7b6b&variables=" +
+ "{\"id\":\"" + id + "\",\"first\":150,\"after\":\"" + endCursor + "\"}";
+ break;
+ case TAGGED:
+ url = "https://www.instagram.com/graphql/query/?query_hash=31fe64d9463cbbe58319dced405c6206&variables=" +
+ "{\"id\":\"" + id + "\",\"first\":150,\"after\":\"" + endCursor + "\"}";
+ break;
+ default:
+ url = "https://www.instagram.com/graphql/query/?query_id=17880160963012870&id=" + id + "&first=50&after=" + endCursor;
+ }
PostModel[] result = null;
try {
final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
@@ -95,14 +95,20 @@ public final class PostsFetcher extends AsyncTask {
if (!Utils.isEmpty(customPath)) customDir = new File(customPath);
}
+ final boolean isHashtag = type == PostItemType.HASHTAG;
+ final boolean isLocation = type == PostItemType.LOCATION;
+ final boolean isSaved = type == PostItemType.SAVED;
+ final boolean isTagged = type == PostItemType.TAGGED;
final JSONObject mediaPosts = new JSONObject(Utils.readFromConnection(conn))
.getJSONObject("data")
- .getJSONObject(isHashTag ? Constants.EXTRAS_HASHTAG :
- (isLocation ? Constants.EXTRAS_LOCATION : Constants.EXTRAS_USER))
- .getJSONObject(isHashTag ? "edge_hashtag_to_media" :
- (isLocation ? "edge_location_to_media" :
- (isSaved ? "edge_saved_media" :
- (isTagged ? "edge_user_to_photos_of_you" : "edge_owner_to_timeline_media"))));
+ .getJSONObject(isHashtag
+ ? Constants.EXTRAS_HASHTAG
+ : (isLocation ? Constants.EXTRAS_LOCATION
+ : Constants.EXTRAS_USER))
+ .getJSONObject(isHashtag ? "edge_hashtag_to_media" :
+ isLocation ? "edge_location_to_media" : isSaved ? "edge_saved_media"
+ : isTagged ? "edge_user_to_photos_of_you"
+ : "edge_owner_to_timeline_media");
final String endCursor;
final boolean hasNextPage;
diff --git a/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java b/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java
index 3ba62570..bfead2b0 100644
--- a/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java
@@ -50,6 +50,7 @@ import awais.instagrabber.models.HashtagModel;
import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.DownloadMethod;
+import awais.instagrabber.models.enums.PostItemType;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils;
import awaisomereport.LogCollector;
@@ -78,14 +79,10 @@ public class HashTagFragment extends Fragment {
private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(false) {
@Override
public void handleOnBackPressed() {
- if (postsAdapter == null) {
- setEnabled(false);
- remove();
- return;
- }
- postsAdapter.clearSelection();
setEnabled(false);
remove();
+ if (postsAdapter == null) return;
+ postsAdapter.clearSelection();
}
};
private final PrimaryActionModeCallback multiSelectAction = new PrimaryActionModeCallback(
@@ -256,7 +253,9 @@ public class HashTagFragment extends Fragment {
stopCurrentExecutor();
binding.btnFollowTag.setVisibility(View.VISIBLE);
binding.swipeRefreshLayout.setRefreshing(true);
- currentlyExecuting = new PostsFetcher(hashtag, false, endCursor, postsFetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ if (Utils.isEmpty(hashtag)) return;
+ currentlyExecuting = new PostsFetcher(hashtag.substring(1), PostItemType.HASHTAG, endCursor, postsFetchListener)
+ .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
if (isLoggedIn) {
new iStoryStatusFetcher(hashtagModel.getName(), null, false, true, false, false, stories -> {
storyModels = stories;
diff --git a/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java b/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java
index 2fee4e8f..1994328c 100644
--- a/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java
@@ -50,6 +50,7 @@ import awais.instagrabber.models.LocationModel;
import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.DownloadMethod;
+import awais.instagrabber.models.enums.PostItemType;
import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils;
import awaisomereport.LogCollector;
@@ -328,7 +329,7 @@ public class LocationFragment extends Fragment {
private void fetchPosts() {
stopCurrentExecutor();
- currentlyExecuting = new PostsFetcher(locationModel.getId(), true, endCursor, postsFetchListener)
+ currentlyExecuting = new PostsFetcher(locationModel.getId(), PostItemType.LOCATION, endCursor, postsFetchListener)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
diff --git a/app/src/main/java/awais/instagrabber/fragments/PostViewFragment.java b/app/src/main/java/awais/instagrabber/fragments/PostViewFragment.java
index 5fa8bc75..bcb58d8b 100644
--- a/app/src/main/java/awais/instagrabber/fragments/PostViewFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/PostViewFragment.java
@@ -139,9 +139,11 @@ public class PostViewFragment extends Fragment {
if (mediaService != null) {
final String userId = Utils.getUserIdFromCookie(COOKIE);
final String csrfToken = Utils.getCsrfTokenFromCookie(COOKIE);
+ v.setEnabled(false);
final ServiceCallback likeCallback = new ServiceCallback() {
@Override
public void onSuccess(final Boolean result) {
+ v.setEnabled(true);
if (result) {
postModel.setManualLike(!postModel.getLike());
adapter.notifyItemChanged(postPosition);
@@ -152,6 +154,7 @@ public class PostViewFragment extends Fragment {
@Override
public void onFailure(final Throwable t) {
+ v.setEnabled(true);
Log.e(TAG, "Error during like/unlike", t);
}
};
@@ -166,9 +169,11 @@ public class PostViewFragment extends Fragment {
if (mediaService != null) {
final String userId = Utils.getUserIdFromCookie(COOKIE);
final String csrfToken = Utils.getCsrfTokenFromCookie(COOKIE);
+ v.setEnabled(false);
final ServiceCallback saveCallback = new ServiceCallback() {
@Override
public void onSuccess(final Boolean result) {
+ v.setEnabled(true);
if (result) {
postModel.setBookmarked(!postModel.getBookmark());
adapter.notifyItemChanged(postPosition);
@@ -179,6 +184,7 @@ public class PostViewFragment extends Fragment {
@Override
public void onFailure(final Throwable t) {
+ v.setEnabled(true);
Log.e(TAG, "Error during save/unsave", t);
}
};
@@ -219,6 +225,7 @@ public class PostViewFragment extends Fragment {
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
if (!shouldRefresh) return;
init();
+ shouldRefresh = false;
}
private void setupViewPager() {
@@ -252,9 +259,7 @@ public class PostViewFragment extends Fragment {
idOrCodeList = Arrays.asList(idOrCodeArray);
viewerPostViewModel.getList().setValue(createPlaceholderModels(idOrCodeArray.length));
isId = fragmentArgs.getIsId();
- // binding.getRoot().postDelayed(() -> binding.getRoot().setCurrentItem(currentPostIndex), 500);
fetchPost();
- // binding.getRoot().setCurrentItem(currentPostIndex);
}
private List createPlaceholderModels(final int size) {
@@ -274,17 +279,6 @@ public class PostViewFragment extends Fragment {
if (viewerPostModels != null && viewerPostModels
.getViewerPostModels() != null && viewerPostModels
.getViewerPostModels().length > 0) {
- // final ViewerPostModel viewerPostModel = viewerPostModels[0];
- // if (viewerPostModel != null) {
- // final String postId = viewerPostModel.getPostId();
- // try {
- // if (postId != null && Integer.parseInt(postId) > 0) {
- // // already fetched, don't fetch again
- // Log.d(TAG, "returning without fetching");
- // return;
- // }
- // } catch (NumberFormatException ignored) {}
- // }
Log.d(TAG, "returning without fetching");
return;
}
diff --git a/app/src/main/java/awais/instagrabber/fragments/SavedViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/SavedViewerFragment.java
new file mode 100644
index 00000000..5587811c
--- /dev/null
+++ b/app/src/main/java/awais/instagrabber/fragments/SavedViewerFragment.java
@@ -0,0 +1,333 @@
+package awais.instagrabber.fragments;
+
+import android.content.pm.PackageManager;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.ActionMode;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+import androidx.activity.OnBackPressedCallback;
+import androidx.activity.OnBackPressedDispatcher;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.Fragment;
+import androidx.lifecycle.Observer;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.navigation.NavDirections;
+import androidx.navigation.fragment.NavHostFragment;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import awais.instagrabber.BuildConfig;
+import awais.instagrabber.R;
+import awais.instagrabber.adapters.PostsAdapter;
+import awais.instagrabber.asyncs.PostsFetcher;
+import awais.instagrabber.asyncs.i.iLikedFetcher;
+import awais.instagrabber.customviews.PrimaryActionModeCallback;
+import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager;
+import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration;
+import awais.instagrabber.customviews.helpers.RecyclerLazyLoader;
+import awais.instagrabber.databinding.FragmentSavedBinding;
+import awais.instagrabber.fragments.main.ProfileFragmentDirections;
+import awais.instagrabber.fragments.main.viewmodels.PostsViewModel;
+import awais.instagrabber.interfaces.FetchListener;
+import awais.instagrabber.models.PostModel;
+import awais.instagrabber.models.enums.DownloadMethod;
+import awais.instagrabber.models.enums.PostItemType;
+import awais.instagrabber.utils.Utils;
+import awaisomereport.LogCollector;
+
+import static awais.instagrabber.utils.Utils.logCollector;
+
+public final class SavedViewerFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
+ private static AsyncTask, ?, ?> currentlyExecuting;
+ private PostsAdapter postsAdapter;
+ private boolean hasNextPage;
+ private boolean autoloadPosts;
+ private FragmentSavedBinding binding;
+ private String username;
+ private String endCursor;
+ private RecyclerLazyLoader lazyLoader;
+ private ArrayList selectedItems = new ArrayList<>();
+ private ActionMode actionMode;
+ private PostsViewModel postsViewModel;
+ private LinearLayout root;
+ private AppCompatActivity fragmentActivity;
+ private boolean shouldRefresh = true;
+ private PostItemType type;
+ private String profileId;
+
+ private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(false) {
+ @Override
+ public void handleOnBackPressed() {
+ setEnabled(false);
+ remove();
+ if (postsAdapter == null) return;
+ postsAdapter.clearSelection();
+ }
+ };
+ private final PrimaryActionModeCallback multiSelectAction = new PrimaryActionModeCallback(
+ R.menu.multi_select_download_menu,
+ new PrimaryActionModeCallback.CallbacksHelper() {
+ @Override
+ public void onDestroy(final ActionMode mode) {
+ onBackPressedCallback.handleOnBackPressed();
+ }
+
+ @Override
+ public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
+ if (item.getItemId() == R.id.action_download) {
+ if (postsAdapter == null || username == null) {
+ return false;
+ }
+ Utils.batchDownload(requireContext(),
+ username,
+ DownloadMethod.DOWNLOAD_SAVED,
+ postsAdapter.getSelectedModels());
+ checkAndResetAction();
+ return true;
+ }
+ return false;
+ }
+ });
+ private final FetchListener postsFetchListener = new FetchListener() {
+ @Override
+ public void onResult(final PostModel[] result) {
+ if (result != null) {
+ final List current = postsViewModel.getList().getValue();
+ final List resultList = Arrays.asList(result);
+ if (current == null) {
+ postsViewModel.getList().postValue(resultList);
+ } else {
+ final List currentCopy = new ArrayList<>(current);
+ currentCopy.addAll(resultList);
+ postsViewModel.getList().postValue(currentCopy);
+ }
+ binding.mainPosts.post(() -> {
+ binding.mainPosts.setNestedScrollingEnabled(true);
+ binding.mainPosts.setVisibility(View.VISIBLE);
+ });
+
+ final PostModel model = result.length > 0 ? result[result.length - 1] : null;
+ if (model != null) {
+ endCursor = model.getEndCursor();
+ hasNextPage = model.hasNextPage();
+ if (autoloadPosts && hasNextPage) {
+ fetchPosts();
+ } else {
+ binding.swipeRefreshLayout.setRefreshing(false);
+ }
+ model.setPageCursor(false, null);
+ }
+ }
+ binding.swipeRefreshLayout.setRefreshing(false);
+ }
+ };
+ private Observer> listObserver;
+
+ @Override
+ public void onCreate(@Nullable final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ fragmentActivity = (AppCompatActivity) getActivity();
+ }
+
+ @Override
+ public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) {
+ if (root != null) {
+ shouldRefresh = false;
+ return root;
+ }
+ binding = FragmentSavedBinding.inflate(getLayoutInflater(), container, false);
+ root = binding.getRoot();
+ return root;
+ }
+
+ @Override
+ public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
+ if (!shouldRefresh) return;
+ init();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ setTitle();
+ observeData();
+ }
+
+ private void observeData() {
+ postsViewModel = new ViewModelProvider(this).get(PostsViewModel.class);
+ postsViewModel.getList().removeObserver(listObserver);
+ if (postsAdapter != null) {
+ postsViewModel.getList().observe(getViewLifecycleOwner(), listObserver);
+ }
+ }
+
+ private void init() {
+ final Bundle arguments = getArguments();
+ if (arguments == null) return;
+ final SavedViewerFragmentArgs fragmentArgs = SavedViewerFragmentArgs.fromBundle(arguments);
+ username = fragmentArgs.getUsername();
+ profileId = fragmentArgs.getProfileId();
+ type = fragmentArgs.getType();
+ setTitle();
+ binding.swipeRefreshLayout.setOnRefreshListener(this);
+ // autoloadPosts = Utils.settingsHelper.getBoolean(AUTOLOAD_POSTS);
+ binding.mainPosts.setNestedScrollingEnabled(false);
+ final GridAutofitLayoutManager layoutManager = new GridAutofitLayoutManager(requireContext(), Utils.convertDpToPx(110));
+ binding.mainPosts.setLayoutManager(layoutManager);
+ binding.mainPosts.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(4)));
+ postsAdapter = new PostsAdapter((postModel, position) -> {
+ if (postsAdapter.isSelecting()) {
+ if (actionMode == null) return;
+ final String title = getString(R.string.number_selected, postsAdapter.getSelectedModels().size());
+ actionMode.setTitle(title);
+ return;
+ }
+ if (checkAndResetAction()) return;
+ final List postModels = postsViewModel.getList().getValue();
+ if (postModels == null || postModels.size() == 0) return;
+ if (postModels.get(0) == null) return;
+ final String postId = postModels.get(0).getPostId();
+ final boolean isId = postId != null;
+ final String[] idsOrShortCodes = new String[postModels.size()];
+ for (int i = 0; i < postModels.size(); i++) {
+ final PostModel tempPostModel = postModels.get(i);
+ final String tempId = tempPostModel.getPostId();
+ final String finalPostId = type == PostItemType.LIKED ? tempId.substring(0, tempId.indexOf("_")) : tempId;
+ idsOrShortCodes[i] = isId ? finalPostId
+ : tempPostModel.getShortCode();
+ }
+ final NavDirections action = ProfileFragmentDirections.actionGlobalPostViewFragment(
+ position,
+ idsOrShortCodes,
+ isId);
+ NavHostFragment.findNavController(this).navigate(action);
+ }, (model, position) -> {
+ if (!postsAdapter.isSelecting()) {
+ checkAndResetAction();
+ return true;
+ }
+ final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity.getOnBackPressedDispatcher();
+ if (onBackPressedCallback.isEnabled()) return true;
+ actionMode = fragmentActivity.startActionMode(multiSelectAction);
+ final String title = getString(R.string.number_selected, 1);
+ actionMode.setTitle(title);
+ onBackPressedDispatcher.addCallback(getViewLifecycleOwner(), onBackPressedCallback);
+ return true;
+ });
+ binding.mainPosts.setAdapter(postsAdapter);
+ listObserver = list -> postsAdapter.submitList(list);
+ observeData();
+ binding.swipeRefreshLayout.setRefreshing(true);
+
+ lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
+ if (!autoloadPosts && hasNextPage) {
+ binding.swipeRefreshLayout.setRefreshing(true);
+ fetchPosts();
+ endCursor = null;
+ }
+ });
+ binding.mainPosts.addOnScrollListener(lazyLoader);
+ fetchPosts();
+ }
+
+ private void fetchPosts() {
+ stopCurrentExecutor();
+ final AsyncTask asyncTask;
+ switch (type) {
+ case LIKED:
+ asyncTask = new iLikedFetcher(endCursor, postsFetchListener);
+ break;
+ case SAVED:
+ case TAGGED:
+ if (Utils.isEmpty(profileId)) return;
+ asyncTask = new PostsFetcher(profileId, type, endCursor, postsFetchListener);
+ break;
+ default:
+ return;
+ }
+ currentlyExecuting = asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+
+ @Override
+ public void onRefresh() {
+ if (lazyLoader != null) lazyLoader.resetState();
+ stopCurrentExecutor();
+ endCursor = null;
+ postsViewModel.getList().postValue(Collections.emptyList());
+ selectedItems.clear();
+ if (postsAdapter != null) {
+ // postsAdapter.isSelecting = false;
+ postsAdapter.notifyDataSetChanged();
+ }
+ binding.swipeRefreshLayout.setRefreshing(true);
+ fetchPosts();
+ }
+
+ @Override
+ public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ if (requestCode == 8020 && grantResults[0] == PackageManager.PERMISSION_GRANTED && selectedItems.size() > 0)
+ Utils.batchDownload(requireContext(), null, DownloadMethod.DOWNLOAD_SAVED, selectedItems);
+ }
+
+ public static void stopCurrentExecutor() {
+ if (currentlyExecuting != null) {
+ try {
+ currentlyExecuting.cancel(true);
+ } catch (final Exception e) {
+ if (logCollector != null)
+ logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor");
+ if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
+ }
+ }
+ }
+
+ private void setTitle() {
+ final ActionBar actionBar = fragmentActivity.getSupportActionBar();
+ if (actionBar == null) return;
+ final int titleRes;
+ switch (type) {
+ case SAVED:
+ titleRes = R.string.saved;
+ break;
+ case LIKED:
+ titleRes = R.string.liked;
+ break;
+ case TAGGED:
+ titleRes = R.string.tagged;
+ break;
+ default:
+ return; // no other types supported in this view
+ }
+ actionBar.setTitle(titleRes);
+ actionBar.setSubtitle(username);
+ }
+
+ private boolean checkAndResetAction() {
+ if (!onBackPressedCallback.isEnabled() && actionMode == null) {
+ return false;
+ }
+ if (onBackPressedCallback.isEnabled()) {
+ onBackPressedCallback.setEnabled(false);
+ onBackPressedCallback.remove();
+ }
+ if (actionMode != null) {
+ actionMode.finish();
+ actionMode = null;
+ }
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java
index 0550fa1b..826ca22c 100644
--- a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java
@@ -150,6 +150,7 @@ public class StoryViewerFragment extends Fragment {
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
if (!shouldRefresh) return;
init();
+ shouldRefresh = false;
}
@Override
diff --git a/app/src/main/java/awais/instagrabber/fragments/main/DiscoverFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/DiscoverFragment.java
index 09453b7b..71eb75b0 100644
--- a/app/src/main/java/awais/instagrabber/fragments/main/DiscoverFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/main/DiscoverFragment.java
@@ -107,15 +107,13 @@ public class DiscoverFragment extends Fragment {
}
}
};
- private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(true) {
+ private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(false) {
@Override
public void handleOnBackPressed() {
- if (discoverAdapter == null) {
- remove();
- return;
- }
- discoverAdapter.clearSelection();
+ setEnabled(false);
remove();
+ if (discoverAdapter == null) return;
+ discoverAdapter.clearSelection();
}
};
private final PrimaryActionModeCallback multiSelectAction = new PrimaryActionModeCallback(
@@ -164,6 +162,7 @@ public class DiscoverFragment extends Fragment {
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
if (!shouldRefresh) return;
setupExplore();
+ shouldRefresh = false;
}
private void setupExplore() {
@@ -228,13 +227,13 @@ public class DiscoverFragment extends Fragment {
return true;
}
final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity.getOnBackPressedDispatcher();
- if (onBackPressedDispatcher.hasEnabledCallbacks()) {
+ if (onBackPressedCallback.isEnabled()) {
return true;
}
actionMode = fragmentActivity.startActionMode(multiSelectAction);
final String title = getString(R.string.number_selected, 1);
actionMode.setTitle(title);
- onBackPressedDispatcher.addCallback(onBackPressedCallback);
+ onBackPressedDispatcher.addCallback(getViewLifecycleOwner(), onBackPressedCallback);
return true;
});
binding.discoverPosts.setAdapter(discoverAdapter);
@@ -251,12 +250,17 @@ public class DiscoverFragment extends Fragment {
}
private boolean checkAndResetAction() {
- final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity.getOnBackPressedDispatcher();
- if (!onBackPressedDispatcher.hasEnabledCallbacks() || actionMode == null) {
+ if (!onBackPressedCallback.isEnabled() && actionMode == null) {
return false;
}
- actionMode.finish();
- actionMode = null;
+ if (onBackPressedCallback.isEnabled()) {
+ onBackPressedCallback.setEnabled(false);
+ onBackPressedCallback.remove();
+ }
+ if (actionMode != null) {
+ actionMode.finish();
+ actionMode = null;
+ }
return true;
}
}
diff --git a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java
index 56e0cbd1..7707fa13 100644
--- a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java
+++ b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java
@@ -41,7 +41,6 @@ import awais.instagrabber.ProfileNavGraphDirections;
import awais.instagrabber.R;
import awais.instagrabber.activities.FollowViewer;
import awais.instagrabber.activities.MainActivity;
-import awais.instagrabber.activities.SavedViewer;
import awais.instagrabber.adapters.PostsAdapter;
import awais.instagrabber.asyncs.HighlightsFetcher;
import awais.instagrabber.asyncs.PostsFetcher;
@@ -61,6 +60,7 @@ import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.DownloadMethod;
+import awais.instagrabber.models.enums.PostItemType;
import awais.instagrabber.repositories.responses.FriendshipRepoChangeRootResponse;
import awais.instagrabber.repositories.responses.FriendshipRepoRestrictRootResponse;
import awais.instagrabber.services.FriendshipService;
@@ -100,48 +100,42 @@ public class ProfileFragment extends Fragment {
final String finalUsername = username.startsWith("@") ? username.substring(1)
: username;
actionBar.setTitle(finalUsername);
+ actionBar.setSubtitle(null);
}
};
- private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(true) {
+ private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(false) {
@Override
public void handleOnBackPressed() {
- if (postsAdapter == null) {
- remove();
- return;
- }
- postsAdapter.clearSelection();
+ setEnabled(false);
remove();
+ if (postsAdapter == null) return;
+ postsAdapter.clearSelection();
}
};
- private final PrimaryActionModeCallback multiSelectAction = new PrimaryActionModeCallback(R.menu.multi_select_download_menu,
- new CallbacksHelper() {
- @Override
- public void onDestroy(
- final ActionMode mode) {
- onBackPressedCallback
- .handleOnBackPressed();
- }
+ private final PrimaryActionModeCallback multiSelectAction = new PrimaryActionModeCallback(
+ R.menu.multi_select_download_menu,
+ new CallbacksHelper() {
+ @Override
+ public void onDestroy(final ActionMode mode) {
+ onBackPressedCallback.handleOnBackPressed();
+ }
- @Override
- public boolean onActionItemClicked(
- final ActionMode mode,
- final MenuItem item) {
- if (item.getItemId() == R.id.action_download) {
- if (postsAdapter == null || username == null) {
- return false;
- }
- Utils.batchDownload(
- requireContext(),
- username,
- DownloadMethod.DOWNLOAD_MAIN,
- postsAdapter
- .getSelectedModels());
- checkAndResetAction();
- return true;
- }
- return false;
- }
- });
+ @Override
+ public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
+ if (item.getItemId() == R.id.action_download) {
+ if (postsAdapter == null || username == null) {
+ return false;
+ }
+ Utils.batchDownload(requireContext(),
+ username,
+ DownloadMethod.DOWNLOAD_MAIN,
+ postsAdapter.getSelectedModels());
+ checkAndResetAction();
+ return true;
+ }
+ return false;
+ }
+ });
private final FetchListener postsFetchListener = new FetchListener() {
@Override
public void onResult(final PostModel[] result) {
@@ -201,9 +195,18 @@ public class ProfileFragment extends Fragment {
final Bundle savedInstanceState) {
if (root != null) {
if (getArguments() != null) {
- final ProfileFragmentArgs fragmentArgs = ProfileFragmentArgs
- .fromBundle(getArguments());
- if (!fragmentArgs.getUsername().equals(username)) {
+ final ProfileFragmentArgs fragmentArgs = ProfileFragmentArgs.fromBundle(getArguments());
+ final String username = fragmentArgs.getUsername();
+ if (Utils.isEmpty(username) && profileModel != null) {
+ final String profileModelUsername = profileModel.getUsername();
+ final boolean isSame = ("@" + profileModelUsername).equals(this.username);
+ if (isSame) {
+ setUsernameDelayed();
+ shouldRefresh = false;
+ return root;
+ }
+ }
+ if (username == null || !username.equals(this.username)) {
shouldRefresh = true;
return root;
}
@@ -264,8 +267,7 @@ public class ProfileFragment extends Fragment {
fetchProfileDetails();
// adds cookies to database for quick access
final DataBox.CookieModel cookieModel = Utils.dataBox.getCookie(uid);
- if (Utils.dataBox.getCookieCount() == 0 || cookieModel == null || Utils
- .isEmpty(cookieModel.getUsername()))
+ if (Utils.dataBox.getCookieCount() == 0 || cookieModel == null || Utils.isEmpty(cookieModel.getUsername()))
Utils.dataBox.addUserCookie(new DataBox.CookieModel(uid, username, cookie));
};
boolean found = false;
@@ -279,8 +281,7 @@ public class ProfileFragment extends Fragment {
}
if (!found) {
// if not in database, fetch info from instagram
- new UsernameFetcher(uid, fetchListener)
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ new UsernameFetcher(uid, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
return;
}
@@ -298,8 +299,7 @@ public class ProfileFragment extends Fragment {
private void setProfileDetails() {
if (profileModel == null) {
binding.swipeRefreshLayout.setRefreshing(false);
- Toast.makeText(requireContext(), R.string.error_loading_profile, Toast.LENGTH_SHORT)
- .show();
+ Toast.makeText(requireContext(), R.string.error_loading_profile, Toast.LENGTH_SHORT).show();
return;
}
binding.isVerified.setVisibility(profileModel.isVerified() ? View.VISIBLE : View.GONE);
@@ -309,7 +309,7 @@ public class ProfileFragment extends Fragment {
profileModel.getUsername(),
false,
false,
- (!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)),
+ !isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG),
false,
result -> {
storyModels = result;
@@ -319,7 +319,7 @@ public class ProfileFragment extends Fragment {
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new HighlightsFetcher(profileId,
- (!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)),
+ !isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG),
result -> {
if (result != null && result.length > 0) {
binding.highlightsList.setVisibility(View.VISIBLE);
@@ -336,9 +336,7 @@ public class ProfileFragment extends Fragment {
binding.btnLiked.setVisibility(View.VISIBLE);
binding.btnSaved.setText(R.string.saved);
ViewCompat.setBackgroundTintList(binding.btnSaved,
- ColorStateList.valueOf(ContextCompat.getColor(
- requireContext(),
- R.color.btn_orange_background)));
+ ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_orange_background)));
} else {
binding.btnTagged.setVisibility(View.GONE);
binding.btnSaved.setVisibility(View.GONE);
@@ -347,74 +345,54 @@ public class ProfileFragment extends Fragment {
if (profileModel.getFollowing()) {
binding.btnFollow.setText(R.string.unfollow);
ViewCompat.setBackgroundTintList(binding.btnFollow,
- ColorStateList.valueOf(ContextCompat.getColor(
- requireContext(),
- R.color.btn_purple_background)));
+ ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_purple_background)));
} else if (profileModel.getRequested()) {
binding.btnFollow.setText(R.string.cancel);
ViewCompat.setBackgroundTintList(binding.btnFollow,
- ColorStateList.valueOf(ContextCompat.getColor(
- requireContext(),
- R.color.btn_purple_background)));
+ ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_purple_background)));
} else {
binding.btnFollow.setText(R.string.follow);
ViewCompat.setBackgroundTintList(binding.btnFollow,
- ColorStateList.valueOf(ContextCompat.getColor(
- requireContext(),
- R.color.btn_pink_background)));
+ ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_pink_background)));
}
binding.btnRestrict.setVisibility(View.VISIBLE);
if (profileModel.getRestricted()) {
binding.btnRestrict.setText(R.string.unrestrict);
ViewCompat.setBackgroundTintList(binding.btnRestrict,
- ColorStateList.valueOf(ContextCompat.getColor(
- requireContext(),
- R.color.btn_green_background)));
+ ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_green_background)));
} else {
binding.btnRestrict.setText(R.string.restrict);
ViewCompat.setBackgroundTintList(binding.btnRestrict,
- ColorStateList.valueOf(ContextCompat.getColor(
- requireContext(),
- R.color.btn_orange_background)));
+ ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_orange_background)));
}
binding.btnBlock.setVisibility(View.VISIBLE);
binding.btnTagged.setVisibility(View.VISIBLE);
if (profileModel.getBlocked()) {
binding.btnBlock.setText(R.string.unblock);
ViewCompat.setBackgroundTintList(binding.btnBlock,
- ColorStateList.valueOf(ContextCompat.getColor(
- requireContext(),
- R.color.btn_green_background)));
+ ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_green_background)));
} else {
binding.btnBlock.setText(R.string.block);
ViewCompat.setBackgroundTintList(binding.btnBlock,
- ColorStateList.valueOf(ContextCompat.getColor(
- requireContext(),
- R.color.btn_red_background)));
+ ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_red_background)));
}
}
} else {
if (Utils.dataBox.getFavorite(username) != null) {
binding.btnFollow.setText(R.string.unfavorite_short);
ViewCompat.setBackgroundTintList(binding.btnFollow,
- ColorStateList.valueOf(ContextCompat.getColor(
- requireContext(),
- R.color.btn_purple_background)));
+ ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_purple_background)));
} else {
binding.btnFollow.setText(R.string.favorite_short);
ViewCompat.setBackgroundTintList(binding.btnFollow,
- ColorStateList.valueOf(ContextCompat.getColor(
- requireContext(),
- R.color.btn_pink_background)));
+ ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_pink_background)));
}
binding.btnFollow.setVisibility(View.VISIBLE);
if (!profileModel.isReallyPrivate()) {
binding.btnRestrict.setVisibility(View.VISIBLE);
binding.btnRestrict.setText(R.string.tagged);
ViewCompat.setBackgroundTintList(binding.btnRestrict,
- ColorStateList.valueOf(ContextCompat.getColor(
- requireContext(),
- R.color.btn_blue_background)));
+ ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.btn_blue_background)));
}
}
@@ -480,10 +458,8 @@ public class ProfileFragment extends Fragment {
if (isLoggedIn) {
final View.OnClickListener followClickListener = v -> startActivity(new Intent(
requireContext(),
- FollowViewer.class).putExtra(Constants.EXTRAS_FOLLOWERS,
- v == binding.mainFollowers)
- .putExtra(Constants.EXTRAS_NAME,
- profileModel.getUsername())
+ FollowViewer.class).putExtra(Constants.EXTRAS_FOLLOWERS, v == binding.mainFollowers)
+ .putExtra(Constants.EXTRAS_NAME, profileModel.getUsername())
.putExtra(Constants.EXTRAS_ID, profileId));
binding.mainFollowers
@@ -517,144 +493,149 @@ public class ProfileFragment extends Fragment {
private void setupCommonListeners() {
final String userIdFromCookie = Utils.getUserIdFromCookie(cookie);
- final boolean isSelf = isLoggedIn && profileModel != null && userIdFromCookie != null && userIdFromCookie
- .equals(profileModel.getId());
+ // final boolean isSelf = isLoggedIn && profileModel != null && userIdFromCookie != null && userIdFromCookie
+ // .equals(profileModel.getId());
final String favorite = Utils.dataBox.getFavorite(username);
binding.btnFollow.setOnClickListener(v -> {
if (!isLoggedIn) {
if (favorite != null && v == binding.btnFollow) {
- Utils.dataBox.delFavorite(new DataBox.FavoriteModel(username,
- Long.parseLong(favorite.split(
- "/")[1]),
- username.replaceAll("^@",
- "")));
+ Utils.dataBox.delFavorite(new DataBox.FavoriteModel(
+ username,
+ Long.parseLong(favorite.split("/")[1]),
+ username.replaceAll("^@", "")));
} else if (v == binding.btnFollow) {
- Utils.dataBox.addFavorite(new DataBox.FavoriteModel(username,
- System.currentTimeMillis(),
- username.replaceAll("^@",
- "")));
+ Utils.dataBox.addFavorite(new DataBox.FavoriteModel(
+ username,
+ System.currentTimeMillis(),
+ username.replaceAll("^@", "")));
}
fetchProfileDetails();
return;
}
if (profileModel.getFollowing() || profileModel.getRequested()) {
- friendshipService.unfollow(userIdFromCookie,
- profileModel.getId(),
- Utils.getCsrfTokenFromCookie(cookie),
- new ServiceCallback() {
- @Override
- public void onSuccess(final FriendshipRepoChangeRootResponse result) {
- Log.d(TAG, "Unfollow success: " + result);
- fetchProfileDetails();
- }
+ friendshipService.unfollow(
+ userIdFromCookie,
+ profileModel.getId(),
+ Utils.getCsrfTokenFromCookie(cookie),
+ new ServiceCallback() {
+ @Override
+ public void onSuccess(final FriendshipRepoChangeRootResponse result) {
+ Log.d(TAG, "Unfollow success: " + result);
+ fetchProfileDetails();
+ }
- @Override
- public void onFailure(final Throwable t) {
- Log.e(TAG, "Error unfollowing", t);
- }
- });
+ @Override
+ public void onFailure(final Throwable t) {
+ Log.e(TAG, "Error unfollowing", t);
+ }
+ });
} else {
- friendshipService.follow(userIdFromCookie,
- profileModel.getId(),
- Utils.getCsrfTokenFromCookie(cookie),
- new ServiceCallback() {
- @Override
- public void onSuccess(final FriendshipRepoChangeRootResponse result) {
- Log.d(TAG, "Follow success: " + result);
- fetchProfileDetails();
- }
+ friendshipService.follow(
+ userIdFromCookie,
+ profileModel.getId(),
+ Utils.getCsrfTokenFromCookie(cookie),
+ new ServiceCallback() {
+ @Override
+ public void onSuccess(final FriendshipRepoChangeRootResponse result) {
+ Log.d(TAG, "Follow success: " + result);
+ fetchProfileDetails();
+ }
- @Override
- public void onFailure(final Throwable t) {
- Log.e(TAG, "Error following", t);
- }
- });
+ @Override
+ public void onFailure(final Throwable t) {
+ Log.e(TAG, "Error following", t);
+ }
+ });
}
});
binding.btnRestrict.setOnClickListener(v -> {
if (!isLoggedIn) return;
final String action = profileModel.getRestricted() ? "Unrestrict" : "Restrict";
- friendshipService.toggleRestrict(profileModel.getId(),
- !profileModel.getRestricted(),
- Utils.getCsrfTokenFromCookie(cookie),
- new ServiceCallback() {
- @Override
- public void onSuccess(final FriendshipRepoRestrictRootResponse result) {
- Log.d(TAG, action + " success: " + result);
- fetchProfileDetails();
- }
+ friendshipService.toggleRestrict(
+ profileModel.getId(),
+ !profileModel.getRestricted(),
+ Utils.getCsrfTokenFromCookie(cookie),
+ new ServiceCallback() {
+ @Override
+ public void onSuccess(final FriendshipRepoRestrictRootResponse result) {
+ Log.d(TAG, action + " success: " + result);
+ fetchProfileDetails();
+ }
- @Override
- public void onFailure(final Throwable t) {
- Log.e(TAG,
- "Error while performing " + action,
- t);
- }
- });
+ @Override
+ public void onFailure(final Throwable t) {
+ Log.e(TAG, "Error while performing " + action, t);
+ }
+ });
});
binding.btnBlock.setOnClickListener(v -> {
if (!isLoggedIn) return;
if (profileModel.getBlocked()) {
- friendshipService.unblock(userIdFromCookie,
- profileModel.getId(),
- Utils.getCsrfTokenFromCookie(cookie),
- new ServiceCallback() {
- @Override
- public void onSuccess(final FriendshipRepoChangeRootResponse result) {
- Log.d(TAG, "Unblock success: " + result);
- fetchProfileDetails();
- }
+ friendshipService.unblock(
+ userIdFromCookie,
+ profileModel.getId(),
+ Utils.getCsrfTokenFromCookie(cookie),
+ new ServiceCallback() {
+ @Override
+ public void onSuccess(final FriendshipRepoChangeRootResponse result) {
+ Log.d(TAG, "Unblock success: " + result);
+ fetchProfileDetails();
+ }
- @Override
- public void onFailure(final Throwable t) {
- Log.e(TAG, "Error unblocking", t);
- }
- });
+ @Override
+ public void onFailure(final Throwable t) {
+ Log.e(TAG, "Error unblocking", t);
+ }
+ });
return;
}
- friendshipService.block(userIdFromCookie,
- profileModel.getId(),
- Utils.getCsrfTokenFromCookie(cookie),
- new ServiceCallback() {
- @Override
- public void onSuccess(final FriendshipRepoChangeRootResponse result) {
- Log.d(TAG, "Block success: " + result);
- fetchProfileDetails();
- }
+ friendshipService.block(
+ userIdFromCookie,
+ profileModel.getId(),
+ Utils.getCsrfTokenFromCookie(cookie),
+ new ServiceCallback() {
+ @Override
+ public void onSuccess(final FriendshipRepoChangeRootResponse result) {
+ Log.d(TAG, "Block success: " + result);
+ fetchProfileDetails();
+ }
- @Override
- public void onFailure(final Throwable t) {
- Log.e(TAG, "Error blocking", t);
- }
- });
+ @Override
+ public void onFailure(final Throwable t) {
+ Log.e(TAG, "Error blocking", t);
+ }
+ });
+ });
+ binding.btnSaved.setOnClickListener(v -> {
+ // startActivity(new Intent(requireContext(), SavedViewerFragment.class)
+ // .putExtra(Constants.EXTRAS_INDEX, "$" + profileModel.getId())
+ // .putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername()));
+ final NavDirections action = ProfileFragmentDirections.actionProfileFragmentToSavedViewerFragment(profileModel.getUsername(),
+ profileModel.getId(),
+ PostItemType.SAVED);
+ NavHostFragment.findNavController(this).navigate(action);
+ });
+ binding.btnLiked.setOnClickListener(v -> {
+ // startActivity(new Intent(requireContext(), SavedViewerFragment.class)
+ // .putExtra(Constants.EXTRAS_INDEX, "^" + profileModel.getId())
+ // .putExtra(Constants.EXTRAS_USER, username));
+ final NavDirections action = ProfileFragmentDirections.actionProfileFragmentToSavedViewerFragment(profileModel.getUsername(),
+ profileModel.getId(),
+ PostItemType.LIKED);
+ NavHostFragment.findNavController(this).navigate(action);
});
- binding.btnSaved.setOnClickListener(v -> startActivity(new Intent(requireContext(),
- SavedViewer.class)
- .putExtra(Constants.EXTRAS_INDEX,
- "$" + profileModel
- .getId())
- .putExtra(Constants.EXTRAS_USER,
- "@" + profileModel
- .getUsername())));
- binding.btnLiked.setOnClickListener(v -> startActivity(new Intent(requireContext(),
- SavedViewer.class)
- .putExtra(Constants.EXTRAS_INDEX,
- "^" + profileModel
- .getId())
- .putExtra(Constants.EXTRAS_USER,
- "@" + profileModel
- .getUsername())));
- binding.btnTagged.setOnClickListener(v -> startActivity(new Intent(requireContext(),
- SavedViewer.class)
- .putExtra(Constants.EXTRAS_INDEX,
- "%" + profileModel
- .getId())
- .putExtra(Constants.EXTRAS_USER,
- "@" + profileModel
- .getUsername())));
+ binding.btnTagged.setOnClickListener(v -> {
+ // startActivity(new Intent(requireContext(), SavedViewerFragment.class)
+ // .putExtra(Constants.EXTRAS_INDEX, "%" + profileModel.getId())
+ // .putExtra(Constants.EXTRAS_USER, username));
+ final NavDirections action = ProfileFragmentDirections.actionProfileFragmentToSavedViewerFragment(profileModel.getUsername(),
+ profileModel.getId(),
+ PostItemType.TAGGED);
+ NavHostFragment.findNavController(this).navigate(action);
+ });
}
private void setUsernameDelayed() {
@@ -666,9 +647,7 @@ public class ProfileFragment extends Fragment {
private void setupPosts() {
postsViewModel = new ViewModelProvider(this).get(PostsViewModel.class);
- final GridAutofitLayoutManager layoutManager = new GridAutofitLayoutManager(requireContext(),
- Utils.convertDpToPx(
- 110));
+ final GridAutofitLayoutManager layoutManager = new GridAutofitLayoutManager(requireContext(), Utils.convertDpToPx(110));
binding.mainPosts.setLayoutManager(layoutManager);
binding.mainPosts.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(4)));
postsAdapter = new PostsAdapter((postModel, position) -> {
@@ -680,11 +659,6 @@ public class ProfileFragment extends Fragment {
return;
}
if (checkAndResetAction()) return;
- // startActivity(new Intent(requireContext(), PostViewer.class)
- // .putExtra(Constants.EXTRAS_INDEX, position)
- // .putExtra(Constants.EXTRAS_POST, postModel)
- // .putExtra(Constants.EXTRAS_USER, username)
- // .putExtra(Constants.EXTRAS_TYPE, PostItemType.MAIN));
final List postModels = postsViewModel.getList().getValue();
if (postModels == null || postModels.size() == 0) return;
if (postModels.get(0) == null) return;
@@ -706,33 +680,31 @@ public class ProfileFragment extends Fragment {
checkAndResetAction();
return true;
}
- final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity
- .getOnBackPressedDispatcher();
- if (onBackPressedDispatcher.hasEnabledCallbacks()) {
+ if (onBackPressedCallback.isEnabled()) {
return true;
}
+ final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity.getOnBackPressedDispatcher();
+ onBackPressedCallback.setEnabled(true);
actionMode = fragmentActivity.startActionMode(multiSelectAction);
final String title = getString(R.string.number_selected, 1);
actionMode.setTitle(title);
- onBackPressedDispatcher.addCallback(onBackPressedCallback);
+ onBackPressedDispatcher.addCallback(getViewLifecycleOwner(), onBackPressedCallback);
return true;
});
postsViewModel.getList().observe(fragmentActivity, postsAdapter::submitList);
binding.mainPosts.setAdapter(postsAdapter);
- final RecyclerLazyLoader lazyLoader = new RecyclerLazyLoader(layoutManager,
- (page, totalItemsCount) -> {
- if (!hasNextPage) return;
- binding.swipeRefreshLayout
- .setRefreshing(true);
- fetchPosts();
- endCursor = null;
- });
+ final RecyclerLazyLoader lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
+ if (!hasNextPage) return;
+ binding.swipeRefreshLayout.setRefreshing(true);
+ fetchPosts();
+ endCursor = null;
+ });
binding.mainPosts.addOnScrollListener(lazyLoader);
}
private void fetchPosts() {
stopCurrentExecutor();
- currentlyExecuting = new PostsFetcher(profileModel.getId(), false, endCursor, postsFetchListener)
+ currentlyExecuting = new PostsFetcher(profileModel.getId(), PostItemType.MAIN, endCursor, postsFetchListener)
.setUsername(profileModel.getUsername())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@@ -742,22 +714,24 @@ public class ProfileFragment extends Fragment {
try {
currentlyExecuting.cancel(true);
} catch (final Exception e) {
- if (logCollector != null) logCollector.appendException(e,
- LogCollector.LogFile.MAIN_HELPER,
- "stopCurrentExecutor");
+ if (logCollector != null) logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor");
Log.e(TAG, "", e);
}
}
}
private boolean checkAndResetAction() {
- final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity
- .getOnBackPressedDispatcher();
- if (!onBackPressedDispatcher.hasEnabledCallbacks() || actionMode == null) {
+ if (!onBackPressedCallback.isEnabled() && actionMode == null) {
return false;
}
- actionMode.finish();
- actionMode = null;
+ if (onBackPressedCallback.isEnabled()) {
+ onBackPressedCallback.setEnabled(false);
+ onBackPressedCallback.remove();
+ }
+ if (actionMode != null) {
+ actionMode.finish();
+ actionMode = null;
+ }
return true;
}
}
diff --git a/app/src/main/java/awais/instagrabber/models/enums/PostItemType.java b/app/src/main/java/awais/instagrabber/models/enums/PostItemType.java
index 4bd0269d..bb4b84d8 100644
--- a/app/src/main/java/awais/instagrabber/models/enums/PostItemType.java
+++ b/app/src/main/java/awais/instagrabber/models/enums/PostItemType.java
@@ -6,5 +6,9 @@ public enum PostItemType implements Serializable {
MAIN,
DISCOVER,
FEED,
- SAVED
+ SAVED,
+ LIKED,
+ TAGGED,
+ HASHTAG,
+ LOCATION
}
\ No newline at end of file
diff --git a/app/src/main/java/awais/instagrabber/utils/Utils.java b/app/src/main/java/awais/instagrabber/utils/Utils.java
index 89ee1216..75874785 100755
--- a/app/src/main/java/awais/instagrabber/utils/Utils.java
+++ b/app/src/main/java/awais/instagrabber/utils/Utils.java
@@ -71,10 +71,6 @@ import javax.crypto.spec.SecretKeySpec;
import awais.instagrabber.BuildConfig;
import awais.instagrabber.R;
-import awais.instagrabber.activities.MainActivity;
-import awais.instagrabber.activities.MainActivityBackup;
-import awais.instagrabber.activities.ProfileViewer;
-import awais.instagrabber.activities.SavedViewer;
import awais.instagrabber.asyncs.DownloadAsync;
import awais.instagrabber.asyncs.PostFetcher;
import awais.instagrabber.customviews.CommentMentionClickSpan;
@@ -265,8 +261,8 @@ public final class Utils {
final int endLen = currChar != '#' ? i : i + 1; // for merged hashtags
stringBuilder.setSpan(new CommentMentionClickSpan(), startLen,
- Math.min(commentLength, endLen), // fixed - crash when end index is greater than comment length ( @kernoeb )
- Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
+ Math.min(commentLength, endLen), // fixed - crash when end index is greater than comment length ( @kernoeb )
+ Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
}
}
@@ -315,8 +311,8 @@ public final class Utils {
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.UTILS, "getHighQualityPost",
- new Pair<>("resourcesNull", resources == null),
- new Pair<>("isVideo", isVideo));
+ new Pair<>("resourcesNull", resources == null),
+ new Pair<>("isVideo", isVideo));
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
}
return null;
@@ -333,7 +329,7 @@ public final class Utils {
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.UTILS, "getHighQualityImage",
- new Pair<>("resourcesNull", resources == null));
+ new Pair<>("resourcesNull", resources == null));
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
}
return src;
@@ -346,7 +342,7 @@ public final class Utils {
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.UTILS, "getLowQualityImage",
- new Pair<>("resourcesNull", resources == null));
+ new Pair<>("resourcesNull", resources == null));
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
}
return src;
@@ -443,13 +439,13 @@ public final class Utils {
if (Utils.isEmpty(id)) id = null;
mediaModel = new DirectItemMediaModel(mediaType,
- mediaObj.optLong("expiring_at"),
- mediaObj.optLong("pk"),
- id,
- getThumbnailUrl(mediaObj, mediaType),
- mediaType == MediaItemType.MEDIA_TYPE_VIDEO ? getVideoUrl(mediaObj) : null,
- user,
- mediaObj.optString("code"));
+ mediaObj.optLong("expiring_at"),
+ mediaObj.optLong("pk"),
+ id,
+ getThumbnailUrl(mediaObj, mediaType),
+ mediaType == MediaItemType.MEDIA_TYPE_VIDEO ? getVideoUrl(mediaObj) : null,
+ user,
+ mediaObj.optString("code"));
}
return mediaModel;
}
@@ -510,28 +506,28 @@ public final class Utils {
for (int j = 0; j < usersLen; ++j) {
final JSONObject userObject = users.getJSONObject(j);
userModels[j] = new ProfileModel(userObject.getBoolean("is_private"),
- false,
- userObject.optBoolean("is_verified"),
- String.valueOf(userObject.get("pk")),
- userObject.getString("username"),
- userObject.getString("full_name"),
- null, null,
- userObject.getString("profile_pic_url"),
- null, 0, 0, 0, false, false, false, false);
+ false,
+ userObject.optBoolean("is_verified"),
+ String.valueOf(userObject.get("pk")),
+ userObject.getString("username"),
+ userObject.getString("full_name"),
+ null, null,
+ userObject.getString("profile_pic_url"),
+ null, 0, 0, 0, false, false, false, false);
}
final ProfileModel[] leftuserModels = new ProfileModel[leftusersLen];
for (int j = 0; j < leftusersLen; ++j) {
final JSONObject userObject = leftusers.getJSONObject(j);
leftuserModels[j] = new ProfileModel(userObject.getBoolean("is_private"),
- false,
- userObject.optBoolean("is_verified"),
- String.valueOf(userObject.get("pk")),
- userObject.getString("username"),
- userObject.getString("full_name"),
- null, null,
- userObject.getString("profile_pic_url"),
- null, 0, 0, 0, false, false, false, false);
+ false,
+ userObject.optBoolean("is_verified"),
+ String.valueOf(userObject.get("pk")),
+ userObject.getString("username"),
+ userObject.getString("full_name"),
+ null, null,
+ userObject.getString("profile_pic_url"),
+ null, 0, 0, 0, false, false, false, false);
}
final Long[] adminIDs = new Long[adminsLen];
@@ -564,9 +560,10 @@ public final class Utils {
final JSONObject stickerImage = animatedMedia.getJSONObject("images").getJSONObject("fixed_height");
animatedMediaModel = new DirectItemAnimatedMediaModel(animatedMedia.getBoolean("is_random"),
- animatedMedia.getBoolean("is_sticker"), animatedMedia.getString("id"),
- stickerImage.getString("url"), stickerImage.optString("webp"), stickerImage.optString("mp4"),
- stickerImage.getInt("height"), stickerImage.getInt("width"));
+ animatedMedia.getBoolean("is_sticker"), animatedMedia.getString("id"),
+ stickerImage.getString("url"), stickerImage.optString("webp"),
+ stickerImage.optString("mp4"),
+ stickerImage.getInt("height"), stickerImage.getInt("width"));
}
break;
@@ -586,8 +583,8 @@ public final class Utils {
}
voiceMediaModel = new DirectItemVoiceMediaModel(voiceMedia.getString("id"),
- audio.getString("audio_src"), audio.getLong("duration"),
- waveformData);
+ audio.getString("audio_src"), audio.getLong("duration"),
+ waveformData);
}
break;
@@ -606,9 +603,9 @@ public final class Utils {
}
linkModel = new DirectItemLinkModel(linkObj.getString("text"),
- linkObj.getString("client_context"),
- linkObj.optString("mutation_token"),
- itemLinkContext);
+ linkObj.getString("client_context"),
+ linkObj.optString("mutation_token"),
+ itemLinkContext);
}
break;
@@ -672,23 +669,23 @@ public final class Utils {
case VIDEO_CALL_EVENT: {
final JSONObject videoCallEvent = itemObject.getJSONObject("video_call_event");
videoCallEventModel = new DirectItemVideoCallEventModel(videoCallEvent.getLong("vc_id"),
- videoCallEvent.optBoolean("thread_has_audio_only_call"),
- videoCallEvent.getString("action"),
- videoCallEvent.getString("description"));
+ videoCallEvent.optBoolean("thread_has_audio_only_call"),
+ videoCallEvent.getString("action"),
+ videoCallEvent.getString("description"));
}
break;
case PROFILE: {
final JSONObject profile = itemObject.getJSONObject("profile");
profileModel = new ProfileModel(profile.getBoolean("is_private"),
- false,
- profile.getBoolean("is_verified"),
- Long.toString(profile.getLong("pk")),
- profile.getString("username"),
- profile.getString("full_name"),
- null, null,
- profile.getString("profile_pic_url"),
- null, 0, 0, 0, false, false, false, false);
+ false,
+ profile.getBoolean("is_verified"),
+ Long.toString(profile.getLong("pk")),
+ profile.getString("username"),
+ profile.getString("full_name"),
+ null, null,
+ profile.getString("profile_pic_url"),
+ null, 0, 0, 0, false, false, false, false);
}
break;
@@ -783,12 +780,12 @@ public final class Utils {
itemModels.trimToSize();
return new InboxThreadModel(readState, threadId, threadV2Id, threadType, threadTitle,
- threadNewestCursor, threadOldestCursor, threadNextCursor, threadPrevCursor,
- null, // todo
- userModels, leftuserModels, adminIDs,
- itemModels.toArray(new DirectItemModel[0]),
- muted, isPin, named, canonical,
- pending, threadHasOlder, unreadCount, isSpam, isGroup, archived, lastActivityAt);
+ threadNewestCursor, threadOldestCursor, threadNextCursor, threadPrevCursor,
+ null, // todo
+ userModels, leftuserModels, adminIDs,
+ itemModels.toArray(new DirectItemModel[0]),
+ muted, isPin, named, canonical,
+ pending, threadHasOlder, unreadCount, isSpam, isGroup, archived, lastActivityAt);
}
private static RavenExpiringMediaType getExpiringMediaType(final String type) {
@@ -945,8 +942,10 @@ public final class Utils {
ActivityCompat.requestPermissions((Activity) context, Utils.PERMS, 8020);
}
- private static void batchDownloadImpl(@NonNull final Context context, @Nullable final String username,
- final DownloadMethod method, final List extends BasePostModel> itemsToDownload) {
+ private static void batchDownloadImpl(@NonNull final Context context,
+ @Nullable final String username,
+ final DownloadMethod method,
+ final List extends BasePostModel> itemsToDownload) {
File dir = new File(Environment.getExternalStorageDirectory(), "Download");
if (settingsHelper.getBoolean(FOLDER_SAVE_TO)) {
@@ -957,61 +956,54 @@ public final class Utils {
if (settingsHelper.getBoolean(Constants.DOWNLOAD_USER_FOLDER) && !isEmpty(username))
dir = new File(dir, username);
- if (dir.exists() || dir.mkdirs()) {
- final MainActivityBackup mainActivity = method != DownloadMethod.DOWNLOAD_FEED && context instanceof MainActivityBackup ? (MainActivityBackup) context : null;
- final ProfileViewer pv = method == DownloadMethod.DOWNLOAD_MAIN && context instanceof ProfileViewer ? (ProfileViewer) context : null;
- final SavedViewer saved = method == DownloadMethod.DOWNLOAD_SAVED && context instanceof SavedViewer ? (SavedViewer) context : null;
-
- final int itemsToDownloadSize = itemsToDownload.size();
-
- final File finalDir = dir;
- for (int i = itemsToDownloadSize - 1; i >= 0; i--) {
- final BasePostModel selectedItem = itemsToDownload.get(i);
-
- if (mainActivity == null && saved == null && pv == null) {
- new DownloadAsync(context,
- selectedItem.getDisplayUrl(),
- getDownloadSaveFile(finalDir, selectedItem, ""),
- null).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-
- } else {
- new PostFetcher(selectedItem.getShortCode(), result -> {
- if (result != null) {
- final int resultsSize = result.length;
- final boolean multiResult = resultsSize > 1;
-
- for (int j = 0; j < resultsSize; j++) {
- final BasePostModel model = result[j];
- final File saveFile = getDownloadSaveFile(finalDir, model, multiResult ? "_slide_" + (j + 1) : "");
-
- new DownloadAsync(context,
- model.getDisplayUrl(),
- saveFile,
- file -> {
- model.setDownloaded(true);
- // if (saved != null)
- // saved.deselectSelection(selectedItem);
- // else if (mainActivity != null)
- // mainActivity.mainHelper.deselectSelection(selectedItem);
- // else pv.deselectSelection(selectedItem);
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- }
- // else {
- // if (saved != null) saved.deselectSelection(selectedItem);
- // else if (mainActivity != null)
- // mainActivity.mainHelper.deselectSelection(selectedItem);
- // else if (pv != null) pv.deselectSelection(selectedItem);
- // }
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- }
- } else
+ if (!dir.exists() && !dir.mkdirs()) {
Toast.makeText(context, R.string.error_creating_folders, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ boolean checkEachPost = false;
+ switch (method) {
+ case DOWNLOAD_SAVED:
+ case DOWNLOAD_MAIN:
+ checkEachPost = true;
+ break;
+ case DOWNLOAD_FEED:
+ checkEachPost = false;
+ break;
+ }
+ final int itemsToDownloadSize = itemsToDownload.size();
+ for (int i = 0; i < itemsToDownloadSize; i++) {
+ final BasePostModel selectedItem = itemsToDownload.get(i);
+ if (!checkEachPost) {
+ final boolean isSlider = itemsToDownloadSize > 1;
+ final File saveFile = getDownloadSaveFile(dir, selectedItem, isSlider ? "_slide_" + (i + 1) : "");
+ new DownloadAsync(context,
+ selectedItem.getDisplayUrl(),
+ saveFile,
+ file -> selectedItem.setDownloaded(true))
+ .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ } else {
+ final File finalDir = dir;
+ new PostFetcher(selectedItem.getShortCode(), result -> {
+ if (result != null) {
+ final int resultsSize = result.length;
+ final boolean multiResult = resultsSize > 1;
+ for (int j = 0; j < resultsSize; j++) {
+ final BasePostModel model = result[j];
+ final File saveFile = getDownloadSaveFile(finalDir, model, multiResult ? "_slide_" + (j + 1) : "");
+ new DownloadAsync(context,
+ model.getDisplayUrl(),
+ saveFile,
+ file -> model.setDownloaded(true))
+ .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+ }
+ }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+ }
}
public static void dmDownload(@NonNull final Context context, @Nullable final String username, final DownloadMethod method,
- final DirectItemMediaModel itemsToDownload) {
+ final DirectItemMediaModel itemsToDownload) {
if (settingsHelper == null) settingsHelper = new SettingsHelper(context);
if (itemsToDownload == null) return;
@@ -1023,7 +1015,7 @@ public final class Utils {
}
private static void dmDownloadImpl(@NonNull final Context context, @Nullable final String username,
- final DownloadMethod method, final DirectItemMediaModel selectedItem) {
+ final DownloadMethod method, final DirectItemMediaModel selectedItem) {
File dir = new File(Environment.getExternalStorageDirectory(), "Download");
if (settingsHelper.getBoolean(FOLDER_SAVE_TO)) {
@@ -1035,11 +1027,10 @@ public final class Utils {
dir = new File(dir, username);
if (dir.exists() || dir.mkdirs()) {
- final File finalDir = dir;
new DownloadAsync(context,
- selectedItem.getMediaType() == MediaItemType.MEDIA_TYPE_VIDEO ? selectedItem.getVideoUrl() : selectedItem.getThumbUrl(),
- getDownloadSaveFileDm(finalDir, selectedItem, ""),
- null).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ selectedItem.getMediaType() == MediaItemType.MEDIA_TYPE_VIDEO ? selectedItem.getVideoUrl() : selectedItem.getThumbUrl(),
+ getDownloadSaveFileDm(dir, selectedItem, ""),
+ null).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else
Toast.makeText(context, R.string.error_creating_folders, Toast.LENGTH_SHORT).show();
}
@@ -1104,8 +1095,8 @@ public final class Utils {
} catch (final Exception e) {
if (logCollector != null)
logCollector.appendException(e, LogCollector.LogFile.UTILS, "checkExistence",
- new Pair<>("isSlider", isSlider),
- new Pair<>("model", model));
+ new Pair<>("isSlider", isSlider),
+ new Pair<>("model", model));
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
}
@@ -1132,7 +1123,7 @@ public final class Utils {
final View importSettingsParent = (View) importExportBinding.cbImportSettings.getParent();
importExportBinding.cbPassword.setOnCheckedChangeListener((buttonView, isChecked) ->
- importExportBinding.etPassword.etPassword.setEnabled(isChecked));
+ importExportBinding.etPassword.etPassword.setEnabled(isChecked));
final AlertDialog[] dialog = new AlertDialog[1];
final View.OnClickListener onClickListener = v -> {
@@ -1171,7 +1162,8 @@ public final class Utils {
flags |= ExportImportUtils.FLAG_COOKIES;
ExportImportUtils.Export(password, flags, file, result -> {
- Toast.makeText(context, result ? R.string.dialog_export_success : R.string.dialog_export_failed, Toast.LENGTH_SHORT).show();
+ Toast.makeText(context, result ? R.string.dialog_export_success : R.string.dialog_export_failed, Toast.LENGTH_SHORT)
+ .show();
if (dialog[0] != null && dialog[0].isShowing()) dialog[0].dismiss();
});
@@ -1190,7 +1182,8 @@ public final class Utils {
ExportImportUtils.Import(context, flags, new File(path), result -> {
((AppCompatActivity) context).recreate();
- Toast.makeText(context, result ? R.string.dialog_import_success : R.string.dialog_import_failed, Toast.LENGTH_SHORT).show();
+ Toast.makeText(context, result ? R.string.dialog_import_success : R.string.dialog_import_failed, Toast.LENGTH_SHORT)
+ .show();
if (dialog[0] != null && dialog[0].isShowing()) dialog[0].dismiss();
});
@@ -1284,8 +1277,8 @@ public final class Utils {
mimeType = mimeTypeMap.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(itemUri.toString()).toLowerCase());
else
mimeType = scheme.equals(ContentResolver.SCHEME_CONTENT) ? contentResolver.getType(itemUri)
- : mimeTypeMap.getMimeTypeFromExtension
- (MimeTypeMap.getFileExtensionFromUrl(itemUri.toString()).toLowerCase());
+ : mimeTypeMap.getMimeTypeFromExtension
+ (MimeTypeMap.getFileExtensionFromUrl(itemUri.toString()).toLowerCase());
if (isEmpty(mimeType)) return true;
mimeType = mimeType.toLowerCase();
diff --git a/app/src/main/res/layout/activity_saved.xml b/app/src/main/res/layout/fragment_saved.xml
similarity index 85%
rename from app/src/main/res/layout/activity_saved.xml
rename to app/src/main/res/layout/fragment_saved.xml
index 7dbd46a1..3dee6ef6 100644
--- a/app/src/main/res/layout/activity_saved.xml
+++ b/app/src/main/res/layout/fragment_saved.xml
@@ -4,11 +4,11 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- tools:context=".activities.SavedViewer">
+ tools:context=".fragments.SavedViewerFragment">
-
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file