diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f90a4aea..d839e3d4 100755 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -51,8 +51,6 @@ - - @@ -60,6 +58,7 @@ + - - - - - - - - { @@ -50,6 +51,8 @@ public class DiscoverTopicsAdapter extends ListAdapter onTopicClickListener.onTopicClick( topicCluster, - binding.getRoot(), binding.cover, - binding.title, titleColor.get(), backgroundColor.get() )); + itemView.setOnLongClickListener(v -> { + onTopicClickListener.onTopicLongClick(topicCluster.getCoverMedia()); + return true; + }); } // binding.title.setTransitionName("title-" + topicCluster.getId()); binding.cover.setTransitionName("cover-" + topicCluster.getId()); diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/dialogs/KeywordsFilterDialogViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/dialogs/KeywordsFilterDialogViewHolder.java index 65fe7b77..9930be59 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/dialogs/KeywordsFilterDialogViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/dialogs/KeywordsFilterDialogViewHolder.java @@ -14,7 +14,7 @@ import java.util.HashSet; import awais.instagrabber.R; import awais.instagrabber.adapters.KeywordsFilterAdapter; -import awais.instagrabber.utils.Constants; +import awais.instagrabber.fragments.settings.PreferenceKeys; import awais.instagrabber.utils.SettingsHelper; public class KeywordsFilterDialogViewHolder extends RecyclerView.ViewHolder { @@ -34,7 +34,7 @@ public class KeywordsFilterDialogViewHolder extends RecyclerView.ViewHolder { final String s = items.get(position); SettingsHelper settingsHelper = new SettingsHelper(context); items.remove(position); - settingsHelper.putStringSet(Constants.KEYWORD_FILTERS, new HashSet<>(items)); + settingsHelper.putStringSet(PreferenceKeys.KEYWORD_FILTERS, new HashSet<>(items)); adapter.notifyDataSetChanged(); final String message = context.getString(R.string.removed_keywords, s); Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedVideoViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedVideoViewHolder.java index 3d56551b..e94af79b 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedVideoViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedVideoViewHolder.java @@ -18,9 +18,9 @@ import awais.instagrabber.adapters.FeedAdapterV2; import awais.instagrabber.customviews.VideoPlayerCallbackAdapter; import awais.instagrabber.customviews.VideoPlayerViewHelper; import awais.instagrabber.databinding.ItemFeedVideoBinding; +import awais.instagrabber.fragments.settings.PreferenceKeys; import awais.instagrabber.repositories.responses.Media; import awais.instagrabber.repositories.responses.VideoVersion; -import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.NumberUtils; import awais.instagrabber.utils.ResponseBodyUtils; import awais.instagrabber.utils.Utils; @@ -65,7 +65,7 @@ public class FeedVideoViewHolder extends FeedItemViewHolder { // Log.d(TAG, "Binding post: " + feedModel.getPostId()); this.media = media; binding.itemFeedBottom.tvVideoViews.setText(String.valueOf(media.getViewCount())); - final float vol = settingsHelper.getBoolean(Constants.MUTED_VIDEOS) ? 0f : 1f; + final float vol = settingsHelper.getBoolean(PreferenceKeys.MUTED_VIDEOS) ? 0f : 1f; final VideoPlayerViewHelper.VideoPlayerCallback videoPlayerCallback = new VideoPlayerCallbackAdapter() { @Override diff --git a/app/src/main/java/awais/instagrabber/customviews/PostsRecyclerView.java b/app/src/main/java/awais/instagrabber/customviews/PostsRecyclerView.java index 2e008a18..ace25beb 100644 --- a/app/src/main/java/awais/instagrabber/customviews/PostsRecyclerView.java +++ b/app/src/main/java/awais/instagrabber/customviews/PostsRecyclerView.java @@ -33,10 +33,10 @@ import awais.instagrabber.adapters.FeedAdapterV2; import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration; import awais.instagrabber.customviews.helpers.PostFetcher; import awais.instagrabber.customviews.helpers.RecyclerLazyLoaderAtEdge; +import awais.instagrabber.fragments.settings.PreferenceKeys; import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.models.PostsLayoutPreferences; import awais.instagrabber.repositories.responses.Media; -import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.KeywordsFilterUtils; import awais.instagrabber.utils.ResponseBodyUtils; import awais.instagrabber.utils.Utils; @@ -81,8 +81,8 @@ public class PostsRecyclerView extends RecyclerView { } final List models = mediaViewModel.getList().getValue(); final List modelsCopy = models == null ? new ArrayList<>() : new ArrayList<>(models); - if (settingsHelper.getBoolean(Constants.TOGGLE_KEYWORD_FILTER)) { - final ArrayList items = new ArrayList<>(settingsHelper.getStringSet(Constants.KEYWORD_FILTERS)); + if (settingsHelper.getBoolean(PreferenceKeys.TOGGLE_KEYWORD_FILTER)) { + final ArrayList items = new ArrayList<>(settingsHelper.getStringSet(PreferenceKeys.KEYWORD_FILTERS)); modelsCopy.addAll(new KeywordsFilterUtils(items).filter(result)); } else { modelsCopy.addAll(result); diff --git a/app/src/main/java/awais/instagrabber/dialogs/CreateBackupDialogFragment.java b/app/src/main/java/awais/instagrabber/dialogs/CreateBackupDialogFragment.java index f612b72c..68f895e0 100644 --- a/app/src/main/java/awais/instagrabber/dialogs/CreateBackupDialogFragment.java +++ b/app/src/main/java/awais/instagrabber/dialogs/CreateBackupDialogFragment.java @@ -29,7 +29,7 @@ import awais.instagrabber.utils.ExportImportUtils; import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; -import static awais.instagrabber.utils.Constants.FOLDER_PATH; +import static awais.instagrabber.fragments.settings.PreferenceKeys.FOLDER_PATH; import static awais.instagrabber.utils.DownloadUtils.PERMS; public class CreateBackupDialogFragment extends DialogFragment { diff --git a/app/src/main/java/awais/instagrabber/dialogs/KeywordsFilterDialog.java b/app/src/main/java/awais/instagrabber/dialogs/KeywordsFilterDialog.java index 2a4d8a04..5997371c 100644 --- a/app/src/main/java/awais/instagrabber/dialogs/KeywordsFilterDialog.java +++ b/app/src/main/java/awais/instagrabber/dialogs/KeywordsFilterDialog.java @@ -22,7 +22,7 @@ import java.util.HashSet; import awais.instagrabber.R; import awais.instagrabber.adapters.KeywordsFilterAdapter; import awais.instagrabber.databinding.DialogKeywordsFilterBinding; -import awais.instagrabber.utils.Constants; +import awais.instagrabber.fragments.settings.PreferenceKeys; import awais.instagrabber.utils.SettingsHelper; import awais.instagrabber.utils.Utils; @@ -54,7 +54,7 @@ public final class KeywordsFilterDialog extends DialogFragment { recyclerView.setLayoutManager(linearLayoutManager); final SettingsHelper settingsHelper = new SettingsHelper(context); - final ArrayList items = new ArrayList<>(settingsHelper.getStringSet(Constants.KEYWORD_FILTERS)); + final ArrayList items = new ArrayList<>(settingsHelper.getStringSet(PreferenceKeys.KEYWORD_FILTERS)); final KeywordsFilterAdapter adapter = new KeywordsFilterAdapter(context, items); recyclerView.setAdapter(adapter); @@ -68,7 +68,7 @@ public final class KeywordsFilterDialog extends DialogFragment { return; } items.add(s.toLowerCase()); - settingsHelper.putStringSet(Constants.KEYWORD_FILTERS, new HashSet<>(items)); + settingsHelper.putStringSet(PreferenceKeys.KEYWORD_FILTERS, new HashSet<>(items)); adapter.notifyItemInserted(items.size()); final String message = context.getString(R.string.added_keywords, s); Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); diff --git a/app/src/main/java/awais/instagrabber/dialogs/RestoreBackupDialogFragment.java b/app/src/main/java/awais/instagrabber/dialogs/RestoreBackupDialogFragment.java index 7967b9e2..7ab5f0fd 100644 --- a/app/src/main/java/awais/instagrabber/dialogs/RestoreBackupDialogFragment.java +++ b/app/src/main/java/awais/instagrabber/dialogs/RestoreBackupDialogFragment.java @@ -28,7 +28,7 @@ import awais.instagrabber.utils.PasswordUtils.IncorrectPasswordException; import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; -import static awais.instagrabber.utils.Constants.FOLDER_PATH; +import static awais.instagrabber.fragments.settings.PreferenceKeys.FOLDER_PATH; import static awais.instagrabber.utils.DownloadUtils.PERMS; public class RestoreBackupDialogFragment extends DialogFragment { diff --git a/app/src/main/java/awais/instagrabber/fragments/NotificationsViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/NotificationsViewerFragment.java index c443652b..c6ccff9f 100644 --- a/app/src/main/java/awais/instagrabber/fragments/NotificationsViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/NotificationsViewerFragment.java @@ -114,6 +114,7 @@ public final class NotificationsViewerFragment extends Fragment implements Swipe bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel); try { navController.navigate(R.id.action_global_post_view, bundle); + alertDialog.dismiss(); } catch (Exception e) { Log.e(TAG, "onSuccess: ", e); } diff --git a/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java b/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java index 35249824..001ce340 100644 --- a/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/PostViewV2Fragment.java @@ -82,6 +82,7 @@ import awais.instagrabber.databinding.DialogPostViewBinding; import awais.instagrabber.databinding.LayoutPostViewBottomBinding; import awais.instagrabber.databinding.LayoutVideoPlayerWithThumbnailBinding; import awais.instagrabber.dialogs.EditTextDialogFragment; +import awais.instagrabber.fragments.settings.PreferenceKeys; import awais.instagrabber.models.Resource; import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.repositories.responses.Caption; @@ -89,7 +90,6 @@ import awais.instagrabber.repositories.responses.Location; import awais.instagrabber.repositories.responses.Media; import awais.instagrabber.repositories.responses.User; import awais.instagrabber.repositories.responses.VideoVersion; -import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.DownloadUtils; import awais.instagrabber.utils.NullSafePair; import awais.instagrabber.utils.NumberUtils; @@ -184,7 +184,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme public void onPause() { super.onPause(); // wasPaused = true; - if (settingsHelper.getBoolean(Constants.PLAY_IN_BACKGROUND)) return; + if (settingsHelper.getBoolean(PreferenceKeys.PLAY_IN_BACKGROUND)) return; final Media media = viewModel.getMedia(); if (media == null) return; switch (media.getMediaType()) { @@ -1058,7 +1058,7 @@ public class PostViewV2Fragment extends Fragment implements EditTextDialogFragme // gestureDetector.onTouchEvent(event); // return true; // }); - final float vol = settingsHelper.getBoolean(Constants.MUTED_VIDEOS) ? 0f : 1f; + final float vol = settingsHelper.getBoolean(PreferenceKeys.MUTED_VIDEOS) ? 0f : 1f; final VideoPlayerViewHelper.VideoPlayerCallback videoPlayerCallback = new VideoPlayerCallbackAdapter() { @Override public void onThumbnailLoaded() { diff --git a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java index 5cc6887b..c59caab6 100644 --- a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java @@ -74,6 +74,7 @@ import awais.instagrabber.asyncs.CreateThreadAction; import awais.instagrabber.customviews.helpers.SwipeGestureListener; import awais.instagrabber.databinding.FragmentStoryViewerBinding; import awais.instagrabber.fragments.main.ProfileFragmentDirections; +import awais.instagrabber.fragments.settings.PreferenceKeys; import awais.instagrabber.interfaces.SwipeEvent; import awais.instagrabber.models.FeedStoryModel; import awais.instagrabber.models.HighlightModel; @@ -109,7 +110,7 @@ import retrofit2.Response; import static awais.instagrabber.customviews.helpers.SwipeGestureListener.SWIPE_THRESHOLD; import static awais.instagrabber.customviews.helpers.SwipeGestureListener.SWIPE_VELOCITY_THRESHOLD; -import static awais.instagrabber.utils.Constants.MARK_AS_SEEN; +import static awais.instagrabber.fragments.settings.PreferenceKeys.MARK_AS_SEEN; import static awais.instagrabber.utils.Utils.settingsHelper; public class StoryViewerFragment extends Fragment { @@ -448,7 +449,10 @@ public class StoryViewerFragment extends Fragment { binding.swipeUp.setOnClickListener(v -> { final Object tag = v.getTag(); if (tag instanceof CharSequence) { - Utils.openURL(context, tag.toString()); + new AlertDialog.Builder(context) + .setTitle(R.string.swipe_up_confirmation) + .setMessage(tag.toString()).setPositiveButton(R.string.yes, (d, w) -> Utils.openURL(context, tag.toString())) + .setNegativeButton(R.string.no, (d, w) -> d.dismiss()).show(); } }); binding.viewStoryPost.setOnClickListener(v -> { @@ -468,6 +472,7 @@ public class StoryViewerFragment extends Fragment { bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel); try { navController.navigate(R.id.action_global_post_view, bundle); + alertDialog.dismiss(); } catch (Exception e) { Log.e(TAG, "openPostDialog: ", e); } @@ -990,7 +995,7 @@ public class StoryViewerFragment extends Fragment { if (context == null) return; player = new SimpleExoPlayer.Builder(context).build(); binding.playerView.setPlayer(player); - player.setPlayWhenReady(settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS)); + player.setPlayWhenReady(settingsHelper.getBoolean(PreferenceKeys.AUTOPLAY_VIDEOS)); final Uri uri = Uri.parse(url); final MediaItem mediaItem = MediaItem.fromUri(uri); @@ -1091,7 +1096,7 @@ public class StoryViewerFragment extends Fragment { if (context == null) return; player = new SimpleExoPlayer.Builder(context).build(); binding.playerView.setPlayer(player); - player.setPlayWhenReady(settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS)); + player.setPlayWhenReady(settingsHelper.getBoolean(PreferenceKeys.AUTOPLAY_VIDEOS)); final Uri uri = Uri.parse(url); final MediaItem mediaItem = MediaItem.fromUri(uri); diff --git a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java index eb97b60f..fe4343e7 100644 --- a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java @@ -101,6 +101,7 @@ import awais.instagrabber.dialogs.MediaPickerBottomDialogFragment; import awais.instagrabber.fragments.PostViewV2Fragment; import awais.instagrabber.fragments.UserSearchFragment; import awais.instagrabber.fragments.UserSearchFragmentDirections; +import awais.instagrabber.fragments.settings.PreferenceKeys; import awais.instagrabber.models.Resource; import awais.instagrabber.models.enums.DirectItemType; import awais.instagrabber.models.enums.MediaItemType; @@ -114,7 +115,6 @@ import awais.instagrabber.repositories.responses.directmessages.DirectItemVisual import awais.instagrabber.repositories.responses.directmessages.DirectThread; import awais.instagrabber.repositories.responses.directmessages.RankedRecipient; import awais.instagrabber.utils.AppExecutors; -import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.DMUtils; import awais.instagrabber.utils.DownloadUtils; import awais.instagrabber.utils.PermissionUtils; @@ -356,7 +356,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact super.onCreate(savedInstanceState); fragmentActivity = (MainActivity) requireActivity(); appStateViewModel = new ViewModelProvider(fragmentActivity).get(AppStateViewModel.class); - autoMarkAsSeen = Utils.settingsHelper.getBoolean(Constants.DM_MARK_AS_SEEN); + autoMarkAsSeen = Utils.settingsHelper.getBoolean(PreferenceKeys.DM_MARK_AS_SEEN); final Bundle arguments = getArguments(); if (arguments == null) return; final DirectMessageThreadFragmentArgs fragmentArgs = DirectMessageThreadFragmentArgs.fromBundle(arguments); diff --git a/app/src/main/java/awais/instagrabber/fragments/main/DiscoverFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/DiscoverFragment.java index 8ec7444a..26ee6ce9 100644 --- a/app/src/main/java/awais/instagrabber/fragments/main/DiscoverFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/main/DiscoverFragment.java @@ -5,24 +5,35 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import androidx.navigation.NavController; import androidx.navigation.fragment.FragmentNavigator; import androidx.navigation.fragment.NavHostFragment; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import java.util.Collections; +import java.util.List; + +import awais.instagrabber.R; import awais.instagrabber.activities.MainActivity; import awais.instagrabber.adapters.DiscoverTopicsAdapter; import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration; import awais.instagrabber.databinding.FragmentDiscoverBinding; +import awais.instagrabber.fragments.PostViewV2Fragment; +import awais.instagrabber.repositories.responses.Media; +import awais.instagrabber.repositories.responses.discover.TopicCluster; import awais.instagrabber.repositories.responses.discover.TopicalExploreFeedResponse; import awais.instagrabber.utils.Utils; import awais.instagrabber.viewmodels.TopicClusterViewModel; import awais.instagrabber.webservices.DiscoverService; +import awais.instagrabber.webservices.MediaService; import awais.instagrabber.webservices.ServiceCallback; public class DiscoverFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener { @@ -34,12 +45,14 @@ public class DiscoverFragment extends Fragment implements SwipeRefreshLayout.OnR private TopicClusterViewModel topicClusterViewModel; private boolean shouldRefresh = true; private DiscoverService discoverService; + private MediaService mediaService; @Override public void onCreate(@Nullable final Bundle savedInstanceState) { super.onCreate(savedInstanceState); fragmentActivity = (MainActivity) requireActivity(); discoverService = DiscoverService.getInstance(); + mediaService = MediaService.getInstance(null, null, 0); } @Override @@ -76,13 +89,47 @@ public class DiscoverFragment extends Fragment implements SwipeRefreshLayout.OnR public void setupTopics() { topicClusterViewModel = new ViewModelProvider(fragmentActivity).get(TopicClusterViewModel.class); binding.topicsRecyclerView.addItemDecoration(new GridSpacingItemDecoration(Utils.convertDpToPx(2))); - final DiscoverTopicsAdapter adapter = new DiscoverTopicsAdapter((topicCluster, root, cover, title, titleColor, backgroundColor) -> { - final FragmentNavigator.Extras.Builder builder = new FragmentNavigator.Extras.Builder() - .addSharedElement(cover, "cover-" + topicCluster.getId()); - final DiscoverFragmentDirections.ActionDiscoverFragmentToTopicPostsFragment action = DiscoverFragmentDirections - .actionDiscoverFragmentToTopicPostsFragment(topicCluster, titleColor, backgroundColor); - NavHostFragment.findNavController(this).navigate(action, builder.build()); - }); + final DiscoverTopicsAdapter.OnTopicClickListener otcl = new DiscoverTopicsAdapter.OnTopicClickListener() { + public void onTopicClick(final TopicCluster topicCluster, final View cover, final int titleColor, final int backgroundColor) { + final FragmentNavigator.Extras.Builder builder = new FragmentNavigator.Extras.Builder() + .addSharedElement(cover, "cover-" + topicCluster.getId()); + final DiscoverFragmentDirections.ActionDiscoverFragmentToTopicPostsFragment action = DiscoverFragmentDirections + .actionDiscoverFragmentToTopicPostsFragment(topicCluster, titleColor, backgroundColor); + NavHostFragment.findNavController(DiscoverFragment.this).navigate(action, builder.build()); + } + + public void onTopicLongClick(final Media coverMedia) { + final AlertDialog alertDialog = new AlertDialog.Builder(requireContext()) + .setCancelable(false) + .setView(R.layout.dialog_opening_post) + .create(); + alertDialog.show(); + mediaService.fetch(Long.valueOf(coverMedia.getPk()), new ServiceCallback() { + @Override + public void onSuccess(final Media feedModel) { + final NavController navController = NavHostFragment.findNavController(DiscoverFragment.this); + final Bundle bundle = new Bundle(); + bundle.putSerializable(PostViewV2Fragment.ARG_MEDIA, feedModel); + try { + navController.navigate(R.id.action_global_post_view, bundle); + alertDialog.dismiss(); + } catch (Exception e) { + Log.e(TAG, "onSuccess: ", e); + } + } + + @Override + public void onFailure(final Throwable t) { + alertDialog.dismiss(); + try { + Toast.makeText(requireContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show(); + } + catch (Throwable e) {} + } + }); + } + }; + final DiscoverTopicsAdapter adapter = new DiscoverTopicsAdapter(otcl); binding.topicsRecyclerView.setAdapter(adapter); topicClusterViewModel.getList().observe(getViewLifecycleOwner(), adapter::submitList); } @@ -93,8 +140,18 @@ public class DiscoverFragment extends Fragment implements SwipeRefreshLayout.OnR @Override public void onSuccess(final TopicalExploreFeedResponse result) { if (result == null) return; - topicClusterViewModel.getList().postValue(result.getClusters()); + final List clusters = result.getClusters(); binding.swipeRefreshLayout.setRefreshing(false); + if (clusters.size() == 1 && result.getItems().size() > 0) { + final TopicCluster cluster = clusters.get(0); + if (cluster.getCoverMedia() == null) + cluster.setCoverMedia(result.getItems().get(0).getMedia()); + topicClusterViewModel.getList().postValue(Collections.singletonList(cluster)); + return; + } + if (clusters.size() > 1 || result.getItems().size() == 0) { + topicClusterViewModel.getList().postValue(clusters); + } } @Override diff --git a/app/src/main/java/awais/instagrabber/fragments/search/SearchFragment.java b/app/src/main/java/awais/instagrabber/fragments/search/SearchFragment.java index 8e31cb70..ab879a77 100644 --- a/app/src/main/java/awais/instagrabber/fragments/search/SearchFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/search/SearchFragment.java @@ -1,5 +1,6 @@ package awais.instagrabber.fragments.search; +import android.content.Context; import android.os.Bundle; import android.text.Editable; import android.text.TextUtils; @@ -7,6 +8,7 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import androidx.annotation.NonNull; @@ -36,6 +38,9 @@ import awais.instagrabber.models.enums.FavoriteType; import awais.instagrabber.repositories.responses.search.SearchItem; import awais.instagrabber.viewmodels.SearchFragmentViewModel; +import static awais.instagrabber.fragments.settings.PreferenceKeys.PREF_SEARCH_FOCUS_KEYBOARD; +import static awais.instagrabber.utils.Utils.settingsHelper; + public class SearchFragment extends Fragment implements SearchCategoryFragment.OnSearchItemClickListener { private static final String TAG = SearchFragment.class.getSimpleName(); private static final String QUERY = "query"; @@ -119,9 +124,11 @@ public class SearchFragment extends Fragment implements SearchCategoryFragment.O if (mainActivity != null) { mainActivity.showSearchView(); } - // if (searchInputLayout != null) { - // searchInputLayout.requestFocus(); - // } + if (settingsHelper.getBoolean(PREF_SEARCH_FOCUS_KEYBOARD)) { + searchInput.requestFocus(); + final InputMethodManager imm = (InputMethodManager) requireContext().getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) imm.showSoftInput(searchInput, InputMethodManager.SHOW_IMPLICIT); + } } private void init(@Nullable final Bundle savedInstanceState) { @@ -147,7 +154,11 @@ public class SearchFragment extends Fragment implements SearchCategoryFragment.O searchInput.setText(savedQuery); triggerEmptyQuery = false; } - // searchInput.requestFocus(); + if (settingsHelper.getBoolean(PREF_SEARCH_FOCUS_KEYBOARD)) { + searchInput.requestFocus(); + final InputMethodManager imm = (InputMethodManager) requireContext().getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) imm.showSoftInput(searchInput, InputMethodManager.SHOW_IMPLICIT); + } if (triggerEmptyQuery) { viewModel.submitQuery(""); } diff --git a/app/src/main/java/awais/instagrabber/fragments/settings/BasePreferencesFragment.java b/app/src/main/java/awais/instagrabber/fragments/settings/BasePreferencesFragment.java index caade8b7..3e7f304d 100644 --- a/app/src/main/java/awais/instagrabber/fragments/settings/BasePreferencesFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/settings/BasePreferencesFragment.java @@ -41,7 +41,7 @@ public abstract class BasePreferencesFragment extends PreferenceFragmentCompat i if (!shouldRecreate) return; final MainActivity activity = (MainActivity) getActivity(); if (activity == null) return; - if (key.equals(Constants.APP_LANGUAGE)) { + if (key.equals(PreferenceKeys.APP_LANGUAGE)) { LocaleUtils.setLocale(activity.getBaseContext()); } shouldRecreate = false; diff --git a/app/src/main/java/awais/instagrabber/fragments/settings/DMPreferencesFragment.java b/app/src/main/java/awais/instagrabber/fragments/settings/DMPreferencesFragment.java index 466e2490..2633bb78 100644 --- a/app/src/main/java/awais/instagrabber/fragments/settings/DMPreferencesFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/settings/DMPreferencesFragment.java @@ -20,7 +20,6 @@ import awais.instagrabber.customviews.helpers.TextWatcherAdapter; import awais.instagrabber.databinding.PrefAutoRefreshDmFreqBinding; import awais.instagrabber.services.DMSyncAlarmReceiver; import awais.instagrabber.services.DMSyncService; -import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.Debouncer; import awais.instagrabber.utils.TextUtils; @@ -43,7 +42,7 @@ public class DMPreferencesFragment extends BasePreferencesFragment { private Preference getMarkDMSeenPreference(@NonNull final Context context) { return PreferenceHelper.getSwitchPreference( context, - Constants.DM_MARK_AS_SEEN, + PreferenceKeys.DM_MARK_AS_SEEN, R.string.dm_mark_as_seen_setting, R.string.dm_mark_as_seen_setting_summary, false, diff --git a/app/src/main/java/awais/instagrabber/fragments/settings/DownloadsPreferencesFragment.java b/app/src/main/java/awais/instagrabber/fragments/settings/DownloadsPreferencesFragment.java index 4e75a97f..6a18c69a 100644 --- a/app/src/main/java/awais/instagrabber/fragments/settings/DownloadsPreferencesFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/settings/DownloadsPreferencesFragment.java @@ -14,12 +14,11 @@ import androidx.preference.SwitchPreferenceCompat; import com.google.android.material.switchmaterial.SwitchMaterial; import awais.instagrabber.R; -import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.DirectoryChooser; import awais.instagrabber.utils.TextUtils; -import static awais.instagrabber.utils.Constants.FOLDER_PATH; -import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO; +import static awais.instagrabber.fragments.settings.PreferenceKeys.FOLDER_PATH; +import static awais.instagrabber.fragments.settings.PreferenceKeys.FOLDER_SAVE_TO; import static awais.instagrabber.utils.Utils.settingsHelper; public class DownloadsPreferencesFragment extends BasePreferencesFragment { @@ -34,7 +33,7 @@ public class DownloadsPreferencesFragment extends BasePreferencesFragment { private Preference getDownloadUserFolderPreference(@NonNull final Context context) { final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(context); - preference.setKey(Constants.DOWNLOAD_USER_FOLDER); + preference.setKey(PreferenceKeys.DOWNLOAD_USER_FOLDER); preference.setTitle(R.string.download_user_folder); preference.setIconSpaceReserved(false); return preference; @@ -52,7 +51,7 @@ public class DownloadsPreferencesFragment extends BasePreferencesFragment { private Preference getPrependUsernameToFilenamePreference(@NonNull final Context context) { final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(context); - preference.setKey(Constants.DOWNLOAD_PREPEND_USER_NAME); + preference.setKey(PreferenceKeys.DOWNLOAD_PREPEND_USER_NAME); preference.setTitle(R.string.download_prepend_username); preference.setIconSpaceReserved(false); return preference; @@ -66,7 +65,7 @@ public class DownloadsPreferencesFragment extends BasePreferencesFragment { public SaveToCustomFolderPreference(final Context context, final OnSelectFolderButtonClickListener onSelectFolderButtonClickListener) { super(context); this.onSelectFolderButtonClickListener = onSelectFolderButtonClickListener; - key = Constants.FOLDER_SAVE_TO; + key = PreferenceKeys.FOLDER_SAVE_TO; setLayoutResource(R.layout.pref_custom_folder); setKey(key); setTitle(R.string.save_to_folder); diff --git a/app/src/main/java/awais/instagrabber/fragments/settings/GeneralPreferencesFragment.java b/app/src/main/java/awais/instagrabber/fragments/settings/GeneralPreferencesFragment.java index 2eba325e..e8403162 100644 --- a/app/src/main/java/awais/instagrabber/fragments/settings/GeneralPreferencesFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/settings/GeneralPreferencesFragment.java @@ -36,6 +36,7 @@ public class GeneralPreferencesFragment extends BasePreferencesFragment implemen } screen.addPreference(getUpdateCheckPreference(context)); screen.addPreference(getFlagSecurePreference(context)); + screen.addPreference(getSearchFocusPreference(context)); final List preferences = FlavorSettings.getInstance() .getPreferences(context, getChildFragmentManager(), @@ -82,7 +83,7 @@ public class GeneralPreferencesFragment extends BasePreferencesFragment implemen private Preference getUpdateCheckPreference(@NonNull final Context context) { final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(context); - preference.setKey(Constants.CHECK_UPDATES); + preference.setKey(PreferenceKeys.CHECK_UPDATES); preference.setTitle(R.string.update_check); preference.setIconSpaceReserved(false); return preference; @@ -91,7 +92,7 @@ public class GeneralPreferencesFragment extends BasePreferencesFragment implemen private Preference getFlagSecurePreference(@NonNull final Context context) { return PreferenceHelper.getSwitchPreference( context, - Constants.FLAG_SECURE, + PreferenceKeys.FLAG_SECURE, R.string.flag_secure, -1, false, @@ -101,6 +102,14 @@ public class GeneralPreferencesFragment extends BasePreferencesFragment implemen }); } + private Preference getSearchFocusPreference(@NonNull final Context context) { + final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(context); + preference.setKey(PreferenceKeys.PREF_SEARCH_FOCUS_KEYBOARD); + preference.setTitle(R.string.pref_search_focus_keyboard); + preference.setIconSpaceReserved(false); + return preference; + } + @Override public void onSave(final boolean orderHasChanged) { if (!orderHasChanged) return; diff --git a/app/src/main/java/awais/instagrabber/fragments/settings/LocalePreferencesFragment.java b/app/src/main/java/awais/instagrabber/fragments/settings/LocalePreferencesFragment.java index a02a8764..06fe32b2 100644 --- a/app/src/main/java/awais/instagrabber/fragments/settings/LocalePreferencesFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/settings/LocalePreferencesFragment.java @@ -36,7 +36,7 @@ public class LocalePreferencesFragment extends BasePreferencesFragment { for (int i = 0; i < length; i++) { values[i] = String.valueOf(i); } - preference.setKey(Constants.APP_LANGUAGE); + preference.setKey(PreferenceKeys.APP_LANGUAGE); preference.setTitle(R.string.select_language); preference.setDialogTitle(R.string.select_language); preference.setEntries(R.array.languages); @@ -59,10 +59,10 @@ public class LocalePreferencesFragment extends BasePreferencesFragment { 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), - settingsHelper.getBoolean(Constants.SWAP_DATE_TIME_FORMAT_ENABLED), + settingsHelper.getBoolean(PreferenceKeys.CUSTOM_DATE_TIME_FORMAT_ENABLED), + settingsHelper.getString(PreferenceKeys.CUSTOM_DATE_TIME_FORMAT), + settingsHelper.getString(PreferenceKeys.DATE_TIME_SELECTION), + settingsHelper.getBoolean(PreferenceKeys.SWAP_DATE_TIME_FORMAT_ENABLED), (isCustomFormat, formatSelection, spTimeFormatSelectedItemPosition, @@ -72,16 +72,16 @@ public class LocalePreferencesFragment extends BasePreferencesFragment { currentFormat, swapDateTime) -> { if (isCustomFormat) { - settingsHelper.putString(Constants.CUSTOM_DATE_TIME_FORMAT, formatSelection); + settingsHelper.putString(PreferenceKeys.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.putString(PreferenceKeys.DATE_TIME_FORMAT, selectedFormat); + settingsHelper.putString(PreferenceKeys.DATE_TIME_SELECTION, formatSelectionUpdated); } - settingsHelper.putBoolean(Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED, isCustomFormat); - settingsHelper.putBoolean(Constants.SWAP_DATE_TIME_FORMAT_ENABLED, swapDateTime); + settingsHelper.putBoolean(PreferenceKeys.CUSTOM_DATE_TIME_FORMAT_ENABLED, isCustomFormat); + settingsHelper.putBoolean(PreferenceKeys.SWAP_DATE_TIME_FORMAT_ENABLED, swapDateTime); Utils.datetimeParser = (SimpleDateFormat) currentFormat.clone(); preference.setSummary(Utils.datetimeParser.format(new Date())); } diff --git a/app/src/main/java/awais/instagrabber/fragments/settings/NotificationsPreferencesFragment.java b/app/src/main/java/awais/instagrabber/fragments/settings/NotificationsPreferencesFragment.java index 50d284e7..2a2dd499 100644 --- a/app/src/main/java/awais/instagrabber/fragments/settings/NotificationsPreferencesFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/settings/NotificationsPreferencesFragment.java @@ -7,7 +7,6 @@ import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import awais.instagrabber.R; -import awais.instagrabber.utils.Constants; public class NotificationsPreferencesFragment extends BasePreferencesFragment { @Override @@ -21,7 +20,7 @@ public class NotificationsPreferencesFragment extends BasePreferencesFragment { private Preference getActivityNotificationsPreference(@NonNull final Context context) { return PreferenceHelper.getSwitchPreference( context, - Constants.CHECK_ACTIVITY, + PreferenceKeys.CHECK_ACTIVITY, R.string.activity_setting, -1, false, diff --git a/app/src/main/java/awais/instagrabber/fragments/settings/PostPreferencesFragment.java b/app/src/main/java/awais/instagrabber/fragments/settings/PostPreferencesFragment.java index c79d009b..b1db2e40 100644 --- a/app/src/main/java/awais/instagrabber/fragments/settings/PostPreferencesFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/settings/PostPreferencesFragment.java @@ -9,7 +9,6 @@ import androidx.preference.SwitchPreferenceCompat; import awais.instagrabber.R; import awais.instagrabber.dialogs.KeywordsFilterDialog; -import awais.instagrabber.utils.Constants; public class PostPreferencesFragment extends BasePreferencesFragment { @Override @@ -34,7 +33,7 @@ public class PostPreferencesFragment extends BasePreferencesFragment { private Preference getBackgroundPlayPreference(@NonNull final Context context) { final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(context); - preference.setKey(Constants.PLAY_IN_BACKGROUND); + preference.setKey(PreferenceKeys.PLAY_IN_BACKGROUND); preference.setTitle(R.string.post_viewer_background_play); preference.setSummary(R.string.post_viewer_background_play_summary); preference.setIconSpaceReserved(false); @@ -43,7 +42,7 @@ public class PostPreferencesFragment extends BasePreferencesFragment { private Preference getAlwaysMuteVideosPreference(@NonNull final Context context) { final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(context); - preference.setKey(Constants.MUTED_VIDEOS); + preference.setKey(PreferenceKeys.MUTED_VIDEOS); preference.setTitle(R.string.post_viewer_muted_autoplay); preference.setIconSpaceReserved(false); return preference; @@ -51,7 +50,7 @@ public class PostPreferencesFragment extends BasePreferencesFragment { private Preference getShowCaptionPreference(@NonNull final Context context) { final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(context); - preference.setKey(Constants.SHOW_CAPTIONS); + preference.setKey(PreferenceKeys.SHOW_CAPTIONS); preference.setDefaultValue(true); preference.setTitle(R.string.post_viewer_show_captions); preference.setIconSpaceReserved(false); @@ -60,7 +59,7 @@ public class PostPreferencesFragment extends BasePreferencesFragment { private Preference getToggleKeywordFilterPreference(@NonNull final Context context) { final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(context); - preference.setKey(Constants.TOGGLE_KEYWORD_FILTER); + preference.setKey(PreferenceKeys.TOGGLE_KEYWORD_FILTER); preference.setDefaultValue(false); preference.setTitle(R.string.toggle_keyword_filter); preference.setIconSpaceReserved(false); diff --git a/app/src/main/java/awais/instagrabber/fragments/settings/PreferenceKeys.java b/app/src/main/java/awais/instagrabber/fragments/settings/PreferenceKeys.java index dacf80f6..878b9678 100644 --- a/app/src/main/java/awais/instagrabber/fragments/settings/PreferenceKeys.java +++ b/app/src/main/java/awais/instagrabber/fragments/settings/PreferenceKeys.java @@ -1,6 +1,7 @@ package awais.instagrabber.fragments.settings; public final class PreferenceKeys { + // new boolean prefs public static final String PREF_ENABLE_DM_NOTIFICATIONS = "enable_dm_notifications"; public static final String PREF_ENABLE_DM_AUTO_REFRESH = "enable_dm_auto_refresh"; public static final String PREF_ENABLE_DM_AUTO_REFRESH_FREQ_UNIT = "enable_dm_auto_refresh_freq_unit"; @@ -8,4 +9,32 @@ public final class PreferenceKeys { public static final String PREF_ENABLE_SENTRY = "enable_sentry"; public static final String PREF_TAB_ORDER = "tab_order"; public static final String PREF_SHOWN_COUNT_TOOLTIP = "shown_count_tooltip"; + public static final String PREF_SEARCH_FOCUS_KEYBOARD = "search_focus_keyboard"; + // string prefs + public static final String FOLDER_PATH = "custom_path"; + public static final String DATE_TIME_FORMAT = "date_time_format"; + public static final String DATE_TIME_SELECTION = "date_time_selection"; + public static final String CUSTOM_DATE_TIME_FORMAT = "date_time_custom_format"; + public static final String APP_THEME = "app_theme_v19"; + public static final String APP_LANGUAGE = "app_language_v19"; + public static final String STORY_SORT = "story_sort"; + // set string prefs + public static final String KEYWORD_FILTERS = "keyword_filters"; + // old boolean prefs + public static final String DOWNLOAD_USER_FOLDER = "download_user_folder"; + public static final String TOGGLE_KEYWORD_FILTER = "toggle_keyword_filter"; + public static final String DOWNLOAD_PREPEND_USER_NAME = "download_user_name"; + public static final String PLAY_IN_BACKGROUND = "play_in_background"; + public static final String FOLDER_SAVE_TO = "saved_to"; + public static final String AUTOPLAY_VIDEOS = "autoplay_videos"; + public static final String MUTED_VIDEOS = "muted_videos"; + public static final String SHOW_CAPTIONS = "show_captions"; + public static final String CUSTOM_DATE_TIME_FORMAT_ENABLED = "data_time_custom_enabled"; + public static final String SWAP_DATE_TIME_FORMAT_ENABLED = "swap_date_time_enabled"; + public static final String MARK_AS_SEEN = "mark_as_seen"; + public static final String HIDE_MUTED_REELS = "hide_muted_reels"; + public static final String DM_MARK_AS_SEEN = "dm_mark_as_seen"; + public static final String CHECK_ACTIVITY = "check_activity"; + public static final String CHECK_UPDATES = "check_updates"; + public static final String FLAG_SECURE = "flag_secure"; } diff --git a/app/src/main/java/awais/instagrabber/fragments/settings/StoriesPreferencesFragment.java b/app/src/main/java/awais/instagrabber/fragments/settings/StoriesPreferencesFragment.java index 0f3850ab..e027389d 100644 --- a/app/src/main/java/awais/instagrabber/fragments/settings/StoriesPreferencesFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/settings/StoriesPreferencesFragment.java @@ -9,7 +9,6 @@ import androidx.preference.PreferenceScreen; import androidx.preference.SwitchPreferenceCompat; import awais.instagrabber.R; -import awais.instagrabber.utils.Constants; public class StoriesPreferencesFragment extends BasePreferencesFragment { @Override @@ -29,7 +28,7 @@ public class StoriesPreferencesFragment extends BasePreferencesFragment { for (int i = 0; i < length; i++) { values[i] = String.valueOf(i); } - preference.setKey(Constants.STORY_SORT); + preference.setKey(PreferenceKeys.STORY_SORT); preference.setTitle(R.string.story_sort_setting); preference.setDialogTitle(R.string.story_sort_setting); preference.setEntries(R.array.story_sorts); @@ -40,7 +39,7 @@ public class StoriesPreferencesFragment extends BasePreferencesFragment { private Preference getHideMutedReelsPreference(@NonNull final Context context) { final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(context); - preference.setKey(Constants.HIDE_MUTED_REELS); + preference.setKey(PreferenceKeys.HIDE_MUTED_REELS); preference.setTitle(R.string.hide_muted_reels_setting); preference.setIconSpaceReserved(false); return preference; @@ -48,7 +47,7 @@ public class StoriesPreferencesFragment extends BasePreferencesFragment { private Preference getMarkStoriesSeenPreference(@NonNull final Context context) { final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(context); - preference.setKey(Constants.MARK_AS_SEEN); + preference.setKey(PreferenceKeys.MARK_AS_SEEN); preference.setTitle(R.string.mark_as_seen_setting); preference.setSummary(R.string.mark_as_seen_setting_summary); preference.setIconSpaceReserved(false); diff --git a/app/src/main/java/awais/instagrabber/fragments/settings/ThemePreferencesFragment.java b/app/src/main/java/awais/instagrabber/fragments/settings/ThemePreferencesFragment.java index bf3aad9e..21435b0f 100644 --- a/app/src/main/java/awais/instagrabber/fragments/settings/ThemePreferencesFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/settings/ThemePreferencesFragment.java @@ -29,7 +29,7 @@ public class ThemePreferencesFragment extends BasePreferencesFragment { for (int i = 0; i < length; i++) { values[i] = String.valueOf(i); } - preference.setKey(Constants.APP_THEME); + preference.setKey(PreferenceKeys.APP_THEME); preference.setTitle(R.string.theme_settings); preference.setDialogTitle(R.string.theme_settings); preference.setEntries(R.array.theme_presets); diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/discover/TopicCluster.java b/app/src/main/java/awais/instagrabber/repositories/responses/discover/TopicCluster.java index 610a4835..436b8ecf 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/discover/TopicCluster.java +++ b/app/src/main/java/awais/instagrabber/repositories/responses/discover/TopicCluster.java @@ -11,7 +11,7 @@ public class TopicCluster implements Serializable { private final boolean canMute; private final boolean isMuted; private final int rankedPosition; - private final Media coverMedia; + private Media coverMedia; public TopicCluster(final String id, final String title, @@ -56,4 +56,8 @@ public class TopicCluster implements Serializable { public Media getCoverMedia() { return coverMedia; } + + public void setCoverMedia(final Media coverMedia) { + this.coverMedia = coverMedia; + } } diff --git a/app/src/main/java/awais/instagrabber/utils/Constants.java b/app/src/main/java/awais/instagrabber/utils/Constants.java index 9f79641e..357b4c24 100644 --- a/app/src/main/java/awais/instagrabber/utils/Constants.java +++ b/app/src/main/java/awais/instagrabber/utils/Constants.java @@ -3,45 +3,13 @@ package awais.instagrabber.utils; public final class Constants { public static final String CRASH_REPORT_EMAIL = "barinsta@austinhuang.me"; - // string prefs - public static final String FOLDER_PATH = "custom_path"; - public static final String DATE_TIME_FORMAT = "date_time_format"; - public static final String DATE_TIME_SELECTION = "date_time_selection"; - public static final String CUSTOM_DATE_TIME_FORMAT = "date_time_custom_format"; - public static final String APP_THEME = "app_theme_v19"; - public static final String APP_LANGUAGE = "app_language_v19"; - public static final String STORY_SORT = "story_sort"; - // set string prefs - public static final String KEYWORD_FILTERS = "keyword_filters"; // int prefs, do not export public static final String PREV_INSTALL_VERSION = "prevVersion"; public static final String BROWSER_UA_CODE = "browser_ua_code"; public static final String APP_UA_CODE = "app_ua_code"; - // boolean prefs - public static final String DOWNLOAD_USER_FOLDER = "download_user_folder"; - public static final String TOGGLE_KEYWORD_FILTER = "toggle_keyword_filter"; - public static final String DOWNLOAD_PREPEND_USER_NAME = "download_user_name"; - public static final String PLAY_IN_BACKGROUND = "play_in_background"; - // deprecated: public static final String BOTTOM_TOOLBAR = "bottom_toolbar"; - public static final String FOLDER_SAVE_TO = "saved_to"; - public static final String AUTOPLAY_VIDEOS = "autoplay_videos"; - public static final String MUTED_VIDEOS = "muted_videos"; - public static final String SHOW_CAPTIONS = "show_captions"; - public static final String CUSTOM_DATE_TIME_FORMAT_ENABLED = "data_time_custom_enabled"; - public static final String SWAP_DATE_TIME_FORMAT_ENABLED = "swap_date_time_enabled"; - public static final String MARK_AS_SEEN = "mark_as_seen"; - public static final String HIDE_MUTED_REELS = "hide_muted_reels"; - public static final String DM_MARK_AS_SEEN = "dm_mark_as_seen"; - // deprecated: public static final String INSTADP = "instadp"; - // deprecated: public static final String STORIESIG = "storiesig"; - // deprecated: public static final String STORY_VIEWER = "story_viewer"; - // deprecated: public static final String AMOLED_THEME = "amoled_theme"; - public static final String CHECK_ACTIVITY = "check_activity"; - public static final String CHECK_UPDATES = "check_updates"; - public static final String FLAG_SECURE = "flag_secure"; // never Export public static final String COOKIE = "cookie"; - public static final String SHOW_QUICK_ACCESS_DIALOG = "show_quick_dlg"; + // deprecated: public static final String SHOW_QUICK_ACCESS_DIALOG = "show_quick_dlg"; public static final String DEVICE_UUID = "device_uuid"; public static final String BROWSER_UA = "browser_ua"; public static final String APP_UA = "app_ua"; diff --git a/app/src/main/java/awais/instagrabber/utils/DownloadUtils.java b/app/src/main/java/awais/instagrabber/utils/DownloadUtils.java index 18bf59c7..be24dd48 100644 --- a/app/src/main/java/awais/instagrabber/utils/DownloadUtils.java +++ b/app/src/main/java/awais/instagrabber/utils/DownloadUtils.java @@ -33,6 +33,7 @@ import java.util.UUID; import java.util.regex.Pattern; import awais.instagrabber.R; +import awais.instagrabber.fragments.settings.PreferenceKeys; import awais.instagrabber.models.StoryModel; import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.repositories.responses.Audio; @@ -41,8 +42,8 @@ import awais.instagrabber.repositories.responses.User; import awais.instagrabber.repositories.responses.VideoVersion; import awais.instagrabber.workers.DownloadWorker; -import static awais.instagrabber.utils.Constants.FOLDER_PATH; -import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO; +import static awais.instagrabber.fragments.settings.PreferenceKeys.FOLDER_PATH; +import static awais.instagrabber.fragments.settings.PreferenceKeys.FOLDER_SAVE_TO; public final class DownloadUtils { private static final String TAG = "DownloadUtils"; @@ -74,7 +75,7 @@ public final class DownloadUtils { final boolean skipCreateDir) { File dir = getDownloadDir(); - if (Utils.settingsHelper.getBoolean(Constants.DOWNLOAD_USER_FOLDER) && !TextUtils.isEmpty(username)) { + if (Utils.settingsHelper.getBoolean(PreferenceKeys.DOWNLOAD_USER_FOLDER) && !TextUtils.isEmpty(username)) { final String finaleUsername = username.startsWith("@") ? username.substring(1) : username; dir = new File(dir, finaleUsername); } @@ -277,7 +278,7 @@ public final class DownloadUtils { : storyModel.getStoryUrl(); final String baseFileName = storyModel.getStoryMediaId() + "_" + storyModel.getTimestamp() + DownloadUtils.getFileExtensionFromUrl(url); - final String usernamePrepend = Utils.settingsHelper.getBoolean(Constants.DOWNLOAD_PREPEND_USER_NAME) + final String usernamePrepend = Utils.settingsHelper.getBoolean(PreferenceKeys.DOWNLOAD_PREPEND_USER_NAME) && storyModel.getUsername() != null ? storyModel.getUsername() + "_" : ""; final File saveFile = new File(downloadDir, usernamePrepend + baseFileName); @@ -318,7 +319,7 @@ public final class DownloadUtils { } if (!TextUtils.isEmpty(media.getCode())) { fileName = media.getCode(); - if (Utils.settingsHelper.getBoolean(Constants.DOWNLOAD_PREPEND_USER_NAME) && mediaUser != null) { + if (Utils.settingsHelper.getBoolean(PreferenceKeys.DOWNLOAD_PREPEND_USER_NAME) && mediaUser != null) { fileName = mediaUser.getUsername() + "_" + fileName; } } @@ -344,7 +345,7 @@ public final class DownloadUtils { } final Media child = sliderItems.get(i); final String url = getUrlOfType(child); - final String usernamePrepend = Utils.settingsHelper.getBoolean(Constants.DOWNLOAD_PREPEND_USER_NAME) && mediaUser != null ? mediaUser.getUsername() : ""; + final String usernamePrepend = Utils.settingsHelper.getBoolean(PreferenceKeys.DOWNLOAD_PREPEND_USER_NAME) && mediaUser != null ? mediaUser.getUsername() : ""; final File file = getDownloadChildSaveFile(downloadDir, media.getCode(), i + 1, url, usernamePrepend); map.put(url, file.getAbsolutePath()); } diff --git a/app/src/main/java/awais/instagrabber/utils/LocaleUtils.java b/app/src/main/java/awais/instagrabber/utils/LocaleUtils.java index 960bd8a6..bdf00582 100755 --- a/app/src/main/java/awais/instagrabber/utils/LocaleUtils.java +++ b/app/src/main/java/awais/instagrabber/utils/LocaleUtils.java @@ -9,6 +9,8 @@ import androidx.annotation.Nullable; import java.util.Locale; +import awais.instagrabber.fragments.settings.PreferenceKeys; + // taken from my app TESV Console Codes public final class LocaleUtils { private static Locale defaultLocale, currentLocale; @@ -22,7 +24,7 @@ public final class LocaleUtils { if (Utils.settingsHelper == null) Utils.settingsHelper = new SettingsHelper(baseContext); - final String appLanguageSettings = Utils.settingsHelper.getString(Constants.APP_LANGUAGE); + final String appLanguageSettings = Utils.settingsHelper.getString(PreferenceKeys.APP_LANGUAGE); final String lang = LocaleUtils.getCorrespondingLanguageCode(appLanguageSettings); currentLocale = TextUtils.isEmpty(lang) ? defaultLocale : diff --git a/app/src/main/java/awais/instagrabber/utils/SettingsHelper.java b/app/src/main/java/awais/instagrabber/utils/SettingsHelper.java index d98e6b37..74c69b9c 100755 --- a/app/src/main/java/awais/instagrabber/utils/SettingsHelper.java +++ b/app/src/main/java/awais/instagrabber/utils/SettingsHelper.java @@ -18,33 +18,33 @@ import static awais.instagrabber.fragments.settings.PreferenceKeys.PREF_ENABLE_D import static awais.instagrabber.fragments.settings.PreferenceKeys.PREF_ENABLE_SENTRY; import static awais.instagrabber.fragments.settings.PreferenceKeys.PREF_SHOWN_COUNT_TOOLTIP; import static awais.instagrabber.fragments.settings.PreferenceKeys.PREF_TAB_ORDER; -import static awais.instagrabber.utils.Constants.APP_LANGUAGE; -import static awais.instagrabber.utils.Constants.APP_THEME; +import static awais.instagrabber.fragments.settings.PreferenceKeys.APP_LANGUAGE; +import static awais.instagrabber.fragments.settings.PreferenceKeys.APP_THEME; import static awais.instagrabber.utils.Constants.APP_UA; import static awais.instagrabber.utils.Constants.APP_UA_CODE; -import static awais.instagrabber.utils.Constants.AUTOPLAY_VIDEOS; +import static awais.instagrabber.fragments.settings.PreferenceKeys.AUTOPLAY_VIDEOS; import static awais.instagrabber.utils.Constants.BROWSER_UA; import static awais.instagrabber.utils.Constants.BROWSER_UA_CODE; -import static awais.instagrabber.utils.Constants.CHECK_ACTIVITY; -import static awais.instagrabber.utils.Constants.CHECK_UPDATES; +import static awais.instagrabber.fragments.settings.PreferenceKeys.CHECK_ACTIVITY; +import static awais.instagrabber.fragments.settings.PreferenceKeys.CHECK_UPDATES; import static awais.instagrabber.utils.Constants.COOKIE; -import static awais.instagrabber.utils.Constants.CUSTOM_DATE_TIME_FORMAT; -import static awais.instagrabber.utils.Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED; -import static awais.instagrabber.utils.Constants.DATE_TIME_FORMAT; -import static awais.instagrabber.utils.Constants.DATE_TIME_SELECTION; +import static awais.instagrabber.fragments.settings.PreferenceKeys.CUSTOM_DATE_TIME_FORMAT; +import static awais.instagrabber.fragments.settings.PreferenceKeys.CUSTOM_DATE_TIME_FORMAT_ENABLED; +import static awais.instagrabber.fragments.settings.PreferenceKeys.DATE_TIME_FORMAT; +import static awais.instagrabber.fragments.settings.PreferenceKeys.DATE_TIME_SELECTION; import static awais.instagrabber.utils.Constants.DEFAULT_TAB; import static awais.instagrabber.utils.Constants.DEVICE_UUID; -import static awais.instagrabber.utils.Constants.DM_MARK_AS_SEEN; -import static awais.instagrabber.utils.Constants.DOWNLOAD_PREPEND_USER_NAME; -import static awais.instagrabber.utils.Constants.DOWNLOAD_USER_FOLDER; -import static awais.instagrabber.utils.Constants.FLAG_SECURE; -import static awais.instagrabber.utils.Constants.FOLDER_PATH; -import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO; -import static awais.instagrabber.utils.Constants.HIDE_MUTED_REELS; -import static awais.instagrabber.utils.Constants.KEYWORD_FILTERS; -import static awais.instagrabber.utils.Constants.MARK_AS_SEEN; -import static awais.instagrabber.utils.Constants.MUTED_VIDEOS; -import static awais.instagrabber.utils.Constants.PLAY_IN_BACKGROUND; +import static awais.instagrabber.fragments.settings.PreferenceKeys.DM_MARK_AS_SEEN; +import static awais.instagrabber.fragments.settings.PreferenceKeys.DOWNLOAD_PREPEND_USER_NAME; +import static awais.instagrabber.fragments.settings.PreferenceKeys.DOWNLOAD_USER_FOLDER; +import static awais.instagrabber.fragments.settings.PreferenceKeys.FLAG_SECURE; +import static awais.instagrabber.fragments.settings.PreferenceKeys.FOLDER_PATH; +import static awais.instagrabber.fragments.settings.PreferenceKeys.FOLDER_SAVE_TO; +import static awais.instagrabber.fragments.settings.PreferenceKeys.HIDE_MUTED_REELS; +import static awais.instagrabber.fragments.settings.PreferenceKeys.KEYWORD_FILTERS; +import static awais.instagrabber.fragments.settings.PreferenceKeys.MARK_AS_SEEN; +import static awais.instagrabber.fragments.settings.PreferenceKeys.MUTED_VIDEOS; +import static awais.instagrabber.fragments.settings.PreferenceKeys.PLAY_IN_BACKGROUND; import static awais.instagrabber.utils.Constants.PREF_DARK_THEME; import static awais.instagrabber.utils.Constants.PREF_EMOJI_VARIANTS; import static awais.instagrabber.utils.Constants.PREF_HASHTAG_POSTS_LAYOUT; @@ -58,12 +58,12 @@ import static awais.instagrabber.utils.Constants.PREF_SAVED_POSTS_LAYOUT; import static awais.instagrabber.utils.Constants.PREF_TAGGED_POSTS_LAYOUT; import static awais.instagrabber.utils.Constants.PREF_TOPIC_POSTS_LAYOUT; import static awais.instagrabber.utils.Constants.PREV_INSTALL_VERSION; -import static awais.instagrabber.utils.Constants.SHOW_CAPTIONS; -import static awais.instagrabber.utils.Constants.SHOW_QUICK_ACCESS_DIALOG; +import static awais.instagrabber.fragments.settings.PreferenceKeys.PREF_SEARCH_FOCUS_KEYBOARD; +import static awais.instagrabber.fragments.settings.PreferenceKeys.SHOW_CAPTIONS; import static awais.instagrabber.utils.Constants.SKIPPED_VERSION; -import static awais.instagrabber.utils.Constants.STORY_SORT; -import static awais.instagrabber.utils.Constants.SWAP_DATE_TIME_FORMAT_ENABLED; -import static awais.instagrabber.utils.Constants.TOGGLE_KEYWORD_FILTER; +import static awais.instagrabber.fragments.settings.PreferenceKeys.STORY_SORT; +import static awais.instagrabber.fragments.settings.PreferenceKeys.SWAP_DATE_TIME_FORMAT_ENABLED; +import static awais.instagrabber.fragments.settings.PreferenceKeys.TOGGLE_KEYWORD_FILTER; public final class SettingsHelper { private final SharedPreferences sharedPreferences; @@ -155,18 +155,18 @@ public final class SettingsHelper { return sharedPreferences != null && sharedPreferences.contains(key); } - @StringDef( - {APP_LANGUAGE, APP_THEME, APP_UA, BROWSER_UA, COOKIE, FOLDER_PATH, DATE_TIME_FORMAT, DATE_TIME_SELECTION, + @StringDef({APP_LANGUAGE, APP_THEME, APP_UA, BROWSER_UA, COOKIE, FOLDER_PATH, DATE_TIME_FORMAT, DATE_TIME_SELECTION, CUSTOM_DATE_TIME_FORMAT, DEVICE_UUID, SKIPPED_VERSION, DEFAULT_TAB, PREF_DARK_THEME, PREF_LIGHT_THEME, PREF_POSTS_LAYOUT, PREF_PROFILE_POSTS_LAYOUT, PREF_TOPIC_POSTS_LAYOUT, PREF_HASHTAG_POSTS_LAYOUT, PREF_LOCATION_POSTS_LAYOUT, PREF_LIKED_POSTS_LAYOUT, PREF_TAGGED_POSTS_LAYOUT, PREF_SAVED_POSTS_LAYOUT, STORY_SORT, PREF_EMOJI_VARIANTS, PREF_REACTIONS, PREF_ENABLE_DM_AUTO_REFRESH_FREQ_UNIT, PREF_TAB_ORDER}) public @interface StringSettings {} - @StringDef({DOWNLOAD_USER_FOLDER, DOWNLOAD_PREPEND_USER_NAME, FOLDER_SAVE_TO, AUTOPLAY_VIDEOS, SHOW_QUICK_ACCESS_DIALOG, MUTED_VIDEOS, + @StringDef({DOWNLOAD_USER_FOLDER, DOWNLOAD_PREPEND_USER_NAME, FOLDER_SAVE_TO, AUTOPLAY_VIDEOS, MUTED_VIDEOS, SHOW_CAPTIONS, CUSTOM_DATE_TIME_FORMAT_ENABLED, MARK_AS_SEEN, DM_MARK_AS_SEEN, CHECK_ACTIVITY, CHECK_UPDATES, SWAP_DATE_TIME_FORMAT_ENABLED, PREF_ENABLE_DM_NOTIFICATIONS, PREF_ENABLE_DM_AUTO_REFRESH, - FLAG_SECURE, TOGGLE_KEYWORD_FILTER, PREF_ENABLE_SENTRY, HIDE_MUTED_REELS, PLAY_IN_BACKGROUND, PREF_SHOWN_COUNT_TOOLTIP}) + FLAG_SECURE, TOGGLE_KEYWORD_FILTER, PREF_ENABLE_SENTRY, HIDE_MUTED_REELS, PLAY_IN_BACKGROUND, + PREF_SHOWN_COUNT_TOOLTIP, PREF_SEARCH_FOCUS_KEYBOARD}) public @interface BooleanSettings {} @StringDef({PREV_INSTALL_VERSION, BROWSER_UA_CODE, APP_UA_CODE, PREF_ENABLE_DM_AUTO_REFRESH_FREQ_NUMBER}) diff --git a/app/src/main/java/awais/instagrabber/utils/TextUtils.java b/app/src/main/java/awais/instagrabber/utils/TextUtils.java index 448c2a90..5df3ac08 100644 --- a/app/src/main/java/awais/instagrabber/utils/TextUtils.java +++ b/app/src/main/java/awais/instagrabber/utils/TextUtils.java @@ -10,11 +10,13 @@ import android.util.Patterns; import androidx.annotation.NonNull; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.regex.Matcher; +import java.util.stream.Collectors; public final class TextUtils { // extracted from String class @@ -106,4 +108,15 @@ public final class TextUtils { } return urls; } + + // https://github.com/notslang/instagram-id-to-url-segment + public static long shortcodeToId(final String shortcode) { + long result = 0L; + for (int i = 0; i < shortcode.length() && i < 11; i++){ + final char c = shortcode.charAt(i); + final int k = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".indexOf(c); + result = result * 64 + k; + } + return result; + } } diff --git a/app/src/main/java/awais/instagrabber/webservices/StoriesService.java b/app/src/main/java/awais/instagrabber/webservices/StoriesService.java index 96e9bc7d..9b6a2f49 100644 --- a/app/src/main/java/awais/instagrabber/webservices/StoriesService.java +++ b/app/src/main/java/awais/instagrabber/webservices/StoriesService.java @@ -17,12 +17,12 @@ import java.util.Map; import java.util.Objects; import java.util.UUID; +import awais.instagrabber.fragments.settings.PreferenceKeys; import awais.instagrabber.models.FeedStoryModel; import awais.instagrabber.models.HighlightModel; import awais.instagrabber.models.StoryModel; import awais.instagrabber.repositories.StoriesRepository; import awais.instagrabber.repositories.requests.StoryViewerOptions; -import awais.instagrabber.repositories.responses.FriendshipStatus; import awais.instagrabber.repositories.responses.StoryStickerResponse; import awais.instagrabber.repositories.responses.User; import awais.instagrabber.utils.Constants; @@ -135,7 +135,7 @@ public class StoriesService extends BaseService { final JSONArray feedStoriesReel = new JSONObject(body).getJSONArray("tray"); for (int i = 0; i < feedStoriesReel.length(); ++i) { final JSONObject node = feedStoriesReel.getJSONObject(i); - if (node.optBoolean("hide_from_feed_unit") && Utils.settingsHelper.getBoolean(Constants.HIDE_MUTED_REELS)) continue; + if (node.optBoolean("hide_from_feed_unit") && Utils.settingsHelper.getBoolean(PreferenceKeys.HIDE_MUTED_REELS)) continue; final JSONObject userJson = node.getJSONObject(node.has("user") ? "user" : "owner"); try { final User user = new User(userJson.getLong("pk"), @@ -505,7 +505,7 @@ public class StoriesService extends BaseService { final List listCopy = new ArrayList<>(list); Collections.sort(listCopy, (o1, o2) -> { int result; - switch (Utils.settingsHelper.getString(Constants.STORY_SORT)) { + switch (Utils.settingsHelper.getString(PreferenceKeys.STORY_SORT)) { case "1": result = Long.compare(o2.getTimestamp(), o1.getTimestamp()); break; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8c59762e..1a841598 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -235,7 +235,7 @@ Approve request Reject request Share this public post to… - This is a private post! Share to those who can view them! + This is a private post! Share to those who can view it. This category is somehow empty… An update is available! (%s) Reminder: If you downloaded from F-Droid, you must update from it! Same applies for GitHub. @@ -269,6 +269,7 @@ Do not show again until next update Version Start screen + Show keyboard on search General Theme Downloads @@ -505,4 +506,5 @@ No Map app found! Click to view full count No profile pic found! + Are you sure you want to open this link? diff --git a/app/src/test/java/awais/instagrabber/utils/IntentUtilsTest.java b/app/src/test/java/awais/instagrabber/utils/IntentUtilsTest.java new file mode 100644 index 00000000..c9cbc6bb --- /dev/null +++ b/app/src/test/java/awais/instagrabber/utils/IntentUtilsTest.java @@ -0,0 +1,28 @@ +// java.lang.RuntimeException: Method parse in android.net.Uri not mocked. +// See http://g.co/androidstudio/not-mocked for details. + +package awais.instagrabber.utils; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import awais.instagrabber.models.IntentModel; +import awais.instagrabber.models.enums.IntentModelType; + +class IntentUtilsTest { + + @Test + void getIntentFromUrl() { + IntentModel intent = IntentUtils.parseUrl("https://instagr.am/austinhuang.me"); + Assertions.assertEquals(new IntentModel(IntentModelType.USERNAME, "austinhuang.me"), intent); + intent = IntentUtils.parseUrl("https://www.instagr.am/_u/austinhuang.me"); + Assertions.assertEquals(new IntentModel(IntentModelType.USERNAME, "austinhuang.me"), intent); + intent = IntentUtils.parseUrl("https://instagram.com/p/BmjKdkxjzO7/"); + Assertions.assertEquals(new IntentModel(IntentModelType.POST, "BmjKdkxjzO7"), intent); + intent = IntentUtils.parseUrl("https://www.instagram.com/explore/tags/metrodemontreal/"); + Assertions.assertEquals(new IntentModel(IntentModelType.HASHTAG, "metrodemontreal"), intent); + intent = IntentUtils.parseUrl("http://www.instagram.com/explore/locations/538444610/abcde"); + Assertions.assertEquals(new IntentModel(IntentModelType.LOCATION, "538444610"), intent); + // todo: reel and igtv test cases that are sfw and preferably n i c e + } +} \ No newline at end of file diff --git a/app/src/test/java/awais/instagrabber/utils/TextUtilsTest.java b/app/src/test/java/awais/instagrabber/utils/TextUtilsTest.java index cf69eb07..00d3f71d 100644 --- a/app/src/test/java/awais/instagrabber/utils/TextUtilsTest.java +++ b/app/src/test/java/awais/instagrabber/utils/TextUtilsTest.java @@ -1,10 +1,11 @@ package awais.instagrabber.utils; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; class TextUtilsTest { - @org.junit.jupiter.api.Test + @Test void testMillisToTimeString() { String timeString = TextUtils.millisToTimeString(18000000); Assertions.assertEquals("05:00:00", timeString); @@ -15,4 +16,12 @@ class TextUtilsTest { timeString = TextUtils.millisToTimeString(300000, true); Assertions.assertEquals("00:05:00", timeString); } + + @Test + void testShortcodeConversion() { + long conversion = TextUtils.shortcodeToId("CA0YnOonSfS"); + Assertions.assertEquals(2320587956892280786L, conversion); + conversion = TextUtils.shortcodeToId("B_7n8mblwx6gv1ZaNvA5ZhAs2qslMnRiMMYW1c0"); + Assertions.assertEquals(2304611322577751162L, conversion); + } } \ No newline at end of file