Preferences! Check description
1. Added preferences screens. 2. Some DM changes. 3. Init profile actions using services
| @ -39,6 +39,7 @@ android { | |||||||
| dependencies { | dependencies { | ||||||
|     def appcompat_version = "1.2.0" |     def appcompat_version = "1.2.0" | ||||||
|     def nav_version = "2.3.0" |     def nav_version = "2.3.0" | ||||||
|  |     def preference_version = "1.1.1" | ||||||
| 
 | 
 | ||||||
|     implementation "androidx.appcompat:appcompat:$appcompat_version" |     implementation "androidx.appcompat:appcompat:$appcompat_version" | ||||||
|     // For loading and tinting drawables on older versions of the platform |     // For loading and tinting drawables on older versions of the platform | ||||||
| @ -50,6 +51,8 @@ dependencies { | |||||||
|     implementation "androidx.navigation:navigation-fragment:$nav_version" |     implementation "androidx.navigation:navigation-fragment:$nav_version" | ||||||
|     implementation "androidx.navigation:navigation-ui:$nav_version" |     implementation "androidx.navigation:navigation-ui:$nav_version" | ||||||
|     implementation "androidx.constraintlayout:constraintlayout:2.0.0" |     implementation "androidx.constraintlayout:constraintlayout:2.0.0" | ||||||
|  |     implementation "androidx.preference:preference:$preference_version" | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|     implementation 'org.jsoup:jsoup:1.13.1' |     implementation 'org.jsoup:jsoup:1.13.1' | ||||||
|     implementation 'com.github.bumptech.glide:glide:4.11.0' |     implementation 'com.github.bumptech.glide:glide:4.11.0' | ||||||
| @ -59,6 +62,7 @@ dependencies { | |||||||
| 
 | 
 | ||||||
|     implementation 'com.squareup.retrofit2:retrofit:2.9.0' |     implementation 'com.squareup.retrofit2:retrofit:2.9.0' | ||||||
|     implementation 'com.squareup.retrofit2:converter-scalars:2.9.0' |     implementation 'com.squareup.retrofit2:converter-scalars:2.9.0' | ||||||
|  |     implementation 'com.squareup.retrofit2:converter-gson:2.9.0' | ||||||
| 
 | 
 | ||||||
|     annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0' |     annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0' | ||||||
| } | } | ||||||
|  | |||||||
| @ -1372,12 +1372,15 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener { | |||||||
|         public void onClick(final View v) { |         public void onClick(final View v) { | ||||||
|             final String userIdFromCookie = Utils.getUserIdFromCookie(MainHelper.this.cookie); |             final String userIdFromCookie = Utils.getUserIdFromCookie(MainHelper.this.cookie); | ||||||
|             final boolean isSelf = (isLoggedIn && mainActivity.profileModel != null) && userIdFromCookie != null && userIdFromCookie.equals(mainActivity.profileModel.getId()); |             final boolean isSelf = (isLoggedIn && mainActivity.profileModel != null) && userIdFromCookie != null && userIdFromCookie.equals(mainActivity.profileModel.getId()); | ||||||
|             if (!isLoggedIn && Utils.dataBox.getFavorite(mainActivity.userQuery) != null && v == mainActivity.mainBinding.profileView.btnFollow) { |             if (!isLoggedIn | ||||||
|  |                     && Utils.dataBox.getFavorite(mainActivity.userQuery) != null | ||||||
|  |                     && v == mainActivity.mainBinding.profileView.btnFollow) { | ||||||
|                 Utils.dataBox.delFavorite(new DataBox.FavoriteModel(mainActivity.userQuery, |                 Utils.dataBox.delFavorite(new DataBox.FavoriteModel(mainActivity.userQuery, | ||||||
|                         Long.parseLong(Utils.dataBox.getFavorite(mainActivity.userQuery).split("/")[1]), |                         Long.parseLong(Utils.dataBox.getFavorite(mainActivity.userQuery).split("/")[1]), | ||||||
|                         mainActivity.locationModel != null ? mainActivity.locationModel.getName() : mainActivity.userQuery.replaceAll("^@", ""))); |                         mainActivity.locationModel != null ? mainActivity.locationModel.getName() : mainActivity.userQuery.replaceAll("^@", ""))); | ||||||
|                 onRefresh(); |                 onRefresh(); | ||||||
|             } else if (!isLoggedIn && (v == mainActivity.mainBinding.profileView.btnFollow || v == mainActivity.mainBinding.profileView.btnFollowTag)) { |             } else if (!isLoggedIn | ||||||
|  |                     && (v == mainActivity.mainBinding.profileView.btnFollow || v == mainActivity.mainBinding.profileView.btnFollowTag)) { | ||||||
|                 Utils.dataBox.addFavorite(new DataBox.FavoriteModel(mainActivity.userQuery, System.currentTimeMillis(), |                 Utils.dataBox.addFavorite(new DataBox.FavoriteModel(mainActivity.userQuery, System.currentTimeMillis(), | ||||||
|                         mainActivity.locationModel != null ? mainActivity.locationModel.getName() : mainActivity.userQuery.replaceAll("^@", ""))); |                         mainActivity.locationModel != null ? mainActivity.locationModel.getName() : mainActivity.userQuery.replaceAll("^@", ""))); | ||||||
|                 onRefresh(); |                 onRefresh(); | ||||||
| @ -1389,7 +1392,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener { | |||||||
|                 new ProfileAction().execute("block"); |                 new ProfileAction().execute("block"); | ||||||
|             } else if (v == mainActivity.mainBinding.profileView.btnFollowTag) { |             } else if (v == mainActivity.mainBinding.profileView.btnFollowTag) { | ||||||
|                 new ProfileAction().execute("followtag"); |                 new ProfileAction().execute("followtag"); | ||||||
|             } else if (v == mainActivity.mainBinding.profileView.btnTagged || (v == mainActivity.mainBinding.profileView.btnRestrict && !isLoggedIn)) { |             } else if (v == mainActivity.mainBinding.profileView.btnTagged || v == mainActivity.mainBinding.profileView.btnRestrict) { | ||||||
|                 mainActivity.startActivity(new Intent(mainActivity, SavedViewer.class) |                 mainActivity.startActivity(new Intent(mainActivity, SavedViewer.class) | ||||||
|                         .putExtra(Constants.EXTRAS_INDEX, "%" + mainActivity.profileModel.getId()) |                         .putExtra(Constants.EXTRAS_INDEX, "%" + mainActivity.profileModel.getId()) | ||||||
|                         .putExtra(Constants.EXTRAS_USER, "@" + mainActivity.profileModel.getUsername()) |                         .putExtra(Constants.EXTRAS_USER, "@" + mainActivity.profileModel.getUsername()) | ||||||
|  | |||||||
| @ -15,7 +15,7 @@ public abstract class BaseLanguageActivity extends AppCompatActivity { | |||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     protected void onCreate(@Nullable final Bundle savedInstanceState) { |     protected void onCreate(@Nullable final Bundle savedInstanceState) { | ||||||
|         Utils.changeTheme(this); |         Utils.changeTheme(getApplicationContext()); | ||||||
|         super.onCreate(savedInstanceState); |         super.onCreate(savedInstanceState); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,7 +1,9 @@ | |||||||
| package awais.instagrabber.activities; | package awais.instagrabber.activities; | ||||||
| 
 | 
 | ||||||
| import android.annotation.SuppressLint; | import android.annotation.SuppressLint; | ||||||
|  | import android.content.Intent; | ||||||
| import android.graphics.Bitmap; | import android.graphics.Bitmap; | ||||||
|  | import android.net.Uri; | ||||||
| import android.os.Build; | import android.os.Build; | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.view.View; | import android.view.View; | ||||||
| @ -36,9 +38,9 @@ public final class Login extends BaseLanguageActivity implements View.OnClickLis | |||||||
|             final String mainCookie = Utils.getCookie(url); |             final String mainCookie = Utils.getCookie(url); | ||||||
|             if (Utils.isEmpty(mainCookie) || !mainCookie.contains("; ds_user_id=")) ready = true; |             if (Utils.isEmpty(mainCookie) || !mainCookie.contains("; ds_user_id=")) ready = true; | ||||||
|             else if (mainCookie.contains("; ds_user_id=") && ready) { |             else if (mainCookie.contains("; ds_user_id=") && ready) { | ||||||
|                 Utils.setupCookies(mainCookie); |                 final Intent intent = new Intent(); | ||||||
|                 settingsHelper.putString(Constants.COOKIE, mainCookie); |                 intent.putExtra("cookie", mainCookie); | ||||||
|                 Toast.makeText(getApplicationContext(), R.string.login_success_loading_cookies, Toast.LENGTH_SHORT).show(); |                 setResult(Constants.LOGIN_RESULT_CODE, intent); | ||||||
|                 finish(); |                 finish(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @ -95,7 +97,6 @@ public final class Login extends BaseLanguageActivity implements View.OnClickLis | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @SuppressLint("SetJavaScriptEnabled") |     @SuppressLint("SetJavaScriptEnabled") | ||||||
|     @SuppressWarnings("deprecation") |  | ||||||
|     private void initWebView() { |     private void initWebView() { | ||||||
|         if (loginBinding != null) { |         if (loginBinding != null) { | ||||||
|             loginBinding.webView.setWebChromeClient(webChromeClient); |             loginBinding.webView.setWebChromeClient(webChromeClient); | ||||||
|  | |||||||
| @ -31,6 +31,19 @@ import static awais.instagrabber.utils.Utils.settingsHelper; | |||||||
| public class MainActivity extends BaseLanguageActivity { | public class MainActivity extends BaseLanguageActivity { | ||||||
|     private static final String TAG = "MainActivity"; |     private static final String TAG = "MainActivity"; | ||||||
| 
 | 
 | ||||||
|  |     private static final List<Integer> SHOW_BOTTOM_VIEW_DESTINATIONS = Arrays.asList( | ||||||
|  |             R.id.directMessagesInboxFragment, | ||||||
|  |             R.id.feedFragment, | ||||||
|  |             R.id.profileFragment, | ||||||
|  |             R.id.discoverFragment, | ||||||
|  |             R.id.morePreferencesFragment); | ||||||
|  |     private static final List<Integer> KEEP_SCROLL_BEHAVIOUR_DESTINATIONS = Arrays.asList( | ||||||
|  |             R.id.directMessagesInboxFragment, | ||||||
|  |             R.id.feedFragment, | ||||||
|  |             R.id.profileFragment, | ||||||
|  |             R.id.discoverFragment, | ||||||
|  |             R.id.morePreferencesFragment, | ||||||
|  |             R.id.settingsPreferencesFragment); | ||||||
|     private ActivityMainBinding binding; |     private ActivityMainBinding binding; | ||||||
|     private LiveData<NavController> currentNavControllerLiveData; |     private LiveData<NavController> currentNavControllerLiveData; | ||||||
| 
 | 
 | ||||||
| @ -69,17 +82,16 @@ public class MainActivity extends BaseLanguageActivity { | |||||||
|                 R.navigation.direct_messages_nav_graph, |                 R.navigation.direct_messages_nav_graph, | ||||||
|                 R.navigation.feed_nav_graph, |                 R.navigation.feed_nav_graph, | ||||||
|                 R.navigation.profile_nav_graph, |                 R.navigation.profile_nav_graph, | ||||||
|                 R.navigation.discover_nav_graph |                 R.navigation.discover_nav_graph, | ||||||
|  |                 R.navigation.more_nav_graph | ||||||
|         )); |         )); | ||||||
| 
 |  | ||||||
|         binding.bottomNavView.setSelectedItemId(R.id.feed_nav_graph); |  | ||||||
|         final LiveData<NavController> navControllerLiveData = setupWithNavController( |         final LiveData<NavController> navControllerLiveData = setupWithNavController( | ||||||
|                 binding.bottomNavView, |                 binding.bottomNavView, | ||||||
|                 navList, |                 navList, | ||||||
|                 getSupportFragmentManager(), |                 getSupportFragmentManager(), | ||||||
|                 R.id.main_nav_host, |                 R.id.main_nav_host, | ||||||
|                 getIntent(), |                 getIntent(), | ||||||
|                 1); |                 0); | ||||||
|         navControllerLiveData.observe(this, this::setupNavigation); |         navControllerLiveData.observe(this, this::setupNavigation); | ||||||
|         currentNavControllerLiveData = navControllerLiveData; |         currentNavControllerLiveData = navControllerLiveData; | ||||||
|     } |     } | ||||||
| @ -89,19 +101,12 @@ public class MainActivity extends BaseLanguageActivity { | |||||||
|         navController.addOnDestinationChangedListener((controller, destination, arguments) -> { |         navController.addOnDestinationChangedListener((controller, destination, arguments) -> { | ||||||
|             binding.appBarLayout.setExpanded(true, true); |             binding.appBarLayout.setExpanded(true, true); | ||||||
|             final int destinationId = destination.getId(); |             final int destinationId = destination.getId(); | ||||||
|             final List<Integer> showBottomView = Arrays.asList( |             binding.bottomNavView.setVisibility(SHOW_BOTTOM_VIEW_DESTINATIONS.contains(destinationId) ? View.VISIBLE : View.GONE); | ||||||
|                     R.id.directMessagesInboxFragment, |             if (KEEP_SCROLL_BEHAVIOUR_DESTINATIONS.contains(destinationId)) { | ||||||
|                     R.id.feedFragment, |  | ||||||
|                     R.id.profileFragment, |  | ||||||
|                     R.id.discoverFragment); |  | ||||||
| 
 |  | ||||||
|             if (showBottomView.contains(destinationId)) { |  | ||||||
|                 setScrollingBehaviour(); |                 setScrollingBehaviour(); | ||||||
|                 binding.bottomNavView.setVisibility(View.VISIBLE); |             } else { | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|                 removeScrollingBehaviour(); |                 removeScrollingBehaviour(); | ||||||
|             binding.bottomNavView.setVisibility(View.GONE); |             } | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -41,7 +41,6 @@ import awais.instagrabber.asyncs.SuggestionsFetcher; | |||||||
| import awais.instagrabber.asyncs.UsernameFetcher; | import awais.instagrabber.asyncs.UsernameFetcher; | ||||||
| import awais.instagrabber.asyncs.i.iStoryStatusFetcher; | import awais.instagrabber.asyncs.i.iStoryStatusFetcher; | ||||||
| import awais.instagrabber.customviews.MouseDrawer; | import awais.instagrabber.customviews.MouseDrawer; | ||||||
| import awais.instagrabber.databinding.ActivityMainBinding; |  | ||||||
| import awais.instagrabber.databinding.ActivityMainbackupBinding; | import awais.instagrabber.databinding.ActivityMainbackupBinding; | ||||||
| import awais.instagrabber.dialogs.AboutDialog; | import awais.instagrabber.dialogs.AboutDialog; | ||||||
| import awais.instagrabber.dialogs.QuickAccessDialog; | import awais.instagrabber.dialogs.QuickAccessDialog; | ||||||
| @ -95,8 +94,7 @@ public final class MainActivityBackup extends BaseLanguageActivity { | |||||||
|                         //         .putExtra(Constants.EXTRAS_HIGHLIGHT, highlightModel.getTitle()) |                         //         .putExtra(Constants.EXTRAS_HIGHLIGHT, highlightModel.getTitle()) | ||||||
|                         //         .putExtra(Constants.EXTRAS_STORIES, result) |                         //         .putExtra(Constants.EXTRAS_STORIES, result) | ||||||
|                         // ); |                         // ); | ||||||
|                     } |                     } else | ||||||
|                     else |  | ||||||
|                         Toast.makeText(MainActivityBackup.this, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show(); |                         Toast.makeText(MainActivityBackup.this, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show(); | ||||||
|                 }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |                 }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | ||||||
|             } |             } | ||||||
| @ -105,7 +103,8 @@ public final class MainActivityBackup extends BaseLanguageActivity { | |||||||
| 
 | 
 | ||||||
|     private SuggestionsAdapter suggestionAdapter; |     private SuggestionsAdapter suggestionAdapter; | ||||||
|     private MenuItem searchAction; |     private MenuItem searchAction; | ||||||
|     public @NonNull ActivityMainbackupBinding mainBinding; |     public @NonNull | ||||||
|  |     ActivityMainbackupBinding mainBinding; | ||||||
|     public SearchView searchView; |     public SearchView searchView; | ||||||
|     public MenuItem downloadAction, settingsAction, dmsAction, notifAction; |     public MenuItem downloadAction, settingsAction, dmsAction, notifAction; | ||||||
|     public StoryModel[] storyModels; |     public StoryModel[] storyModels; | ||||||
| @ -253,7 +252,7 @@ public final class MainActivityBackup extends BaseLanguageActivity { | |||||||
|         final boolean isQueryNull = userQuery == null; |         final boolean isQueryNull = userQuery == null; | ||||||
|         if (isQueryNull) { |         if (isQueryNull) { | ||||||
|             allItems.clear(); |             allItems.clear(); | ||||||
|             mainBinding.profileView.privatePage1.setImageResource(R.drawable.ic_info); |             mainBinding.profileView.privatePage1.setImageResource(R.drawable.ic_outline_info_24); | ||||||
|             mainBinding.profileView.privatePage2.setTextSize(20); |             mainBinding.profileView.privatePage2.setTextSize(20); | ||||||
|             mainBinding.profileView.privatePage2.setText(isLoggedIn ? R.string.no_acc_logged_in : R.string.no_acc); |             mainBinding.profileView.privatePage2.setText(isLoggedIn ? R.string.no_acc_logged_in : R.string.no_acc); | ||||||
|             mainBinding.profileView.privatePage.setVisibility(View.VISIBLE); |             mainBinding.profileView.privatePage.setVisibility(View.VISIBLE); | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ import androidx.recyclerview.widget.DiffUtil; | |||||||
| import androidx.recyclerview.widget.ListAdapter; | import androidx.recyclerview.widget.ListAdapter; | ||||||
| 
 | 
 | ||||||
| import awais.instagrabber.adapters.viewholder.DirectMessageInboxItemViewHolder; | import awais.instagrabber.adapters.viewholder.DirectMessageInboxItemViewHolder; | ||||||
| import awais.instagrabber.databinding.LayoutIncludeSimpleItemBinding; | import awais.instagrabber.databinding.LayoutDmInboxItemBinding; | ||||||
| import awais.instagrabber.models.direct_messages.InboxThreadModel; | import awais.instagrabber.models.direct_messages.InboxThreadModel; | ||||||
| 
 | 
 | ||||||
| public final class DirectMessageInboxAdapter extends ListAdapter<InboxThreadModel, DirectMessageInboxItemViewHolder> { | public final class DirectMessageInboxAdapter extends ListAdapter<InboxThreadModel, DirectMessageInboxItemViewHolder> { | ||||||
| @ -35,7 +35,7 @@ public final class DirectMessageInboxAdapter extends ListAdapter<InboxThreadMode | |||||||
|     @Override |     @Override | ||||||
|     public DirectMessageInboxItemViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int type) { |     public DirectMessageInboxItemViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int type) { | ||||||
|         final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext()); |         final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext()); | ||||||
|         final LayoutIncludeSimpleItemBinding binding = LayoutIncludeSimpleItemBinding.inflate(layoutInflater, parent, false); |         final LayoutDmInboxItemBinding binding = LayoutDmInboxItemBinding.inflate(layoutInflater, parent, false); | ||||||
|         return new DirectMessageInboxItemViewHolder(binding); |         return new DirectMessageInboxItemViewHolder(binding); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,18 +2,16 @@ package awais.instagrabber.adapters.viewholder; | |||||||
| 
 | 
 | ||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.view.View; | import android.view.View; | ||||||
| import android.widget.ImageView; |  | ||||||
| import android.widget.LinearLayout; | import android.widget.LinearLayout; | ||||||
| 
 | 
 | ||||||
| import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||||
| import androidx.core.text.HtmlCompat; | import androidx.core.text.HtmlCompat; | ||||||
| import androidx.recyclerview.widget.RecyclerView; | import androidx.recyclerview.widget.RecyclerView; | ||||||
| 
 | 
 | ||||||
| import com.bumptech.glide.Glide; | import com.facebook.drawee.view.SimpleDraweeView; | ||||||
| import com.bumptech.glide.RequestManager; |  | ||||||
| 
 | 
 | ||||||
| import awais.instagrabber.R; | import awais.instagrabber.R; | ||||||
| import awais.instagrabber.databinding.LayoutIncludeSimpleItemBinding; | import awais.instagrabber.databinding.LayoutDmInboxItemBinding; | ||||||
| import awais.instagrabber.models.ProfileModel; | import awais.instagrabber.models.ProfileModel; | ||||||
| import awais.instagrabber.models.direct_messages.DirectItemModel; | import awais.instagrabber.models.direct_messages.DirectItemModel; | ||||||
| import awais.instagrabber.models.direct_messages.InboxThreadModel; | import awais.instagrabber.models.direct_messages.InboxThreadModel; | ||||||
| @ -21,19 +19,18 @@ import awais.instagrabber.models.enums.DirectItemType; | |||||||
| 
 | 
 | ||||||
| public final class DirectMessageInboxItemViewHolder extends RecyclerView.ViewHolder { | public final class DirectMessageInboxItemViewHolder extends RecyclerView.ViewHolder { | ||||||
|     private final LinearLayout multipleProfilePicsContainer; |     private final LinearLayout multipleProfilePicsContainer; | ||||||
|     private final ImageView[] multipleProfilePics; |     private final SimpleDraweeView[] multipleProfilePics; | ||||||
|     private final LayoutIncludeSimpleItemBinding binding; |     private final LayoutDmInboxItemBinding binding; | ||||||
| 
 | 
 | ||||||
|     public DirectMessageInboxItemViewHolder(@NonNull final LayoutIncludeSimpleItemBinding binding) { |     public DirectMessageInboxItemViewHolder(@NonNull final LayoutDmInboxItemBinding binding) { | ||||||
|         super(binding.getRoot()); |         super(binding.getRoot()); | ||||||
|         this.binding = binding; |         this.binding = binding; | ||||||
|         binding.tvLikes.setVisibility(View.GONE); |         multipleProfilePicsContainer = binding.multiPicContainer; | ||||||
|         multipleProfilePicsContainer = binding.container; |  | ||||||
|         final LinearLayout containerChild = (LinearLayout) multipleProfilePicsContainer.getChildAt(1); |         final LinearLayout containerChild = (LinearLayout) multipleProfilePicsContainer.getChildAt(1); | ||||||
|         multipleProfilePics = new ImageView[]{ |         multipleProfilePics = new SimpleDraweeView[]{ | ||||||
|                 (ImageView) multipleProfilePicsContainer.getChildAt(0), |                 (SimpleDraweeView) multipleProfilePicsContainer.getChildAt(0), | ||||||
|                 (ImageView) containerChild.getChildAt(0), |                 (SimpleDraweeView) containerChild.getChildAt(0), | ||||||
|                 (ImageView) containerChild.getChildAt(1) |                 (SimpleDraweeView) containerChild.getChildAt(1) | ||||||
|         }; |         }; | ||||||
|         binding.tvDate.setSelected(true); |         binding.tvDate.setSelected(true); | ||||||
|         binding.tvUsername.setSelected(true); |         binding.tvUsername.setSelected(true); | ||||||
| @ -45,17 +42,17 @@ public final class DirectMessageInboxItemViewHolder extends RecyclerView.ViewHol | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         itemView.setTag(model); |         itemView.setTag(model); | ||||||
|         final RequestManager glideRequestManager = Glide.with(itemView); |  | ||||||
|         final ProfileModel[] users = model.getUsers(); |         final ProfileModel[] users = model.getUsers(); | ||||||
|         if (users.length > 1) { |         if (users.length > 1) { | ||||||
|             binding.ivProfilePic.setVisibility(View.GONE); |             binding.ivProfilePic.setVisibility(View.GONE); | ||||||
|             multipleProfilePicsContainer.setVisibility(View.VISIBLE); |             multipleProfilePicsContainer.setVisibility(View.VISIBLE); | ||||||
|             for (int i = 0; i < Math.min(3, users.length); ++i) |             for (int i = 0; i < Math.min(3, users.length); ++i) { | ||||||
|                 glideRequestManager.load(users[i].getSdProfilePic()).into(multipleProfilePics[i]); |                 multipleProfilePics[i].setImageURI(users[i].getSdProfilePic()); | ||||||
|  |             } | ||||||
|         } else { |         } else { | ||||||
|             binding.ivProfilePic.setVisibility(View.VISIBLE); |             binding.ivProfilePic.setVisibility(View.VISIBLE); | ||||||
|             multipleProfilePicsContainer.setVisibility(View.GONE); |             multipleProfilePicsContainer.setVisibility(View.GONE); | ||||||
|             glideRequestManager.load(users.length == 1 ? users[0].getSdProfilePic() : null).into(binding.ivProfilePic); |             binding.ivProfilePic.setImageURI(users.length == 1 ? users[0].getSdProfilePic() : null); | ||||||
|         } |         } | ||||||
|         binding.tvUsername.setText(model.getThreadTitle()); |         binding.tvUsername.setText(model.getThreadTitle()); | ||||||
|         final DirectItemModel lastItemModel = itemModels[itemModels.length - 1]; |         final DirectItemModel lastItemModel = itemModels[itemModels.length - 1]; | ||||||
|  | |||||||
| @ -25,6 +25,8 @@ import awaisomereport.LogCollector; | |||||||
| import static awais.instagrabber.utils.Utils.logCollector; | import static awais.instagrabber.utils.Utils.logCollector; | ||||||
| 
 | 
 | ||||||
| public final class FeedFetcher extends AsyncTask<Void, Void, FeedModel[]> { | public final class FeedFetcher extends AsyncTask<Void, Void, FeedModel[]> { | ||||||
|  |     private static final String TAG = "FeedFetcher"; | ||||||
|  | 
 | ||||||
|     private static final int maxItemsToLoad = 25; // max is 50, but that's too many posts, setting more than 30 is gay |     private static final int maxItemsToLoad = 25; // max is 50, but that's too many posts, setting more than 30 is gay | ||||||
|     private final String endCursor; |     private final String endCursor; | ||||||
|     private final FetchListener<FeedModel[]> fetchListener; |     private final FetchListener<FeedModel[]> fetchListener; | ||||||
| @ -61,7 +63,9 @@ public final class FeedFetcher extends AsyncTask<Void, Void, FeedModel[]> { | |||||||
|             final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection(); |             final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection(); | ||||||
| 
 | 
 | ||||||
|             if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { |             if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { | ||||||
|                 final JSONObject timelineFeed = new JSONObject(Utils.readFromConnection(urlConnection)).getJSONObject("data") |                 final String json = Utils.readFromConnection(urlConnection); | ||||||
|  |                 Log.d(TAG, json); | ||||||
|  |                 final JSONObject timelineFeed = new JSONObject(json).getJSONObject("data") | ||||||
|                                                                     .getJSONObject(Constants.EXTRAS_USER).getJSONObject("edge_web_feed_timeline"); |                                                                     .getJSONObject(Constants.EXTRAS_USER).getJSONObject("edge_web_feed_timeline"); | ||||||
| 
 | 
 | ||||||
|                 final String endCursor; |                 final String endCursor; | ||||||
| @ -83,7 +87,8 @@ public final class FeedFetcher extends AsyncTask<Void, Void, FeedModel[]> { | |||||||
|                 for (int i = 0; i < feedLen; ++i) { |                 for (int i = 0; i < feedLen; ++i) { | ||||||
|                     final JSONObject feedItem = feedItems.getJSONObject(i).getJSONObject("node"); |                     final JSONObject feedItem = feedItems.getJSONObject(i).getJSONObject("node"); | ||||||
|                     final String mediaType = feedItem.optString("__typename"); |                     final String mediaType = feedItem.optString("__typename"); | ||||||
|                     if (mediaType.isEmpty() || "GraphSuggestedUserFeedUnit".equals(mediaType)) continue; |                     if (mediaType.isEmpty() || "GraphSuggestedUserFeedUnit".equals(mediaType)) | ||||||
|  |                         continue; | ||||||
| 
 | 
 | ||||||
|                     final boolean isVideo = feedItem.optBoolean("is_video"); |                     final boolean isVideo = feedItem.optBoolean("is_video"); | ||||||
|                     final long videoViews = feedItem.optLong("video_view_count", 0); |                     final long videoViews = feedItem.optLong("video_view_count", 0); | ||||||
| @ -93,7 +98,8 @@ public final class FeedFetcher extends AsyncTask<Void, Void, FeedModel[]> { | |||||||
|                     final String resourceUrl; |                     final String resourceUrl; | ||||||
| 
 | 
 | ||||||
|                     if (isVideo) resourceUrl = feedItem.getString("video_url"); |                     if (isVideo) resourceUrl = feedItem.getString("video_url"); | ||||||
|                     else resourceUrl = feedItem.has("display_resources") ? Utils.getHighQualityImage(feedItem) : displayUrl; |                     else | ||||||
|  |                         resourceUrl = feedItem.has("display_resources") ? Utils.getHighQualityImage(feedItem) : displayUrl; | ||||||
| 
 | 
 | ||||||
|                     ProfileModel profileModel = null; |                     ProfileModel profileModel = null; | ||||||
|                     if (feedItem.has("owner")) { |                     if (feedItem.has("owner")) { | ||||||
|  | |||||||
| @ -8,6 +8,9 @@ import androidx.annotation.Nullable; | |||||||
| import org.json.JSONArray; | import org.json.JSONArray; | ||||||
| import org.json.JSONObject; | import org.json.JSONObject; | ||||||
| 
 | 
 | ||||||
|  | import java.io.BufferedReader; | ||||||
|  | import java.io.InputStream; | ||||||
|  | import java.io.InputStreamReader; | ||||||
| import java.net.HttpURLConnection; | import java.net.HttpURLConnection; | ||||||
| import java.net.URL; | import java.net.URL; | ||||||
| 
 | 
 | ||||||
| @ -23,6 +26,8 @@ import static awais.instagrabber.utils.Utils.logCollector; | |||||||
| import static awaisomereport.LogCollector.LogFile; | import static awaisomereport.LogCollector.LogFile; | ||||||
| 
 | 
 | ||||||
| public final class InboxFetcher extends AsyncTask<Void, Void, InboxModel> { | public final class InboxFetcher extends AsyncTask<Void, Void, InboxModel> { | ||||||
|  |     private static final String TAG = "InboxFetcher"; | ||||||
|  | 
 | ||||||
|     private final String endCursor; |     private final String endCursor; | ||||||
|     private final FetchListener<InboxModel> fetchListener; |     private final FetchListener<InboxModel> fetchListener; | ||||||
| 
 | 
 | ||||||
| @ -43,7 +48,21 @@ public final class InboxFetcher extends AsyncTask<Void, Void, InboxModel> { | |||||||
|             conn.setRequestProperty("Accept-Language", LocaleUtils.getCurrentLocale().getLanguage() + ",en-US;q=0.8"); |             conn.setRequestProperty("Accept-Language", LocaleUtils.getCurrentLocale().getLanguage() + ",en-US;q=0.8"); | ||||||
|             conn.setUseCaches(false); |             conn.setUseCaches(false); | ||||||
| 
 | 
 | ||||||
|             if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { |             if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) { | ||||||
|  |                 final InputStream responseInputStream = conn.getErrorStream(); | ||||||
|  |                 final BufferedReader r = new BufferedReader(new InputStreamReader(responseInputStream)); | ||||||
|  |                 final StringBuilder builder = new StringBuilder(); | ||||||
|  |                 for (String line = r.readLine(); line != null; line = r.readLine()) { | ||||||
|  |                     if (builder.length() != 0) { | ||||||
|  |                         builder.append("\n"); | ||||||
|  |                     } | ||||||
|  |                     builder.append(line); | ||||||
|  |                 } | ||||||
|  |                 Log.e(TAG, "Error response: " + conn.getResponseCode() + ", " + builder.toString()); | ||||||
|  |                 r.close(); | ||||||
|  |                 conn.disconnect(); | ||||||
|  |                 return null; | ||||||
|  |             } | ||||||
|             JSONObject data = new JSONObject(Utils.readFromConnection(conn)); |             JSONObject data = new JSONObject(Utils.readFromConnection(conn)); | ||||||
|             // try (FileWriter fileWriter = new FileWriter(new File("/sdcard/test.json"))) { |             // try (FileWriter fileWriter = new FileWriter(new File("/sdcard/test.json"))) { | ||||||
|             //     fileWriter.write(data.toString(2)); |             //     fileWriter.write(data.toString(2)); | ||||||
| @ -75,14 +94,13 @@ public final class InboxFetcher extends AsyncTask<Void, Void, InboxModel> { | |||||||
|             result = new InboxModel(hasOlder, hasPendingTopRequests, |             result = new InboxModel(hasOlder, hasPendingTopRequests, | ||||||
|                     blendedInboxEnabled, unseenCount, pendingRequestsCount, |                     blendedInboxEnabled, unseenCount, pendingRequestsCount, | ||||||
|                     seqId, unseenCountTimestamp, oldestCursor, inboxThreadModels); |                     seqId, unseenCountTimestamp, oldestCursor, inboxThreadModels); | ||||||
|             } |  | ||||||
| 
 | 
 | ||||||
|             conn.disconnect(); |             conn.disconnect(); | ||||||
|         } catch (final Exception e) { |         } catch (final Exception e) { | ||||||
|             result = null; |             result = null; | ||||||
|             if (logCollector != null) |             if (logCollector != null) | ||||||
|                 logCollector.appendException(e, LogFile.ASYNC_DMS, "doInBackground"); |                 logCollector.appendException(e, LogFile.ASYNC_DMS, "doInBackground"); | ||||||
|             if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e); |             if (BuildConfig.DEBUG) Log.e(TAG, "", e); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return result; |         return result; | ||||||
|  | |||||||
| @ -24,6 +24,8 @@ import androidx.fragment.app.FragmentManager; | |||||||
| 
 | 
 | ||||||
| import com.google.android.material.bottomsheet.BottomSheetDialogFragment; | import com.google.android.material.bottomsheet.BottomSheetDialogFragment; | ||||||
| 
 | 
 | ||||||
|  | import java.text.SimpleDateFormat; | ||||||
|  | 
 | ||||||
| import awais.instagrabber.BuildConfig; | import awais.instagrabber.BuildConfig; | ||||||
| import awais.instagrabber.R; | import awais.instagrabber.R; | ||||||
| import awais.instagrabber.activities.Login; | import awais.instagrabber.activities.Login; | ||||||
| @ -50,6 +52,7 @@ import static awais.instagrabber.utils.Constants.MUTED_VIDEOS; | |||||||
| import static awais.instagrabber.utils.Constants.STORIESIG; | import static awais.instagrabber.utils.Constants.STORIESIG; | ||||||
| import static awais.instagrabber.utils.Utils.settingsHelper; | import static awais.instagrabber.utils.Utils.settingsHelper; | ||||||
| 
 | 
 | ||||||
|  | @Deprecated | ||||||
| public final class SettingsDialog extends BottomSheetDialogFragment implements View.OnClickListener, AdapterView.OnItemSelectedListener, | public final class SettingsDialog extends BottomSheetDialogFragment implements View.OnClickListener, AdapterView.OnItemSelectedListener, | ||||||
|         CompoundButton.OnCheckedChangeListener { |         CompoundButton.OnCheckedChangeListener { | ||||||
|     private Activity activity; |     private Activity activity; | ||||||
| @ -65,7 +68,8 @@ public final class SettingsDialog extends BottomSheetDialogFragment implements V | |||||||
|     public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) { |     public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) { | ||||||
|         if (requestCode != 6200) return; |         if (requestCode != 6200) return; | ||||||
|         if (grantResults[0] == PackageManager.PERMISSION_GRANTED) showDirectoryChooser(); |         if (grantResults[0] == PackageManager.PERMISSION_GRANTED) showDirectoryChooser(); | ||||||
|         else Toast.makeText(activity, R.string.direct_download_perms_ask, Toast.LENGTH_SHORT).show(); |         else | ||||||
|  |             Toast.makeText(activity, R.string.direct_download_perms_ask, Toast.LENGTH_SHORT).show(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void showDirectoryChooser() { |     private void showDirectoryChooser() { | ||||||
| @ -115,12 +119,12 @@ public final class SettingsDialog extends BottomSheetDialogFragment implements V | |||||||
|         if (Utils.isEmpty(settingsHelper.getString(Constants.COOKIE))) btnLogout.setEnabled(false); |         if (Utils.isEmpty(settingsHelper.getString(Constants.COOKIE))) btnLogout.setEnabled(false); | ||||||
| 
 | 
 | ||||||
|         spAppTheme = contentView.findViewById(R.id.spAppTheme); |         spAppTheme = contentView.findViewById(R.id.spAppTheme); | ||||||
|         currentTheme = settingsHelper.getInteger(APP_THEME); |         currentTheme = Integer.parseInt(settingsHelper.getString(APP_THEME)); | ||||||
|         spAppTheme.setSelection(currentTheme); |         spAppTheme.setSelection(currentTheme); | ||||||
|         spAppTheme.setOnItemSelectedListener(this); |         spAppTheme.setOnItemSelectedListener(this); | ||||||
| 
 | 
 | ||||||
|         spLanguage = contentView.findViewById(R.id.spLanguage); |         spLanguage = contentView.findViewById(R.id.spLanguage); | ||||||
|         currentLanguage = settingsHelper.getInteger(APP_LANGUAGE); |         currentLanguage = Integer.parseInt(settingsHelper.getString(APP_LANGUAGE)); | ||||||
|         spLanguage.setSelection(currentLanguage); |         spLanguage.setSelection(currentLanguage); | ||||||
|         spLanguage.setOnItemSelectedListener(this); |         spLanguage.setOnItemSelectedListener(this); | ||||||
| 
 | 
 | ||||||
| @ -178,13 +182,13 @@ public final class SettingsDialog extends BottomSheetDialogFragment implements V | |||||||
|     public void onItemSelected(final AdapterView<?> spinner, final View view, final int position, final long id) { |     public void onItemSelected(final AdapterView<?> spinner, final View view, final int position, final long id) { | ||||||
|         if (spinner == spAppTheme) { |         if (spinner == spAppTheme) { | ||||||
|             if (position != currentTheme) { |             if (position != currentTheme) { | ||||||
|                 settingsHelper.putInteger(APP_THEME, position); |                 settingsHelper.putString(APP_THEME, String.valueOf(position)); | ||||||
|                 somethingChanged = true; |                 somethingChanged = true; | ||||||
|             } |             } | ||||||
|         } else if (spinner == spLanguage) { |         } else if (spinner == spLanguage) { | ||||||
|             selectedLanguage = position; |             selectedLanguage = position; | ||||||
|             if (position != currentLanguage) { |             if (position != currentLanguage) { | ||||||
|                 settingsHelper.putInteger(APP_LANGUAGE, position); |                 settingsHelper.putString(APP_LANGUAGE, String.valueOf(position)); | ||||||
|                 somethingChanged = true; |                 somethingChanged = true; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @ -205,7 +209,28 @@ public final class SettingsDialog extends BottomSheetDialogFragment implements V | |||||||
|                 requestPermissions(Utils.PERMS, 6007); |                 requestPermissions(Utils.PERMS, 6007); | ||||||
|             else Utils.showImportExportDialog(activity); |             else Utils.showImportExportDialog(activity); | ||||||
|         } else if (v == btnTimeSettings) { |         } else if (v == btnTimeSettings) { | ||||||
|             new TimeSettingsDialog().show(fragmentManager, null); |             new TimeSettingsDialog(settingsHelper.getBoolean(Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED), | ||||||
|  |                     settingsHelper.getString(Constants.CUSTOM_DATE_TIME_FORMAT), | ||||||
|  |                     settingsHelper.getString(Constants.DATE_TIME_SELECTION), | ||||||
|  |                     (isCustomFormat, | ||||||
|  |                      formatSelection, | ||||||
|  |                      spTimeFormatSelectedItemPosition, | ||||||
|  |                      spSeparatorSelectedItemPosition, | ||||||
|  |                      spDateFormatSelectedItemPosition, | ||||||
|  |                      selectedFormat, currentFormat) -> { | ||||||
|  |                         if (isCustomFormat) { | ||||||
|  |                             settingsHelper.putString(Constants.CUSTOM_DATE_TIME_FORMAT, formatSelection); | ||||||
|  |                         } else { | ||||||
|  |                             final String formatSelectionUpdated = spTimeFormatSelectedItemPosition + ";" | ||||||
|  |                                     + spSeparatorSelectedItemPosition + ';' | ||||||
|  |                                     + spDateFormatSelectedItemPosition; // time;separator;date | ||||||
|  |                             settingsHelper.putString(Constants.DATE_TIME_FORMAT, selectedFormat); | ||||||
|  |                             settingsHelper.putString(Constants.DATE_TIME_SELECTION, formatSelectionUpdated); | ||||||
|  |                         } | ||||||
|  |                         settingsHelper.putBoolean(Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED, isCustomFormat); | ||||||
|  |                         Utils.datetimeParser = (SimpleDateFormat) currentFormat.clone(); | ||||||
|  |                     } | ||||||
|  |             ).show(fragmentManager, null); | ||||||
|         } else if (v == btnReport) { |         } else if (v == btnReport) { | ||||||
|             CrashReporter.get(activity.getApplication()).zipLogs().startCrashEmailIntent(activity, true); |             CrashReporter.get(activity.getApplication()).zipLogs().startCrashEmailIntent(activity, true); | ||||||
|         } else if (v == btnSaveTo) { |         } else if (v == btnSaveTo) { | ||||||
|  | |||||||
| @ -6,6 +6,9 @@ import android.text.Editable; | |||||||
| import android.text.TextWatcher; | import android.text.TextWatcher; | ||||||
| import android.view.LayoutInflater; | import android.view.LayoutInflater; | ||||||
| import android.view.View; | import android.view.View; | ||||||
|  | import android.view.ViewGroup; | ||||||
|  | import android.view.Window; | ||||||
|  | import android.view.WindowManager; | ||||||
| import android.widget.AdapterView; | import android.widget.AdapterView; | ||||||
| import android.widget.CompoundButton; | import android.widget.CompoundButton; | ||||||
| 
 | 
 | ||||||
| @ -19,38 +22,42 @@ import java.util.Date; | |||||||
| import java.util.GregorianCalendar; | import java.util.GregorianCalendar; | ||||||
| 
 | 
 | ||||||
| import awais.instagrabber.databinding.DialogTimeSettingsBinding; | import awais.instagrabber.databinding.DialogTimeSettingsBinding; | ||||||
| import awais.instagrabber.utils.Constants; |  | ||||||
| import awais.instagrabber.utils.LocaleUtils; | import awais.instagrabber.utils.LocaleUtils; | ||||||
| import awais.instagrabber.utils.Utils; | import awais.instagrabber.utils.Utils; | ||||||
| 
 | 
 | ||||||
| import static awais.instagrabber.utils.Utils.settingsHelper; |  | ||||||
| 
 |  | ||||||
| public final class TimeSettingsDialog extends DialogFragment implements AdapterView.OnItemSelectedListener, CompoundButton.OnCheckedChangeListener, | public final class TimeSettingsDialog extends DialogFragment implements AdapterView.OnItemSelectedListener, CompoundButton.OnCheckedChangeListener, | ||||||
|         View.OnClickListener, TextWatcher { |         View.OnClickListener, TextWatcher { | ||||||
|     private DialogTimeSettingsBinding timeSettingsBinding; |     private DialogTimeSettingsBinding timeSettingsBinding; | ||||||
|     private final Date magicDate; |     private final Date magicDate; | ||||||
|     private SimpleDateFormat currentFormat; |     private SimpleDateFormat currentFormat; | ||||||
|     private String selectedFormat; |     private String selectedFormat; | ||||||
|  |     private boolean customDateTimeFormatEnabled; | ||||||
|  |     private String customDateTimeFormat; | ||||||
|  |     private String dateTimeSelection; | ||||||
|  |     private final OnConfirmListener onConfirmListener; | ||||||
| 
 | 
 | ||||||
|     public TimeSettingsDialog() { |     public TimeSettingsDialog(final boolean customDateTimeFormatEnabled, | ||||||
|         super(); |                               final String customDateTimeFormat, | ||||||
|  |                               final String dateTimeSelection, | ||||||
|  |                               final OnConfirmListener onConfirmListener) { | ||||||
|  |         this.customDateTimeFormatEnabled = customDateTimeFormatEnabled; | ||||||
|  |         this.customDateTimeFormat = customDateTimeFormat; | ||||||
|  |         this.dateTimeSelection = dateTimeSelection; | ||||||
|  |         this.onConfirmListener = onConfirmListener; | ||||||
|         final Calendar instance = GregorianCalendar.getInstance(); |         final Calendar instance = GregorianCalendar.getInstance(); | ||||||
|         instance.set(2020, 5, 22, 8, 17, 13); |         instance.set(2020, 5, 22, 8, 17, 13); | ||||||
|         magicDate = instance.getTime(); |         magicDate = instance.getTime(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @NonNull |  | ||||||
|     @Override |     @Override | ||||||
|     public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) { |     public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) { | ||||||
|         final Dialog dialog = super.onCreateDialog(savedInstanceState); |         timeSettingsBinding = DialogTimeSettingsBinding.inflate(inflater, container, false); | ||||||
|         timeSettingsBinding = DialogTimeSettingsBinding.inflate(LayoutInflater.from(getContext())); |  | ||||||
| 
 | 
 | ||||||
|         timeSettingsBinding.cbCustomFormat.setOnCheckedChangeListener(this); |         timeSettingsBinding.cbCustomFormat.setOnCheckedChangeListener(this); | ||||||
|  |         timeSettingsBinding.cbCustomFormat.setChecked(customDateTimeFormatEnabled); | ||||||
|  |         timeSettingsBinding.etCustomFormat.setText(customDateTimeFormat); | ||||||
| 
 | 
 | ||||||
|         timeSettingsBinding.cbCustomFormat.setChecked(settingsHelper.getBoolean(Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED)); |         final String[] dateTimeFormat = dateTimeSelection.split(";"); // output = time;separator;date | ||||||
|         timeSettingsBinding.etCustomFormat.setText(settingsHelper.getString(Constants.CUSTOM_DATE_TIME_FORMAT)); |  | ||||||
| 
 |  | ||||||
|         final String[] dateTimeFormat = settingsHelper.getString(Constants.DATE_TIME_SELECTION).split(";"); // output = time;separator;date |  | ||||||
|         timeSettingsBinding.spTimeFormat.setSelection(Integer.parseInt(dateTimeFormat[0])); |         timeSettingsBinding.spTimeFormat.setSelection(Integer.parseInt(dateTimeFormat[0])); | ||||||
|         timeSettingsBinding.spSeparator.setSelection(Integer.parseInt(dateTimeFormat[1])); |         timeSettingsBinding.spSeparator.setSelection(Integer.parseInt(dateTimeFormat[1])); | ||||||
|         timeSettingsBinding.spDateFormat.setSelection(Integer.parseInt(dateTimeFormat[2])); |         timeSettingsBinding.spDateFormat.setSelection(Integer.parseInt(dateTimeFormat[2])); | ||||||
| @ -67,8 +74,7 @@ public final class TimeSettingsDialog extends DialogFragment implements AdapterV | |||||||
|         timeSettingsBinding.btnConfirm.setOnClickListener(this); |         timeSettingsBinding.btnConfirm.setOnClickListener(this); | ||||||
|         timeSettingsBinding.btnInfo.setOnClickListener(this); |         timeSettingsBinding.btnInfo.setOnClickListener(this); | ||||||
| 
 | 
 | ||||||
|         dialog.setContentView(timeSettingsBinding.getRoot()); |         return timeSettingsBinding.getRoot(); | ||||||
|         return dialog; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void refreshTimeFormat() { |     private void refreshTimeFormat() { | ||||||
| @ -87,7 +93,8 @@ public final class TimeSettingsDialog extends DialogFragment implements AdapterV | |||||||
|                     + (isSwapTime ? dateStr : timeStr); |                     + (isSwapTime ? dateStr : timeStr); | ||||||
| 
 | 
 | ||||||
|             timeSettingsBinding.btnConfirm.setEnabled(true); |             timeSettingsBinding.btnConfirm.setEnabled(true); | ||||||
|             timeSettingsBinding.timePreview.setText((currentFormat = new SimpleDateFormat(selectedFormat, LocaleUtils.getCurrentLocale())).format(magicDate)); |             currentFormat = new SimpleDateFormat(selectedFormat, LocaleUtils.getCurrentLocale()); | ||||||
|  |             timeSettingsBinding.timePreview.setText(currentFormat.format(magicDate)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -96,8 +103,8 @@ public final class TimeSettingsDialog extends DialogFragment implements AdapterV | |||||||
|             //noinspection ConstantConditions |             //noinspection ConstantConditions | ||||||
|             final String string = timeSettingsBinding.etCustomFormat.getText().toString(); |             final String string = timeSettingsBinding.etCustomFormat.getText().toString(); | ||||||
|             if (Utils.isEmpty(string)) throw new NullPointerException(); |             if (Utils.isEmpty(string)) throw new NullPointerException(); | ||||||
| 
 |             currentFormat = new SimpleDateFormat(string, LocaleUtils.getCurrentLocale()); | ||||||
|             final String format = (currentFormat = new SimpleDateFormat(string, LocaleUtils.getCurrentLocale())).format(magicDate); |             final String format = currentFormat.format(magicDate); | ||||||
|             timeSettingsBinding.timePreview.setText(format); |             timeSettingsBinding.timePreview.setText(format); | ||||||
| 
 | 
 | ||||||
|             timeSettingsBinding.btnConfirm.setEnabled(true); |             timeSettingsBinding.btnConfirm.setEnabled(true); | ||||||
| @ -115,6 +122,8 @@ public final class TimeSettingsDialog extends DialogFragment implements AdapterV | |||||||
|     @Override |     @Override | ||||||
|     public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) { |     public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) { | ||||||
|         if (buttonView == timeSettingsBinding.cbCustomFormat) { |         if (buttonView == timeSettingsBinding.cbCustomFormat) { | ||||||
|  |             final View parent = (View) timeSettingsBinding.etCustomFormat.getParent(); | ||||||
|  |             parent.setVisibility(isChecked ? View.VISIBLE : View.GONE); | ||||||
|             timeSettingsBinding.etCustomFormat.setEnabled(isChecked); |             timeSettingsBinding.etCustomFormat.setEnabled(isChecked); | ||||||
|             timeSettingsBinding.btnInfo.setEnabled(isChecked); |             timeSettingsBinding.btnInfo.setEnabled(isChecked); | ||||||
| 
 | 
 | ||||||
| @ -134,26 +143,16 @@ public final class TimeSettingsDialog extends DialogFragment implements AdapterV | |||||||
|     @Override |     @Override | ||||||
|     public void onClick(final View v) { |     public void onClick(final View v) { | ||||||
|         if (v == timeSettingsBinding.btnConfirm) { |         if (v == timeSettingsBinding.btnConfirm) { | ||||||
|             final String formatSelection; |             final Editable etCustomFormatText = timeSettingsBinding.etCustomFormat.getText(); | ||||||
| 
 |             if (onConfirmListener != null) { | ||||||
|             final boolean isCustomFormat = timeSettingsBinding.cbCustomFormat.isChecked(); |                 onConfirmListener.onConfirm(timeSettingsBinding.cbCustomFormat.isChecked(), | ||||||
| 
 |                         etCustomFormatText == null ? null : etCustomFormatText.toString(), | ||||||
|             if (isCustomFormat) { |                         timeSettingsBinding.spTimeFormat.getSelectedItemPosition(), | ||||||
|                 //noinspection ConstantConditions |                         timeSettingsBinding.spSeparator.getSelectedItemPosition(), | ||||||
|                 formatSelection = timeSettingsBinding.etCustomFormat.getText().toString(); |                         timeSettingsBinding.spDateFormat.getSelectedItemPosition(), | ||||||
|                 settingsHelper.putString(Constants.CUSTOM_DATE_TIME_FORMAT, formatSelection); |                         selectedFormat, | ||||||
|             } else { |                         currentFormat); | ||||||
|                 formatSelection = timeSettingsBinding.spTimeFormat.getSelectedItemPosition() + ";" |  | ||||||
|                         + timeSettingsBinding.spSeparator.getSelectedItemPosition() + ';' |  | ||||||
|                         + timeSettingsBinding.spDateFormat.getSelectedItemPosition(); // time;separator;date |  | ||||||
| 
 |  | ||||||
|                 settingsHelper.putString(Constants.DATE_TIME_FORMAT, selectedFormat); |  | ||||||
|                 settingsHelper.putString(Constants.DATE_TIME_SELECTION, formatSelection); |  | ||||||
|             } |             } | ||||||
| 
 |  | ||||||
|             settingsHelper.putBoolean(Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED, isCustomFormat); |  | ||||||
| 
 |  | ||||||
|             Utils.datetimeParser = (SimpleDateFormat) currentFormat.clone(); |  | ||||||
|             dismiss(); |             dismiss(); | ||||||
|         } else if (v == timeSettingsBinding.btnInfo) { |         } else if (v == timeSettingsBinding.btnInfo) { | ||||||
|             timeSettingsBinding.customPanel.setVisibility(timeSettingsBinding.customPanel |             timeSettingsBinding.customPanel.setVisibility(timeSettingsBinding.customPanel | ||||||
| @ -162,6 +161,14 @@ public final class TimeSettingsDialog extends DialogFragment implements AdapterV | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public interface OnConfirmListener { | ||||||
|  |         void onConfirm(boolean isCustomFormat, | ||||||
|  |                        String formatSelection, | ||||||
|  |                        int spTimeFormatSelectedItemPosition, | ||||||
|  |                        int spSeparatorSelectedItemPosition, | ||||||
|  |                        int spDateFormatSelectedItemPosition, final String selectedFormat, final SimpleDateFormat currentFormat); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void onNothingSelected(final AdapterView<?> parent) { } |     public void onNothingSelected(final AdapterView<?> parent) { } | ||||||
| 
 | 
 | ||||||
| @ -170,4 +177,17 @@ public final class TimeSettingsDialog extends DialogFragment implements AdapterV | |||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void afterTextChanged(final Editable s) { } |     public void afterTextChanged(final Editable s) { } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void onResume() { | ||||||
|  |         super.onResume(); | ||||||
|  |         final Dialog dialog = getDialog(); | ||||||
|  |         if (dialog == null) return; | ||||||
|  |         final Window window = dialog.getWindow(); | ||||||
|  |         if (window == null) return; | ||||||
|  |         final WindowManager.LayoutParams params = window.getAttributes(); | ||||||
|  |         params.width = ViewGroup.LayoutParams.MATCH_PARENT; | ||||||
|  |         params.height = ViewGroup.LayoutParams.WRAP_CONTENT; | ||||||
|  |         window.setAttributes(params); | ||||||
|  |     } | ||||||
| } | } | ||||||
| @ -11,6 +11,8 @@ import android.os.Bundle; | |||||||
| import android.os.Handler; | import android.os.Handler; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
| import android.view.LayoutInflater; | import android.view.LayoutInflater; | ||||||
|  | import android.view.Menu; | ||||||
|  | import android.view.MenuItem; | ||||||
| import android.view.View; | import android.view.View; | ||||||
| import android.view.ViewGroup; | import android.view.ViewGroup; | ||||||
| import android.widget.ArrayAdapter; | import android.widget.ArrayAdapter; | ||||||
| @ -19,11 +21,11 @@ import android.widget.Toast; | |||||||
| 
 | 
 | ||||||
| import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||||
| import androidx.annotation.Nullable; | import androidx.annotation.Nullable; | ||||||
|  | import androidx.appcompat.app.ActionBar; | ||||||
| import androidx.appcompat.app.AlertDialog; | import androidx.appcompat.app.AlertDialog; | ||||||
| import androidx.appcompat.widget.AppCompatImageView; | import androidx.appcompat.app.AppCompatActivity; | ||||||
| import androidx.coordinatorlayout.widget.CoordinatorLayout; |  | ||||||
| import androidx.fragment.app.Fragment; | import androidx.fragment.app.Fragment; | ||||||
| import androidx.fragment.app.FragmentActivity; | import androidx.fragment.app.FragmentContainerView; | ||||||
| import androidx.lifecycle.MutableLiveData; | import androidx.lifecycle.MutableLiveData; | ||||||
| import androidx.lifecycle.ViewModel; | import androidx.lifecycle.ViewModel; | ||||||
| import androidx.lifecycle.ViewModelProvider; | import androidx.lifecycle.ViewModelProvider; | ||||||
| @ -49,7 +51,6 @@ import java.util.List; | |||||||
| 
 | 
 | ||||||
| import awais.instagrabber.R; | import awais.instagrabber.R; | ||||||
| import awais.instagrabber.activities.PostViewer; | import awais.instagrabber.activities.PostViewer; | ||||||
| import awais.instagrabber.activities.ProfileViewer; |  | ||||||
| import awais.instagrabber.adapters.DirectMessageItemsAdapter; | import awais.instagrabber.adapters.DirectMessageItemsAdapter; | ||||||
| import awais.instagrabber.asyncs.ImageUploader; | import awais.instagrabber.asyncs.ImageUploader; | ||||||
| import awais.instagrabber.asyncs.direct_messages.DirectMessageInboxThreadFetcher; | import awais.instagrabber.asyncs.direct_messages.DirectMessageInboxThreadFetcher; | ||||||
| @ -61,7 +62,6 @@ import awais.instagrabber.interfaces.MentionClickListener; | |||||||
| import awais.instagrabber.models.ImageUploadOptions; | import awais.instagrabber.models.ImageUploadOptions; | ||||||
| import awais.instagrabber.models.PostModel; | import awais.instagrabber.models.PostModel; | ||||||
| import awais.instagrabber.models.ProfileModel; | import awais.instagrabber.models.ProfileModel; | ||||||
| import awais.instagrabber.models.StoryModel; |  | ||||||
| import awais.instagrabber.models.direct_messages.DirectItemModel; | import awais.instagrabber.models.direct_messages.DirectItemModel; | ||||||
| import awais.instagrabber.models.direct_messages.InboxThreadModel; | import awais.instagrabber.models.direct_messages.InboxThreadModel; | ||||||
| import awais.instagrabber.models.enums.DirectItemType; | import awais.instagrabber.models.enums.DirectItemType; | ||||||
| @ -74,7 +74,7 @@ public class DirectMessageThreadFragment extends Fragment { | |||||||
|     private static final String TAG = "DirectMessagesThreadFmt"; |     private static final String TAG = "DirectMessagesThreadFmt"; | ||||||
|     private static final int PICK_IMAGE = 100; |     private static final int PICK_IMAGE = 100; | ||||||
| 
 | 
 | ||||||
|     private FragmentActivity fragmentActivity; |     private AppCompatActivity fragmentActivity; | ||||||
|     private String threadId, threadTitle; |     private String threadId, threadTitle; | ||||||
|     private String cursor; |     private String cursor; | ||||||
|     private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE); |     private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE); | ||||||
| @ -83,7 +83,7 @@ public class DirectMessageThreadFragment extends Fragment { | |||||||
|     private DirectItemModelListViewModel listViewModel; |     private DirectItemModelListViewModel listViewModel; | ||||||
|     private DirectItemModel directItemModel; |     private DirectItemModel directItemModel; | ||||||
|     private RecyclerView messageList; |     private RecyclerView messageList; | ||||||
|     private AppCompatImageView dmInfo; |     // private AppCompatImageView dmInfo; | ||||||
|     private boolean hasSentSomething, hasDeletedSomething; |     private boolean hasSentSomething, hasDeletedSomething; | ||||||
|     private boolean hasOlder = true; |     private boolean hasOlder = true; | ||||||
| 
 | 
 | ||||||
| @ -157,7 +157,8 @@ public class DirectMessageThreadFragment extends Fragment { | |||||||
|     @Override |     @Override | ||||||
|     public void onCreate(@Nullable final Bundle savedInstanceState) { |     public void onCreate(@Nullable final Bundle savedInstanceState) { | ||||||
|         super.onCreate(savedInstanceState); |         super.onCreate(savedInstanceState); | ||||||
|         fragmentActivity = requireActivity(); |         fragmentActivity = (AppCompatActivity) requireActivity(); | ||||||
|  |         setHasOptionsMenu(true); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
| @ -165,8 +166,8 @@ public class DirectMessageThreadFragment extends Fragment { | |||||||
|                              final ViewGroup container, |                              final ViewGroup container, | ||||||
|                              final Bundle savedInstanceState) { |                              final Bundle savedInstanceState) { | ||||||
|         binding = FragmentDirectMessagesThreadBinding.inflate(inflater, container, false); |         binding = FragmentDirectMessagesThreadBinding.inflate(inflater, container, false); | ||||||
|         CoordinatorLayout containerTwo = (CoordinatorLayout) container.getParent(); |         final FragmentContainerView containerTwo = (FragmentContainerView) container.getParent(); | ||||||
|         dmInfo = containerTwo.findViewById(R.id.dmInfo); |         // dmInfo = containerTwo.findViewById(R.id.dmInfo); | ||||||
|         final LinearLayout root = binding.getRoot(); |         final LinearLayout root = binding.getRoot(); | ||||||
|         listViewModel = new ViewModelProvider(fragmentActivity).get(DirectItemModelListViewModel.class); |         listViewModel = new ViewModelProvider(fragmentActivity).get(DirectItemModelListViewModel.class); | ||||||
|         if (getArguments() == null) { |         if (getArguments() == null) { | ||||||
| @ -177,6 +178,10 @@ public class DirectMessageThreadFragment extends Fragment { | |||||||
|             threadId = DirectMessageThreadFragmentArgs.fromBundle(getArguments()).getThreadId(); |             threadId = DirectMessageThreadFragmentArgs.fromBundle(getArguments()).getThreadId(); | ||||||
|         } |         } | ||||||
|         threadTitle = DirectMessageThreadFragmentArgs.fromBundle(getArguments()).getTitle(); |         threadTitle = DirectMessageThreadFragmentArgs.fromBundle(getArguments()).getTitle(); | ||||||
|  |         final ActionBar actionBar = fragmentActivity.getSupportActionBar(); | ||||||
|  |         if (actionBar != null) { | ||||||
|  |             actionBar.setTitle(threadTitle); | ||||||
|  |         } | ||||||
|         binding.swipeRefreshLayout.setEnabled(false); |         binding.swipeRefreshLayout.setEnabled(false); | ||||||
|         messageList = binding.messageList; |         messageList = binding.messageList; | ||||||
|         messageList.setHasFixedSize(true); |         messageList.setHasFixedSize(true); | ||||||
| @ -192,11 +197,11 @@ public class DirectMessageThreadFragment extends Fragment { | |||||||
|             } |             } | ||||||
|             new DirectMessageInboxThreadFetcher(threadId, UserInboxDirection.OLDER, cursor, fetchListener).execute(); // serial because we don't want messages to be randomly ordered |             new DirectMessageInboxThreadFetcher(threadId, UserInboxDirection.OLDER, cursor, fetchListener).execute(); // serial because we don't want messages to be randomly ordered | ||||||
|         })); |         })); | ||||||
|         dmInfo.setOnClickListener(v -> { |         // dmInfo.setOnClickListener(v -> { | ||||||
|             final NavDirections action = |         //     final NavDirections action = | ||||||
|                     DirectMessageThreadFragmentDirections.actionDMThreadFragmentToDMSettingsFragment(threadId, threadTitle); |         //             DirectMessageThreadFragmentDirections.actionDMThreadFragmentToDMSettingsFragment(threadId, threadTitle); | ||||||
|             NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(action); |         //     NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(action); | ||||||
|         }); |         // }); | ||||||
| 
 | 
 | ||||||
|         final DialogInterface.OnClickListener onDialogListener = (dialogInterface, which) -> { |         final DialogInterface.OnClickListener onDialogListener = (dialogInterface, which) -> { | ||||||
|             if (which == 0) { |             if (which == 0) { | ||||||
| @ -250,12 +255,11 @@ public class DirectMessageThreadFragment extends Fragment { | |||||||
|                     default: |                     default: | ||||||
|                         Log.d("austin_debug", "unsupported type " + itemType); |                         Log.d("austin_debug", "unsupported type " + itemType); | ||||||
|                 } |                 } | ||||||
|             } |             } else if (which == 1) { | ||||||
|             else if (which == 1) { |  | ||||||
|                 sendText(null, directItemModel.getItemId(), directItemModel.isLiked()); |                 sendText(null, directItemModel.getItemId(), directItemModel.isLiked()); | ||||||
|             } |             } else if (which == 2) { | ||||||
|             else if (which == 2) { |                 if (String.valueOf(directItemModel.getUserId()).equals(myId)) | ||||||
|                 if (String.valueOf(directItemModel.getUserId()).equals(myId)) new Unsend().execute(); |                     new Unsend().execute(); | ||||||
|                 else searchUsername(getUser(directItemModel.getUserId()).getUsername()); |                 else searchUsername(getUser(directItemModel.getUserId()).getUsername()); | ||||||
|             } |             } | ||||||
|         }; |         }; | ||||||
| @ -320,6 +324,12 @@ public class DirectMessageThreadFragment extends Fragment { | |||||||
|         return root; |         return root; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @Override | ||||||
|  |     public void onPrepareOptionsMenu(@NonNull final Menu menu) { | ||||||
|  |         final MenuItem item = menu.findItem(R.id.favourites); | ||||||
|  |         item.setVisible(false); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { |     public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { | ||||||
|         super.onActivityResult(requestCode, resultCode, data); |         super.onActivityResult(requestCode, resultCode, data); | ||||||
| @ -423,7 +433,9 @@ public class DirectMessageThreadFragment extends Fragment { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void searchUsername(final String text) { |     private void searchUsername(final String text) { | ||||||
|         startActivity(new Intent(requireContext(), ProfileViewer.class).putExtra(Constants.EXTRAS_USERNAME, text)); |         // startActivity(new Intent(requireContext(), ProfileViewer.class).putExtra(Constants.EXTRAS_USERNAME, text)); | ||||||
|  |         final NavDirections action = DirectMessageThreadFragmentDirections.actionDirectMessagesThreadFragmentToProfileFragment("@" + text); | ||||||
|  |         NavHostFragment.findNavController(this).navigate(action); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static class DirectItemModelListViewModel extends ViewModel { |     public static class DirectItemModelListViewModel extends ViewModel { | ||||||
| @ -434,8 +446,7 @@ public class DirectMessageThreadFragment extends Fragment { | |||||||
|             if (list == null) { |             if (list == null) { | ||||||
|                 list = new MutableLiveData<>(); |                 list = new MutableLiveData<>(); | ||||||
|                 isEmpty = true; |                 isEmpty = true; | ||||||
|             } |             } else isEmpty = false; | ||||||
|             else isEmpty = false; |  | ||||||
|             return list; |             return list; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @ -451,10 +462,10 @@ public class DirectMessageThreadFragment extends Fragment { | |||||||
| 
 | 
 | ||||||
|     class Unsend extends AsyncTask<Void, Void, Void> { |     class Unsend extends AsyncTask<Void, Void, Void> { | ||||||
|         protected Void doInBackground(Void... lmao) { |         protected Void doInBackground(Void... lmao) { | ||||||
|             final String url = "https://i.instagram.com/api/v1/direct_v2/threads/"+threadId+"/items/"+directItemModel.getItemId()+"/delete/"; |             final String url = "https://i.instagram.com/api/v1/direct_v2/threads/" + threadId + "/items/" + directItemModel.getItemId() + "/delete/"; | ||||||
|             try { |             try { | ||||||
|                 String urlParameters = "_csrftoken=" + cookie.split("csrftoken=")[1].split(";")[0] |                 String urlParameters = "_csrftoken=" + cookie.split("csrftoken=")[1].split(";")[0] | ||||||
|                         +"&_uuid=" + Utils.settingsHelper.getString(Constants.DEVICE_UUID); |                         + "&_uuid=" + Utils.settingsHelper.getString(Constants.DEVICE_UUID); | ||||||
|                 final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection(); |                 final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection(); | ||||||
|                 urlConnection.setRequestMethod("POST"); |                 urlConnection.setRequestMethod("POST"); | ||||||
|                 urlConnection.setUseCaches(false); |                 urlConnection.setUseCaches(false); | ||||||
|  | |||||||
| @ -60,6 +60,7 @@ public class DiscoverFragment extends Fragment { | |||||||
|     private String discoverEndMaxId; |     private String discoverEndMaxId; | ||||||
|     private ActionMode actionMode; |     private ActionMode actionMode; | ||||||
|     private DiscoverItemViewModel discoverItemViewModel; |     private DiscoverItemViewModel discoverItemViewModel; | ||||||
|  |     private boolean shouldRefresh = true; | ||||||
| 
 | 
 | ||||||
|     private final FetchListener<DiscoverTopicModel> topicFetchListener = new FetchListener<DiscoverTopicModel>() { |     private final FetchListener<DiscoverTopicModel> topicFetchListener = new FetchListener<DiscoverTopicModel>() { | ||||||
|         @Override |         @Override | ||||||
| @ -154,14 +155,20 @@ public class DiscoverFragment extends Fragment { | |||||||
|                              final ViewGroup container, |                              final ViewGroup container, | ||||||
|                              final Bundle savedInstanceState) { |                              final Bundle savedInstanceState) { | ||||||
|         if (root != null) { |         if (root != null) { | ||||||
|  |             shouldRefresh = false; | ||||||
|             return root; |             return root; | ||||||
|         } |         } | ||||||
|         binding = FragmentDiscoverBinding.inflate(inflater, container, false); |         binding = FragmentDiscoverBinding.inflate(inflater, container, false); | ||||||
|         root = binding.getRoot(); |         root = binding.getRoot(); | ||||||
|         setupExplore(); |  | ||||||
|         return root; |         return root; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @Override | ||||||
|  |     public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) { | ||||||
|  |         if (!shouldRefresh) return; | ||||||
|  |         setupExplore(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     private void setupExplore() { |     private void setupExplore() { | ||||||
|         discoverItemViewModel = new ViewModelProvider(fragmentActivity).get(DiscoverItemViewModel.class); |         discoverItemViewModel = new ViewModelProvider(fragmentActivity).get(DiscoverItemViewModel.class); | ||||||
|         final GridAutofitLayoutManager layoutManager = new GridAutofitLayoutManager(requireContext(), Utils.convertDpToPx(110)); |         final GridAutofitLayoutManager layoutManager = new GridAutofitLayoutManager(requireContext(), Utils.convertDpToPx(110)); | ||||||
|  | |||||||
| @ -80,6 +80,7 @@ public class FeedFragment extends Fragment { | |||||||
|     private String feedEndCursor = null; |     private String feedEndCursor = null; | ||||||
|     private FeedViewModel feedViewModel; |     private FeedViewModel feedViewModel; | ||||||
|     private VideoAwareRecyclerScroller videoAwareRecyclerScroller; |     private VideoAwareRecyclerScroller videoAwareRecyclerScroller; | ||||||
|  |     private boolean shouldRefresh = true; | ||||||
| 
 | 
 | ||||||
|     private final FetchListener<FeedModel[]> feedFetchListener = new FetchListener<FeedModel[]>() { |     private final FetchListener<FeedModel[]> feedFetchListener = new FetchListener<FeedModel[]>() { | ||||||
|         @Override |         @Override | ||||||
| @ -164,14 +165,21 @@ public class FeedFragment extends Fragment { | |||||||
|                              final ViewGroup container, |                              final ViewGroup container, | ||||||
|                              final Bundle savedInstanceState) { |                              final Bundle savedInstanceState) { | ||||||
|         if (root != null) { |         if (root != null) { | ||||||
|  |             shouldRefresh = false; | ||||||
|             return root; |             return root; | ||||||
|         } |         } | ||||||
|         binding = FragmentFeedBinding.inflate(inflater, container, false); |         binding = FragmentFeedBinding.inflate(inflater, container, false); | ||||||
|         root = binding.getRoot(); |         root = binding.getRoot(); | ||||||
|  |         return root; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) { | ||||||
|  |         if (!shouldRefresh) return; | ||||||
|         // setupActionBar(); |         // setupActionBar(); | ||||||
|         setupFeedStories(); |         setupFeedStories(); | ||||||
|         setupFeed(); |         setupFeed(); | ||||||
|         return root; |         shouldRefresh = false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ import android.os.Looper; | |||||||
| import android.text.SpannableStringBuilder; | import android.text.SpannableStringBuilder; | ||||||
| import android.text.style.RelativeSizeSpan; | import android.text.style.RelativeSizeSpan; | ||||||
| import android.text.style.StyleSpan; | import android.text.style.StyleSpan; | ||||||
|  | import android.util.Log; | ||||||
| import android.view.ActionMode; | import android.view.ActionMode; | ||||||
| import android.view.LayoutInflater; | import android.view.LayoutInflater; | ||||||
| import android.view.MenuItem; | import android.view.MenuItem; | ||||||
| @ -29,8 +30,10 @@ import androidx.core.view.ViewCompat; | |||||||
| import androidx.fragment.app.Fragment; | import androidx.fragment.app.Fragment; | ||||||
| import androidx.lifecycle.ViewModelProvider; | import androidx.lifecycle.ViewModelProvider; | ||||||
| 
 | 
 | ||||||
|  | import java.util.ArrayList; | ||||||
| import java.util.Arrays; | import java.util.Arrays; | ||||||
| import java.util.Collections; | import java.util.Collections; | ||||||
|  | import java.util.List; | ||||||
| 
 | 
 | ||||||
| import awais.instagrabber.R; | import awais.instagrabber.R; | ||||||
| import awais.instagrabber.activities.FollowViewer; | import awais.instagrabber.activities.FollowViewer; | ||||||
| @ -47,17 +50,24 @@ import awais.instagrabber.customviews.PrimaryActionModeCallback; | |||||||
| import awais.instagrabber.customviews.PrimaryActionModeCallback.CallbacksHelper; | import awais.instagrabber.customviews.PrimaryActionModeCallback.CallbacksHelper; | ||||||
| import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager; | import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager; | ||||||
| import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration; | import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration; | ||||||
|  | import awais.instagrabber.customviews.helpers.RecyclerLazyLoader; | ||||||
| import awais.instagrabber.databinding.FragmentProfileBinding; | import awais.instagrabber.databinding.FragmentProfileBinding; | ||||||
| import awais.instagrabber.fragments.main.viewmodels.ProfilePostsViewModel; | import awais.instagrabber.fragments.main.viewmodels.ProfilePostsViewModel; | ||||||
| import awais.instagrabber.interfaces.FetchListener; | import awais.instagrabber.interfaces.FetchListener; | ||||||
|  | import awais.instagrabber.models.PostModel; | ||||||
| import awais.instagrabber.models.ProfileModel; | import awais.instagrabber.models.ProfileModel; | ||||||
|  | import awais.instagrabber.models.StoryModel; | ||||||
| import awais.instagrabber.models.enums.DownloadMethod; | import awais.instagrabber.models.enums.DownloadMethod; | ||||||
| import awais.instagrabber.models.enums.ItemGetType; | import awais.instagrabber.models.enums.ItemGetType; | ||||||
| import awais.instagrabber.services.ProfileService; | import awais.instagrabber.repositories.responses.FriendshipRepositoryChangeResponseRootObject; | ||||||
|  | import awais.instagrabber.services.FriendshipService; | ||||||
|  | import awais.instagrabber.services.ServiceCallback; | ||||||
| import awais.instagrabber.utils.Constants; | import awais.instagrabber.utils.Constants; | ||||||
| import awais.instagrabber.utils.DataBox; | import awais.instagrabber.utils.DataBox; | ||||||
| import awais.instagrabber.utils.Utils; | import awais.instagrabber.utils.Utils; | ||||||
|  | import awaisomereport.LogCollector; | ||||||
| 
 | 
 | ||||||
|  | import static awais.instagrabber.utils.Utils.logCollector; | ||||||
| import static awais.instagrabber.utils.Utils.settingsHelper; | import static awais.instagrabber.utils.Utils.settingsHelper; | ||||||
| 
 | 
 | ||||||
| public class ProfileFragment extends Fragment { | public class ProfileFragment extends Fragment { | ||||||
| @ -74,8 +84,13 @@ public class ProfileFragment extends Fragment { | |||||||
|     private PostsAdapter postsAdapter; |     private PostsAdapter postsAdapter; | ||||||
|     private ActionMode actionMode; |     private ActionMode actionMode; | ||||||
|     private Handler usernameSettingHandler; |     private Handler usernameSettingHandler; | ||||||
|     private ProfileService profileService; |     private FriendshipService friendshipService; | ||||||
| 
 |     private boolean shouldRefresh = true; | ||||||
|  |     private StoryModel[] storyModels; | ||||||
|  |     private boolean hasNextPage; | ||||||
|  |     private String endCursor; | ||||||
|  |     private AsyncTask<Void, Void, PostModel[]> currentlyExecuting; | ||||||
|  |     ; | ||||||
|     private final Runnable usernameSettingRunnable = () -> { |     private final Runnable usernameSettingRunnable = () -> { | ||||||
|         final ActionBar actionBar = fragmentActivity.getSupportActionBar(); |         final ActionBar actionBar = fragmentActivity.getSupportActionBar(); | ||||||
|         if (actionBar != null) { |         if (actionBar != null) { | ||||||
| @ -118,11 +133,38 @@ public class ProfileFragment extends Fragment { | |||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
| 
 | 
 | ||||||
|  |     private final FetchListener<PostModel[]> postsFetchListener = new FetchListener<PostModel[]>() { | ||||||
|  |         @Override | ||||||
|  |         public void onResult(final PostModel[] result) { | ||||||
|  |             binding.swipeRefreshLayout.setRefreshing(false); | ||||||
|  |             if (result != null) { | ||||||
|  |                 binding.mainPosts.post(() -> binding.mainPosts.setVisibility(View.VISIBLE)); | ||||||
|  |                 // final int oldSize = mainActivity.allItems.size(); | ||||||
|  |                 final List<PostModel> postModels = profilePostsViewModel.getList().getValue(); | ||||||
|  |                 final List<PostModel> finalList = postModels == null || postModels.isEmpty() ? new ArrayList<>() : new ArrayList<>(postModels); | ||||||
|  |                 finalList.addAll(Arrays.asList(result)); | ||||||
|  |                 profilePostsViewModel.getList().postValue(finalList); | ||||||
|  |                 PostModel model = null; | ||||||
|  |                 if (result.length != 0) { | ||||||
|  |                     model = result[result.length - 1]; | ||||||
|  |                 } | ||||||
|  |                 if (model == null) return; | ||||||
|  |                 endCursor = model.getEndCursor(); | ||||||
|  |                 hasNextPage = model.hasNextPage(); | ||||||
|  |                 model.setPageCursor(false, null); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             binding.privatePage1.setImageResource(R.drawable.ic_cancel); | ||||||
|  |             binding.privatePage2.setText(R.string.empty_acc); | ||||||
|  |             binding.privatePage.setVisibility(View.VISIBLE); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void onCreate(@Nullable final Bundle savedInstanceState) { |     public void onCreate(@Nullable final Bundle savedInstanceState) { | ||||||
|         super.onCreate(savedInstanceState); |         super.onCreate(savedInstanceState); | ||||||
|         fragmentActivity = (MainActivity) requireActivity(); |         fragmentActivity = (MainActivity) requireActivity(); | ||||||
|         profileService = ProfileService.getInstance(); |         friendshipService = FriendshipService.getInstance(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
| @ -130,6 +172,15 @@ public class ProfileFragment extends Fragment { | |||||||
|                              final ViewGroup container, |                              final ViewGroup container, | ||||||
|                              final Bundle savedInstanceState) { |                              final Bundle savedInstanceState) { | ||||||
|         if (root != null) { |         if (root != null) { | ||||||
|  |             if (getArguments() != null) { | ||||||
|  |                 final ProfileFragmentArgs fragmentArgs = ProfileFragmentArgs.fromBundle(getArguments()); | ||||||
|  |                 if (!fragmentArgs.getUsername().equals(username)) { | ||||||
|  |                     shouldRefresh = true; | ||||||
|  |                     return root; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             setUsernameDelayed(); | ||||||
|  |             shouldRefresh = false; | ||||||
|             return root; |             return root; | ||||||
|         } |         } | ||||||
|         binding = FragmentProfileBinding.inflate(inflater, container, false); |         binding = FragmentProfileBinding.inflate(inflater, container, false); | ||||||
| @ -139,7 +190,9 @@ public class ProfileFragment extends Fragment { | |||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) { |     public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) { | ||||||
|  |         if (!shouldRefresh) return; | ||||||
|         init(); |         init(); | ||||||
|  |         shouldRefresh = false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
| @ -162,12 +215,13 @@ public class ProfileFragment extends Fragment { | |||||||
|             setUsernameDelayed(); |             setUsernameDelayed(); | ||||||
|         } |         } | ||||||
|         if (!isLoggedIn) { |         if (!isLoggedIn) { | ||||||
|             binding.privatePage1.setImageResource(R.drawable.ic_info); |             binding.privatePage1.setImageResource(R.drawable.ic_outline_info_24); | ||||||
|             binding.privatePage2.setText(R.string.no_acc); |             binding.privatePage2.setText(R.string.no_acc); | ||||||
|             binding.privatePage.setVisibility(View.VISIBLE); |             binding.privatePage.setVisibility(View.VISIBLE); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         setupPosts(); |         setupPosts(); | ||||||
|  |         setupCommonListeners(); | ||||||
|         fetchProfile(); |         fetchProfile(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -205,18 +259,12 @@ public class ProfileFragment extends Fragment { | |||||||
|     private void fetchProfileDetails() { |     private void fetchProfileDetails() { | ||||||
|         new ProfileFetcher(username.substring(1), profileModel -> { |         new ProfileFetcher(username.substring(1), profileModel -> { | ||||||
|             this.profileModel = profileModel; |             this.profileModel = profileModel; | ||||||
|             new PostsFetcher(profileModel.getId(), |  | ||||||
|                     null, |  | ||||||
|                     result -> profilePostsViewModel.getList().postValue(Arrays.asList(result))) |  | ||||||
|                     .setUsername(profileModel.getUsername()) |  | ||||||
|                     .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |  | ||||||
|             setProfileDetails(); |             setProfileDetails(); | ||||||
| 
 | 
 | ||||||
|         }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |         }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void setProfileDetails() { |     private void setProfileDetails() { | ||||||
|         setupCommonListeners(); |  | ||||||
|         if (profileModel == null) { |         if (profileModel == null) { | ||||||
|             binding.swipeRefreshLayout.setRefreshing(false); |             binding.swipeRefreshLayout.setRefreshing(false); | ||||||
|             Toast.makeText(requireContext(), R.string.error_loading_profile, Toast.LENGTH_SHORT).show(); |             Toast.makeText(requireContext(), R.string.error_loading_profile, Toast.LENGTH_SHORT).show(); | ||||||
| @ -225,12 +273,18 @@ public class ProfileFragment extends Fragment { | |||||||
|         binding.isVerified.setVisibility(profileModel.isVerified() ? View.VISIBLE : View.GONE); |         binding.isVerified.setVisibility(profileModel.isVerified() ? View.VISIBLE : View.GONE); | ||||||
|         final String profileId = profileModel.getId(); |         final String profileId = profileModel.getId(); | ||||||
|         if (settingsHelper.getBoolean(Constants.STORIESIG)) { |         if (settingsHelper.getBoolean(Constants.STORIESIG)) { | ||||||
|             new iStoryStatusFetcher(profileId, profileModel.getUsername(), false, false, |             new iStoryStatusFetcher( | ||||||
|                     (!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)), false, |                     profileId, | ||||||
|  |                     profileModel.getUsername(), | ||||||
|  |                     false, | ||||||
|  |                     false, | ||||||
|  |                     (!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)), | ||||||
|  |                     false, | ||||||
|                     result -> { |                     result -> { | ||||||
|                         // mainActivity.storyModels = result; |                         storyModels = result; | ||||||
|                         // if (result != null && result.length > 0) |                         if (result != null && result.length > 0) { | ||||||
|                         //     binding.mainProfileImage.setStoriesBorder(); |                             binding.mainProfileImage.setStoriesBorder(); | ||||||
|  |                         } | ||||||
|                     }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |                     }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | ||||||
| 
 | 
 | ||||||
|             new HighlightsFetcher(profileId, (!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)), result -> { |             new HighlightsFetcher(profileId, (!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)), result -> { | ||||||
| @ -412,9 +466,7 @@ public class ProfileFragment extends Fragment { | |||||||
|             } else { |             } else { | ||||||
|                 binding.swipeRefreshLayout.setRefreshing(true); |                 binding.swipeRefreshLayout.setRefreshing(true); | ||||||
|                 binding.mainPosts.setVisibility(View.VISIBLE); |                 binding.mainPosts.setVisibility(View.VISIBLE); | ||||||
|                 // currentlyExecuting = new PostsFetcher(profileId, postsFetchListener) |                 fetchPosts(); | ||||||
|                 //         .setUsername(profileModel.getUsername()) |  | ||||||
|                 //         .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |  | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             binding.mainFollowers.setClickable(false); |             binding.mainFollowers.setClickable(false); | ||||||
| @ -451,14 +503,53 @@ public class ProfileFragment extends Fragment { | |||||||
|                             new DataBox.FavoriteModel(username, System.currentTimeMillis(), |                             new DataBox.FavoriteModel(username, System.currentTimeMillis(), | ||||||
|                                     username.replaceAll("^@", ""))); |                                     username.replaceAll("^@", ""))); | ||||||
|                 } |                 } | ||||||
|                 // onRefresh(); |                 fetchProfileDetails(); | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             profileService.followProfile(username); |             if (profileModel.getFollowing() || profileModel.getRequested()) { | ||||||
|  |                 friendshipService.unfollow( | ||||||
|  |                         userIdFromCookie, | ||||||
|  |                         profileModel.getId(), | ||||||
|  |                         Utils.getCsrfTokenFromCookie(cookie), | ||||||
|  |                         new ServiceCallback<FriendshipRepositoryChangeResponseRootObject>() { | ||||||
|  |                             @Override | ||||||
|  |                             public void onSuccess(final FriendshipRepositoryChangeResponseRootObject result) { | ||||||
|  |                                 Log.d(TAG, "Unfollow success: " + result); | ||||||
|  |                             } | ||||||
|  | 
 | ||||||
|  |                             @Override | ||||||
|  |                             public void onFailure(final Throwable t) { | ||||||
|  |                                 Log.e(TAG, "Error unfollowing", t); | ||||||
|  |                             } | ||||||
|  |                         }); | ||||||
|  |             } else { | ||||||
|  |                 friendshipService.follow( | ||||||
|  |                         userIdFromCookie, | ||||||
|  |                         profileModel.getId(), | ||||||
|  |                         Utils.getCsrfTokenFromCookie(cookie), | ||||||
|  |                         new ServiceCallback<FriendshipRepositoryChangeResponseRootObject>() { | ||||||
|  |                             @Override | ||||||
|  |                             public void onSuccess(final FriendshipRepositoryChangeResponseRootObject result) { | ||||||
|  |                                 Log.d(TAG, "Follow success: " + result); | ||||||
|  |                             } | ||||||
|  | 
 | ||||||
|  |                             @Override | ||||||
|  |                             public void onFailure(final Throwable t) { | ||||||
|  |                                 Log.e(TAG, "Error following", t); | ||||||
|  |                             } | ||||||
|  |                         }); | ||||||
|  |             } | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         // binding.btnRestrict.setOnClickListener(profileActionListener); |         binding.btnRestrict.setOnClickListener(v -> { | ||||||
|         // binding.btnBlock.setOnClickListener(profileActionListener); |             if (!isLoggedIn) return; | ||||||
|  |             // restrict | ||||||
|  |             // new ProfileAction().execute("restrict"); | ||||||
|  |         }); | ||||||
|  |         binding.btnBlock.setOnClickListener(v -> { | ||||||
|  |             if (!isLoggedIn) return; | ||||||
|  |             // new MainHelper.ProfileAction().execute("block"); | ||||||
|  |         }); | ||||||
|         binding.btnSaved.setOnClickListener(v -> startActivity(new Intent(requireContext(), SavedViewer.class) |         binding.btnSaved.setOnClickListener(v -> startActivity(new Intent(requireContext(), SavedViewer.class) | ||||||
|                 .putExtra(Constants.EXTRAS_INDEX, "$" + profileModel.getId()) |                 .putExtra(Constants.EXTRAS_INDEX, "$" + profileModel.getId()) | ||||||
|                 .putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername()) |                 .putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername()) | ||||||
| @ -516,8 +607,34 @@ public class ProfileFragment extends Fragment { | |||||||
|             onBackPressedDispatcher.addCallback(onBackPressedCallback); |             onBackPressedDispatcher.addCallback(onBackPressedCallback); | ||||||
|             return true; |             return true; | ||||||
|         }); |         }); | ||||||
|         binding.mainPosts.setAdapter(postsAdapter); |  | ||||||
|         profilePostsViewModel.getList().observe(fragmentActivity, postsAdapter::submitList); |         profilePostsViewModel.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; | ||||||
|  |         }); | ||||||
|  |         binding.mainPosts.addOnScrollListener(lazyLoader); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void fetchPosts() { | ||||||
|  |         stopCurrentExecutor(); | ||||||
|  |         currentlyExecuting = new PostsFetcher(profileModel.getId(), endCursor, postsFetchListener) | ||||||
|  |                 .setUsername(profileModel.getUsername()) | ||||||
|  |                 .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void stopCurrentExecutor() { | ||||||
|  |         if (currentlyExecuting != null) { | ||||||
|  |             try { | ||||||
|  |                 currentlyExecuting.cancel(true); | ||||||
|  |             } catch (final Exception e) { | ||||||
|  |                 if (logCollector != null) | ||||||
|  |                     logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor"); | ||||||
|  |                 Log.e(TAG, "", e); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private boolean checkAndResetAction() { |     private boolean checkAndResetAction() { | ||||||
|  | |||||||
| @ -0,0 +1,44 @@ | |||||||
|  | package awais.instagrabber.fragments.settings; | ||||||
|  | 
 | ||||||
|  | import android.content.SharedPreferences; | ||||||
|  | import android.os.Bundle; | ||||||
|  | 
 | ||||||
|  | import androidx.preference.PreferenceFragmentCompat; | ||||||
|  | import androidx.preference.PreferenceManager; | ||||||
|  | import androidx.preference.PreferenceScreen; | ||||||
|  | 
 | ||||||
|  | import awais.instagrabber.activities.MainActivity; | ||||||
|  | import awais.instagrabber.utils.Constants; | ||||||
|  | import awais.instagrabber.utils.LocaleUtils; | ||||||
|  | 
 | ||||||
|  | public abstract class BasePreferencesFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener { | ||||||
|  |     private boolean shouldRecreate = false; | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { | ||||||
|  |         final PreferenceManager preferenceManager = getPreferenceManager(); | ||||||
|  |         preferenceManager.setSharedPreferencesName("settings"); | ||||||
|  |         preferenceManager.getSharedPreferences().registerOnSharedPreferenceChangeListener(this); | ||||||
|  |         final PreferenceScreen screen = preferenceManager.createPreferenceScreen(requireContext()); | ||||||
|  |         setupPreferenceScreen(screen); | ||||||
|  |         setPreferenceScreen(screen); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     abstract void setupPreferenceScreen(PreferenceScreen screen); | ||||||
|  | 
 | ||||||
|  |     protected void shouldRecreate() { | ||||||
|  |         this.shouldRecreate = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) { | ||||||
|  |         if (!shouldRecreate) return; | ||||||
|  |         final MainActivity activity = (MainActivity) getActivity(); | ||||||
|  |         if (activity == null) return; | ||||||
|  |         if (key.equals(Constants.APP_LANGUAGE)) { | ||||||
|  |             LocaleUtils.setLocale(activity.getBaseContext()); | ||||||
|  |         } | ||||||
|  |         shouldRecreate = false; | ||||||
|  |         activity.recreate(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,105 @@ | |||||||
|  | package awais.instagrabber.fragments.settings; | ||||||
|  | 
 | ||||||
|  | import android.content.Context; | ||||||
|  | import android.content.Intent; | ||||||
|  | import android.widget.Toast; | ||||||
|  | 
 | ||||||
|  | import androidx.annotation.NonNull; | ||||||
|  | import androidx.annotation.Nullable; | ||||||
|  | import androidx.navigation.NavDirections; | ||||||
|  | import androidx.navigation.fragment.NavHostFragment; | ||||||
|  | import androidx.preference.Preference; | ||||||
|  | import androidx.preference.PreferenceCategory; | ||||||
|  | import androidx.preference.PreferenceScreen; | ||||||
|  | 
 | ||||||
|  | import awais.instagrabber.R; | ||||||
|  | import awais.instagrabber.activities.Login; | ||||||
|  | import awais.instagrabber.utils.Constants; | ||||||
|  | import awais.instagrabber.utils.Utils; | ||||||
|  | 
 | ||||||
|  | import static awais.instagrabber.utils.Utils.settingsHelper; | ||||||
|  | 
 | ||||||
|  | public class MorePreferencesFragment extends BasePreferencesFragment { | ||||||
|  |     private final String cookie = settingsHelper.getString(Constants.COOKIE); | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     void setupPreferenceScreen(final PreferenceScreen screen) { | ||||||
|  |         screen.addPreference(new MoreHeaderPreference(requireContext())); | ||||||
|  | 
 | ||||||
|  |         final PreferenceCategory accountCategory = new PreferenceCategory(requireContext()); | ||||||
|  |         accountCategory.setTitle("Account"); | ||||||
|  |         accountCategory.setIconSpaceReserved(false); | ||||||
|  |         screen.addPreference(accountCategory); | ||||||
|  |         final boolean isLoggedIn = !Utils.isEmpty(cookie) && Utils.getUserIdFromCookie(cookie) != null; | ||||||
|  |         screen.addPreference(getPreference(isLoggedIn ? R.string.relogin : R.string.login, | ||||||
|  |                 isLoggedIn ? R.string.relogin_summary : -1, | ||||||
|  |                 -1, | ||||||
|  |                 preference -> { | ||||||
|  |                     startActivityForResult(new Intent(requireContext(), Login.class), Constants.LOGIN_RESULT_CODE); | ||||||
|  |                     return true; | ||||||
|  |                 })); | ||||||
|  |         if (isLoggedIn) { | ||||||
|  |             screen.addPreference(getPreference(R.string.logout, -1, preference -> { | ||||||
|  |                 Utils.setupCookies("LOGOUT"); | ||||||
|  |                 shouldRecreate(); | ||||||
|  |                 Toast.makeText(requireContext(), R.string.logout_success, Toast.LENGTH_SHORT).show(); | ||||||
|  |                 settingsHelper.putString(Constants.COOKIE, ""); | ||||||
|  |                 return true; | ||||||
|  |             })); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         final PreferenceCategory defaultCategory = new PreferenceCategory(requireContext()); | ||||||
|  |         screen.addPreference(defaultCategory); | ||||||
|  |         defaultCategory.addPreference(getPreference(R.string.action_notif, R.drawable.ic_not_liked, preference -> false)); | ||||||
|  |         defaultCategory.addPreference(getPreference(R.string.action_settings, R.drawable.ic_outline_settings_24, preference -> { | ||||||
|  |             final NavDirections navDirections = MorePreferencesFragmentDirections.actionMorePreferencesFragmentToSettingsPreferencesFragment(); | ||||||
|  |             NavHostFragment.findNavController(this).navigate(navDirections); | ||||||
|  |             return true; | ||||||
|  |         })); | ||||||
|  |         defaultCategory.addPreference(getPreference(R.string.action_about, R.drawable.ic_outline_info_24, preference -> false)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void onActivityResult(final int requestCode, final int resultCode, @Nullable final Intent data) { | ||||||
|  |         if (resultCode == Constants.LOGIN_RESULT_CODE) { | ||||||
|  |             if (data == null) return; | ||||||
|  |             final String cookie = data.getStringExtra("cookie"); | ||||||
|  |             Utils.setupCookies(cookie); | ||||||
|  |             shouldRecreate(); | ||||||
|  |             Toast.makeText(requireContext(), R.string.login_success_loading_cookies, Toast.LENGTH_SHORT).show(); | ||||||
|  |             settingsHelper.putString(Constants.COOKIE, cookie); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @NonNull | ||||||
|  |     private Preference getPreference(final int title, | ||||||
|  |                                      final int icon, | ||||||
|  |                                      final Preference.OnPreferenceClickListener clickListener) { | ||||||
|  |         return getPreference(title, -1, icon, clickListener); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @NonNull | ||||||
|  |     private Preference getPreference(final int title, | ||||||
|  |                                      final int summary, | ||||||
|  |                                      final int icon, | ||||||
|  |                                      final Preference.OnPreferenceClickListener clickListener) { | ||||||
|  |         final Preference preference = new Preference(requireContext()); | ||||||
|  |         if (icon <= 0) preference.setIconSpaceReserved(false); | ||||||
|  |         if (icon > 0) preference.setIcon(icon); | ||||||
|  |         preference.setTitle(title); | ||||||
|  |         if (summary > 0) { | ||||||
|  |             preference.setSummary(summary); | ||||||
|  |         } | ||||||
|  |         preference.setOnPreferenceClickListener(clickListener); | ||||||
|  |         return preference; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static class MoreHeaderPreference extends Preference { | ||||||
|  | 
 | ||||||
|  |         public MoreHeaderPreference(final Context context) { | ||||||
|  |             super(context); | ||||||
|  |             setLayoutResource(R.layout.pref_more_header); | ||||||
|  |             setSelectable(false); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,285 @@ | |||||||
|  | package awais.instagrabber.fragments.settings; | ||||||
|  | 
 | ||||||
|  | import android.content.Context; | ||||||
|  | import android.os.Bundle; | ||||||
|  | import android.view.Menu; | ||||||
|  | import android.view.MenuItem; | ||||||
|  | import android.view.View; | ||||||
|  | 
 | ||||||
|  | import androidx.annotation.NonNull; | ||||||
|  | import androidx.annotation.Nullable; | ||||||
|  | import androidx.appcompat.widget.AppCompatButton; | ||||||
|  | import androidx.appcompat.widget.AppCompatTextView; | ||||||
|  | import androidx.preference.DropDownPreference; | ||||||
|  | import androidx.preference.ListPreference; | ||||||
|  | import androidx.preference.Preference; | ||||||
|  | import androidx.preference.PreferenceCategory; | ||||||
|  | import androidx.preference.PreferenceScreen; | ||||||
|  | import androidx.preference.PreferenceViewHolder; | ||||||
|  | import androidx.preference.SwitchPreferenceCompat; | ||||||
|  | 
 | ||||||
|  | import com.google.android.material.switchmaterial.SwitchMaterial; | ||||||
|  | 
 | ||||||
|  | import java.text.SimpleDateFormat; | ||||||
|  | 
 | ||||||
|  | import awais.instagrabber.R; | ||||||
|  | import awais.instagrabber.dialogs.TimeSettingsDialog; | ||||||
|  | import awais.instagrabber.utils.Constants; | ||||||
|  | import awais.instagrabber.utils.DirectoryChooser; | ||||||
|  | import awais.instagrabber.utils.Utils; | ||||||
|  | 
 | ||||||
|  | import static awais.instagrabber.utils.Constants.FOLDER_PATH; | ||||||
|  | import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO; | ||||||
|  | import static awais.instagrabber.utils.Utils.settingsHelper; | ||||||
|  | 
 | ||||||
|  | public class SettingsPreferencesFragment extends BasePreferencesFragment { | ||||||
|  |     private static final String TAG = "SettingsPrefsFrag"; | ||||||
|  |     private static AppCompatTextView customPathTextView; | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void onCreate(@Nullable final Bundle savedInstanceState) { | ||||||
|  |         super.onCreate(savedInstanceState); | ||||||
|  |         setHasOptionsMenu(true); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void onPrepareOptionsMenu(@NonNull final Menu menu) { | ||||||
|  |         super.onPrepareOptionsMenu(menu); | ||||||
|  |         final MenuItem item = menu.findItem(R.id.favourites); | ||||||
|  |         item.setVisible(false); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     void setupPreferenceScreen(final PreferenceScreen screen) { | ||||||
|  |         screen.addPreference(getLanguagePreference()); | ||||||
|  |         screen.addPreference(getThemePreference()); | ||||||
|  |         screen.addPreference(getAmoledThemePreference()); | ||||||
|  |         screen.addPreference(getDownloadUserFolderPreference()); | ||||||
|  |         screen.addPreference(getSaveToCustomFolderPreference()); | ||||||
|  |         screen.addPreference(getAutoPlayVideosPreference()); | ||||||
|  |         screen.addPreference(getAlwaysMuteVideosPreference()); | ||||||
|  |         screen.addPreference(getPostTimePreference()); | ||||||
|  | 
 | ||||||
|  |         final PreferenceCategory loggedInUsersPreferenceCategory = new PreferenceCategory(requireContext()); | ||||||
|  |         loggedInUsersPreferenceCategory.setIconSpaceReserved(false); | ||||||
|  |         screen.addPreference(loggedInUsersPreferenceCategory); | ||||||
|  |         loggedInUsersPreferenceCategory.setTitle(R.string.login_settings); | ||||||
|  |         loggedInUsersPreferenceCategory.addPreference(getMarkStoriesSeenPreference()); | ||||||
|  |         loggedInUsersPreferenceCategory.addPreference(getEnableActivityNotificationsPreference()); | ||||||
|  | 
 | ||||||
|  |         final PreferenceCategory anonUsersPreferenceCategory = new PreferenceCategory(requireContext()); | ||||||
|  |         anonUsersPreferenceCategory.setIconSpaceReserved(false); | ||||||
|  |         screen.addPreference(anonUsersPreferenceCategory); | ||||||
|  |         anonUsersPreferenceCategory.setTitle(R.string.anonymous_settings); | ||||||
|  |         anonUsersPreferenceCategory.addPreference(getUseInstaDpPreference()); | ||||||
|  |         anonUsersPreferenceCategory.addPreference(getUseStoriesIgPreference()); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @NonNull | ||||||
|  |     private DropDownPreference getLanguagePreference() { | ||||||
|  |         final DropDownPreference preference = new DropDownPreference(requireContext()); | ||||||
|  |         preference.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance()); | ||||||
|  |         final int length = getResources().getStringArray(R.array.languages).length; | ||||||
|  |         final String[] values = new String[length]; | ||||||
|  |         for (int i = 0; i < length; i++) { | ||||||
|  |             values[i] = String.valueOf(i); | ||||||
|  |         } | ||||||
|  |         preference.setKey(Constants.APP_LANGUAGE); | ||||||
|  |         preference.setTitle(R.string.select_language); | ||||||
|  |         preference.setEntries(R.array.languages); | ||||||
|  |         preference.setIconSpaceReserved(false); | ||||||
|  |         preference.setEntryValues(values); | ||||||
|  |         preference.setOnPreferenceChangeListener((preference1, newValue) -> { | ||||||
|  |             shouldRecreate(); | ||||||
|  |             return true; | ||||||
|  |         }); | ||||||
|  |         return preference; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @NonNull | ||||||
|  |     private DropDownPreference getThemePreference() { | ||||||
|  |         final DropDownPreference preference = new DropDownPreference(requireContext()); | ||||||
|  |         preference.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance()); | ||||||
|  |         final int length = getResources().getStringArray(R.array.theme_presets).length; | ||||||
|  |         final String[] values = new String[length]; | ||||||
|  |         for (int i = 0; i < length; i++) { | ||||||
|  |             values[i] = String.valueOf(i); | ||||||
|  |         } | ||||||
|  |         preference.setKey(Constants.APP_THEME); | ||||||
|  |         preference.setTitle(R.string.theme_settings); | ||||||
|  |         preference.setEntries(R.array.theme_presets); | ||||||
|  |         preference.setIconSpaceReserved(false); | ||||||
|  |         preference.setEntryValues(values); | ||||||
|  |         preference.setOnPreferenceChangeListener((preference1, newValue) -> { | ||||||
|  |             shouldRecreate(); | ||||||
|  |             return true; | ||||||
|  |         }); | ||||||
|  |         return preference; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private SwitchPreferenceCompat getAmoledThemePreference() { | ||||||
|  |         final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(requireContext()); | ||||||
|  |         preference.setKey(Constants.AMOLED_THEME); | ||||||
|  |         preference.setTitle(R.string.use_amoled_dark_theme); | ||||||
|  |         preference.setIconSpaceReserved(false); | ||||||
|  |         preference.setOnPreferenceChangeListener((preference1, newValue) -> { | ||||||
|  |             final boolean isNight = Utils.isNight(requireContext(), settingsHelper.getThemeCode(true)); | ||||||
|  |             if (isNight) shouldRecreate(); | ||||||
|  |             return true; | ||||||
|  |         }); | ||||||
|  |         return preference; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private Preference getDownloadUserFolderPreference() { | ||||||
|  |         final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(requireContext()); | ||||||
|  |         preference.setKey(Constants.DOWNLOAD_USER_FOLDER); | ||||||
|  |         preference.setTitle("Download to username folder"); | ||||||
|  |         preference.setSummary(R.string.download_user_folder); | ||||||
|  |         preference.setIconSpaceReserved(false); | ||||||
|  |         return preference; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private Preference getSaveToCustomFolderPreference() { | ||||||
|  |         return new SaveToCustomFolderPreference(requireContext(), (resultCallback) -> { | ||||||
|  |             new DirectoryChooser() | ||||||
|  |                     .setInitialDirectory(settingsHelper.getString(FOLDER_PATH)) | ||||||
|  |                     .setInteractionListener(path -> { | ||||||
|  |                         settingsHelper.putString(FOLDER_PATH, path); | ||||||
|  |                         resultCallback.onResult(path); | ||||||
|  |                     }) | ||||||
|  |                     .show(getParentFragmentManager(), null); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private Preference getAutoPlayVideosPreference() { | ||||||
|  |         final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(requireContext()); | ||||||
|  |         preference.setKey(Constants.AUTOPLAY_VIDEOS); | ||||||
|  |         preference.setTitle(R.string.post_viewer_autoplay_video); | ||||||
|  |         preference.setIconSpaceReserved(false); | ||||||
|  |         return preference; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private Preference getAlwaysMuteVideosPreference() { | ||||||
|  |         final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(requireContext()); | ||||||
|  |         preference.setKey(Constants.MUTED_VIDEOS); | ||||||
|  |         preference.setTitle(R.string.post_viewer_muted_autoplay); | ||||||
|  |         preference.setIconSpaceReserved(false); | ||||||
|  |         return preference; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private Preference getMarkStoriesSeenPreference() { | ||||||
|  |         final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(requireContext()); | ||||||
|  |         preference.setKey(Constants.MARK_AS_SEEN); | ||||||
|  |         preference.setTitle(R.string.mark_as_seen_setting); | ||||||
|  |         preference.setSummary(R.string.mark_as_seen_setting_summary); | ||||||
|  |         preference.setIconSpaceReserved(false); | ||||||
|  |         return preference; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private Preference getEnableActivityNotificationsPreference() { | ||||||
|  |         final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(requireContext()); | ||||||
|  |         preference.setKey(Constants.CHECK_ACTIVITY); | ||||||
|  |         preference.setTitle(R.string.activity_setting); | ||||||
|  |         preference.setIconSpaceReserved(false); | ||||||
|  |         return preference; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private Preference getUseInstaDpPreference() { | ||||||
|  |         final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(requireContext()); | ||||||
|  |         preference.setKey(Constants.INSTADP); | ||||||
|  |         preference.setTitle(R.string.instadp_settings); | ||||||
|  |         preference.setIconSpaceReserved(false); | ||||||
|  |         return preference; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private Preference getUseStoriesIgPreference() { | ||||||
|  |         final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(requireContext()); | ||||||
|  |         preference.setKey(Constants.STORIESIG); | ||||||
|  |         preference.setTitle(R.string.storiesig_settings); | ||||||
|  |         preference.setIconSpaceReserved(false); | ||||||
|  |         return preference; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private Preference getPostTimePreference() { | ||||||
|  |         final Preference preference = new Preference(requireContext()); | ||||||
|  |         preference.setTitle(R.string.time_settings); | ||||||
|  |         preference.setIconSpaceReserved(false); | ||||||
|  |         preference.setOnPreferenceClickListener(preference1 -> { | ||||||
|  |             new TimeSettingsDialog(settingsHelper.getBoolean(Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED), | ||||||
|  |                     settingsHelper.getString(Constants.CUSTOM_DATE_TIME_FORMAT), | ||||||
|  |                     settingsHelper.getString(Constants.DATE_TIME_SELECTION), | ||||||
|  |                     (isCustomFormat, | ||||||
|  |                      formatSelection, | ||||||
|  |                      spTimeFormatSelectedItemPosition, | ||||||
|  |                      spSeparatorSelectedItemPosition, | ||||||
|  |                      spDateFormatSelectedItemPosition, | ||||||
|  |                      selectedFormat, currentFormat) -> { | ||||||
|  |                         if (isCustomFormat) { | ||||||
|  |                             settingsHelper.putString(Constants.CUSTOM_DATE_TIME_FORMAT, formatSelection); | ||||||
|  |                         } else { | ||||||
|  |                             final String formatSelectionUpdated = spTimeFormatSelectedItemPosition + ";" | ||||||
|  |                                     + spSeparatorSelectedItemPosition + ';' | ||||||
|  |                                     + spDateFormatSelectedItemPosition; // time;separator;date | ||||||
|  |                             settingsHelper.putString(Constants.DATE_TIME_FORMAT, selectedFormat); | ||||||
|  |                             settingsHelper.putString(Constants.DATE_TIME_SELECTION, formatSelectionUpdated); | ||||||
|  |                         } | ||||||
|  |                         settingsHelper.putBoolean(Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED, isCustomFormat); | ||||||
|  |                         Utils.datetimeParser = (SimpleDateFormat) currentFormat.clone(); | ||||||
|  |                     } | ||||||
|  |             ).show(getParentFragmentManager(), null); | ||||||
|  |             return true; | ||||||
|  |         }); | ||||||
|  |         return preference; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static class SaveToCustomFolderPreference extends Preference { | ||||||
|  | 
 | ||||||
|  |         private final OnSelectFolderButtonClickListener onSelectFolderButtonClickListener; | ||||||
|  |         private String key; | ||||||
|  | 
 | ||||||
|  |         public SaveToCustomFolderPreference(final Context context, final OnSelectFolderButtonClickListener onSelectFolderButtonClickListener) { | ||||||
|  |             super(context); | ||||||
|  |             this.onSelectFolderButtonClickListener = onSelectFolderButtonClickListener; | ||||||
|  |             key = Constants.FOLDER_SAVE_TO; | ||||||
|  |             setLayoutResource(R.layout.pref_custom_folder); | ||||||
|  |             setKey(key); | ||||||
|  |             setTitle(R.string.save_to_folder); | ||||||
|  |             setIconSpaceReserved(false); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Override | ||||||
|  |         public void onBindViewHolder(final PreferenceViewHolder holder) { | ||||||
|  |             super.onBindViewHolder(holder); | ||||||
|  |             final SwitchMaterial cbSaveTo = (SwitchMaterial) holder.findViewById(R.id.cbSaveTo); | ||||||
|  |             final View buttonContainer = holder.findViewById(R.id.button_container); | ||||||
|  |             customPathTextView = (AppCompatTextView) holder.findViewById(R.id.custom_path); | ||||||
|  |             cbSaveTo.setOnCheckedChangeListener((buttonView, isChecked) -> { | ||||||
|  |                 settingsHelper.putBoolean(FOLDER_SAVE_TO, isChecked); | ||||||
|  |                 buttonContainer.setVisibility(isChecked ? View.VISIBLE : View.GONE); | ||||||
|  |                 final String customPath = settingsHelper.getString(FOLDER_PATH); | ||||||
|  |                 customPathTextView.setText(customPath); | ||||||
|  |             }); | ||||||
|  |             final boolean savedToEnabled = settingsHelper.getBoolean(key); | ||||||
|  |             holder.itemView.setOnClickListener(v -> cbSaveTo.toggle()); | ||||||
|  |             cbSaveTo.setChecked(savedToEnabled); | ||||||
|  |             buttonContainer.setVisibility(savedToEnabled ? View.VISIBLE : View.GONE); | ||||||
|  |             final AppCompatButton btnSaveTo = (AppCompatButton) holder.findViewById(R.id.btnSaveTo); | ||||||
|  |             btnSaveTo.setOnClickListener(v -> { | ||||||
|  |                 if (onSelectFolderButtonClickListener == null) return; | ||||||
|  |                 onSelectFolderButtonClickListener.onClick(result -> { | ||||||
|  |                     if (Utils.isEmpty(result)) return; | ||||||
|  |                     customPathTextView.setText(result); | ||||||
|  |                 }); | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public interface ResultCallback { | ||||||
|  |             void onResult(String result); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public interface OnSelectFolderButtonClickListener { | ||||||
|  |             void onClick(ResultCallback resultCallback); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,4 @@ | |||||||
|  | package awais.instagrabber.fragments.settings.helpers; | ||||||
|  | 
 | ||||||
|  | public class AutoSummaryDropDownPreference { | ||||||
|  | } | ||||||
| @ -0,0 +1,19 @@ | |||||||
|  | package awais.instagrabber.repositories; | ||||||
|  | 
 | ||||||
|  | import java.util.Map; | ||||||
|  | 
 | ||||||
|  | import awais.instagrabber.repositories.responses.FriendshipRepositoryChangeResponseRootObject; | ||||||
|  | import retrofit2.Call; | ||||||
|  | import retrofit2.http.FieldMap; | ||||||
|  | import retrofit2.http.FormUrlEncoded; | ||||||
|  | import retrofit2.http.POST; | ||||||
|  | import retrofit2.http.Path; | ||||||
|  | 
 | ||||||
|  | public interface FriendshipRepository { | ||||||
|  | 
 | ||||||
|  |     @FormUrlEncoded | ||||||
|  |     @POST("/api/v1/friendships/{action}/{id}/") | ||||||
|  |     Call<FriendshipRepositoryChangeResponseRootObject> change(@Path("action") String action, | ||||||
|  |                                                               @Path("id") String id, | ||||||
|  |                                                               @FieldMap Map<String, String> form); | ||||||
|  | } | ||||||
| @ -1,4 +0,0 @@ | |||||||
| package awais.instagrabber.repositories; |  | ||||||
| 
 |  | ||||||
| public interface ProfileRepository { |  | ||||||
| } |  | ||||||
| @ -0,0 +1,76 @@ | |||||||
|  | package awais.instagrabber.repositories.responses; | ||||||
|  | 
 | ||||||
|  | public class FriendshipRepositoryChangeResponseFriendshipStatus { | ||||||
|  |     private boolean following; | ||||||
|  |     private boolean followedBy; | ||||||
|  |     private boolean blocking; | ||||||
|  |     private boolean muting; | ||||||
|  |     private boolean isPrivate; | ||||||
|  |     private boolean incomingRequest; | ||||||
|  |     private boolean outgoingRequest; | ||||||
|  |     private boolean isBestie; | ||||||
|  | 
 | ||||||
|  |     public FriendshipRepositoryChangeResponseFriendshipStatus(final boolean following, | ||||||
|  |                                                               final boolean followedBy, | ||||||
|  |                                                               final boolean blocking, | ||||||
|  |                                                               final boolean muting, | ||||||
|  |                                                               final boolean isPrivate, | ||||||
|  |                                                               final boolean incomingRequest, | ||||||
|  |                                                               final boolean outgoingRequest, | ||||||
|  |                                                               final boolean isBestie) { | ||||||
|  |         this.following = following; | ||||||
|  |         this.followedBy = followedBy; | ||||||
|  |         this.blocking = blocking; | ||||||
|  |         this.muting = muting; | ||||||
|  |         this.isPrivate = isPrivate; | ||||||
|  |         this.incomingRequest = incomingRequest; | ||||||
|  |         this.outgoingRequest = outgoingRequest; | ||||||
|  |         this.isBestie = isBestie; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public boolean isFollowing() { | ||||||
|  |         return following; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public boolean isFollowedBy() { | ||||||
|  |         return followedBy; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public boolean isBlocking() { | ||||||
|  |         return blocking; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public boolean isMuting() { | ||||||
|  |         return muting; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public boolean isPrivate() { | ||||||
|  |         return isPrivate; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public boolean isIncomingRequest() { | ||||||
|  |         return incomingRequest; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public boolean isOutgoingRequest() { | ||||||
|  |         return outgoingRequest; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public boolean isBestie() { | ||||||
|  |         return isBestie; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public String toString() { | ||||||
|  |         return "FriendshipRepositoryChangeResponseFriendshipStatus{" + | ||||||
|  |                 "following=" + following + | ||||||
|  |                 ", followedBy=" + followedBy + | ||||||
|  |                 ", blocking=" + blocking + | ||||||
|  |                 ", muting=" + muting + | ||||||
|  |                 ", isPrivate=" + isPrivate + | ||||||
|  |                 ", incomingRequest=" + incomingRequest + | ||||||
|  |                 ", outgoingRequest=" + outgoingRequest + | ||||||
|  |                 ", isBestie=" + isBestie + | ||||||
|  |                 '}'; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,27 @@ | |||||||
|  | package awais.instagrabber.repositories.responses; | ||||||
|  | 
 | ||||||
|  | public class FriendshipRepositoryChangeResponseRootObject { | ||||||
|  |     private FriendshipRepositoryChangeResponseFriendshipStatus friendshipStatus; | ||||||
|  |     private String status; | ||||||
|  | 
 | ||||||
|  |     public FriendshipRepositoryChangeResponseRootObject(final FriendshipRepositoryChangeResponseFriendshipStatus friendshipStatus, final String status) { | ||||||
|  |         this.friendshipStatus = friendshipStatus; | ||||||
|  |         this.status = status; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public FriendshipRepositoryChangeResponseFriendshipStatus getFriendshipStatus() { | ||||||
|  |         return friendshipStatus; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getStatus() { | ||||||
|  |         return status; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public String toString() { | ||||||
|  |         return "FriendshipRepositoryChangeResponseRootObject{" + | ||||||
|  |                 "friendshipStatus=" + friendshipStatus + | ||||||
|  |                 ", status='" + status + '\'' + | ||||||
|  |                 '}'; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -2,6 +2,7 @@ package awais.instagrabber.services; | |||||||
| 
 | 
 | ||||||
| import okhttp3.OkHttpClient; | import okhttp3.OkHttpClient; | ||||||
| import retrofit2.Retrofit; | import retrofit2.Retrofit; | ||||||
|  | import retrofit2.converter.gson.GsonConverterFactory; | ||||||
| import retrofit2.converter.scalars.ScalarsConverterFactory; | import retrofit2.converter.scalars.ScalarsConverterFactory; | ||||||
| 
 | 
 | ||||||
| public abstract class BaseService { | public abstract class BaseService { | ||||||
| @ -17,6 +18,7 @@ public abstract class BaseService { | |||||||
|                     .build(); |                     .build(); | ||||||
|             builder = new Retrofit.Builder() |             builder = new Retrofit.Builder() | ||||||
|                     .addConverterFactory(ScalarsConverterFactory.create()) |                     .addConverterFactory(ScalarsConverterFactory.create()) | ||||||
|  |                     .addConverterFactory(GsonConverterFactory.create()) | ||||||
|                     .client(client); |                     .client(client); | ||||||
|         } |         } | ||||||
|         return builder; |         return builder; | ||||||
|  | |||||||
| @ -0,0 +1,82 @@ | |||||||
|  | package awais.instagrabber.services; | ||||||
|  | 
 | ||||||
|  | import androidx.annotation.NonNull; | ||||||
|  | 
 | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.UUID; | ||||||
|  | 
 | ||||||
|  | import awais.instagrabber.repositories.FriendshipRepository; | ||||||
|  | import awais.instagrabber.repositories.responses.FriendshipRepositoryChangeResponseRootObject; | ||||||
|  | import awais.instagrabber.utils.Utils; | ||||||
|  | import retrofit2.Call; | ||||||
|  | import retrofit2.Callback; | ||||||
|  | import retrofit2.Response; | ||||||
|  | import retrofit2.Retrofit; | ||||||
|  | 
 | ||||||
|  | public class FriendshipService extends BaseService { | ||||||
|  |     private static final String TAG = "ProfileService"; | ||||||
|  | 
 | ||||||
|  |     private final FriendshipRepository repository; | ||||||
|  | 
 | ||||||
|  |     private static FriendshipService instance; | ||||||
|  | 
 | ||||||
|  |     private FriendshipService() { | ||||||
|  |         final Retrofit retrofit = getRetrofitBuilder() | ||||||
|  |                 .baseUrl("https://i.instagram.com") | ||||||
|  |                 .build(); | ||||||
|  |         repository = retrofit.create(FriendshipRepository.class); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static FriendshipService getInstance() { | ||||||
|  |         if (instance == null) { | ||||||
|  |             instance = new FriendshipService(); | ||||||
|  |         } | ||||||
|  |         return instance; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void follow(final String userId, | ||||||
|  |                        final String targetUserId, | ||||||
|  |                        final String crsfToken, | ||||||
|  |                        final ServiceCallback<FriendshipRepositoryChangeResponseRootObject> callback) { | ||||||
|  |         change("create", userId, targetUserId, crsfToken, callback); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void unfollow(final String userId, | ||||||
|  |                          final String targetUserId, | ||||||
|  |                          final String crsfToken, | ||||||
|  |                          final ServiceCallback<FriendshipRepositoryChangeResponseRootObject> callback) { | ||||||
|  |         change("destroy", userId, targetUserId, crsfToken, callback); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void change(final String action, | ||||||
|  |                         final String userId, | ||||||
|  |                         final String targetUserId, | ||||||
|  |                         final String crsfToken, | ||||||
|  |                         final ServiceCallback<FriendshipRepositoryChangeResponseRootObject> callback) { | ||||||
|  |         final Map<String, Object> form = new HashMap<>(5); | ||||||
|  |         form.put("_csrftoken", crsfToken); | ||||||
|  |         form.put("_uid", userId); | ||||||
|  |         form.put("_uuid", UUID.randomUUID().toString()); | ||||||
|  |         form.put("user_id", targetUserId); | ||||||
|  |         final Map<String, String> signedForm = Utils.sign(form); | ||||||
|  |         final Call<FriendshipRepositoryChangeResponseRootObject> request = repository.change(action, targetUserId, signedForm); | ||||||
|  |         request.enqueue(new Callback<FriendshipRepositoryChangeResponseRootObject>() { | ||||||
|  |             @Override | ||||||
|  |             public void onResponse(@NonNull final Call<FriendshipRepositoryChangeResponseRootObject> call, | ||||||
|  |                                    @NonNull final Response<FriendshipRepositoryChangeResponseRootObject> response) { | ||||||
|  |                 if (callback != null) { | ||||||
|  |                     callback.onSuccess(response.body()); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             @Override | ||||||
|  |             public void onFailure(@NonNull final Call<FriendshipRepositoryChangeResponseRootObject> call, | ||||||
|  |                                   @NonNull final Throwable t) { | ||||||
|  |                 if (callback != null) { | ||||||
|  |                     callback.onFailure(t); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,35 +0,0 @@ | |||||||
| package awais.instagrabber.services; |  | ||||||
| 
 |  | ||||||
| import awais.instagrabber.repositories.ProfileRepository; |  | ||||||
| import retrofit2.Retrofit; |  | ||||||
| 
 |  | ||||||
| public class ProfileService extends BaseService { |  | ||||||
|     private static final String TAG = "ProfileService"; |  | ||||||
| 
 |  | ||||||
|     private final ProfileRepository repository; |  | ||||||
| 
 |  | ||||||
|     private static ProfileService instance; |  | ||||||
| 
 |  | ||||||
|     private ProfileService() { |  | ||||||
|         final Retrofit retrofit = getRetrofitBuilder() |  | ||||||
|                 .baseUrl("https://i.instagram.com") |  | ||||||
|                 .build(); |  | ||||||
|         repository = retrofit.create(ProfileRepository.class); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public static ProfileService getInstance() { |  | ||||||
|         if (instance == null) { |  | ||||||
|             instance = new ProfileService(); |  | ||||||
|         } |  | ||||||
|         return instance; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void followProfile(final String username) { |  | ||||||
|         // final String url = "https://www.instagram.com/web/" + (action.equals("followtag") && mainActivity.hashtagModel != null ? "tags/" + (mainActivity.hashtagModel.getFollowing() ? "unfollow/" : "follow/") + mainActivity.hashtagModel.getName() + "/" : (action.equals("restrict") && mainActivity.profileModel != null ? "restrict_action" : "friendships/" + mainActivity.profileModel.getId()) + "/" + (action.equals("follow") ? |  | ||||||
|         //         mainActivity.profileModel.getFollowing() || mainActivity.profileModel.getRequested() |  | ||||||
|         //                 ? "unfollow/" : "follow/" : |  | ||||||
|         //         action.equals("restrict") ? |  | ||||||
|         //                 mainActivity.profileModel.getRestricted() ? "unrestrict/" : "restrict/" : |  | ||||||
|         //                 mainActivity.profileModel.getBlocked() ? "unblock/" : "block/")); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -64,4 +64,5 @@ public final class Constants { | |||||||
|             "\"gyroscope\", \"value\": \"gyroscope_enabled\" } ]"; |             "\"gyroscope\", \"value\": \"gyroscope_enabled\" } ]"; | ||||||
|     public static final String SIGNATURE_VERSION = "4"; |     public static final String SIGNATURE_VERSION = "4"; | ||||||
|     public static final String SIGNATURE_KEY = "9193488027538fd3450b83b7d05286d4ca9599a0f7eeed90d8c85925698a05dc"; |     public static final String SIGNATURE_KEY = "9193488027538fd3450b83b7d05286d4ca9599a0f7eeed90d8c85925698a05dc"; | ||||||
|  |     public static final int LOGIN_RESULT_CODE = 5000; | ||||||
| } | } | ||||||
| @ -217,8 +217,8 @@ public final class ExportImportUtils { | |||||||
|         if (settingsHelper != null) { |         if (settingsHelper != null) { | ||||||
|             try { |             try { | ||||||
|                 final JSONObject json = new JSONObject(); |                 final JSONObject json = new JSONObject(); | ||||||
|                 json.put(Constants.APP_THEME, settingsHelper.getInteger(Constants.APP_THEME)); |                 json.put(Constants.APP_THEME, settingsHelper.getString(Constants.APP_THEME)); | ||||||
|                 json.put(Constants.APP_LANGUAGE, settingsHelper.getInteger(Constants.APP_LANGUAGE)); |                 json.put(Constants.APP_LANGUAGE, settingsHelper.getString(Constants.APP_LANGUAGE)); | ||||||
| 
 | 
 | ||||||
|                 String str = settingsHelper.getString(Constants.FOLDER_PATH); |                 String str = settingsHelper.getString(Constants.FOLDER_PATH); | ||||||
|                 if (!Utils.isEmpty(str)) json.put(Constants.FOLDER_PATH, str); |                 if (!Utils.isEmpty(str)) json.put(Constants.FOLDER_PATH, str); | ||||||
|  | |||||||
| @ -55,7 +55,7 @@ public final class LocaleUtils { | |||||||
|         if (Utils.settingsHelper == null) |         if (Utils.settingsHelper == null) | ||||||
|             Utils.settingsHelper = new SettingsHelper(baseContext); |             Utils.settingsHelper = new SettingsHelper(baseContext); | ||||||
| 
 | 
 | ||||||
|         final int appLanguageIndex = Utils.settingsHelper.getInteger(Constants.APP_LANGUAGE); |         final int appLanguageIndex = Integer.parseInt(Utils.settingsHelper.getString(Constants.APP_LANGUAGE)); | ||||||
| 
 | 
 | ||||||
|         if (appLanguageIndex == 1) return "en"; |         if (appLanguageIndex == 1) return "en"; | ||||||
|         if (appLanguageIndex == 2) return "fr"; |         if (appLanguageIndex == 2) return "fr"; | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| package awais.instagrabber.utils; | package awais.instagrabber.utils; | ||||||
| 
 | 
 | ||||||
|  | import android.annotation.SuppressLint; | ||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||||
| import android.os.Build; | import android.os.Build; | ||||||
| @ -83,10 +84,18 @@ public final class SettingsHelper { | |||||||
|         int themeCode = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; |         int themeCode = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; | ||||||
| 
 | 
 | ||||||
|         if (!fromHelper && sharedPreferences != null) { |         if (!fromHelper && sharedPreferences != null) { | ||||||
|             themeCode = sharedPreferences.getInt(APP_THEME, themeCode); |             themeCode = Integer.parseInt(sharedPreferences.getString(APP_THEME, String.valueOf(themeCode))); | ||||||
|             if (themeCode == 1) themeCode = AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY; |             switch (themeCode) { | ||||||
|             else if (themeCode == 3) themeCode = AppCompatDelegate.MODE_NIGHT_NO; |                 case 1: | ||||||
|             else if (themeCode == 0) themeCode = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; |                     themeCode = AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY; | ||||||
|  |                     break; | ||||||
|  |                 case 3: | ||||||
|  |                     themeCode = AppCompatDelegate.MODE_NIGHT_NO; | ||||||
|  |                     break; | ||||||
|  |                 case 0: | ||||||
|  |                     themeCode = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (themeCode == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM && Build.VERSION.SDK_INT < 29) |         if (themeCode == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM && Build.VERSION.SDK_INT < 29) | ||||||
| @ -107,13 +116,13 @@ public final class SettingsHelper { | |||||||
|         if (sharedPreferences != null) sharedPreferences.edit().putBoolean(key, val).apply(); |         if (sharedPreferences != null) sharedPreferences.edit().putBoolean(key, val).apply(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @StringDef({COOKIE, FOLDER_PATH, DATE_TIME_FORMAT, DATE_TIME_SELECTION, CUSTOM_DATE_TIME_FORMAT, DEVICE_UUID}) |     @StringDef({APP_LANGUAGE, APP_THEME, COOKIE, FOLDER_PATH, DATE_TIME_FORMAT, DATE_TIME_SELECTION, CUSTOM_DATE_TIME_FORMAT, DEVICE_UUID}) | ||||||
|     public @interface StringSettings {} |     public @interface StringSettings {} | ||||||
| 
 | 
 | ||||||
|     @StringDef({DOWNLOAD_USER_FOLDER, BOTTOM_TOOLBAR, FOLDER_SAVE_TO, AUTOPLAY_VIDEOS, SHOW_QUICK_ACCESS_DIALOG, MUTED_VIDEOS, |     @StringDef({DOWNLOAD_USER_FOLDER, BOTTOM_TOOLBAR, FOLDER_SAVE_TO, AUTOPLAY_VIDEOS, SHOW_QUICK_ACCESS_DIALOG, MUTED_VIDEOS, | ||||||
|             AUTOLOAD_POSTS, CUSTOM_DATE_TIME_FORMAT_ENABLED, MARK_AS_SEEN, INSTADP, STORIESIG, AMOLED_THEME, CHECK_ACTIVITY}) |             AUTOLOAD_POSTS, CUSTOM_DATE_TIME_FORMAT_ENABLED, MARK_AS_SEEN, INSTADP, STORIESIG, AMOLED_THEME, CHECK_ACTIVITY}) | ||||||
|     public @interface BooleanSettings {} |     public @interface BooleanSettings {} | ||||||
| 
 | 
 | ||||||
|     @StringDef({APP_THEME, APP_LANGUAGE, PREV_INSTALL_VERSION}) |     @StringDef({PREV_INSTALL_VERSION}) | ||||||
|     public @interface IntegerSettings {} |     public @interface IntegerSettings {} | ||||||
| } | } | ||||||
| @ -59,6 +59,7 @@ import java.net.URI; | |||||||
| import java.net.URISyntaxException; | import java.net.URISyntaxException; | ||||||
| import java.text.SimpleDateFormat; | import java.text.SimpleDateFormat; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
|  | import java.util.HashMap; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Locale; | import java.util.Locale; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| @ -820,7 +821,14 @@ public final class Utils { | |||||||
|         } |         } | ||||||
|         AppCompatDelegate.setDefaultNightMode(themeCode); |         AppCompatDelegate.setDefaultNightMode(themeCode); | ||||||
|         // use amoled theme only if enabled in settings |         // use amoled theme only if enabled in settings | ||||||
|         if (isAmoledEnabled) { |         if (isAmoledEnabled && isNight(context, themeCode)) { | ||||||
|  |             // set amoled theme | ||||||
|  |             Log.d(TAG, "settings amoled theme"); | ||||||
|  |             context.setTheme(R.style.Theme_Amoled); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static boolean isNight(final Context context, final int themeCode) { | ||||||
|         // check if setting is set to 'Dark' |         // check if setting is set to 'Dark' | ||||||
|         boolean isNight = themeCode == AppCompatDelegate.MODE_NIGHT_YES; |         boolean isNight = themeCode == AppCompatDelegate.MODE_NIGHT_YES; | ||||||
|         // if not dark check if themeCode is MODE_NIGHT_FOLLOW_SYSTEM or MODE_NIGHT_AUTO_BATTERY |         // if not dark check if themeCode is MODE_NIGHT_FOLLOW_SYSTEM or MODE_NIGHT_AUTO_BATTERY | ||||||
| @ -829,15 +837,10 @@ public final class Utils { | |||||||
|             final int uiMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; |             final int uiMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; | ||||||
|             isNight = uiMode == Configuration.UI_MODE_NIGHT_YES; |             isNight = uiMode == Configuration.UI_MODE_NIGHT_YES; | ||||||
|         } |         } | ||||||
|             if (isNight) { |         return isNight; | ||||||
|                 // set amoled theme |  | ||||||
|                 Log.d("InstaGrabber", "settings amoled theme"); |  | ||||||
|                 context.setTheme(R.style.Theme_Amoled); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|     public static void setTooltipText(final View view, @StringRes final int tooltipTextRes) { |     public static void setTooltipText(final View view, @StringRes final int tooltipTextRes) { | ||||||
|         if (view != null && tooltipTextRes != 0 && tooltipTextRes != -1) { |         if (view != null && tooltipTextRes != 0 && tooltipTextRes != -1) { | ||||||
|             final Context context = view.getContext(); |             final Context context = view.getContext(); | ||||||
| @ -1208,6 +1211,20 @@ public final class Utils { | |||||||
|         dialog[0] = new AlertDialog.Builder(context).setView(importExportBinding.getRoot()).show(); |         dialog[0] = new AlertDialog.Builder(context).setView(importExportBinding.getRoot()).show(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public static Map<String, String> sign(final Map<String, Object> form) { | ||||||
|  |         final String signed = sign(new JSONObject(form).toString()); | ||||||
|  |         if (signed == null) { | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |         final String[] parts = signed.split("&"); | ||||||
|  |         final Map<String, String> map = new HashMap<>(); | ||||||
|  |         for (final String part : parts) { | ||||||
|  |             final String[] partSplit = part.split("="); | ||||||
|  |             map.put(partSplit[0], partSplit[1]); | ||||||
|  |         } | ||||||
|  |         return map; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public static String sign(final String message) { |     public static String sign(final String message) { | ||||||
|         try { |         try { | ||||||
|             final Mac hasher = Mac.getInstance("HmacSHA256"); |             final Mac hasher = Mac.getInstance("HmacSHA256"); | ||||||
| @ -1440,4 +1457,11 @@ public final class Utils { | |||||||
|     public static int getResultingWidth(final int requiredHeight, final int height, final int width) { |     public static int getResultingWidth(final int requiredHeight, final int height, final int width) { | ||||||
|         return requiredHeight * width / height; |         return requiredHeight * width / height; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     public static String getCsrfTokenFromCookie(final String cookie) { | ||||||
|  |         if (cookie == null) { | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |         return cookie.split("csrftoken=")[1].split(";")[0]; | ||||||
|  |     } | ||||||
| } | } | ||||||
| Before Width: | Height: | Size: 451 B | 
| Before Width: | Height: | Size: 333 B | 
| Before Width: | Height: | Size: 435 B | 
| Before Width: | Height: | Size: 253 B | 
| Before Width: | Height: | Size: 239 B | 
| Before Width: | Height: | Size: 311 B | 
| Before Width: | Height: | Size: 597 B | 
| Before Width: | Height: | Size: 415 B | 
| Before Width: | Height: | Size: 560 B | 
| Before Width: | Height: | Size: 811 B | 
| Before Width: | Height: | Size: 570 B | 
| Before Width: | Height: | Size: 815 B | 
| @ -1,10 +1,9 @@ | |||||||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" | <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|     android:width="24dp" |     android:width="24dp" | ||||||
|     android:height="24dp" |     android:height="24dp" | ||||||
|     android:alpha="0.8" |  | ||||||
|     android:tint="?attr/colorControlNormal" |  | ||||||
|     android:viewportWidth="24" |     android:viewportWidth="24" | ||||||
|     android:viewportHeight="24"> |     android:viewportHeight="24" | ||||||
|  |     android:tint="?attr/colorControlNormal"> | ||||||
|   <path |   <path | ||||||
|       android:fillColor="@android:color/white" |       android:fillColor="@android:color/white" | ||||||
|       android:pathData="M11,7h2v2h-2zM11,11h2v6h-2zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z"/> |       android:pathData="M11,7h2v2h-2zM11,11h2v6h-2zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z"/> | ||||||
							
								
								
									
										10
									
								
								app/src/main/res/drawable/ic_outline_settings_24.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,10 @@ | |||||||
|  | <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |     android:width="24dp" | ||||||
|  |     android:height="24dp" | ||||||
|  |     android:viewportWidth="24" | ||||||
|  |     android:viewportHeight="24" | ||||||
|  |     android:tint="?attr/colorControlNormal"> | ||||||
|  |   <path | ||||||
|  |       android:fillColor="@android:color/white" | ||||||
|  |       android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98 0,-0.34 -0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.09,-0.16 -0.26,-0.25 -0.44,-0.25 -0.06,0 -0.12,0.01 -0.17,0.03l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.06,-0.02 -0.12,-0.03 -0.18,-0.03 -0.17,0 -0.34,0.09 -0.43,0.25l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98 0,0.33 0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.09,0.16 0.26,0.25 0.44,0.25 0.06,0 0.12,-0.01 0.17,-0.03l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.06,0.02 0.12,0.03 0.18,0.03 0.17,0 0.34,-0.09 0.43,-0.25l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM17.45,11.27c0.04,0.31 0.05,0.52 0.05,0.73 0,0.21 -0.02,0.43 -0.05,0.73l-0.14,1.13 0.89,0.7 1.08,0.84 -0.7,1.21 -1.27,-0.51 -1.04,-0.42 -0.9,0.68c-0.43,0.32 -0.84,0.56 -1.25,0.73l-1.06,0.43 -0.16,1.13 -0.2,1.35h-1.4l-0.19,-1.35 -0.16,-1.13 -1.06,-0.43c-0.43,-0.18 -0.83,-0.41 -1.23,-0.71l-0.91,-0.7 -1.06,0.43 -1.27,0.51 -0.7,-1.21 1.08,-0.84 0.89,-0.7 -0.14,-1.13c-0.03,-0.31 -0.05,-0.54 -0.05,-0.74s0.02,-0.43 0.05,-0.73l0.14,-1.13 -0.89,-0.7 -1.08,-0.84 0.7,-1.21 1.27,0.51 1.04,0.42 0.9,-0.68c0.43,-0.32 0.84,-0.56 1.25,-0.73l1.06,-0.43 0.16,-1.13 0.2,-1.35h1.39l0.19,1.35 0.16,1.13 1.06,0.43c0.43,0.18 0.83,0.41 1.23,0.71l0.91,0.7 1.06,-0.43 1.27,-0.51 0.7,1.21 -1.07,0.85 -0.89,0.7 0.14,1.13zM12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM12,14c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2z"/> | ||||||
|  | </vector> | ||||||
| @ -63,7 +63,7 @@ | |||||||
|                     android:paddingEnd="8dp" |                     android:paddingEnd="8dp" | ||||||
|                     android:paddingRight="8dp" |                     android:paddingRight="8dp" | ||||||
|                     android:paddingBottom="4dp" |                     android:paddingBottom="4dp" | ||||||
|                     app:srcCompat="@drawable/ic_info" /> |                     app:srcCompat="@drawable/ic_outline_info_24" /> | ||||||
|             </androidx.appcompat.widget.Toolbar> |             </androidx.appcompat.widget.Toolbar> | ||||||
|         </com.google.android.material.appbar.CollapsingToolbarLayout> |         </com.google.android.material.appbar.CollapsingToolbarLayout> | ||||||
|     </com.google.android.material.appbar.AppBarLayout> |     </com.google.android.material.appbar.AppBarLayout> | ||||||
|  | |||||||
| @ -1,13 +1,10 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||||||
| <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" | <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||||
|     xmlns:tools="http://schemas.android.com/tools" |     xmlns:tools="http://schemas.android.com/tools" | ||||||
|     android:layout_width="match_parent" |     android:layout_width="match_parent" | ||||||
|     android:layout_height="wrap_content" |     android:layout_height="wrap_content" | ||||||
|     android:paddingStart="4dp" |     android:padding="16dp"> | ||||||
|     android:paddingLeft="4dp" |  | ||||||
|     android:paddingTop="12dp" |  | ||||||
|     android:paddingEnd="4dp" |  | ||||||
|     android:paddingRight="4dp"> |  | ||||||
| 
 | 
 | ||||||
|     <LinearLayout |     <LinearLayout | ||||||
|         android:layout_width="match_parent" |         android:layout_width="match_parent" | ||||||
| @ -25,9 +22,8 @@ | |||||||
|                 android:orientation="horizontal"> |                 android:orientation="horizontal"> | ||||||
| 
 | 
 | ||||||
|                 <TextView |                 <TextView | ||||||
|                     android:layout_width="0dp" |                     android:layout_width="wrap_content" | ||||||
|                     android:layout_height="wrap_content" |                     android:layout_height="wrap_content" | ||||||
|                     android:layout_weight="1" |  | ||||||
|                     android:text="@string/time_settings_title_custom" /> |                     android:text="@string/time_settings_title_custom" /> | ||||||
| 
 | 
 | ||||||
|                 <CheckBox |                 <CheckBox | ||||||
| @ -40,7 +36,8 @@ | |||||||
|             <LinearLayout |             <LinearLayout | ||||||
|                 android:layout_width="match_parent" |                 android:layout_width="match_parent" | ||||||
|                 android:layout_height="wrap_content" |                 android:layout_height="wrap_content" | ||||||
|                 android:orientation="horizontal"> |                 android:orientation="horizontal" | ||||||
|  |                 android:visibility="gone"> | ||||||
| 
 | 
 | ||||||
|                 <androidx.appcompat.widget.AppCompatEditText |                 <androidx.appcompat.widget.AppCompatEditText | ||||||
|                     android:id="@+id/etCustomFormat" |                     android:id="@+id/etCustomFormat" | ||||||
| @ -55,7 +52,7 @@ | |||||||
|                     android:layout_width="wrap_content" |                     android:layout_width="wrap_content" | ||||||
|                     android:layout_height="wrap_content" |                     android:layout_height="wrap_content" | ||||||
|                     android:layout_gravity="start" |                     android:layout_gravity="start" | ||||||
|                     android:src="@android:drawable/ic_menu_info_details" /> |                     app:srcCompat="@drawable/ic_outline_info_24" /> | ||||||
|             </LinearLayout> |             </LinearLayout> | ||||||
| 
 | 
 | ||||||
|             <FrameLayout |             <FrameLayout | ||||||
| @ -73,63 +70,72 @@ | |||||||
|             android:layout_height="wrap_content" |             android:layout_height="wrap_content" | ||||||
|             android:layout_marginTop="8dp" |             android:layout_marginTop="8dp" | ||||||
|             android:baselineAligned="false" |             android:baselineAligned="false" | ||||||
|             android:orientation="horizontal"> |  | ||||||
| 
 |  | ||||||
|             <LinearLayout |  | ||||||
|                 android:layout_width="0dp" |  | ||||||
|                 android:layout_height="wrap_content" |  | ||||||
|                 android:layout_weight="0.84" |  | ||||||
|             android:orientation="vertical"> |             android:orientation="vertical"> | ||||||
| 
 | 
 | ||||||
|                 <TextView |             <LinearLayout | ||||||
|                 android:layout_width="match_parent" |                 android:layout_width="match_parent" | ||||||
|                 android:layout_height="wrap_content" |                 android:layout_height="wrap_content" | ||||||
|  |                 android:orientation="horizontal"> | ||||||
|  | 
 | ||||||
|  |                 <TextView | ||||||
|  |                     android:layout_width="0dp" | ||||||
|  |                     android:layout_height="wrap_content" | ||||||
|  |                     android:layout_weight="1" | ||||||
|                     android:text="@string/time_settings_title_time_format" /> |                     android:text="@string/time_settings_title_time_format" /> | ||||||
| 
 | 
 | ||||||
|                 <androidx.appcompat.widget.AppCompatSpinner |                 <androidx.appcompat.widget.AppCompatSpinner | ||||||
|                     android:id="@+id/spTimeFormat" |                     android:id="@+id/spTimeFormat" | ||||||
|                     android:layout_width="match_parent" |                     android:layout_width="0dp" | ||||||
|                     android:layout_height="wrap_content" |                     android:layout_height="36dp" | ||||||
|  |                     android:layout_weight="1" | ||||||
|                     android:entries="@array/time_presets" /> |                     android:entries="@array/time_presets" /> | ||||||
|             </LinearLayout> |             </LinearLayout> | ||||||
| 
 | 
 | ||||||
|             <LinearLayout |             <LinearLayout | ||||||
|                 android:layout_width="0dp" |  | ||||||
|                 android:layout_height="wrap_content" |  | ||||||
|                 android:layout_weight="0.7" |  | ||||||
|                 android:orientation="vertical"> |  | ||||||
| 
 |  | ||||||
|                 <TextView |  | ||||||
|                 android:layout_width="match_parent" |                 android:layout_width="match_parent" | ||||||
|                 android:layout_height="wrap_content" |                 android:layout_height="wrap_content" | ||||||
|  |                 android:orientation="horizontal"> | ||||||
|  | 
 | ||||||
|  |                 <TextView | ||||||
|  |                     android:layout_width="0dp" | ||||||
|  |                     android:layout_height="wrap_content" | ||||||
|  |                     android:layout_weight="1" | ||||||
|                     android:text="@string/time_settings_title_separator" /> |                     android:text="@string/time_settings_title_separator" /> | ||||||
| 
 | 
 | ||||||
|                 <androidx.appcompat.widget.AppCompatSpinner |                 <androidx.appcompat.widget.AppCompatSpinner | ||||||
|                     android:id="@+id/spSeparator" |                     android:id="@+id/spSeparator" | ||||||
|                     android:layout_width="match_parent" |                     android:layout_width="0dp" | ||||||
|                     android:layout_height="wrap_content" |                     android:layout_height="36dp" | ||||||
|  |                     android:layout_weight="1" | ||||||
|                     android:entries="@array/separator_presets" /> |                     android:entries="@array/separator_presets" /> | ||||||
|             </LinearLayout> |             </LinearLayout> | ||||||
| 
 | 
 | ||||||
|             <LinearLayout |             <LinearLayout | ||||||
|  |                 android:layout_width="match_parent" | ||||||
|  |                 android:layout_height="wrap_content" | ||||||
|  |                 android:orientation="horizontal"> | ||||||
|  | 
 | ||||||
|  |                 <TextView | ||||||
|                     android:layout_width="0dp" |                     android:layout_width="0dp" | ||||||
|                     android:layout_height="wrap_content" |                     android:layout_height="wrap_content" | ||||||
|                     android:layout_weight="1" |                     android:layout_weight="1" | ||||||
|                 android:orientation="vertical"> |  | ||||||
| 
 |  | ||||||
|                 <TextView |  | ||||||
|                     android:layout_width="match_parent" |  | ||||||
|                     android:layout_height="wrap_content" |  | ||||||
|                     android:text="@string/time_settings_title_date_format" /> |                     android:text="@string/time_settings_title_date_format" /> | ||||||
| 
 | 
 | ||||||
|                 <androidx.appcompat.widget.AppCompatSpinner |                 <androidx.appcompat.widget.AppCompatSpinner | ||||||
|                     android:id="@+id/spDateFormat" |                     android:id="@+id/spDateFormat" | ||||||
|                     android:layout_width="match_parent" |                     android:layout_width="0dp" | ||||||
|                     android:layout_height="wrap_content" |                     android:layout_height="36dp" | ||||||
|  |                     android:layout_weight="1" | ||||||
|                     android:entries="@array/date_presets" /> |                     android:entries="@array/date_presets" /> | ||||||
|             </LinearLayout> |             </LinearLayout> | ||||||
|         </LinearLayout> |         </LinearLayout> | ||||||
| 
 | 
 | ||||||
|  |         <CheckBox | ||||||
|  |             android:id="@+id/cbSwapTimeDate" | ||||||
|  |             android:layout_width="match_parent" | ||||||
|  |             android:layout_height="wrap_content" | ||||||
|  |             android:text="@string/time_settings_swap_time" /> | ||||||
|  | 
 | ||||||
|         <LinearLayout |         <LinearLayout | ||||||
|             android:layout_width="match_parent" |             android:layout_width="match_parent" | ||||||
|             android:layout_height="wrap_content" |             android:layout_height="wrap_content" | ||||||
| @ -137,25 +143,11 @@ | |||||||
|             android:baselineAligned="false" |             android:baselineAligned="false" | ||||||
|             android:orientation="vertical"> |             android:orientation="vertical"> | ||||||
| 
 | 
 | ||||||
|             <LinearLayout |  | ||||||
|                 android:layout_width="match_parent" |  | ||||||
|                 android:layout_height="wrap_content" |  | ||||||
|                 android:orientation="horizontal"> |  | ||||||
| 
 |  | ||||||
|             <TextView |             <TextView | ||||||
|                     android:layout_width="0dp" |  | ||||||
|                     android:layout_height="wrap_content" |  | ||||||
|                     android:layout_gravity="bottom" |  | ||||||
|                     android:layout_weight="1" |  | ||||||
|                     android:text="@string/time_settings_title_preview" /> |  | ||||||
| 
 |  | ||||||
|                 <CheckBox |  | ||||||
|                     android:id="@+id/cbSwapTimeDate" |  | ||||||
|                 android:layout_width="wrap_content" |                 android:layout_width="wrap_content" | ||||||
|                 android:layout_height="wrap_content" |                 android:layout_height="wrap_content" | ||||||
|                     android:gravity="center" |                 android:layout_gravity="bottom" | ||||||
|                     android:text="@string/time_settings_swap_time" /> |                 android:text="@string/time_settings_title_preview" /> | ||||||
|             </LinearLayout> |  | ||||||
| 
 | 
 | ||||||
|             <TextView |             <TextView | ||||||
|                 android:id="@+id/timePreview" |                 android:id="@+id/timePreview" | ||||||
|  | |||||||
| @ -16,6 +16,6 @@ | |||||||
|             android:id="@+id/inbox_list" |             android:id="@+id/inbox_list" | ||||||
|             android:layout_width="match_parent" |             android:layout_width="match_parent" | ||||||
|             android:layout_height="match_parent" |             android:layout_height="match_parent" | ||||||
|             tools:listitem="@layout/layout_include_simple_item" /> |             tools:listitem="@layout/layout_dm_inbox_item" /> | ||||||
|     </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> |     </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> | ||||||
| </awais.instagrabber.customviews.helpers.NestedCoordinatorLayout> | </awais.instagrabber.customviews.helpers.NestedCoordinatorLayout> | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ | |||||||
| 
 | 
 | ||||||
|     <include |     <include | ||||||
|         android:id="@+id/container" |         android:id="@+id/container" | ||||||
|         layout="@layout/layout_include_simple_item" /> |         layout="@layout/layout_dm_inbox_item" /> | ||||||
| 
 | 
 | ||||||
|     <androidx.recyclerview.widget.RecyclerView |     <androidx.recyclerview.widget.RecyclerView | ||||||
|         android:id="@+id/rvChildComments" |         android:id="@+id/rvChildComments" | ||||||
|  | |||||||
| @ -13,7 +13,7 @@ | |||||||
|             android:layout_width="match_parent" |             android:layout_width="match_parent" | ||||||
|             android:layout_height="1dip" |             android:layout_height="1dip" | ||||||
|             android:layout_alignParentTop="true" |             android:layout_alignParentTop="true" | ||||||
|             android:background="?android:attr/dividerVertical" /> |             android:background="@android:color/darker_gray" /> | ||||||
| 
 | 
 | ||||||
|         <View |         <View | ||||||
|             android:id="@+id/horizontalDivider" |             android:id="@+id/horizontalDivider" | ||||||
| @ -23,9 +23,9 @@ | |||||||
|             android:layout_centerHorizontal="true" |             android:layout_centerHorizontal="true" | ||||||
|             android:layout_marginTop="4dp" |             android:layout_marginTop="4dp" | ||||||
|             android:layout_marginBottom="4dp" |             android:layout_marginBottom="4dp" | ||||||
|             android:background="?android:attr/dividerVertical" /> |             android:background="@android:color/darker_gray" /> | ||||||
| 
 | 
 | ||||||
|         <Button |         <androidx.appcompat.widget.AppCompatButton | ||||||
|             android:id="@+id/btnCancel" |             android:id="@+id/btnCancel" | ||||||
|             android:layout_width="wrap_content" |             android:layout_width="wrap_content" | ||||||
|             android:layout_height="wrap_content" |             android:layout_height="wrap_content" | ||||||
| @ -38,7 +38,7 @@ | |||||||
|             android:background="?android:selectableItemBackground" |             android:background="?android:selectableItemBackground" | ||||||
|             android:text="@string/cancel" /> |             android:text="@string/cancel" /> | ||||||
| 
 | 
 | ||||||
|         <Button |         <androidx.appcompat.widget.AppCompatButton | ||||||
|             android:id="@+id/btnConfirm" |             android:id="@+id/btnConfirm" | ||||||
|             android:layout_width="wrap_content" |             android:layout_width="wrap_content" | ||||||
|             android:layout_height="wrap_content" |             android:layout_height="wrap_content" | ||||||
| @ -103,7 +103,7 @@ | |||||||
|             android:layout_width="match_parent" |             android:layout_width="match_parent" | ||||||
|             android:layout_height="1dp" |             android:layout_height="1dp" | ||||||
|             android:layout_below="@id/btnNavUp" |             android:layout_below="@id/btnNavUp" | ||||||
|             android:background="#33B5E5" /> |             android:background="@android:color/darker_gray" /> | ||||||
|     </RelativeLayout> |     </RelativeLayout> | ||||||
| 
 | 
 | ||||||
|     <androidx.recyclerview.widget.RecyclerView |     <androidx.recyclerview.widget.RecyclerView | ||||||
|  | |||||||
							
								
								
									
										121
									
								
								app/src/main/res/layout/layout_dm_inbox_item.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,121 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||||
|  |     xmlns:tools="http://schemas.android.com/tools" | ||||||
|  |     android:layout_width="match_parent" | ||||||
|  |     android:layout_height="wrap_content" | ||||||
|  |     android:background="?android:selectableItemBackground" | ||||||
|  |     android:orientation="horizontal"> | ||||||
|  | 
 | ||||||
|  |     <FrameLayout | ||||||
|  |         android:layout_width="@dimen/simple_item_picture_size" | ||||||
|  |         android:layout_height="@dimen/simple_item_picture_size" | ||||||
|  |         android:gravity="center" | ||||||
|  |         android:padding="4dp"> | ||||||
|  | 
 | ||||||
|  |         <com.facebook.drawee.view.SimpleDraweeView | ||||||
|  |             android:id="@+id/ivProfilePic" | ||||||
|  |             android:layout_width="match_parent" | ||||||
|  |             android:layout_height="match_parent" | ||||||
|  |             app:roundAsCircle="true" /> | ||||||
|  | 
 | ||||||
|  |         <LinearLayout | ||||||
|  |             android:id="@+id/multi_pic_container" | ||||||
|  |             android:layout_width="match_parent" | ||||||
|  |             android:layout_height="match_parent" | ||||||
|  |             android:orientation="horizontal"> | ||||||
|  | 
 | ||||||
|  |             <com.facebook.drawee.view.SimpleDraweeView | ||||||
|  |                 android:layout_width="@dimen/simple_item_picture_size_half" | ||||||
|  |                 android:layout_height="match_parent" | ||||||
|  |                 app:roundAsCircle="true" /> | ||||||
|  | 
 | ||||||
|  |             <LinearLayout | ||||||
|  |                 android:layout_width="@dimen/simple_item_picture_size_half" | ||||||
|  |                 android:layout_height="match_parent" | ||||||
|  |                 android:orientation="vertical"> | ||||||
|  | 
 | ||||||
|  |                 <com.facebook.drawee.view.SimpleDraweeView | ||||||
|  |                     android:layout_width="@dimen/simple_item_picture_size_half" | ||||||
|  |                     android:layout_height="@dimen/simple_item_picture_size_half" | ||||||
|  |                     app:roundAsCircle="true" /> | ||||||
|  | 
 | ||||||
|  |                 <com.facebook.drawee.view.SimpleDraweeView | ||||||
|  |                     android:layout_width="@dimen/simple_item_picture_size_half" | ||||||
|  |                     android:layout_height="@dimen/simple_item_picture_size_half" | ||||||
|  |                     app:roundAsCircle="true" /> | ||||||
|  |             </LinearLayout> | ||||||
|  |         </LinearLayout> | ||||||
|  |     </FrameLayout> | ||||||
|  | 
 | ||||||
|  |     <androidx.constraintlayout.widget.ConstraintLayout | ||||||
|  |         android:layout_width="match_parent" | ||||||
|  |         android:layout_height="wrap_content" | ||||||
|  |         android:layout_gravity="center" | ||||||
|  |         android:padding="8dp" | ||||||
|  |         android:orientation="vertical"> | ||||||
|  | 
 | ||||||
|  |         <androidx.appcompat.widget.AppCompatTextView | ||||||
|  |             android:id="@+id/tvUsername" | ||||||
|  |             android:layout_width="wrap_content" | ||||||
|  |             android:layout_height="0dp" | ||||||
|  |             android:ellipsize="marquee" | ||||||
|  |             android:gravity="center_vertical" | ||||||
|  |             android:singleLine="true" | ||||||
|  |             android:textAppearance="@style/TextAppearance.AppCompat.Medium" | ||||||
|  |             android:textColor="?android:textColorPrimary" | ||||||
|  |             android:textStyle="bold" | ||||||
|  |             app:layout_constraintEnd_toStartOf="@id/tvDate" | ||||||
|  |             app:layout_constraintStart_toStartOf="parent" | ||||||
|  |             app:layout_constraintTop_toTopOf="parent" | ||||||
|  |             tools:text="username" /> | ||||||
|  | 
 | ||||||
|  |         <androidx.appcompat.widget.AppCompatTextView | ||||||
|  |             android:id="@+id/tvDate" | ||||||
|  |             android:layout_width="0dp" | ||||||
|  |             android:layout_height="0dp" | ||||||
|  |             android:ellipsize="marquee" | ||||||
|  |             android:gravity="center_vertical|end" | ||||||
|  |             android:singleLine="true" | ||||||
|  |             android:textAppearance="@style/TextAppearance.AppCompat.Caption" | ||||||
|  |             android:textStyle="italic" | ||||||
|  |             app:layout_constraintBottom_toTopOf="@id/comment_container" | ||||||
|  |             app:layout_constraintEnd_toEndOf="parent" | ||||||
|  |             app:layout_constraintStart_toEndOf="@id/tvUsername" | ||||||
|  |             app:layout_constraintTop_toTopOf="parent" | ||||||
|  |             tools:text="long date................................" /> | ||||||
|  | 
 | ||||||
|  |         <LinearLayout | ||||||
|  |             android:id="@+id/comment_container" | ||||||
|  |             android:layout_width="0dp" | ||||||
|  |             android:layout_height="wrap_content" | ||||||
|  |             android:orientation="horizontal" | ||||||
|  |             app:layout_constraintBottom_toBottomOf="parent" | ||||||
|  |             app:layout_constraintEnd_toEndOf="parent" | ||||||
|  |             app:layout_constraintStart_toStartOf="parent" | ||||||
|  |             app:layout_constraintTop_toBottomOf="@id/tvUsername"> | ||||||
|  | 
 | ||||||
|  |             <androidx.appcompat.widget.AppCompatImageView | ||||||
|  |                 android:id="@+id/notTextType" | ||||||
|  |                 android:layout_width="4dp" | ||||||
|  |                 android:layout_height="4dp" | ||||||
|  |                 android:layout_gravity="center_vertical" | ||||||
|  |                 android:layout_marginEnd="4dp" | ||||||
|  |                 android:layout_marginRight="4dp" | ||||||
|  |                 android:visibility="gone" | ||||||
|  |                 app:srcCompat="@android:drawable/ic_notification_overlay" | ||||||
|  |                 app:tint="@color/feed_text_primary_color" /> | ||||||
|  | 
 | ||||||
|  |             <awais.instagrabber.customviews.RamboTextView | ||||||
|  |                 android:id="@+id/tvComment" | ||||||
|  |                 android:layout_width="match_parent" | ||||||
|  |                 android:layout_height="match_parent" | ||||||
|  |                 android:layout_gravity="center_vertical" | ||||||
|  |                 android:autoLink="web|email" | ||||||
|  |                 android:ellipsize="end" | ||||||
|  |                 android:linksClickable="true" | ||||||
|  |                 android:textAppearance="@style/TextAppearance.AppCompat.Caption" | ||||||
|  |                 tools:text="comment" /> | ||||||
|  |         </LinearLayout> | ||||||
|  |     </androidx.constraintlayout.widget.ConstraintLayout> | ||||||
|  | </LinearLayout> | ||||||
| @ -1,138 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> |  | ||||||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |  | ||||||
|     xmlns:app="http://schemas.android.com/apk/res-auto" |  | ||||||
|     android:layout_width="match_parent" |  | ||||||
|     android:layout_height="wrap_content" |  | ||||||
|     android:background="?android:selectableItemBackground" |  | ||||||
|     android:orientation="horizontal" |  | ||||||
|     android:paddingStart="0dp" |  | ||||||
|     android:paddingLeft="0dp" |  | ||||||
|     android:paddingEnd="4dp" |  | ||||||
|     android:paddingRight="4dp"> |  | ||||||
| 
 |  | ||||||
|     <FrameLayout |  | ||||||
|         android:layout_width="@dimen/simple_item_picture_size" |  | ||||||
|         android:layout_height="@dimen/simple_item_picture_size" |  | ||||||
|         android:gravity="center"> |  | ||||||
| 
 |  | ||||||
|         <androidx.appcompat.widget.AppCompatImageView |  | ||||||
|             android:id="@+id/ivProfilePic" |  | ||||||
|             android:layout_width="match_parent" |  | ||||||
|             android:layout_height="match_parent" /> |  | ||||||
| 
 |  | ||||||
|         <LinearLayout |  | ||||||
|             android:id="@+id/container" |  | ||||||
|             android:layout_width="match_parent" |  | ||||||
|             android:layout_height="match_parent" |  | ||||||
|             android:orientation="horizontal"> |  | ||||||
| 
 |  | ||||||
|             <androidx.appcompat.widget.AppCompatImageView |  | ||||||
|                 android:layout_width="@dimen/simple_item_picture_size_half" |  | ||||||
|                 android:layout_height="match_parent" /> |  | ||||||
| 
 |  | ||||||
|             <LinearLayout |  | ||||||
|                 android:layout_width="@dimen/simple_item_picture_size_half" |  | ||||||
|                 android:layout_height="match_parent" |  | ||||||
|                 android:orientation="vertical"> |  | ||||||
| 
 |  | ||||||
|                 <androidx.appcompat.widget.AppCompatImageView |  | ||||||
|                     android:layout_width="@dimen/simple_item_picture_size_half" |  | ||||||
|                     android:layout_height="@dimen/simple_item_picture_size_half" /> |  | ||||||
| 
 |  | ||||||
|                 <androidx.appcompat.widget.AppCompatImageView |  | ||||||
|                     android:layout_width="@dimen/simple_item_picture_size_half" |  | ||||||
|                     android:layout_height="@dimen/simple_item_picture_size_half" /> |  | ||||||
|             </LinearLayout> |  | ||||||
|         </LinearLayout> |  | ||||||
|     </FrameLayout> |  | ||||||
| 
 |  | ||||||
|     <LinearLayout |  | ||||||
|         android:layout_width="match_parent" |  | ||||||
|         android:layout_height="wrap_content" |  | ||||||
|         android:orientation="vertical"> |  | ||||||
| 
 |  | ||||||
|             <androidx.appcompat.widget.AppCompatTextView |  | ||||||
|                 android:id="@+id/tvUsername" |  | ||||||
|                 android:layout_width="match_parent" |  | ||||||
|                 android:layout_height="wrap_content" |  | ||||||
|                 android:layout_gravity="start" |  | ||||||
|                 android:layout_weight="1.0" |  | ||||||
|                 android:ellipsize="marquee" |  | ||||||
|                 android:paddingStart="8dp" |  | ||||||
|                 android:paddingLeft="8dp" |  | ||||||
|                 android:paddingTop="4dp" |  | ||||||
|                 android:paddingEnd="4dp" |  | ||||||
|                 android:paddingRight="4dp" |  | ||||||
|                 android:singleLine="true" |  | ||||||
|                 android:textAppearance="@style/TextAppearance.AppCompat.Medium" |  | ||||||
|                 android:textColor="?android:textColorPrimary" |  | ||||||
|                 android:textStyle="bold" /> |  | ||||||
| 
 |  | ||||||
|             <LinearLayout |  | ||||||
|             android:layout_width="match_parent" |  | ||||||
|             android:layout_height="wrap_content" |  | ||||||
|             android:orientation="horizontal" |  | ||||||
|             android:paddingLeft="8dp" |  | ||||||
|             android:paddingTop="4dp" |  | ||||||
|             android:paddingRight="8dp" |  | ||||||
|             android:paddingBottom="16dp"> |  | ||||||
| 
 |  | ||||||
|             <androidx.appcompat.widget.AppCompatImageView |  | ||||||
|                 android:id="@+id/notTextType" |  | ||||||
|                 android:layout_width="4dp" |  | ||||||
|                 android:layout_height="4dp" |  | ||||||
|                 android:layout_gravity="center_vertical" |  | ||||||
|                 android:layout_marginEnd="4dp" |  | ||||||
|                 android:layout_marginRight="4dp" |  | ||||||
|                 android:visibility="gone" |  | ||||||
|                 app:srcCompat="@android:drawable/ic_notification_overlay" |  | ||||||
|                 app:tint="@color/feed_text_primary_color" /> |  | ||||||
| 
 |  | ||||||
|             <awais.instagrabber.customviews.RamboTextView |  | ||||||
|                 android:id="@+id/tvComment" |  | ||||||
|                 android:layout_width="match_parent" |  | ||||||
|                 android:layout_height="wrap_content" |  | ||||||
|                 android:layout_gravity="start" |  | ||||||
|                 android:autoLink="web|email" |  | ||||||
|                 android:ellipsize="end" |  | ||||||
|                 android:linksClickable="true" |  | ||||||
|                 android:textAppearance="@style/TextAppearance.AppCompat" /> |  | ||||||
|         </LinearLayout> |  | ||||||
| 
 |  | ||||||
|         <LinearLayout |  | ||||||
|             android:layout_width="match_parent" |  | ||||||
|             android:layout_height="wrap_content" |  | ||||||
|             android:weightSum="3"> |  | ||||||
|             <androidx.appcompat.widget.AppCompatTextView |  | ||||||
|                 android:id="@+id/tvLikes" |  | ||||||
|                 android:layout_width="0dp" |  | ||||||
|                 android:layout_height="wrap_content" |  | ||||||
|                 android:layout_weight="1" |  | ||||||
|                 android:ellipsize="marquee" |  | ||||||
|                 android:paddingStart="4dp" |  | ||||||
|                 android:paddingLeft="4dp" |  | ||||||
|                 android:paddingTop="4dp" |  | ||||||
|                 android:paddingEnd="8dp" |  | ||||||
|                 android:paddingRight="8dp" |  | ||||||
|                 android:singleLine="true" |  | ||||||
|                 android:textAppearance="@style/TextAppearance.AppCompat.Small" |  | ||||||
|                 android:textSize="14sp" /> |  | ||||||
|             <androidx.appcompat.widget.AppCompatTextView |  | ||||||
|                 android:id="@+id/tvDate" |  | ||||||
|                 android:layout_width="0dp" |  | ||||||
|                 android:layout_height="wrap_content" |  | ||||||
|                 android:layout_weight="2" |  | ||||||
|                 android:layout_gravity="start" |  | ||||||
|                 android:ellipsize="marquee" |  | ||||||
|                 android:paddingStart="4dp" |  | ||||||
|                 android:paddingLeft="4dp" |  | ||||||
|                 android:paddingTop="4dp" |  | ||||||
|                 android:paddingEnd="8dp" |  | ||||||
|                 android:paddingRight="8dp" |  | ||||||
|                 android:singleLine="true" |  | ||||||
|                 android:textStyle="italic" |  | ||||||
|                 android:gravity="right"/> |  | ||||||
|         </LinearLayout> |  | ||||||
| 
 |  | ||||||
|     </LinearLayout> |  | ||||||
| </LinearLayout> |  | ||||||
							
								
								
									
										93
									
								
								app/src/main/res/layout/pref_custom_folder.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,93 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |     xmlns:tools="http://schemas.android.com/tools" | ||||||
|  |     android:layout_width="match_parent" | ||||||
|  |     android:layout_height="wrap_content" | ||||||
|  |     android:animateLayoutChanges="true" | ||||||
|  |     android:background="?android:attr/selectableItemBackground" | ||||||
|  |     android:gravity="center_vertical" | ||||||
|  |     android:minHeight="?android:attr/listPreferredItemHeight" | ||||||
|  |     android:orientation="vertical" | ||||||
|  |     android:paddingEnd="?android:attr/scrollbarSize" | ||||||
|  |     android:paddingRight="?android:attr/scrollbarSize"> | ||||||
|  | 
 | ||||||
|  |     <LinearLayout | ||||||
|  |         android:layout_width="match_parent" | ||||||
|  |         android:layout_height="wrap_content" | ||||||
|  |         android:baselineAligned="false" | ||||||
|  |         android:gravity="center_vertical"> | ||||||
|  | 
 | ||||||
|  |         <RelativeLayout | ||||||
|  |             android:layout_width="0dp" | ||||||
|  |             android:layout_height="wrap_content" | ||||||
|  |             android:layout_marginStart="15dip" | ||||||
|  |             android:layout_marginLeft="15dip" | ||||||
|  |             android:layout_marginTop="6dip" | ||||||
|  |             android:layout_marginEnd="6dip" | ||||||
|  |             android:layout_marginRight="6dip" | ||||||
|  |             android:layout_marginBottom="6dip" | ||||||
|  |             android:layout_weight="1"> | ||||||
|  | 
 | ||||||
|  |             <TextView | ||||||
|  |                 android:id="@android:id/title" | ||||||
|  |                 android:layout_width="wrap_content" | ||||||
|  |                 android:layout_height="wrap_content" | ||||||
|  |                 android:ellipsize="marquee" | ||||||
|  |                 android:fadingEdge="horizontal" | ||||||
|  |                 android:singleLine="true" | ||||||
|  |                 android:textAppearance="?android:attr/textAppearanceListItem" | ||||||
|  |                 android:textColor="?android:attr/textColorPrimary" | ||||||
|  |                 tools:text="Test" /> | ||||||
|  | 
 | ||||||
|  |             <TextView | ||||||
|  |                 android:id="@android:id/summary" | ||||||
|  |                 android:layout_width="wrap_content" | ||||||
|  |                 android:layout_height="wrap_content" | ||||||
|  |                 android:layout_below="@android:id/title" | ||||||
|  |                 android:layout_alignStart="@android:id/title" | ||||||
|  |                 android:layout_alignLeft="@android:id/title" | ||||||
|  |                 android:maxLines="4" | ||||||
|  |                 android:textAppearance="?android:attr/textAppearanceListItemSmall" | ||||||
|  |                 android:textColor="?android:attr/textColorSecondary" | ||||||
|  |                 tools:text="summary" /> | ||||||
|  | 
 | ||||||
|  |         </RelativeLayout> | ||||||
|  | 
 | ||||||
|  |         <com.google.android.material.switchmaterial.SwitchMaterial | ||||||
|  |             android:id="@+id/cbSaveTo" | ||||||
|  |             android:layout_width="wrap_content" | ||||||
|  |             android:layout_height="match_parent" | ||||||
|  |             android:layout_gravity="center_vertical" | ||||||
|  |             android:contentDescription="@string/save_to_folder" | ||||||
|  |             android:paddingEnd="10dp" | ||||||
|  |             android:paddingRight="10dp" /> | ||||||
|  | 
 | ||||||
|  |     </LinearLayout> | ||||||
|  | 
 | ||||||
|  |     <LinearLayout | ||||||
|  |         android:id="@+id/button_container" | ||||||
|  |         android:layout_width="match_parent" | ||||||
|  |         android:layout_height="wrap_content" | ||||||
|  |         android:layout_marginStart="15dip" | ||||||
|  |         android:layout_marginLeft="15dip" | ||||||
|  |         android:gravity="center_vertical" | ||||||
|  |         android:orientation="horizontal" | ||||||
|  |         android:visibility="gone"> | ||||||
|  | 
 | ||||||
|  |         <androidx.appcompat.widget.AppCompatButton | ||||||
|  |             android:id="@+id/btnSaveTo" | ||||||
|  |             android:layout_width="wrap_content" | ||||||
|  |             android:layout_height="wrap_content" | ||||||
|  |             android:text="@string/select_folder" /> | ||||||
|  | 
 | ||||||
|  |         <androidx.appcompat.widget.AppCompatTextView | ||||||
|  |             android:id="@+id/custom_path" | ||||||
|  |             android:layout_width="wrap_content" | ||||||
|  |             android:layout_height="wrap_content" | ||||||
|  |             android:ellipsize="marquee" | ||||||
|  |             android:singleLine="true" | ||||||
|  |             android:textAppearance="?android:attr/textAppearanceListItemSmall" | ||||||
|  |             android:textColor="?android:attr/textColorSecondary" | ||||||
|  |             tools:text="test path" /> | ||||||
|  |     </LinearLayout> | ||||||
|  | </LinearLayout> | ||||||
							
								
								
									
										14
									
								
								app/src/main/res/layout/pref_more_header.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,14 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||||
|  |     android:layout_width="match_parent" | ||||||
|  |     android:layout_height="wrap_content" | ||||||
|  |     android:orientation="vertical"> | ||||||
|  | 
 | ||||||
|  |     <androidx.appcompat.widget.AppCompatImageView | ||||||
|  |         android:layout_width="match_parent" | ||||||
|  |         android:layout_height="200dp" | ||||||
|  |         android:scaleType="fitCenter" | ||||||
|  |         app:srcCompat="@mipmap/ic_launcher" /> | ||||||
|  | 
 | ||||||
|  | </LinearLayout> | ||||||
| @ -24,7 +24,7 @@ | |||||||
|     <!--    android:title="@string/title_favorites"/>--> |     <!--    android:title="@string/title_favorites"/>--> | ||||||
| 
 | 
 | ||||||
|     <item |     <item | ||||||
|         android:id="@+id/moreFragment" |         android:id="@+id/more_nav_graph" | ||||||
|         android:icon="@drawable/ic_more_horiz_24" |         android:icon="@drawable/ic_more_horiz_24" | ||||||
|         android:title="@string/more" /> |         android:title="@string/more" /> | ||||||
| </menu> | </menu> | ||||||
| @ -28,6 +28,9 @@ | |||||||
|         <action |         <action | ||||||
|             android:id="@+id/action_dMThreadFragment_to_dMSettingsFragment" |             android:id="@+id/action_dMThreadFragment_to_dMSettingsFragment" | ||||||
|             app:destination="@id/directMessagesSettingsFragment" /> |             app:destination="@id/directMessagesSettingsFragment" /> | ||||||
|  |         <action | ||||||
|  |             android:id="@+id/action_directMessagesThreadFragment_to_profileFragment" | ||||||
|  |             app:destination="@id/profileFragment" /> | ||||||
|     </fragment> |     </fragment> | ||||||
|     <fragment |     <fragment | ||||||
|         android:id="@+id/directMessagesSettingsFragment" |         android:id="@+id/directMessagesSettingsFragment" | ||||||
| @ -41,4 +44,14 @@ | |||||||
|             android:name="title" |             android:name="title" | ||||||
|             app:argType="string" /> |             app:argType="string" /> | ||||||
|     </fragment> |     </fragment> | ||||||
|  |     <fragment | ||||||
|  |         android:id="@+id/profileFragment" | ||||||
|  |         android:name="awais.instagrabber.fragments.main.ProfileFragment" | ||||||
|  |         android:label="ProfileFragment" | ||||||
|  |         tools:layout="@layout/fragment_profile"> | ||||||
|  |         <argument | ||||||
|  |             android:name="username" | ||||||
|  |             app:argType="string" | ||||||
|  |             app:nullable="false" /> | ||||||
|  |     </fragment> | ||||||
| </navigation> | </navigation> | ||||||
							
								
								
									
										19
									
								
								app/src/main/res/navigation/more_nav_graph.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,19 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <navigation xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||||
|  |     android:id="@+id/more_nav_graph" | ||||||
|  |     app:startDestination="@id/morePreferencesFragment"> | ||||||
|  | 
 | ||||||
|  |     <fragment | ||||||
|  |         android:id="@+id/morePreferencesFragment" | ||||||
|  |         android:name="awais.instagrabber.fragments.settings.MorePreferencesFragment" | ||||||
|  |         android:label="More"> | ||||||
|  |         <action | ||||||
|  |             android:id="@+id/action_morePreferencesFragment_to_settingsPreferencesFragment" | ||||||
|  |             app:destination="@id/settingsPreferencesFragment" /> | ||||||
|  |     </fragment> | ||||||
|  |     <fragment | ||||||
|  |         android:id="@+id/settingsPreferencesFragment" | ||||||
|  |         android:name="awais.instagrabber.fragments.settings.SettingsPreferencesFragment" | ||||||
|  |         android:label="@string/action_settings" /> | ||||||
|  | </navigation> | ||||||
| @ -13,12 +13,31 @@ | |||||||
|         <item>Turkish [Thanks to @faydin90 (Telegram)]</item> |         <item>Turkish [Thanks to @faydin90 (Telegram)]</item> | ||||||
|         <item>Brazilian Portuguese [Thanks to @wagnim (GitHub)]</item> |         <item>Brazilian Portuguese [Thanks to @wagnim (GitHub)]</item> | ||||||
|     </string-array> |     </string-array> | ||||||
|  |     <string-array name="languages_values"> | ||||||
|  |         <item>0</item> | ||||||
|  |         <item>1</item> | ||||||
|  |         <item>2</item> | ||||||
|  |         <item>3</item> | ||||||
|  |         <item>4</item> | ||||||
|  |         <item>5</item> | ||||||
|  |         <item>6</item> | ||||||
|  |         <item>7</item> | ||||||
|  |         <item>8</item> | ||||||
|  |         <item>9</item> | ||||||
|  |         <item>10</item> | ||||||
|  |     </string-array> | ||||||
|     <string-array name="theme_presets"> |     <string-array name="theme_presets"> | ||||||
|         <item>Auto / Follow System</item> |         <item>Auto / Follow System</item> | ||||||
|         <item>Auto / Follow Battery</item> |         <item>Auto / Follow Battery</item> | ||||||
|         <item>Dark</item> |         <item>Dark</item> | ||||||
|         <item>Light</item> |         <item>Light</item> | ||||||
|     </string-array> |     </string-array> | ||||||
|  |     <string-array name="theme_presets_values"> | ||||||
|  |         <item>0</item> | ||||||
|  |         <item>1</item> | ||||||
|  |         <item>2</item> | ||||||
|  |         <item>3</item> | ||||||
|  |     </string-array> | ||||||
|     <string-array name="separator_presets"> |     <string-array name="separator_presets"> | ||||||
|         <item>None</item> |         <item>None</item> | ||||||
|         <item>\@</item> |         <item>\@</item> | ||||||
|  | |||||||
| @ -12,8 +12,8 @@ | |||||||
|     <dimen name="story_item_height">80dp</dimen> |     <dimen name="story_item_height">80dp</dimen> | ||||||
|     <dimen name="story_item_width">45dp</dimen> |     <dimen name="story_item_width">45dp</dimen> | ||||||
| 
 | 
 | ||||||
|     <dimen name="simple_item_picture_size">@dimen/story_item_height</dimen> |     <dimen name="simple_item_picture_size">80dp</dimen> | ||||||
|     <dimen name="simple_item_picture_size_half">@dimen/story_item_width</dimen> |     <dimen name="simple_item_picture_size_half">40dp</dimen> | ||||||
| 
 | 
 | ||||||
|     <dimen name="message_item_size">@dimen/simple_item_picture_size</dimen> |     <dimen name="message_item_size">@dimen/simple_item_picture_size</dimen> | ||||||
|     <dimen name="message_item_profile_size">@dimen/feed_profile_size</dimen> |     <dimen name="message_item_profile_size">@dimen/feed_profile_size</dimen> | ||||||
|  | |||||||
| @ -36,7 +36,8 @@ | |||||||
|     <string name="bottom_toolbar">Show toolbar at bottom</string> |     <string name="bottom_toolbar">Show toolbar at bottom</string> | ||||||
|     <string name="download_user_folder">Download posts to username folder in Downloads</string> |     <string name="download_user_folder">Download posts to username folder in Downloads</string> | ||||||
|     <string name="autoload_posts">Auto-load all posts from user</string> |     <string name="autoload_posts">Auto-load all posts from user</string> | ||||||
|     <string name="mark_as_seen_setting">Mark stories as seen after viewing\n(Story author will know you viewed it)</string> |     <string name="mark_as_seen_setting">Mark stories as seen after viewing</string> | ||||||
|  |     <string name="mark_as_seen_setting_summary">Story author will know you viewed it</string> | ||||||
|     <string name="activity_setting">Enable activity notifications</string> |     <string name="activity_setting">Enable activity notifications</string> | ||||||
|     <string name="error_loading_profile">Error loading profile!\nTry logging in and search again.</string> |     <string name="error_loading_profile">Error loading profile!\nTry logging in and search again.</string> | ||||||
|     <string name="error_creating_folders">Error creating Download folder(s).</string> |     <string name="error_creating_folders">Error creating Download folder(s).</string> | ||||||
| @ -129,12 +130,12 @@ | |||||||
|     <string name="refresh">Refresh</string> |     <string name="refresh">Refresh</string> | ||||||
|     <string name="get_cookies">Get cookies</string> |     <string name="get_cookies">Get cookies</string> | ||||||
|     <string name="desktop_2fa">Desktop Mode</string> |     <string name="desktop_2fa">Desktop Mode</string> | ||||||
|     <string name="time_settings_title_custom">Custom Format</string> |     <string name="time_settings_title_custom">Use custom format</string> | ||||||
|     <string name="time_settings_title_separator">Separator</string> |     <string name="time_settings_title_separator">Separator</string> | ||||||
|     <string name="time_settings_title_time_format">Time Format</string> |     <string name="time_settings_title_time_format">Time Format</string> | ||||||
|     <string name="time_settings_title_date_format">Date Format</string> |     <string name="time_settings_title_date_format">Date Format</string> | ||||||
|     <string name="time_settings_title_preview">Preview</string> |     <string name="time_settings_title_preview">Preview</string> | ||||||
|     <string name="time_settings_swap_time">Swap Time and\nDate positions</string> |     <string name="time_settings_swap_time">Swap Time and Date positions</string> | ||||||
|     <string name="quick_access_info_dialog">Favorites panel is for adding your favorite hashtags and/or usernames.\n\nAnd the Quick Access panel is for quickly switching between accounts.\n\nNote 1: Make sure to Login into each account [Settings > Login] to add account to the list!\n\nNote 2: Log out of the current account and then log into the other account.</string> |     <string name="quick_access_info_dialog">Favorites panel is for adding your favorite hashtags and/or usernames.\n\nAnd the Quick Access panel is for quickly switching between accounts.\n\nNote 1: Make sure to Login into each account [Settings > Login] to add account to the list!\n\nNote 2: Log out of the current account and then log into the other account.</string> | ||||||
|     <string name="quick_access_cannot_delete_curr">Cannot delete currently in use account</string> |     <string name="quick_access_cannot_delete_curr">Cannot delete currently in use account</string> | ||||||
|     <string name="quick_access_confirm_delete">Are you sure you want to delete %s?</string> |     <string name="quick_access_confirm_delete">Are you sure you want to delete %s?</string> | ||||||
| @ -239,4 +240,7 @@ | |||||||
|     <string name="more">More</string> |     <string name="more">More</string> | ||||||
|     <string name="title_dm">DM</string> |     <string name="title_dm">DM</string> | ||||||
|     <string name="number_selected">%d selected</string> |     <string name="number_selected">%d selected</string> | ||||||
|  |     <string name="relogin">Relogin</string> | ||||||
|  |     <string name="relogin_summary">Refresh your cookies if facing any issues</string> | ||||||
|  |     <string name="logout_success">Successfully logged out!</string> | ||||||
| </resources> | </resources> | ||||||
|  | |||||||