Two new options: Long Press on Post (Non-Media Area) and Long Press on Media in Settings->Gestures & Buttons. SharedPreferencesLiveData.

This commit is contained in:
Docile-Alligator 2025-07-07 10:53:02 -04:00
parent f0f3719fdc
commit ba99e7e55e
14 changed files with 377 additions and 34 deletions

View File

@ -22,6 +22,7 @@ import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.Window; import android.view.Window;
@ -43,6 +44,8 @@ import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayout;
import org.greenrobot.eventbus.EventBus;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Locale; import java.util.Locale;
@ -51,6 +54,7 @@ import ml.docilealligator.infinityforreddit.R;
import ml.docilealligator.infinityforreddit.account.Account; import ml.docilealligator.infinityforreddit.account.Account;
import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper;
import ml.docilealligator.infinityforreddit.customviews.slidr.widget.SliderPanel; import ml.docilealligator.infinityforreddit.customviews.slidr.widget.SliderPanel;
import ml.docilealligator.infinityforreddit.events.FinishViewMediaActivityEvent;
import ml.docilealligator.infinityforreddit.font.ContentFontFamily; import ml.docilealligator.infinityforreddit.font.ContentFontFamily;
import ml.docilealligator.infinityforreddit.font.ContentFontStyle; import ml.docilealligator.infinityforreddit.font.ContentFontStyle;
import ml.docilealligator.infinityforreddit.font.FontFamily; import ml.docilealligator.infinityforreddit.font.FontFamily;
@ -71,6 +75,7 @@ public abstract class BaseActivity extends AppCompatActivity implements CustomFo
private boolean isImmersiveInterfaceApplicable = true; private boolean isImmersiveInterfaceApplicable = true;
private int systemVisibilityToolbarExpanded = 0; private int systemVisibilityToolbarExpanded = 0;
private int systemVisibilityToolbarCollapsed = 0; private int systemVisibilityToolbarCollapsed = 0;
private boolean shouldTrackFullscreenMediaPeekTouchEvent;
public CustomThemeWrapper customThemeWrapper; public CustomThemeWrapper customThemeWrapper;
public Typeface typeface; public Typeface typeface;
public Typeface titleTypeface; public Typeface titleTypeface;
@ -261,6 +266,18 @@ public abstract class BaseActivity extends AppCompatActivity implements CustomFo
mHandler.removeCallbacksAndMessages(null); mHandler.removeCallbacksAndMessages(null);
} }
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (shouldTrackFullscreenMediaPeekTouchEvent) {
if (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP) {
shouldTrackFullscreenMediaPeekTouchEvent = false;
EventBus.getDefault().post(new FinishViewMediaActivityEvent());
}
return true;
}
return super.dispatchTouchEvent(ev);
}
public abstract SharedPreferences getDefaultSharedPreferences(); public abstract SharedPreferences getDefaultSharedPreferences();
public abstract SharedPreferences getCurrentAccountSharedPreferences(); public abstract SharedPreferences getCurrentAccountSharedPreferences();
@ -527,4 +544,8 @@ public abstract class BaseActivity extends AppCompatActivity implements CustomFo
public void triggerBackPress() { public void triggerBackPress() {
getOnBackPressedDispatcher().onBackPressed(); getOnBackPressedDispatcher().onBackPressed();
} }
public void setShouldTrackFullscreenMediaPeekTouchEvent(boolean value) {
shouldTrackFullscreenMediaPeekTouchEvent = value;
}
} }

View File

@ -47,6 +47,9 @@ import com.github.piasy.biv.BigImageViewer;
import com.github.piasy.biv.loader.ImageLoader; import com.github.piasy.biv.loader.ImageLoader;
import com.github.piasy.biv.loader.glide.GlideImageLoader; import com.github.piasy.biv.loader.glide.GlideImageLoader;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import java.io.File; import java.io.File;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@ -68,6 +71,7 @@ import ml.docilealligator.infinityforreddit.customviews.slidr.Slidr;
import ml.docilealligator.infinityforreddit.customviews.slidr.model.SlidrConfig; import ml.docilealligator.infinityforreddit.customviews.slidr.model.SlidrConfig;
import ml.docilealligator.infinityforreddit.customviews.slidr.model.SlidrPosition; import ml.docilealligator.infinityforreddit.customviews.slidr.model.SlidrPosition;
import ml.docilealligator.infinityforreddit.databinding.ActivityViewImageOrGifBinding; import ml.docilealligator.infinityforreddit.databinding.ActivityViewImageOrGifBinding;
import ml.docilealligator.infinityforreddit.events.FinishViewMediaActivityEvent;
import ml.docilealligator.infinityforreddit.font.ContentFontFamily; import ml.docilealligator.infinityforreddit.font.ContentFontFamily;
import ml.docilealligator.infinityforreddit.font.ContentFontStyle; import ml.docilealligator.infinityforreddit.font.ContentFontStyle;
import ml.docilealligator.infinityforreddit.font.FontFamily; import ml.docilealligator.infinityforreddit.font.FontFamily;
@ -136,6 +140,8 @@ public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWa
binding = ActivityViewImageOrGifBinding.inflate(getLayoutInflater()); binding = ActivityViewImageOrGifBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot()); setContentView(binding.getRoot());
EventBus.getDefault().register(this);
getWindow().getDecorView().setSystemUiVisibility( getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
@ -541,12 +547,18 @@ public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWa
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); EventBus.getDefault().unregister(this);
BigImageViewer.imageLoader().cancelAll(); BigImageViewer.imageLoader().cancelAll();
super.onDestroy();
} }
@Override @Override
public void setCustomFont(Typeface typeface, Typeface titleTypeface, Typeface contentTypeface) { public void setCustomFont(Typeface typeface, Typeface titleTypeface, Typeface contentTypeface) {
this.typeface = typeface; this.typeface = typeface;
} }
@Subscribe
public void onFinishViewMediaActivityEvent(FinishViewMediaActivityEvent e) {
finish();
}
} }

View File

@ -30,6 +30,9 @@ import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter; import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager; import androidx.viewpager.widget.ViewPager;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@ -43,6 +46,7 @@ import ml.docilealligator.infinityforreddit.R;
import ml.docilealligator.infinityforreddit.SetAsWallpaperCallback; import ml.docilealligator.infinityforreddit.SetAsWallpaperCallback;
import ml.docilealligator.infinityforreddit.WallpaperSetter; import ml.docilealligator.infinityforreddit.WallpaperSetter;
import ml.docilealligator.infinityforreddit.databinding.ActivityViewRedditGalleryBinding; import ml.docilealligator.infinityforreddit.databinding.ActivityViewRedditGalleryBinding;
import ml.docilealligator.infinityforreddit.events.FinishViewMediaActivityEvent;
import ml.docilealligator.infinityforreddit.font.ContentFontFamily; import ml.docilealligator.infinityforreddit.font.ContentFontFamily;
import ml.docilealligator.infinityforreddit.font.ContentFontStyle; import ml.docilealligator.infinityforreddit.font.ContentFontStyle;
import ml.docilealligator.infinityforreddit.font.FontFamily; import ml.docilealligator.infinityforreddit.font.FontFamily;
@ -135,6 +139,8 @@ public class ViewRedditGalleryActivity extends AppCompatActivity implements SetA
binding = ActivityViewRedditGalleryBinding.inflate(getLayoutInflater()); binding = ActivityViewRedditGalleryBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot()); setContentView(binding.getRoot());
EventBus.getDefault().register(this);
useBottomAppBar = sharedPreferences.getBoolean(SharedPreferencesUtils.USE_BOTTOM_TOOLBAR_IN_MEDIA_VIEWER, false); useBottomAppBar = sharedPreferences.getBoolean(SharedPreferencesUtils.USE_BOTTOM_TOOLBAR_IN_MEDIA_VIEWER, false);
if (!useBottomAppBar) { if (!useBottomAppBar) {
@ -304,6 +310,11 @@ public class ViewRedditGalleryActivity extends AppCompatActivity implements SetA
this.isActionBarHidden = isActionBarHidden; this.isActionBarHidden = isActionBarHidden;
} }
@Subscribe
public void onFinishViewMediaActivityEvent(FinishViewMediaActivityEvent e) {
finish();
}
private class SectionsPagerAdapter extends FragmentStatePagerAdapter { private class SectionsPagerAdapter extends FragmentStatePagerAdapter {
SectionsPagerAdapter(@NonNull FragmentManager fm) { SectionsPagerAdapter(@NonNull FragmentManager fm) {

View File

@ -81,6 +81,8 @@ import com.otaliastudios.zoom.ZoomEngine;
import com.otaliastudios.zoom.ZoomSurfaceView; import com.otaliastudios.zoom.ZoomSurfaceView;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@ -99,6 +101,7 @@ import ml.docilealligator.infinityforreddit.bottomsheetfragments.PlaybackSpeedBo
import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper;
import ml.docilealligator.infinityforreddit.databinding.ActivityViewVideoBinding; import ml.docilealligator.infinityforreddit.databinding.ActivityViewVideoBinding;
import ml.docilealligator.infinityforreddit.databinding.ActivityViewVideoZoomableBinding; import ml.docilealligator.infinityforreddit.databinding.ActivityViewVideoZoomableBinding;
import ml.docilealligator.infinityforreddit.events.FinishViewMediaActivityEvent;
import ml.docilealligator.infinityforreddit.font.ContentFontFamily; import ml.docilealligator.infinityforreddit.font.ContentFontFamily;
import ml.docilealligator.infinityforreddit.font.ContentFontStyle; import ml.docilealligator.infinityforreddit.font.ContentFontStyle;
import ml.docilealligator.infinityforreddit.font.FontFamily; import ml.docilealligator.infinityforreddit.font.FontFamily;
@ -285,6 +288,8 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
setContentView(binding.getRoot()); setContentView(binding.getRoot());
} }
EventBus.getDefault().register(this);
applyCustomTheme(); applyCustomTheme();
setVolumeControlStream(AudioManager.STREAM_MUSIC); setVolumeControlStream(AudioManager.STREAM_MUSIC);
@ -905,6 +910,7 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
@Override @Override
protected void onDestroy() { protected void onDestroy() {
EventBus.getDefault().unregister(this);
super.onDestroy(); super.onDestroy();
player.seekToDefaultPosition(); player.seekToDefaultPosition();
player.stop(); player.stop();
@ -1052,4 +1058,9 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
public void setCustomFont(Typeface typeface, Typeface titleTypeface, Typeface contentTypeface) { public void setCustomFont(Typeface typeface, Typeface titleTypeface, Typeface contentTypeface) {
this.typeface = typeface; this.typeface = typeface;
} }
@Subscribe
public void onFinishViewMediaActivityEvent(FinishViewMediaActivityEvent e) {
finish();
}
} }

View File

@ -10,6 +10,7 @@ import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.view.HapticFeedbackConstants;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
@ -255,6 +256,8 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
private boolean mFixedHeightPreviewInCard; private boolean mFixedHeightPreviewInCard;
private boolean mHideTextPostContent; private boolean mHideTextPostContent;
private boolean mEasierToWatchInFullScreen; private boolean mEasierToWatchInFullScreen;
private String mLongPressPostNonMediaAreaAction = SharedPreferencesUtils.LONG_PRESS_POST_VALUE_SHOW_POST_OPTIONS;
private String mLongPressPostMediaAction = SharedPreferencesUtils.LONG_PRESS_POST_VALUE_SHOW_POST_OPTIONS;
private boolean mHandleReadPost; private boolean mHandleReadPost;
private ExoCreator mExoCreator; private ExoCreator mExoCreator;
private Callback mCallback; private Callback mCallback;
@ -1567,6 +1570,14 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
this.mEasierToWatchInFullScreen = easierToWatchInFullScreen; this.mEasierToWatchInFullScreen = easierToWatchInFullScreen;
} }
public void setLongPressPostNonMediaAreaAction(String value) {
mLongPressPostNonMediaAreaAction = value;
}
public void setLongPressPostMediaAction(String value) {
mLongPressPostMediaAction = value;
}
@OptIn(markerClass = UnstableApi.class) @OptIn(markerClass = UnstableApi.class)
@Override @Override
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
@ -1766,21 +1777,31 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
} }
private void openMedia(Post post) { private void openMedia(Post post) {
openMedia(post, 0); openMedia(post, 0, false);
} }
private void openMedia(Post post, int galleryItemIndex) { private void openMedia(Post post, boolean peekMedia) {
openMedia(post, galleryItemIndex, -1); openMedia(post, 0, peekMedia);
}
private void openMedia(Post post, int galleryItemIndex, boolean peekMedia) {
openMedia(post, galleryItemIndex, -1, peekMedia);
} }
private void openMedia(Post post, long videoProgress) { private void openMedia(Post post, long videoProgress) {
openMedia(post, 0, videoProgress); openMedia(post, 0, videoProgress, false);
} }
private void openMedia(Post post, int galleryItemIndex, long videoProgress) { private void openMedia(Post post, long videoProgress, boolean peekMedia) {
openMedia(post, 0, videoProgress, peekMedia);
}
private void openMedia(Post post, int galleryItemIndex, long videoProgress, boolean peekMedia) {
if (canStartActivity) { if (canStartActivity) {
canStartActivity = false; canStartActivity = false;
if (post.getPostType() == Post.VIDEO_TYPE) { if (post.getPostType() == Post.VIDEO_TYPE) {
mActivity.setShouldTrackFullscreenMediaPeekTouchEvent(true);
Intent intent = new Intent(mActivity, ViewVideoActivity.class); Intent intent = new Intent(mActivity, ViewVideoActivity.class);
if (post.isImgur()) { if (post.isImgur()) {
intent.setData(Uri.parse(post.getVideoUrl())); intent.setData(Uri.parse(post.getVideoUrl()));
@ -1812,6 +1833,8 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, post.isNSFW()); intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, post.isNSFW());
mActivity.startActivity(intent); mActivity.startActivity(intent);
} else if (post.getPostType() == Post.IMAGE_TYPE) { } else if (post.getPostType() == Post.IMAGE_TYPE) {
mActivity.setShouldTrackFullscreenMediaPeekTouchEvent(true);
Intent intent = new Intent(mActivity, ViewImageOrGifActivity.class); Intent intent = new Intent(mActivity, ViewImageOrGifActivity.class);
intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, post.getUrl()); intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, post.getUrl());
intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, post.getSubredditName() intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, post.getSubredditName()
@ -1821,6 +1844,8 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
intent.putExtra(ViewImageOrGifActivity.EXTRA_IS_NSFW, post.isNSFW()); intent.putExtra(ViewImageOrGifActivity.EXTRA_IS_NSFW, post.isNSFW());
mActivity.startActivity(intent); mActivity.startActivity(intent);
} else if (post.getPostType() == Post.GIF_TYPE) { } else if (post.getPostType() == Post.GIF_TYPE) {
mActivity.setShouldTrackFullscreenMediaPeekTouchEvent(true);
if (post.getMp4Variant() != null) { if (post.getMp4Variant() != null) {
Intent intent = new Intent(mActivity, ViewVideoActivity.class); Intent intent = new Intent(mActivity, ViewVideoActivity.class);
intent.setData(Uri.parse(post.getMp4Variant())); intent.setData(Uri.parse(post.getMp4Variant()));
@ -1841,13 +1866,15 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
intent.putExtra(ViewImageOrGifActivity.EXTRA_IS_NSFW, post.isNSFW()); intent.putExtra(ViewImageOrGifActivity.EXTRA_IS_NSFW, post.isNSFW());
mActivity.startActivity(intent); mActivity.startActivity(intent);
} }
} else if (post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { } else if (!peekMedia && post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) {
Intent intent = new Intent(mActivity, LinkResolverActivity.class); Intent intent = new Intent(mActivity, LinkResolverActivity.class);
Uri uri = Uri.parse(post.getUrl()); Uri uri = Uri.parse(post.getUrl());
intent.setData(uri); intent.setData(uri);
intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, post.isNSFW()); intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, post.isNSFW());
mActivity.startActivity(intent); mActivity.startActivity(intent);
} else if (post.getPostType() == Post.GALLERY_TYPE) { } else if (post.getPostType() == Post.GALLERY_TYPE) {
mActivity.setShouldTrackFullscreenMediaPeekTouchEvent(true);
Intent intent = new Intent(mActivity, ViewRedditGalleryActivity.class); Intent intent = new Intent(mActivity, ViewRedditGalleryActivity.class);
intent.putExtra(ViewRedditGalleryActivity.EXTRA_POST, post); intent.putExtra(ViewRedditGalleryActivity.EXTRA_POST, post);
intent.putExtra(ViewRedditGalleryActivity.EXTRA_GALLERY_ITEM_INDEX, galleryItemIndex); intent.putExtra(ViewRedditGalleryActivity.EXTRA_GALLERY_ITEM_INDEX, galleryItemIndex);
@ -2936,23 +2963,32 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
itemView.setOnLongClickListener(v -> { itemView.setOnLongClickListener(v -> {
Post post = getItem(getBindingAdapterPosition()); Post post = getItem(getBindingAdapterPosition());
if (post == null) { if (post == null || mLongPressPostNonMediaAreaAction.equals(SharedPreferencesUtils.LONG_PRESS_POST_VALUE_NONE)) {
return false; return false;
} }
PostOptionsBottomSheetFragment postOptionsBottomSheetFragment; if (mLongPressPostNonMediaAreaAction.equals(SharedPreferencesUtils.LONG_PRESS_POST_VALUE_SHOW_POST_OPTIONS)) {
if (post.getPostType() == Post.GALLERY_TYPE && this instanceof PostBaseGalleryTypeViewHolder) { showPostOptions();
postOptionsBottomSheetFragment = PostOptionsBottomSheetFragment.newInstance(post, } else if (mLongPressPostNonMediaAreaAction.equals(SharedPreferencesUtils.LONG_PRESS_POST_VALUE_PREVIEW_IN_FULLSCREEN)) {
getBindingAdapterPosition(), markPostRead(post, true);
((LinearLayoutManagerBugFixed) ((PostBaseGalleryTypeViewHolder) this).galleryRecyclerView.getLayoutManager()).findFirstVisibleItemPosition()); openMedia(post, true);
} else {
postOptionsBottomSheetFragment = PostOptionsBottomSheetFragment.newInstance(post, getBindingAdapterPosition());
} }
postOptionsBottomSheetFragment.show(mActivity.getSupportFragmentManager(), postOptionsBottomSheetFragment.getTag());
return true; return true;
}); });
} }
void showPostOptions() {
PostOptionsBottomSheetFragment postOptionsBottomSheetFragment;
if (post.getPostType() == Post.GALLERY_TYPE && this instanceof PostBaseGalleryTypeViewHolder) {
postOptionsBottomSheetFragment = PostOptionsBottomSheetFragment.newInstance(post,
getBindingAdapterPosition(),
((LinearLayoutManagerBugFixed) ((PostBaseGalleryTypeViewHolder) this).galleryRecyclerView.getLayoutManager()).findFirstVisibleItemPosition());
} else {
postOptionsBottomSheetFragment = PostOptionsBottomSheetFragment.newInstance(post, getBindingAdapterPosition());
}
postOptionsBottomSheetFragment.show(mActivity.getSupportFragmentManager(), postOptionsBottomSheetFragment.getTag());
}
@Override @Override
void markPostRead(Post post, boolean changePostItemColor) { void markPostRead(Post post, boolean changePostItemColor) {
if (!mHandleReadPost) { if (!mHandleReadPost) {
@ -3318,7 +3354,17 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
} }
}); });
imageView.setOnLongClickListener(view -> itemView.performLongClick()); imageView.setOnLongClickListener(view -> {
if (mLongPressPostMediaAction.equals(SharedPreferencesUtils.LONG_PRESS_POST_VALUE_SHOW_POST_OPTIONS)) {
showPostOptions();
return true;
} else if (mLongPressPostMediaAction.equals(SharedPreferencesUtils.LONG_PRESS_POST_VALUE_PREVIEW_IN_FULLSCREEN)) {
markPostRead(post, true);
openMedia(post, true);
return true;
}
return false;
});
loadImageErrorTextView.setOnClickListener(view -> { loadImageErrorTextView.setOnClickListener(view -> {
loadingIndicator.setVisibility(View.VISIBLE); loadingIndicator.setVisibility(View.VISIBLE);
@ -3480,8 +3526,16 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
if (!dragged && !longPressed) { if (!dragged && !longPressed) {
if (System.currentTimeMillis() - downTime >= longClickThreshold) { if (System.currentTimeMillis() - downTime >= longClickThreshold) {
itemView.performLongClick(); if (mLongPressPostMediaAction.equals(SharedPreferencesUtils.LONG_PRESS_POST_VALUE_SHOW_POST_OPTIONS)) {
longPressed = true; galleryRecyclerView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
showPostOptions();
longPressed = true;
} else if (mLongPressPostMediaAction.equals(SharedPreferencesUtils.LONG_PRESS_POST_VALUE_PREVIEW_IN_FULLSCREEN)) {
galleryRecyclerView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
markPostRead(post, true);
openMedia(post, layoutManager.findFirstVisibleItemPosition(), true);
longPressed = true;
}
} }
} }
@ -3548,7 +3602,17 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
} }
}); });
noPreviewImageView.setOnLongClickListener(view -> itemView.performLongClick()); noPreviewImageView.setOnLongClickListener(view -> {
if (mLongPressPostMediaAction.equals(SharedPreferencesUtils.LONG_PRESS_POST_VALUE_SHOW_POST_OPTIONS)) {
showPostOptions();
return true;
} else if (mLongPressPostMediaAction.equals(SharedPreferencesUtils.LONG_PRESS_POST_VALUE_PREVIEW_IN_FULLSCREEN)) {
markPostRead(post, true);
openMedia(post, layoutManager.findFirstVisibleItemPosition(), true);
return true;
}
return false;
});
} }
public boolean isSwipeLocked() { public boolean isSwipeLocked() {
@ -3880,17 +3944,16 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
params.height = 0; params.height = 0;
bottomConstraintLayout.setLayoutParams(params); bottomConstraintLayout.setLayoutParams(params);
} }
} else { return true;
Post post = getItem(getBindingAdapterPosition()); } else if (mLongPressPostNonMediaAreaAction.equals(SharedPreferencesUtils.LONG_PRESS_POST_VALUE_SHOW_POST_OPTIONS)) {
if (post == null) { showPostOptions();
return false; return true;
} } else if (mLongPressPostNonMediaAreaAction.equals(SharedPreferencesUtils.LONG_PRESS_POST_VALUE_PREVIEW_IN_FULLSCREEN)) {
markPostRead(post, true);
PostOptionsBottomSheetFragment postOptionsBottomSheetFragment; openMedia(post, true);
postOptionsBottomSheetFragment = PostOptionsBottomSheetFragment.newInstance(post, getBindingAdapterPosition()); return true;
postOptionsBottomSheetFragment.show(mActivity.getSupportFragmentManager(), postOptionsBottomSheetFragment.getTag());
} }
return true; return false;
}); });
imageView.setOnClickListener(view -> { imageView.setOnClickListener(view -> {
@ -3905,10 +3968,24 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
} }
}); });
imageView.setOnLongClickListener(v -> {
if (mLongPressPostMediaAction.equals(SharedPreferencesUtils.LONG_PRESS_POST_VALUE_SHOW_POST_OPTIONS)) {
showPostOptions();
return true;
} else if (mLongPressPostMediaAction.equals(SharedPreferencesUtils.LONG_PRESS_POST_VALUE_PREVIEW_IN_FULLSCREEN)) {
markPostRead(post, true);
openMedia(post, true);
return true;
}
return false;
});
noPreviewLinkImageFrameLayout.setOnClickListener(view -> { noPreviewLinkImageFrameLayout.setOnClickListener(view -> {
imageView.performClick(); imageView.performClick();
}); });
noPreviewLinkImageFrameLayout.setOnLongClickListener(view -> imageView.performLongClick());
requestListener = new RequestListener<>() { requestListener = new RequestListener<>() {
@Override @Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, @NonNull Target<Drawable> target, boolean isFirstResource) { public boolean onLoadFailed(@Nullable GlideException e, Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
@ -3924,6 +4001,17 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
}; };
} }
void showPostOptions() {
Post post = getItem(getBindingAdapterPosition());
if (post == null) {
return;
}
PostOptionsBottomSheetFragment postOptionsBottomSheetFragment;
postOptionsBottomSheetFragment = PostOptionsBottomSheetFragment.newInstance(post, getBindingAdapterPosition());
postOptionsBottomSheetFragment.show(mActivity.getSupportFragmentManager(), postOptionsBottomSheetFragment.getTag());
}
@Override @Override
void setItemViewBackgroundColor(boolean isReadPost) { void setItemViewBackgroundColor(boolean isReadPost) {
itemView.setBackgroundColor(isReadPost ? mReadPostCardViewBackgroundColor : mCardViewBackgroundColor); itemView.setBackgroundColor(isReadPost ? mReadPostCardViewBackgroundColor : mCardViewBackgroundColor);

View File

@ -0,0 +1,22 @@
package ml.docilealligator.infinityforreddit.customviews
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import com.google.android.material.card.MaterialCardView
class TouchInterceptableMaterialCardView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : MaterialCardView(context, attrs) {
private var mShouldInterceptTouchEvent: Boolean = false
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
return mShouldInterceptTouchEvent || super.onInterceptTouchEvent(ev)
}
public fun setShouldInterceptTouch(value: Boolean) {
mShouldInterceptTouchEvent = value
}
}

View File

@ -0,0 +1,4 @@
package ml.docilealligator.infinityforreddit.events
class FinishViewMediaActivityEvent {
}

View File

@ -102,6 +102,7 @@ import ml.docilealligator.infinityforreddit.events.PostUpdateEventToPostList;
import ml.docilealligator.infinityforreddit.events.ShowDividerInCompactLayoutPreferenceEvent; import ml.docilealligator.infinityforreddit.events.ShowDividerInCompactLayoutPreferenceEvent;
import ml.docilealligator.infinityforreddit.events.ShowThumbnailOnTheLeftInCompactLayoutEvent; import ml.docilealligator.infinityforreddit.events.ShowThumbnailOnTheLeftInCompactLayoutEvent;
import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.post.Post;
import ml.docilealligator.infinityforreddit.utils.SharedPreferencesLiveDataKt;
import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils;
import ml.docilealligator.infinityforreddit.utils.Utils; import ml.docilealligator.infinityforreddit.utils.Utils;
import retrofit2.Retrofit; import retrofit2.Retrofit;
@ -340,6 +341,18 @@ public abstract class PostFragmentBase extends Fragment {
}); });
} }
SharedPreferencesLiveDataKt.stringLiveData(mSharedPreferences, SharedPreferencesUtils.LONG_PRESS_POST_NON_MEDIA_AREA, SharedPreferencesUtils.LONG_PRESS_POST_VALUE_SHOW_POST_OPTIONS).observe(getViewLifecycleOwner(), s -> {
if (getPostAdapter() != null) {
getPostAdapter().setLongPressPostNonMediaAreaAction(s);
}
});
SharedPreferencesLiveDataKt.stringLiveData(mSharedPreferences, SharedPreferencesUtils.LONG_PRESS_POST_MEDIA, SharedPreferencesUtils.LONG_PRESS_POST_VALUE_SHOW_POST_OPTIONS).observe(getViewLifecycleOwner(), s -> {
if (getPostAdapter() != null) {
getPostAdapter().setLongPressPostMediaAction(s);
}
});
return super.onCreateView(inflater, container, savedInstanceState); return super.onCreateView(inflater, container, savedInstanceState);
} }
@ -970,7 +983,6 @@ public abstract class PostFragmentBase extends Fragment {
int spanIndex = layoutParams.getSpanIndex(); int spanIndex = layoutParams.getSpanIndex();
int viewPosition = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewLayoutPosition();
if (parent.getAdapter() != null) { if (parent.getAdapter() != null) {
RecyclerView.ViewHolder viewHolder = parent.getChildViewHolder(view); RecyclerView.ViewHolder viewHolder = parent.getChildViewHolder(view);
if (viewHolder instanceof PostRecyclerViewAdapter.PostMaterial3CardVideoAutoplayViewHolder || if (viewHolder instanceof PostRecyclerViewAdapter.PostMaterial3CardVideoAutoplayViewHolder ||

View File

@ -0,0 +1,112 @@
package ml.docilealligator.infinityforreddit.utils
import android.content.SharedPreferences
import androidx.lifecycle.LiveData
abstract class SharedPreferenceLiveData<T>(
val sharedPrefs: SharedPreferences,
val key: String,
private val defValue: T
) : LiveData<T>() {
private val preferenceChangeListener =
SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
if (key == this.key) {
value = getValueFromPreferences(key, defValue)
}
}
abstract fun getValueFromPreferences(key: String, defValue: T): T
override fun onActive() {
super.onActive()
value = getValueFromPreferences(key, defValue)
sharedPrefs.registerOnSharedPreferenceChangeListener(preferenceChangeListener)
}
override fun onInactive() {
sharedPrefs.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener)
super.onInactive()
}
}
class SharedPreferenceIntLiveData(sharedPrefs: SharedPreferences, key: String, defValue: Int) :
SharedPreferenceLiveData<Int>(sharedPrefs, key, defValue) {
override fun getValueFromPreferences(key: String, defValue: Int): Int =
sharedPrefs.getInt(key, defValue)
}
class SharedPreferenceStringLiveData(
sharedPrefs: SharedPreferences,
key: String,
defValue: String
) :
SharedPreferenceLiveData<String>(sharedPrefs, key, defValue) {
override fun getValueFromPreferences(key: String, defValue: String): String =
sharedPrefs.getString(key, defValue)!!
}
class SharedPreferenceBooleanLiveData(
sharedPrefs: SharedPreferences,
key: String,
defValue: Boolean
) :
SharedPreferenceLiveData<Boolean>(sharedPrefs, key, defValue) {
override fun getValueFromPreferences(key: String, defValue: Boolean): Boolean =
sharedPrefs.getBoolean(key, defValue)
}
class SharedPreferenceFloatLiveData(sharedPrefs: SharedPreferences, key: String, defValue: Float) :
SharedPreferenceLiveData<Float>(sharedPrefs, key, defValue) {
override fun getValueFromPreferences(key: String, defValue: Float): Float =
sharedPrefs.getFloat(key, defValue)
}
class SharedPreferenceLongLiveData(sharedPrefs: SharedPreferences, key: String, defValue: Long) :
SharedPreferenceLiveData<Long>(sharedPrefs, key, defValue) {
override fun getValueFromPreferences(key: String, defValue: Long): Long =
sharedPrefs.getLong(key, defValue)
}
class SharedPreferenceStringSetLiveData(
sharedPrefs: SharedPreferences,
key: String,
defValue: Set<String>
) :
SharedPreferenceLiveData<Set<String>>(sharedPrefs, key, defValue) {
override fun getValueFromPreferences(key: String, defValue: Set<String>): Set<String> =
sharedPrefs.getStringSet(key, defValue)!!
}
fun SharedPreferences.intLiveData(key: String, defValue: Int): SharedPreferenceLiveData<Int> {
return SharedPreferenceIntLiveData(this, key, defValue)
}
fun SharedPreferences.stringLiveData(
key: String,
defValue: String
): SharedPreferenceLiveData<String> {
return SharedPreferenceStringLiveData(this, key, defValue)
}
fun SharedPreferences.booleanLiveData(
key: String,
defValue: Boolean
): SharedPreferenceLiveData<Boolean> {
return SharedPreferenceBooleanLiveData(this, key, defValue)
}
fun SharedPreferences.floatLiveData(key: String, defValue: Float): SharedPreferenceLiveData<Float> {
return SharedPreferenceFloatLiveData(this, key, defValue)
}
fun SharedPreferences.longLiveData(key: String, defValue: Long): SharedPreferenceLiveData<Long> {
return SharedPreferenceLongLiveData(this, key, defValue)
}
fun SharedPreferences.stringSetLiveData(
key: String,
defValue: Set<String>
): SharedPreferenceLiveData<Set<String>> {
return SharedPreferenceStringSetLiveData(this, key, defValue)
}

View File

@ -226,6 +226,11 @@ public class SharedPreferencesUtils {
private static final String POST_DETAIL_FAB_LANDSCAPE_Y_BASE = "fab_landscape_y_"; private static final String POST_DETAIL_FAB_LANDSCAPE_Y_BASE = "fab_landscape_y_";
public static final String REDDIT_VIDEO_DEFAULT_RESOLUTION_NO_DATA_SAVING = "reddit_video_default_resolution_no_data_saving"; public static final String REDDIT_VIDEO_DEFAULT_RESOLUTION_NO_DATA_SAVING = "reddit_video_default_resolution_no_data_saving";
public static final String HIDE_FAB_IN_POST_DETAILS = "hide_fab_in_post_details"; public static final String HIDE_FAB_IN_POST_DETAILS = "hide_fab_in_post_details";
public static final String LONG_PRESS_POST_NON_MEDIA_AREA = "long_press_post_non_media_area";
public static final String LONG_PRESS_POST_MEDIA = "long_press_post_media";
public static final String LONG_PRESS_POST_VALUE_NONE = "0";
public static final String LONG_PRESS_POST_VALUE_SHOW_POST_OPTIONS = "1";
public static final String LONG_PRESS_POST_VALUE_PREVIEW_IN_FULLSCREEN = "2";
public static String getPostDetailFabPortraitX(@Nullable Display display) { public static String getPostDetailFabPortraitX(@Nullable Display display) {
if (display == null) { if (display == null) {

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android" <ml.docilealligator.infinityforreddit.customviews.TouchInterceptableMaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -355,4 +355,4 @@
</LinearLayout> </LinearLayout>
</com.google.android.material.card.MaterialCardView> </ml.docilealligator.infinityforreddit.customviews.TouchInterceptableMaterialCardView>

View File

@ -749,4 +749,28 @@
<item>DIRECT</item> <item>DIRECT</item>
</string-array> </string-array>
<string-array name="settings_long_press_post_non_media_area_action">
<item>@string/none</item>
<item>@string/show_post_options</item>
<item>@string/preview_in_fullscreen</item>
</string-array>
<string-array name="settings_long_press_post_non_media_area_action_values">
<item>0</item>
<item>1</item>
<item>2</item>
</string-array>
<string-array name="settings_long_press_post_media_action">
<item>@string/none</item>
<item>@string/show_post_options</item>
<item>@string/preview_in_fullscreen</item>
</string-array>
<string-array name="settings_long_press_post_media_action_values">
<item>0</item>
<item>1</item>
<item>2</item>
</string-array>
</resources> </resources>

View File

@ -1542,4 +1542,8 @@
<string name="proxy_direct">Direct</string> <string name="proxy_direct">Direct</string>
<string name="jump_to_parent_comment">Jump to Parent Comment</string> <string name="jump_to_parent_comment">Jump to Parent Comment</string>
<string name="long_press_post_non_media_area">Long Press on Post (Non-Media Area)</string>
<string name="long_press_post_media">Long Press on Media</string>
<string name="show_post_options">Show Post Options</string>
<string name="preview_in_fullscreen">Preview in Fullscreen</string>
</resources> </resources>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"> <PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<ml.docilealligator.infinityforreddit.customviews.preference.CustomFontSwitchPreference <ml.docilealligator.infinityforreddit.customviews.preference.CustomFontSwitchPreference
app:defaultValue="true" app:defaultValue="true"
@ -60,6 +61,22 @@
app:title="@string/settings_pinch_to_zoom_video_title" app:title="@string/settings_pinch_to_zoom_video_title"
app:summary="@string/settings_experimental_feature" /> app:summary="@string/settings_experimental_feature" />
<ml.docilealligator.infinityforreddit.customviews.preference.CustomFontListPreference
app:defaultValue="1"
android:entries="@array/settings_long_press_post_non_media_area_action"
app:entryValues="@array/settings_long_press_post_non_media_area_action_values"
app:key="long_press_post_non_media_area"
app:title="@string/long_press_post_non_media_area"
app:useSimpleSummaryProvider="true" />
<ml.docilealligator.infinityforreddit.customviews.preference.CustomFontListPreference
app:defaultValue="1"
android:entries="@array/settings_long_press_post_media_action"
app:entryValues="@array/settings_long_press_post_media_action_values"
app:key="long_press_post_media"
app:title="@string/long_press_post_media"
app:useSimpleSummaryProvider="true" />
<ml.docilealligator.infinityforreddit.customviews.preference.CustomFontPreference <ml.docilealligator.infinityforreddit.customviews.preference.CustomFontPreference
app:title="@string/settings_swipe_action_title" app:title="@string/settings_swipe_action_title"
app:fragment="ml.docilealligator.infinityforreddit.settings.SwipeActionPreferenceFragment" /> app:fragment="ml.docilealligator.infinityforreddit.settings.SwipeActionPreferenceFragment" />