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