Browse Source

Converted SavedViewer activity to fragment

renovate/org.robolectric-robolectric-4.x
Ammar Githam 4 years ago
parent
commit
93fc9d82b9
  1. 70
      app/src/main/AndroidManifest.xml
  2. 26
      app/src/main/java/awais/instagrabber/MainHelper.java
  3. 3
      app/src/main/java/awais/instagrabber/activities/MainActivity.java
  4. 9
      app/src/main/java/awais/instagrabber/activities/PostViewer.java
  5. 25
      app/src/main/java/awais/instagrabber/activities/ProfileViewer.java
  6. 288
      app/src/main/java/awais/instagrabber/activities/SavedViewer.java
  7. 62
      app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java
  8. 11
      app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java
  9. 3
      app/src/main/java/awais/instagrabber/fragments/LocationFragment.java
  10. 20
      app/src/main/java/awais/instagrabber/fragments/PostViewFragment.java
  11. 333
      app/src/main/java/awais/instagrabber/fragments/SavedViewerFragment.java
  12. 1
      app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java
  13. 22
      app/src/main/java/awais/instagrabber/fragments/main/DiscoverFragment.java
  14. 238
      app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java
  15. 6
      app/src/main/java/awais/instagrabber/models/enums/PostItemType.java
  16. 77
      app/src/main/java/awais/instagrabber/utils/Utils.java
  17. 8
      app/src/main/res/layout/fragment_saved.xml
  18. 1
      app/src/main/res/navigation/discover_nav_graph.xml
  19. 21
      app/src/main/res/navigation/profile_nav_graph.xml

70
app/src/main/AndroidManifest.xml

@ -132,14 +132,14 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity
android:name=".activities.PostViewer"
android:parentActivityName=".activities.MainActivity">
<!--<activity-->
<!-- android:name=".activities.PostViewer"-->
<!-- android:parentActivityName=".activities.MainActivity">-->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.MainActivity" />
</activity>
<!-- <meta-data-->
<!-- android:name="android.support.PARENT_ACTIVITY"-->
<!-- android:value=".activities.MainActivity" />-->
<!--</activity>-->
<activity <activity
android:name=".activities.CommentsViewer" android:name=".activities.CommentsViewer"
@ -150,14 +150,14 @@
android:value=".activities.PostViewer" /> android:value=".activities.PostViewer" />
</activity> </activity>
<activity
android:name=".activities.StoryViewer"
android:parentActivityName=".activities.MainActivity">
<!--<activity-->
<!-- android:name=".activities.StoryViewer"-->
<!-- android:parentActivityName=".activities.MainActivity">-->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.MainActivity" />
</activity>
<!-- <meta-data-->
<!-- android:name="android.support.PARENT_ACTIVITY"-->
<!-- android:value=".activities.MainActivity" />-->
<!--</activity>-->
<activity <activity
android:name=".activities.FollowViewer" android:name=".activities.FollowViewer"
@ -177,23 +177,23 @@
android:value=".activities.MainActivity" /> android:value=".activities.MainActivity" />
</activity> </activity>
<activity
android:name=".activities.ProfileViewer"
android:parentActivityName=".activities.PostViewer">
<!--<activity-->
<!-- android:name=".activities.ProfileViewer"-->
<!-- android:parentActivityName=".activities.PostViewer">-->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.PostViewer" />
</activity>
<!-- <meta-data-->
<!-- android:name="android.support.PARENT_ACTIVITY"-->
<!-- android:value=".activities.PostViewer" />-->
<!--</activity>-->
<activity
android:name=".activities.SavedViewer"
android:parentActivityName=".activities.MainActivity">
<!--<activity-->
<!-- android:name=".activities.SavedViewerFragment"-->
<!-- android:parentActivityName=".activities.MainActivity">-->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.MainActivity" />
</activity>
<!-- <meta-data-->
<!-- android:name="android.support.PARENT_ACTIVITY"-->
<!-- android:value=".activities.MainActivity" />-->
<!--</activity>-->
<activity <activity
android:name=".activities.NotificationsViewer" android:name=".activities.NotificationsViewer"
@ -214,14 +214,14 @@
android:value=".activities.MainActivity" /> android:value=".activities.MainActivity" />
</activity> </activity>
<activity
android:name=".activities.DirectMessagesActivity"
android:parentActivityName=".activities.MainActivity">
<!--<activity-->
<!-- android:name=".activities.DirectMessagesActivity"-->
<!-- android:parentActivityName=".activities.MainActivity">-->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.MainActivity" />
</activity>
<!-- <meta-data-->
<!-- android:name="android.support.PARENT_ACTIVITY"-->
<!-- android:value=".activities.MainActivity" />-->
<!--</activity>-->
<provider <provider
android:name="androidx.core.content.FileProvider" android:name="androidx.core.content.FileProvider"

26
app/src/main/java/awais/instagrabber/MainHelper.java

@ -53,7 +53,7 @@ import awais.instagrabber.activities.CommentsViewer;
import awais.instagrabber.activities.FollowViewer; import awais.instagrabber.activities.FollowViewer;
import awais.instagrabber.activities.MainActivityBackup; import awais.instagrabber.activities.MainActivityBackup;
import awais.instagrabber.activities.PostViewer; import awais.instagrabber.activities.PostViewer;
import awais.instagrabber.activities.SavedViewer;
import awais.instagrabber.fragments.SavedViewerFragment;
import awais.instagrabber.adapters.DiscoverAdapter; import awais.instagrabber.adapters.DiscoverAdapter;
import awais.instagrabber.adapters.FeedAdapter; import awais.instagrabber.adapters.FeedAdapter;
import awais.instagrabber.adapters.PostsAdapter; import awais.instagrabber.adapters.PostsAdapter;
@ -152,7 +152,9 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
: (mainActivity.hashtagModel != null : (mainActivity.hashtagModel != null
? mainActivity.userQuery ? mainActivity.userQuery
: mainActivity.locationModel.getId()), : mainActivity.locationModel.getId()),
false,
mainActivity.profileModel != null
? PostItemType.MAIN
: (mainActivity.hashtagModel != null ? PostItemType.HASHTAG : PostItemType.LOCATION),
endCursor, endCursor,
this) this)
.setUsername((isLocation || isHashtag) ? null : mainActivity.profileModel.getUsername()) .setUsername((isLocation || isHashtag) ? null : mainActivity.profileModel.getUsername())
@ -568,7 +570,9 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
: (mainActivity.hashtagModel != null : (mainActivity.hashtagModel != null
? mainActivity.userQuery ? mainActivity.userQuery
: mainActivity.locationModel.getId()), : mainActivity.locationModel.getId()),
false,
mainActivity.profileModel != null
? PostItemType.MAIN
: (mainActivity.hashtagModel != null ? PostItemType.HASHTAG : PostItemType.LOCATION),
endCursor, endCursor,
postsFetchListener) postsFetchListener)
.setUsername((isHashtag || isLocation) ? null : mainActivity.profileModel.getUsername()) .setUsername((isHashtag || isLocation) ? null : mainActivity.profileModel.getUsername())
@ -920,7 +924,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
return; return;
} }
currentlyExecuting = new PostsFetcher(mainActivity.userQuery, postsFetchListener)
currentlyExecuting = new PostsFetcher(mainActivity.userQuery, PostItemType.HASHTAG, null, postsFetchListener)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
mainActivity.mainBinding.profileView.btnFollowTag.setVisibility(View.VISIBLE); mainActivity.mainBinding.profileView.btnFollowTag.setVisibility(View.VISIBLE);
@ -1167,7 +1171,8 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
} else { } else {
mainActivity.mainBinding.profileView.swipeRefreshLayout.setRefreshing(true); mainActivity.mainBinding.profileView.swipeRefreshLayout.setRefreshing(true);
mainActivity.mainBinding.profileView.mainPosts.setVisibility(View.VISIBLE); mainActivity.mainBinding.profileView.mainPosts.setVisibility(View.VISIBLE);
currentlyExecuting = new PostsFetcher(profileId, postsFetchListener).setUsername(profileModel.getUsername())
currentlyExecuting = new PostsFetcher(profileId, PostItemType.MAIN, null, postsFetchListener)
.setUsername(profileModel.getUsername())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
} else { } else {
@ -1274,7 +1279,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
} else { } else {
mainActivity.mainBinding.profileView.swipeRefreshLayout.setRefreshing(true); mainActivity.mainBinding.profileView.swipeRefreshLayout.setRefreshing(true);
mainActivity.mainBinding.profileView.mainPosts.setVisibility(View.VISIBLE); mainActivity.mainBinding.profileView.mainPosts.setVisibility(View.VISIBLE);
currentlyExecuting = new PostsFetcher(profileId, postsFetchListener)
currentlyExecuting = new PostsFetcher(profileId, PostItemType.LOCATION, null, postsFetchListener)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
} }
@ -1422,8 +1427,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
.setNegativeButton(R.string.no, null) .setNegativeButton(R.string.no, null)
.setPositiveButton(R.string.yes, (dialog, which) -> new ProfileAction().execute("follow")) .setPositiveButton(R.string.yes, (dialog, which) -> new ProfileAction().execute("follow"))
.show(); .show();
}
else new ProfileAction().execute("follow");
} else new ProfileAction().execute("follow");
} else if (v == mainActivity.mainBinding.profileView.btnRestrict && isLoggedIn) { } else if (v == mainActivity.mainBinding.profileView.btnRestrict && isLoggedIn) {
new ProfileAction().execute("restrict"); new ProfileAction().execute("restrict");
} else if (v == mainActivity.mainBinding.profileView.btnSaved && !isSelf) { } 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) { } else if (v == mainActivity.mainBinding.profileView.btnFollowTag) {
new ProfileAction().execute("followtag"); new ProfileAction().execute("followtag");
} else if (v == mainActivity.mainBinding.profileView.btnTagged || v == mainActivity.mainBinding.profileView.btnRestrict) { } 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_INDEX, "%" + mainActivity.profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + mainActivity.profileModel.getUsername()) .putExtra(Constants.EXTRAS_USER, "@" + mainActivity.profileModel.getUsername())
); );
} else if (v == mainActivity.mainBinding.profileView.btnSaved) { } 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_INDEX, "$" + mainActivity.profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + mainActivity.profileModel.getUsername()) .putExtra(Constants.EXTRAS_USER, "@" + mainActivity.profileModel.getUsername())
); );
} else if (v == mainActivity.mainBinding.profileView.btnLiked) { } 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_INDEX, "^" + mainActivity.profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + mainActivity.profileModel.getUsername()) .putExtra(Constants.EXTRAS_USER, "@" + mainActivity.profileModel.getUsername())
); );

3
app/src/main/java/awais/instagrabber/activities/MainActivity.java

@ -45,7 +45,8 @@ public class MainActivity extends BaseLanguageActivity {
R.id.morePreferencesFragment, R.id.morePreferencesFragment,
R.id.settingsPreferencesFragment, R.id.settingsPreferencesFragment,
R.id.hashTagFragment, R.id.hashTagFragment,
R.id.locationFragment);
R.id.locationFragment,
R.id.savedViewerFragment);
private ActivityMainBinding binding; private ActivityMainBinding binding;
private LiveData<NavController> currentNavControllerLiveData; private LiveData<NavController> currentNavControllerLiveData;

9
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 List<? extends BasePostModel> itemGetterItems;
final boolean isSwipeable; 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); itemGetterItems = MainActivityBackup.itemGetter.get(postItemType);
isSwipeable = !(itemGetterItems.size() < 1 || postItemType == PostItemType.MAIN && isFromShare); isSwipeable = !(itemGetterItems.size() < 1 || postItemType == PostItemType.MAIN && isFromShare);
} else { } else {

25
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.GridSpacingItemDecoration;
import awais.instagrabber.customviews.helpers.RecyclerLazyLoader; import awais.instagrabber.customviews.helpers.RecyclerLazyLoader;
import awais.instagrabber.databinding.ActivityProfileBinding; import awais.instagrabber.databinding.ActivityProfileBinding;
import awais.instagrabber.fragments.SavedViewerFragment;
import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.interfaces.FetchListener;
import awais.instagrabber.interfaces.MentionClickListener; import awais.instagrabber.interfaces.MentionClickListener;
import awais.instagrabber.models.BasePostModel; import awais.instagrabber.models.BasePostModel;
@ -62,6 +63,7 @@ import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.ProfileModel; import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.StoryModel; import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.DownloadMethod; import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.PostItemType;
import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.DataBox; import awais.instagrabber.utils.DataBox;
import awais.instagrabber.utils.Utils; import awais.instagrabber.utils.Utils;
@ -109,8 +111,8 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
if (autoloadPosts && hasNextPage) if (autoloadPosts && hasNextPage)
currentlyExecuting = new PostsFetcher( currentlyExecuting = new PostsFetcher(
profileModel != null ? profileModel.getId() 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, endCursor,
this) this)
.setUsername((isLocation || isHashtag) ? null : profileModel.getUsername()) .setUsername((isLocation || isHashtag) ? null : profileModel.getUsername())
@ -247,7 +249,9 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
: (hashtagModel != null : (hashtagModel != null
? ("#" + hashtagModel.getName()) ? ("#" + hashtagModel.getName())
: locationModel.getId()), : locationModel.getId()),
isHashtag,
profileModel != null
? PostItemType.MAIN
: (hashtagModel != null ? PostItemType.HASHTAG : PostItemType.LOCATION),
endCursor, postsFetchListener) endCursor, postsFetchListener)
.setUsername((isHashtag || isLocation) ? null : profileModel.getUsername()) .setUsername((isHashtag || isLocation) ? null : profileModel.getUsername())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
@ -371,7 +375,7 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
return; return;
} }
currentlyExecuting = new PostsFetcher(userQuery, postsFetchListener)
currentlyExecuting = new PostsFetcher(userQuery, PostItemType.HASHTAG, null, postsFetchListener)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
profileBinding.profileView.btnFollowTag.setVisibility(View.VISIBLE); profileBinding.profileView.btnFollowTag.setVisibility(View.VISIBLE);
@ -383,7 +387,7 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
profileBinding.profileView.mainHashtagImage.setStoriesBorder(); profileBinding.profileView.mainHashtagImage.setStoriesBorder();
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
if (hashtagModel.getFollowing() == true) {
if (hashtagModel.getFollowing()) {
profileBinding.profileView.btnFollowTag.setText(R.string.unfollow); profileBinding.profileView.btnFollowTag.setText(R.string.unfollow);
profileBinding.profileView.btnFollowTag.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor( profileBinding.profileView.btnFollowTag.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(
ProfileViewer.this, R.color.btn_purple_background))); ProfileViewer.this, R.color.btn_purple_background)));
@ -614,7 +618,8 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
} else { } else {
profileBinding.profileView.swipeRefreshLayout.setRefreshing(true); profileBinding.profileView.swipeRefreshLayout.setRefreshing(true);
profileBinding.profileView.mainPosts.setVisibility(View.VISIBLE); profileBinding.profileView.mainPosts.setVisibility(View.VISIBLE);
currentlyExecuting = new PostsFetcher(profileId, postsFetchListener).setUsername(profileModel.getUsername())
currentlyExecuting = new PostsFetcher(profileId, PostItemType.MAIN, null, postsFetchListener)
.setUsername(profileModel.getUsername())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
} else { } else {
@ -720,7 +725,7 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
} else { } else {
profileBinding.profileView.swipeRefreshLayout.setRefreshing(true); profileBinding.profileView.swipeRefreshLayout.setRefreshing(true);
profileBinding.profileView.mainPosts.setVisibility(View.VISIBLE); profileBinding.profileView.mainPosts.setVisibility(View.VISIBLE);
currentlyExecuting = new PostsFetcher(profileId, postsFetchListener)
currentlyExecuting = new PostsFetcher(profileId, PostItemType.LOCATION, null, postsFetchListener)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
} }
@ -870,17 +875,17 @@ public final class ProfileViewer extends BaseLanguageActivity implements SwipeRe
} else if (v == profileBinding.profileView.btnFollowTag) { } else if (v == profileBinding.profileView.btnFollowTag) {
new ProfileAction().execute("followtag"); new ProfileAction().execute("followtag");
} else if (v == profileBinding.profileView.btnTagged || (v == profileBinding.profileView.btnRestrict && !isLoggedIn)) { } 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_INDEX, "%" + profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername()) .putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername())
); );
} else if (v == profileBinding.profileView.btnSaved) { } 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_INDEX, "$" + profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername()) .putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername())
); );
} else if (v == profileBinding.profileView.btnLiked) { } 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_INDEX, "^" + profileModel.getId())
.putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername()) .putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername())
); );

288
app/src/main/java/awais/instagrabber/activities/SavedViewer.java

@ -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<PostModel> 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<PostModel[]> postsFetchListener = new FetchListener<PostModel[]>() {
@Override
public void onResult(final PostModel[] result) {
if (result != null) {
final List<PostModel> current = postsViewModel.getList().getValue();
final List<PostModel> resultList = Arrays.asList(result);
if (current == null) {
postsViewModel.getList().postValue(resultList);
} else {
final List<PostModel> 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;
}
}

62
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.interfaces.FetchListener;
import awais.instagrabber.models.PostModel; import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.models.enums.MediaItemType;
import awais.instagrabber.models.enums.PostItemType;
import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils; import awais.instagrabber.utils.Utils;
import awaisomereport.LogCollector; import awaisomereport.LogCollector;
@ -26,24 +27,18 @@ import static awais.instagrabber.utils.Utils.logCollector;
public final class PostsFetcher extends AsyncTask<Void, Void, PostModel[]> { public final class PostsFetcher extends AsyncTask<Void, Void, PostModel[]> {
private static final String TAG = "PostsFetcher"; private static final String TAG = "PostsFetcher";
private boolean isLocation;
private final PostItemType type;
private final String endCursor; private final String endCursor;
private final String id; private final String id;
private final FetchListener<PostModel[]> fetchListener; private final FetchListener<PostModel[]> fetchListener;
private String username = null; private String username = null;
public PostsFetcher(final String id, final FetchListener<PostModel[]> fetchListener) {
this.id = id;
this.endCursor = "";
this.fetchListener = fetchListener;
}
public PostsFetcher(final String id, public PostsFetcher(final String id,
final boolean isLocation,
final PostItemType type,
final String endCursor, final String endCursor,
final FetchListener<PostModel[]> fetchListener) { final FetchListener<PostModel[]> fetchListener) {
this.id = id; this.id = id;
this.isLocation = isLocation;
this.type = type;
this.endCursor = endCursor == null ? "" : endCursor; this.endCursor = endCursor == null ? "" : endCursor;
this.fetchListener = fetchListener; this.fetchListener = fetchListener;
} }
@ -55,27 +50,32 @@ public final class PostsFetcher extends AsyncTask<Void, Void, PostModel[]> {
@Override @Override
protected PostModel[] doInBackground(final Void... voids) { 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 boolean isLocation = id.contains("/");
final String url; final String url;
if (isHashTag)
switch (type) {
case HASHTAG:
url = "https://www.instagram.com/graphql/query/?query_hash=9b498c08113f1e09617a1703c22b2f32&variables=" + url = "https://www.instagram.com/graphql/query/?query_hash=9b498c08113f1e09617a1703c22b2f32&variables=" +
"{\"tag_name\":\"" + id.substring(1).toLowerCase() + "\",\"first\":150,\"after\":\"" + endCursor + "\"}";
else if (isLocation)
"{\"tag_name\":\"" + id.toLowerCase() + "\",\"first\":150,\"after\":\"" + endCursor + "\"}";
break;
case LOCATION:
url = "https://www.instagram.com/graphql/query/?query_hash=36bd0f2bf5911908de389b8ceaa3be6d&variables=" + url = "https://www.instagram.com/graphql/query/?query_hash=36bd0f2bf5911908de389b8ceaa3be6d&variables=" +
"{\"id\":\"" + id + "\",\"first\":150,\"after\":\"" + endCursor + "\"}"; "{\"id\":\"" + id + "\",\"first\":150,\"after\":\"" + endCursor + "\"}";
else if (isSaved)
break;
case SAVED:
url = "https://www.instagram.com/graphql/query/?query_hash=8c86fed24fa03a8a2eea2a70a80c7b6b&variables=" + 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
"{\"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; url = "https://www.instagram.com/graphql/query/?query_id=17880160963012870&id=" + id + "&first=50&after=" + endCursor;
}
PostModel[] result = null; PostModel[] result = null;
try { try {
final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
@ -95,14 +95,20 @@ public final class PostsFetcher extends AsyncTask<Void, Void, PostModel[]> {
if (!Utils.isEmpty(customPath)) customDir = new File(customPath); 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)) final JSONObject mediaPosts = new JSONObject(Utils.readFromConnection(conn))
.getJSONObject("data") .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 String endCursor;
final boolean hasNextPage; final boolean hasNextPage;

11
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.PostModel;
import awais.instagrabber.models.StoryModel; import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.DownloadMethod; import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.PostItemType;
import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils; import awais.instagrabber.utils.Utils;
import awaisomereport.LogCollector; import awaisomereport.LogCollector;
@ -78,14 +79,10 @@ public class HashTagFragment extends Fragment {
private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(false) { private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(false) {
@Override @Override
public void handleOnBackPressed() { public void handleOnBackPressed() {
if (postsAdapter == null) {
setEnabled(false); setEnabled(false);
remove(); remove();
return;
}
if (postsAdapter == null) return;
postsAdapter.clearSelection(); postsAdapter.clearSelection();
setEnabled(false);
remove();
} }
}; };
private final PrimaryActionModeCallback multiSelectAction = new PrimaryActionModeCallback( private final PrimaryActionModeCallback multiSelectAction = new PrimaryActionModeCallback(
@ -256,7 +253,9 @@ public class HashTagFragment extends Fragment {
stopCurrentExecutor(); stopCurrentExecutor();
binding.btnFollowTag.setVisibility(View.VISIBLE); binding.btnFollowTag.setVisibility(View.VISIBLE);
binding.swipeRefreshLayout.setRefreshing(true); 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) { if (isLoggedIn) {
new iStoryStatusFetcher(hashtagModel.getName(), null, false, true, false, false, stories -> { new iStoryStatusFetcher(hashtagModel.getName(), null, false, true, false, false, stories -> {
storyModels = stories; storyModels = stories;

3
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.PostModel;
import awais.instagrabber.models.StoryModel; import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.DownloadMethod; import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.PostItemType;
import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.Constants;
import awais.instagrabber.utils.Utils; import awais.instagrabber.utils.Utils;
import awaisomereport.LogCollector; import awaisomereport.LogCollector;
@ -328,7 +329,7 @@ public class LocationFragment extends Fragment {
private void fetchPosts() { private void fetchPosts() {
stopCurrentExecutor(); stopCurrentExecutor();
currentlyExecuting = new PostsFetcher(locationModel.getId(), true, endCursor, postsFetchListener)
currentlyExecuting = new PostsFetcher(locationModel.getId(), PostItemType.LOCATION, endCursor, postsFetchListener)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }

20
app/src/main/java/awais/instagrabber/fragments/PostViewFragment.java

@ -139,9 +139,11 @@ public class PostViewFragment extends Fragment {
if (mediaService != null) { if (mediaService != null) {
final String userId = Utils.getUserIdFromCookie(COOKIE); final String userId = Utils.getUserIdFromCookie(COOKIE);
final String csrfToken = Utils.getCsrfTokenFromCookie(COOKIE); final String csrfToken = Utils.getCsrfTokenFromCookie(COOKIE);
v.setEnabled(false);
final ServiceCallback<Boolean> likeCallback = new ServiceCallback<Boolean>() { final ServiceCallback<Boolean> likeCallback = new ServiceCallback<Boolean>() {
@Override @Override
public void onSuccess(final Boolean result) { public void onSuccess(final Boolean result) {
v.setEnabled(true);
if (result) { if (result) {
postModel.setManualLike(!postModel.getLike()); postModel.setManualLike(!postModel.getLike());
adapter.notifyItemChanged(postPosition); adapter.notifyItemChanged(postPosition);
@ -152,6 +154,7 @@ public class PostViewFragment extends Fragment {
@Override @Override
public void onFailure(final Throwable t) { public void onFailure(final Throwable t) {
v.setEnabled(true);
Log.e(TAG, "Error during like/unlike", t); Log.e(TAG, "Error during like/unlike", t);
} }
}; };
@ -166,9 +169,11 @@ public class PostViewFragment extends Fragment {
if (mediaService != null) { if (mediaService != null) {
final String userId = Utils.getUserIdFromCookie(COOKIE); final String userId = Utils.getUserIdFromCookie(COOKIE);
final String csrfToken = Utils.getCsrfTokenFromCookie(COOKIE); final String csrfToken = Utils.getCsrfTokenFromCookie(COOKIE);
v.setEnabled(false);
final ServiceCallback<Boolean> saveCallback = new ServiceCallback<Boolean>() { final ServiceCallback<Boolean> saveCallback = new ServiceCallback<Boolean>() {
@Override @Override
public void onSuccess(final Boolean result) { public void onSuccess(final Boolean result) {
v.setEnabled(true);
if (result) { if (result) {
postModel.setBookmarked(!postModel.getBookmark()); postModel.setBookmarked(!postModel.getBookmark());
adapter.notifyItemChanged(postPosition); adapter.notifyItemChanged(postPosition);
@ -179,6 +184,7 @@ public class PostViewFragment extends Fragment {
@Override @Override
public void onFailure(final Throwable t) { public void onFailure(final Throwable t) {
v.setEnabled(true);
Log.e(TAG, "Error during save/unsave", t); 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) { public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
if (!shouldRefresh) return; if (!shouldRefresh) return;
init(); init();
shouldRefresh = false;
} }
private void setupViewPager() { private void setupViewPager() {
@ -252,9 +259,7 @@ public class PostViewFragment extends Fragment {
idOrCodeList = Arrays.asList(idOrCodeArray); idOrCodeList = Arrays.asList(idOrCodeArray);
viewerPostViewModel.getList().setValue(createPlaceholderModels(idOrCodeArray.length)); viewerPostViewModel.getList().setValue(createPlaceholderModels(idOrCodeArray.length));
isId = fragmentArgs.getIsId(); isId = fragmentArgs.getIsId();
// binding.getRoot().postDelayed(() -> binding.getRoot().setCurrentItem(currentPostIndex), 500);
fetchPost(); fetchPost();
// binding.getRoot().setCurrentItem(currentPostIndex);
} }
private List<ViewerPostModelWrapper> createPlaceholderModels(final int size) { private List<ViewerPostModelWrapper> createPlaceholderModels(final int size) {
@ -274,17 +279,6 @@ public class PostViewFragment extends Fragment {
if (viewerPostModels != null && viewerPostModels if (viewerPostModels != null && viewerPostModels
.getViewerPostModels() != null && viewerPostModels .getViewerPostModels() != null && viewerPostModels
.getViewerPostModels().length > 0) { .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"); Log.d(TAG, "returning without fetching");
return; return;
} }

333
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<PostModel> 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<PostModel[]> postsFetchListener = new FetchListener<PostModel[]>() {
@Override
public void onResult(final PostModel[] result) {
if (result != null) {
final List<PostModel> current = postsViewModel.getList().getValue();
final List<PostModel> resultList = Arrays.asList(result);
if (current == null) {
postsViewModel.getList().postValue(resultList);
} else {
final List<PostModel> 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<List<PostModel>> 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<PostModel> 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<Void, Void, PostModel[]> 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;
}
}

1
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) { public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
if (!shouldRefresh) return; if (!shouldRefresh) return;
init(); init();
shouldRefresh = false;
} }
@Override @Override

22
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 @Override
public void handleOnBackPressed() { public void handleOnBackPressed() {
if (discoverAdapter == null) {
setEnabled(false);
remove(); remove();
return;
}
if (discoverAdapter == null) return;
discoverAdapter.clearSelection(); discoverAdapter.clearSelection();
remove();
} }
}; };
private final PrimaryActionModeCallback multiSelectAction = new PrimaryActionModeCallback( 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) { public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
if (!shouldRefresh) return; if (!shouldRefresh) return;
setupExplore(); setupExplore();
shouldRefresh = false;
} }
private void setupExplore() { private void setupExplore() {
@ -228,13 +227,13 @@ public class DiscoverFragment extends Fragment {
return true; return true;
} }
final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity.getOnBackPressedDispatcher(); final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity.getOnBackPressedDispatcher();
if (onBackPressedDispatcher.hasEnabledCallbacks()) {
if (onBackPressedCallback.isEnabled()) {
return true; return true;
} }
actionMode = fragmentActivity.startActionMode(multiSelectAction); actionMode = fragmentActivity.startActionMode(multiSelectAction);
final String title = getString(R.string.number_selected, 1); final String title = getString(R.string.number_selected, 1);
actionMode.setTitle(title); actionMode.setTitle(title);
onBackPressedDispatcher.addCallback(onBackPressedCallback);
onBackPressedDispatcher.addCallback(getViewLifecycleOwner(), onBackPressedCallback);
return true; return true;
}); });
binding.discoverPosts.setAdapter(discoverAdapter); binding.discoverPosts.setAdapter(discoverAdapter);
@ -251,12 +250,17 @@ public class DiscoverFragment extends Fragment {
} }
private boolean checkAndResetAction() { private boolean checkAndResetAction() {
final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity.getOnBackPressedDispatcher();
if (!onBackPressedDispatcher.hasEnabledCallbacks() || actionMode == null) {
if (!onBackPressedCallback.isEnabled() && actionMode == null) {
return false; return false;
} }
if (onBackPressedCallback.isEnabled()) {
onBackPressedCallback.setEnabled(false);
onBackPressedCallback.remove();
}
if (actionMode != null) {
actionMode.finish(); actionMode.finish();
actionMode = null; actionMode = null;
}
return true; return true;
} }
} }

238
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.R;
import awais.instagrabber.activities.FollowViewer; import awais.instagrabber.activities.FollowViewer;
import awais.instagrabber.activities.MainActivity; import awais.instagrabber.activities.MainActivity;
import awais.instagrabber.activities.SavedViewer;
import awais.instagrabber.adapters.PostsAdapter; import awais.instagrabber.adapters.PostsAdapter;
import awais.instagrabber.asyncs.HighlightsFetcher; import awais.instagrabber.asyncs.HighlightsFetcher;
import awais.instagrabber.asyncs.PostsFetcher; import awais.instagrabber.asyncs.PostsFetcher;
@ -61,6 +60,7 @@ import awais.instagrabber.models.PostModel;
import awais.instagrabber.models.ProfileModel; import awais.instagrabber.models.ProfileModel;
import awais.instagrabber.models.StoryModel; import awais.instagrabber.models.StoryModel;
import awais.instagrabber.models.enums.DownloadMethod; import awais.instagrabber.models.enums.DownloadMethod;
import awais.instagrabber.models.enums.PostItemType;
import awais.instagrabber.repositories.responses.FriendshipRepoChangeRootResponse; import awais.instagrabber.repositories.responses.FriendshipRepoChangeRootResponse;
import awais.instagrabber.repositories.responses.FriendshipRepoRestrictRootResponse; import awais.instagrabber.repositories.responses.FriendshipRepoRestrictRootResponse;
import awais.instagrabber.services.FriendshipService; import awais.instagrabber.services.FriendshipService;
@ -100,42 +100,36 @@ public class ProfileFragment extends Fragment {
final String finalUsername = username.startsWith("@") ? username.substring(1) final String finalUsername = username.startsWith("@") ? username.substring(1)
: username; : username;
actionBar.setTitle(finalUsername); actionBar.setTitle(finalUsername);
actionBar.setSubtitle(null);
} }
}; };
private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(true) {
private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(false) {
@Override @Override
public void handleOnBackPressed() { public void handleOnBackPressed() {
if (postsAdapter == null) {
setEnabled(false);
remove(); remove();
return;
}
if (postsAdapter == null) return;
postsAdapter.clearSelection(); postsAdapter.clearSelection();
remove();
} }
}; };
private final PrimaryActionModeCallback multiSelectAction = new PrimaryActionModeCallback(R.menu.multi_select_download_menu,
private final PrimaryActionModeCallback multiSelectAction = new PrimaryActionModeCallback(
R.menu.multi_select_download_menu,
new CallbacksHelper() { new CallbacksHelper() {
@Override @Override
public void onDestroy(
final ActionMode mode) {
onBackPressedCallback
.handleOnBackPressed();
public void onDestroy(final ActionMode mode) {
onBackPressedCallback.handleOnBackPressed();
} }
@Override @Override
public boolean onActionItemClicked(
final ActionMode mode,
final MenuItem item) {
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
if (item.getItemId() == R.id.action_download) { if (item.getItemId() == R.id.action_download) {
if (postsAdapter == null || username == null) { if (postsAdapter == null || username == null) {
return false; return false;
} }
Utils.batchDownload(
requireContext(),
Utils.batchDownload(requireContext(),
username, username,
DownloadMethod.DOWNLOAD_MAIN, DownloadMethod.DOWNLOAD_MAIN,
postsAdapter
.getSelectedModels());
postsAdapter.getSelectedModels());
checkAndResetAction(); checkAndResetAction();
return true; return true;
} }
@ -201,9 +195,18 @@ public class ProfileFragment extends Fragment {
final Bundle savedInstanceState) { final Bundle savedInstanceState) {
if (root != null) { if (root != null) {
if (getArguments() != 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; shouldRefresh = true;
return root; return root;
} }
@ -264,8 +267,7 @@ public class ProfileFragment extends Fragment {
fetchProfileDetails(); fetchProfileDetails();
// adds cookies to database for quick access // adds cookies to database for quick access
final DataBox.CookieModel cookieModel = Utils.dataBox.getCookie(uid); 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)); Utils.dataBox.addUserCookie(new DataBox.CookieModel(uid, username, cookie));
}; };
boolean found = false; boolean found = false;
@ -279,8 +281,7 @@ public class ProfileFragment extends Fragment {
} }
if (!found) { if (!found) {
// if not in database, fetch info from instagram // 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; return;
} }
@ -298,8 +299,7 @@ public class ProfileFragment extends Fragment {
private void setProfileDetails() { private void setProfileDetails() {
if (profileModel == null) { if (profileModel == null) {
binding.swipeRefreshLayout.setRefreshing(false); 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; return;
} }
binding.isVerified.setVisibility(profileModel.isVerified() ? View.VISIBLE : View.GONE); binding.isVerified.setVisibility(profileModel.isVerified() ? View.VISIBLE : View.GONE);
@ -309,7 +309,7 @@ public class ProfileFragment extends Fragment {
profileModel.getUsername(), profileModel.getUsername(),
false, false,
false, false,
(!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)),
!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG),
false, false,
result -> { result -> {
storyModels = result; storyModels = result;
@ -319,7 +319,7 @@ public class ProfileFragment extends Fragment {
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new HighlightsFetcher(profileId, new HighlightsFetcher(profileId,
(!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)),
!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG),
result -> { result -> {
if (result != null && result.length > 0) { if (result != null && result.length > 0) {
binding.highlightsList.setVisibility(View.VISIBLE); binding.highlightsList.setVisibility(View.VISIBLE);
@ -336,9 +336,7 @@ public class ProfileFragment extends Fragment {
binding.btnLiked.setVisibility(View.VISIBLE); binding.btnLiked.setVisibility(View.VISIBLE);
binding.btnSaved.setText(R.string.saved); binding.btnSaved.setText(R.string.saved);
ViewCompat.setBackgroundTintList(binding.btnSaved, 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 { } else {
binding.btnTagged.setVisibility(View.GONE); binding.btnTagged.setVisibility(View.GONE);
binding.btnSaved.setVisibility(View.GONE); binding.btnSaved.setVisibility(View.GONE);
@ -347,74 +345,54 @@ public class ProfileFragment extends Fragment {
if (profileModel.getFollowing()) { if (profileModel.getFollowing()) {
binding.btnFollow.setText(R.string.unfollow); binding.btnFollow.setText(R.string.unfollow);
ViewCompat.setBackgroundTintList(binding.btnFollow, 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()) { } else if (profileModel.getRequested()) {
binding.btnFollow.setText(R.string.cancel); binding.btnFollow.setText(R.string.cancel);
ViewCompat.setBackgroundTintList(binding.btnFollow, 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 { } else {
binding.btnFollow.setText(R.string.follow); binding.btnFollow.setText(R.string.follow);
ViewCompat.setBackgroundTintList(binding.btnFollow, 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); binding.btnRestrict.setVisibility(View.VISIBLE);
if (profileModel.getRestricted()) { if (profileModel.getRestricted()) {
binding.btnRestrict.setText(R.string.unrestrict); binding.btnRestrict.setText(R.string.unrestrict);
ViewCompat.setBackgroundTintList(binding.btnRestrict, 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 { } else {
binding.btnRestrict.setText(R.string.restrict); binding.btnRestrict.setText(R.string.restrict);
ViewCompat.setBackgroundTintList(binding.btnRestrict, 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.btnBlock.setVisibility(View.VISIBLE);
binding.btnTagged.setVisibility(View.VISIBLE); binding.btnTagged.setVisibility(View.VISIBLE);
if (profileModel.getBlocked()) { if (profileModel.getBlocked()) {
binding.btnBlock.setText(R.string.unblock); binding.btnBlock.setText(R.string.unblock);
ViewCompat.setBackgroundTintList(binding.btnBlock, 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 { } else {
binding.btnBlock.setText(R.string.block); binding.btnBlock.setText(R.string.block);
ViewCompat.setBackgroundTintList(binding.btnBlock, 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 { } else {
if (Utils.dataBox.getFavorite(username) != null) { if (Utils.dataBox.getFavorite(username) != null) {
binding.btnFollow.setText(R.string.unfavorite_short); binding.btnFollow.setText(R.string.unfavorite_short);
ViewCompat.setBackgroundTintList(binding.btnFollow, 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 { } else {
binding.btnFollow.setText(R.string.favorite_short); binding.btnFollow.setText(R.string.favorite_short);
ViewCompat.setBackgroundTintList(binding.btnFollow, 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); binding.btnFollow.setVisibility(View.VISIBLE);
if (!profileModel.isReallyPrivate()) { if (!profileModel.isReallyPrivate()) {
binding.btnRestrict.setVisibility(View.VISIBLE); binding.btnRestrict.setVisibility(View.VISIBLE);
binding.btnRestrict.setText(R.string.tagged); binding.btnRestrict.setText(R.string.tagged);
ViewCompat.setBackgroundTintList(binding.btnRestrict, 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) { if (isLoggedIn) {
final View.OnClickListener followClickListener = v -> startActivity(new Intent( final View.OnClickListener followClickListener = v -> startActivity(new Intent(
requireContext(), 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)); .putExtra(Constants.EXTRAS_ID, profileId));
binding.mainFollowers binding.mainFollowers
@ -517,29 +493,29 @@ public class ProfileFragment extends Fragment {
private void setupCommonListeners() { private void setupCommonListeners() {
final String userIdFromCookie = Utils.getUserIdFromCookie(cookie); 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); final String favorite = Utils.dataBox.getFavorite(username);
binding.btnFollow.setOnClickListener(v -> { binding.btnFollow.setOnClickListener(v -> {
if (!isLoggedIn) { if (!isLoggedIn) {
if (favorite != null && v == binding.btnFollow) { 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) { } else if (v == binding.btnFollow) {
Utils.dataBox.addFavorite(new DataBox.FavoriteModel(username,
Utils.dataBox.addFavorite(new DataBox.FavoriteModel(
username,
System.currentTimeMillis(), System.currentTimeMillis(),
username.replaceAll("^@",
"")));
username.replaceAll("^@", "")));
} }
fetchProfileDetails(); fetchProfileDetails();
return; return;
} }
if (profileModel.getFollowing() || profileModel.getRequested()) { if (profileModel.getFollowing() || profileModel.getRequested()) {
friendshipService.unfollow(userIdFromCookie,
friendshipService.unfollow(
userIdFromCookie,
profileModel.getId(), profileModel.getId(),
Utils.getCsrfTokenFromCookie(cookie), Utils.getCsrfTokenFromCookie(cookie),
new ServiceCallback<FriendshipRepoChangeRootResponse>() { new ServiceCallback<FriendshipRepoChangeRootResponse>() {
@ -555,7 +531,8 @@ public class ProfileFragment extends Fragment {
} }
}); });
} else { } else {
friendshipService.follow(userIdFromCookie,
friendshipService.follow(
userIdFromCookie,
profileModel.getId(), profileModel.getId(),
Utils.getCsrfTokenFromCookie(cookie), Utils.getCsrfTokenFromCookie(cookie),
new ServiceCallback<FriendshipRepoChangeRootResponse>() { new ServiceCallback<FriendshipRepoChangeRootResponse>() {
@ -576,7 +553,8 @@ public class ProfileFragment extends Fragment {
binding.btnRestrict.setOnClickListener(v -> { binding.btnRestrict.setOnClickListener(v -> {
if (!isLoggedIn) return; if (!isLoggedIn) return;
final String action = profileModel.getRestricted() ? "Unrestrict" : "Restrict"; final String action = profileModel.getRestricted() ? "Unrestrict" : "Restrict";
friendshipService.toggleRestrict(profileModel.getId(),
friendshipService.toggleRestrict(
profileModel.getId(),
!profileModel.getRestricted(), !profileModel.getRestricted(),
Utils.getCsrfTokenFromCookie(cookie), Utils.getCsrfTokenFromCookie(cookie),
new ServiceCallback<FriendshipRepoRestrictRootResponse>() { new ServiceCallback<FriendshipRepoRestrictRootResponse>() {
@ -588,16 +566,15 @@ public class ProfileFragment extends Fragment {
@Override @Override
public void onFailure(final Throwable t) { public void onFailure(final Throwable t) {
Log.e(TAG,
"Error while performing " + action,
t);
Log.e(TAG, "Error while performing " + action, t);
} }
}); });
}); });
binding.btnBlock.setOnClickListener(v -> { binding.btnBlock.setOnClickListener(v -> {
if (!isLoggedIn) return; if (!isLoggedIn) return;
if (profileModel.getBlocked()) { if (profileModel.getBlocked()) {
friendshipService.unblock(userIdFromCookie,
friendshipService.unblock(
userIdFromCookie,
profileModel.getId(), profileModel.getId(),
Utils.getCsrfTokenFromCookie(cookie), Utils.getCsrfTokenFromCookie(cookie),
new ServiceCallback<FriendshipRepoChangeRootResponse>() { new ServiceCallback<FriendshipRepoChangeRootResponse>() {
@ -614,7 +591,8 @@ public class ProfileFragment extends Fragment {
}); });
return; return;
} }
friendshipService.block(userIdFromCookie,
friendshipService.block(
userIdFromCookie,
profileModel.getId(), profileModel.getId(),
Utils.getCsrfTokenFromCookie(cookie), Utils.getCsrfTokenFromCookie(cookie),
new ServiceCallback<FriendshipRepoChangeRootResponse>() { new ServiceCallback<FriendshipRepoChangeRootResponse>() {
@ -630,31 +608,34 @@ public class ProfileFragment extends Fragment {
} }
}); });
}); });
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.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.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() { private void setUsernameDelayed() {
@ -666,9 +647,7 @@ public class ProfileFragment extends Fragment {
private void setupPosts() { private void setupPosts() {
postsViewModel = new ViewModelProvider(this).get(PostsViewModel.class); 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.setLayoutManager(layoutManager);
binding.mainPosts.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(4))); binding.mainPosts.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(4)));
postsAdapter = new PostsAdapter((postModel, position) -> { postsAdapter = new PostsAdapter((postModel, position) -> {
@ -680,11 +659,6 @@ public class ProfileFragment extends Fragment {
return; return;
} }
if (checkAndResetAction()) 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<PostModel> postModels = postsViewModel.getList().getValue(); final List<PostModel> postModels = postsViewModel.getList().getValue();
if (postModels == null || postModels.size() == 0) return; if (postModels == null || postModels.size() == 0) return;
if (postModels.get(0) == null) return; if (postModels.get(0) == null) return;
@ -706,24 +680,22 @@ public class ProfileFragment extends Fragment {
checkAndResetAction(); checkAndResetAction();
return true; return true;
} }
final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity
.getOnBackPressedDispatcher();
if (onBackPressedDispatcher.hasEnabledCallbacks()) {
if (onBackPressedCallback.isEnabled()) {
return true; return true;
} }
final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity.getOnBackPressedDispatcher();
onBackPressedCallback.setEnabled(true);
actionMode = fragmentActivity.startActionMode(multiSelectAction); actionMode = fragmentActivity.startActionMode(multiSelectAction);
final String title = getString(R.string.number_selected, 1); final String title = getString(R.string.number_selected, 1);
actionMode.setTitle(title); actionMode.setTitle(title);
onBackPressedDispatcher.addCallback(onBackPressedCallback);
onBackPressedDispatcher.addCallback(getViewLifecycleOwner(), onBackPressedCallback);
return true; return true;
}); });
postsViewModel.getList().observe(fragmentActivity, postsAdapter::submitList); postsViewModel.getList().observe(fragmentActivity, postsAdapter::submitList);
binding.mainPosts.setAdapter(postsAdapter); binding.mainPosts.setAdapter(postsAdapter);
final RecyclerLazyLoader lazyLoader = new RecyclerLazyLoader(layoutManager,
(page, totalItemsCount) -> {
final RecyclerLazyLoader lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
if (!hasNextPage) return; if (!hasNextPage) return;
binding.swipeRefreshLayout
.setRefreshing(true);
binding.swipeRefreshLayout.setRefreshing(true);
fetchPosts(); fetchPosts();
endCursor = null; endCursor = null;
}); });
@ -732,7 +704,7 @@ public class ProfileFragment extends Fragment {
private void fetchPosts() { private void fetchPosts() {
stopCurrentExecutor(); stopCurrentExecutor();
currentlyExecuting = new PostsFetcher(profileModel.getId(), false, endCursor, postsFetchListener)
currentlyExecuting = new PostsFetcher(profileModel.getId(), PostItemType.MAIN, endCursor, postsFetchListener)
.setUsername(profileModel.getUsername()) .setUsername(profileModel.getUsername())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
@ -742,22 +714,24 @@ public class ProfileFragment extends Fragment {
try { try {
currentlyExecuting.cancel(true); currentlyExecuting.cancel(true);
} catch (final Exception e) { } 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); Log.e(TAG, "", e);
} }
} }
} }
private boolean checkAndResetAction() { private boolean checkAndResetAction() {
final OnBackPressedDispatcher onBackPressedDispatcher = fragmentActivity
.getOnBackPressedDispatcher();
if (!onBackPressedDispatcher.hasEnabledCallbacks() || actionMode == null) {
if (!onBackPressedCallback.isEnabled() && actionMode == null) {
return false; return false;
} }
if (onBackPressedCallback.isEnabled()) {
onBackPressedCallback.setEnabled(false);
onBackPressedCallback.remove();
}
if (actionMode != null) {
actionMode.finish(); actionMode.finish();
actionMode = null; actionMode = null;
}
return true; return true;
} }
} }

6
app/src/main/java/awais/instagrabber/models/enums/PostItemType.java

@ -6,5 +6,9 @@ public enum PostItemType implements Serializable {
MAIN, MAIN,
DISCOVER, DISCOVER,
FEED, FEED,
SAVED
SAVED,
LIKED,
TAGGED,
HASHTAG,
LOCATION
} }

77
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.BuildConfig;
import awais.instagrabber.R; 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.DownloadAsync;
import awais.instagrabber.asyncs.PostFetcher; import awais.instagrabber.asyncs.PostFetcher;
import awais.instagrabber.customviews.CommentMentionClickSpan; import awais.instagrabber.customviews.CommentMentionClickSpan;
@ -565,7 +561,8 @@ public final class Utils {
animatedMediaModel = new DirectItemAnimatedMediaModel(animatedMedia.getBoolean("is_random"), animatedMediaModel = new DirectItemAnimatedMediaModel(animatedMedia.getBoolean("is_random"),
animatedMedia.getBoolean("is_sticker"), animatedMedia.getString("id"), animatedMedia.getBoolean("is_sticker"), animatedMedia.getString("id"),
stickerImage.getString("url"), stickerImage.optString("webp"), stickerImage.optString("mp4"),
stickerImage.getString("url"), stickerImage.optString("webp"),
stickerImage.optString("mp4"),
stickerImage.getInt("height"), stickerImage.getInt("width")); stickerImage.getInt("height"), stickerImage.getInt("width"));
} }
break; break;
@ -945,8 +942,10 @@ public final class Utils {
ActivityCompat.requestPermissions((Activity) context, Utils.PERMS, 8020); 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"); File dir = new File(Environment.getExternalStorageDirectory(), "Download");
if (settingsHelper.getBoolean(FOLDER_SAVE_TO)) { if (settingsHelper.getBoolean(FOLDER_SAVE_TO)) {
@ -957,57 +956,50 @@ public final class Utils {
if (settingsHelper.getBoolean(Constants.DOWNLOAD_USER_FOLDER) && !isEmpty(username)) if (settingsHelper.getBoolean(Constants.DOWNLOAD_USER_FOLDER) && !isEmpty(username))
dir = new File(dir, 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;
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(); final int itemsToDownloadSize = itemsToDownload.size();
final File finalDir = dir;
for (int i = itemsToDownloadSize - 1; i >= 0; i--) {
for (int i = 0; i < itemsToDownloadSize; i++) {
final BasePostModel selectedItem = itemsToDownload.get(i); final BasePostModel selectedItem = itemsToDownload.get(i);
if (mainActivity == null && saved == null && pv == null) {
if (!checkEachPost) {
final boolean isSlider = itemsToDownloadSize > 1;
final File saveFile = getDownloadSaveFile(dir, selectedItem, isSlider ? "_slide_" + (i + 1) : "");
new DownloadAsync(context, new DownloadAsync(context,
selectedItem.getDisplayUrl(), selectedItem.getDisplayUrl(),
getDownloadSaveFile(finalDir, selectedItem, ""),
null).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
saveFile,
file -> selectedItem.setDownloaded(true))
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else { } else {
final File finalDir = dir;
new PostFetcher(selectedItem.getShortCode(), result -> { new PostFetcher(selectedItem.getShortCode(), result -> {
if (result != null) { if (result != null) {
final int resultsSize = result.length; final int resultsSize = result.length;
final boolean multiResult = resultsSize > 1; final boolean multiResult = resultsSize > 1;
for (int j = 0; j < resultsSize; j++) { for (int j = 0; j < resultsSize; j++) {
final BasePostModel model = result[j]; final BasePostModel model = result[j];
final File saveFile = getDownloadSaveFile(finalDir, model, multiResult ? "_slide_" + (j + 1) : ""); final File saveFile = getDownloadSaveFile(finalDir, model, multiResult ? "_slide_" + (j + 1) : "");
new DownloadAsync(context, new DownloadAsync(context,
model.getDisplayUrl(), model.getDisplayUrl(),
saveFile, 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);
file -> model.setDownloaded(true))
.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); }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
} }
} else
Toast.makeText(context, R.string.error_creating_folders, Toast.LENGTH_SHORT).show();
} }
public static void dmDownload(@NonNull final Context context, @Nullable final String username, final DownloadMethod method, public static void dmDownload(@NonNull final Context context, @Nullable final String username, final DownloadMethod method,
@ -1035,10 +1027,9 @@ public final class Utils {
dir = new File(dir, username); dir = new File(dir, username);
if (dir.exists() || dir.mkdirs()) { if (dir.exists() || dir.mkdirs()) {
final File finalDir = dir;
new DownloadAsync(context, new DownloadAsync(context,
selectedItem.getMediaType() == MediaItemType.MEDIA_TYPE_VIDEO ? selectedItem.getVideoUrl() : selectedItem.getThumbUrl(), selectedItem.getMediaType() == MediaItemType.MEDIA_TYPE_VIDEO ? selectedItem.getVideoUrl() : selectedItem.getThumbUrl(),
getDownloadSaveFileDm(finalDir, selectedItem, ""),
getDownloadSaveFileDm(dir, selectedItem, ""),
null).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); null).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else } else
Toast.makeText(context, R.string.error_creating_folders, Toast.LENGTH_SHORT).show(); Toast.makeText(context, R.string.error_creating_folders, Toast.LENGTH_SHORT).show();
@ -1171,7 +1162,8 @@ public final class Utils {
flags |= ExportImportUtils.FLAG_COOKIES; flags |= ExportImportUtils.FLAG_COOKIES;
ExportImportUtils.Export(password, flags, file, result -> { 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(); 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 -> { ExportImportUtils.Import(context, flags, new File(path), result -> {
((AppCompatActivity) context).recreate(); ((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(); if (dialog[0] != null && dialog[0].isShowing()) dialog[0].dismiss();
}); });

8
app/src/main/res/layout/activity_saved.xml → app/src/main/res/layout/fragment_saved.xml

@ -4,11 +4,11 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
tools:context=".activities.SavedViewer">
tools:context=".fragments.SavedViewerFragment">
<include
android:id="@+id/toolbar"
layout="@layout/layout_include_toolbar" />
<!--<include-->
<!-- android:id="@+id/toolbar"-->
<!-- layout="@layout/layout_include_toolbar" />-->
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout" android:id="@+id/swipeRefreshLayout"

1
app/src/main/res/navigation/discover_nav_graph.xml

@ -6,6 +6,7 @@
app:startDestination="@id/discoverFragment"> app:startDestination="@id/discoverFragment">
<include app:graph="@navigation/post_view_nav_graph" /> <include app:graph="@navigation/post_view_nav_graph" />
<include app:graph="@navigation/profile_nav_graph" />
<action <action
android:id="@+id/action_global_postViewFragment" android:id="@+id/action_global_postViewFragment"

21
app/src/main/res/navigation/profile_nav_graph.xml

@ -52,5 +52,26 @@
android:defaultValue="" android:defaultValue=""
app:argType="string" app:argType="string"
app:nullable="true" /> app:nullable="true" />
<action
android:id="@+id/action_profileFragment_to_savedViewerFragment"
app:destination="@id/savedViewerFragment" />
</fragment>
<fragment
android:id="@+id/savedViewerFragment"
android:name="awais.instagrabber.fragments.SavedViewerFragment"
android:label="Saved"
tools:layout="@layout/fragment_saved">
<argument
android:name="username"
app:argType="string"
app:nullable="false" />
<argument
android:name="profileId"
app:argType="string"
app:nullable="false" />
<argument
android:name="type"
app:argType="awais.instagrabber.models.enums.PostItemType"
app:nullable="false" />
</fragment> </fragment>
</navigation> </navigation>
Loading…
Cancel
Save