From fad978432e2f8c3a676d137d9683bf1f470da1f0 Mon Sep 17 00:00:00 2001 From: Sergei Kozelko Date: Sun, 25 Sep 2022 15:13:59 +0700 Subject: Fix spoiler interactions with links and long clicks (#1129) * Prioritize clicks on hidden spoilers over links Extend BetterLinkMovementMethod to override selection of span that will be touched and give spoilers and links following priorities: 1. Hidden spoiler 2. Non-spoiler span (i.e. link) 3. Shown spoiler #609 * Ignore long clicks on spoilers Ignore long clicks if it is a SpoilerSpan. Also don't apply highlight because it breaks spoiler effect. #529 --- .../activities/CommentActivity.java | 3 + .../activities/FullMarkdownActivity.java | 3 + .../infinityforreddit/activities/WikiActivity.java | 4 +- .../CommentsListingRecyclerViewAdapter.java | 4 +- .../adapters/CommentsRecyclerViewAdapter.java | 4 +- .../adapters/MessageRecyclerViewAdapter.java | 3 + .../adapters/PostDetailRecyclerViewAdapter.java | 4 +- .../PrivateMessagesDetailRecyclerViewAdapter.java | 3 + .../adapters/RulesRecyclerViewAdapter.java | 5 +- .../markdown/SpoilerAwareMovementMethod.java | 102 +++++++++++++++++++++ .../infinityforreddit/markdown/SpoilerSpan.java | 10 ++ 11 files changed, 135 insertions(+), 10 deletions(-) create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SpoilerAwareMovementMethod.java diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java index 4aac3cbe..07df4287 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java @@ -56,6 +56,7 @@ import io.noties.markwon.inlineparser.BangInlineProcessor; import io.noties.markwon.inlineparser.HtmlInlineProcessor; import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; import io.noties.markwon.linkify.LinkifyPlugin; +import io.noties.markwon.movement.MovementMethodPlugin; import io.noties.markwon.recycler.MarkwonAdapter; import io.noties.markwon.recycler.table.TableEntry; import io.noties.markwon.recycler.table.TableEntryPlugin; @@ -78,6 +79,7 @@ import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFi import ml.docilealligator.infinityforreddit.databinding.ActivityCommentBinding; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.markdown.RedditHeadingPlugin; +import ml.docilealligator.infinityforreddit.markdown.SpoilerAwareMovementMethod; import ml.docilealligator.infinityforreddit.markdown.SpoilerParserPlugin; import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; @@ -239,6 +241,7 @@ public class CommentActivity extends BaseActivity implements UploadImageEnabledA .usePlugin(SpoilerParserPlugin.create(parentTextColor, parentSpoilerBackgroundColor)) .usePlugin(RedditHeadingPlugin.create()) .usePlugin(StrikethroughPlugin.create()) + .usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod())) .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) .usePlugin(TableEntryPlugin.create(this)) .build(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java index 32f20d82..59e964a3 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java @@ -45,6 +45,7 @@ import io.noties.markwon.inlineparser.BangInlineProcessor; import io.noties.markwon.inlineparser.HtmlInlineProcessor; import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; import io.noties.markwon.linkify.LinkifyPlugin; +import io.noties.markwon.movement.MovementMethodPlugin; import io.noties.markwon.recycler.MarkwonAdapter; import io.noties.markwon.recycler.table.TableEntry; import io.noties.markwon.recycler.table.TableEntryPlugin; @@ -55,6 +56,7 @@ import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFi import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.markdown.RedditHeadingPlugin; +import ml.docilealligator.infinityforreddit.markdown.SpoilerAwareMovementMethod; import ml.docilealligator.infinityforreddit.markdown.SpoilerParserPlugin; import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; @@ -172,6 +174,7 @@ public class FullMarkdownActivity extends BaseActivity { .usePlugin(SpoilerParserPlugin.create(markdownColor, spoilerBackgroundColor)) .usePlugin(RedditHeadingPlugin.create()) .usePlugin(StrikethroughPlugin.create()) + .usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod())) .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) .usePlugin(TableEntryPlugin.create(this)) .build(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java index 7d0e3168..f8ef602b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java @@ -55,7 +55,6 @@ import io.noties.markwon.movement.MovementMethodPlugin; import io.noties.markwon.recycler.MarkwonAdapter; import io.noties.markwon.recycler.table.TableEntry; import io.noties.markwon.recycler.table.TableEntryPlugin; -import me.saket.bettermovementmethod.BetterLinkMovementMethod; import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.apis.RedditAPI; @@ -65,6 +64,7 @@ import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFi import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.markdown.RedditHeadingPlugin; +import ml.docilealligator.infinityforreddit.markdown.SpoilerAwareMovementMethod; import ml.docilealligator.infinityforreddit.markdown.SpoilerParserPlugin; import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.JSONUtils; @@ -201,7 +201,7 @@ public class WikiActivity extends BaseActivity { .usePlugin(SpoilerParserPlugin.create(markdownColor, spoilerBackgroundColor)) .usePlugin(RedditHeadingPlugin.create()) .usePlugin(StrikethroughPlugin.create()) - .usePlugin(MovementMethodPlugin.create(BetterLinkMovementMethod.linkify(Linkify.WEB_URLS).setOnLinkLongClickListener((textView, url) -> { + .usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod().setOnLinkLongClickListener((textView, url) -> { UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); Bundle bundle = new Bundle(); bundle.putString(UrlMenuBottomSheetFragment.EXTRA_URL, url); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java index d199f885..6b8ad84f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java @@ -48,7 +48,6 @@ import io.noties.markwon.linkify.LinkifyPlugin; import io.noties.markwon.movement.MovementMethodPlugin; import io.noties.markwon.recycler.table.TableEntry; import io.noties.markwon.recycler.table.TableEntryPlugin; -import me.saket.bettermovementmethod.BetterLinkMovementMethod; import ml.docilealligator.infinityforreddit.NetworkState; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.SaveThing; @@ -69,6 +68,7 @@ import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFi import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager; import ml.docilealligator.infinityforreddit.customviews.SpoilerOnClickTextView; import ml.docilealligator.infinityforreddit.markdown.RedditHeadingPlugin; +import ml.docilealligator.infinityforreddit.markdown.SpoilerAwareMovementMethod; import ml.docilealligator.infinityforreddit.markdown.SpoilerParserPlugin; import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.APIUtils; @@ -195,7 +195,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter { + .usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod().setOnLinkLongClickListener((textView, url) -> { if (!activity.isDestroyed() && !activity.isFinishing()) { UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); Bundle bundle = new Bundle(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java index fe452064..7fc55c01 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java @@ -58,7 +58,6 @@ import io.noties.markwon.movement.MovementMethodPlugin; import io.noties.markwon.recycler.table.TableEntry; import io.noties.markwon.recycler.table.TableEntryPlugin; import jp.wasabeef.glide.transformations.RoundedCornersTransformation; -import me.saket.bettermovementmethod.BetterLinkMovementMethod; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.SaveThing; import ml.docilealligator.infinityforreddit.VoteThing; @@ -79,6 +78,7 @@ import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManag import ml.docilealligator.infinityforreddit.customviews.SpoilerOnClickTextView; import ml.docilealligator.infinityforreddit.fragments.ViewPostDetailFragment; import ml.docilealligator.infinityforreddit.markdown.RedditHeadingPlugin; +import ml.docilealligator.infinityforreddit.markdown.SpoilerAwareMovementMethod; import ml.docilealligator.infinityforreddit.markdown.SpoilerParserPlugin; import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.post.Post; @@ -227,7 +227,7 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter { + .usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod().setOnLinkLongClickListener((textView, url) -> { if (!activity.isDestroyed() && !activity.isFinishing()) { UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); Bundle bundle = new Bundle(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MessageRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MessageRecyclerViewAdapter.java index 01408328..8a2aa51d 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MessageRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MessageRecyclerViewAdapter.java @@ -35,6 +35,7 @@ import io.noties.markwon.inlineparser.BangInlineProcessor; import io.noties.markwon.inlineparser.HtmlInlineProcessor; import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; import io.noties.markwon.linkify.LinkifyPlugin; +import io.noties.markwon.movement.MovementMethodPlugin; import ml.docilealligator.infinityforreddit.NetworkState; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.activities.BaseActivity; @@ -44,6 +45,7 @@ import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.events.ChangeInboxCountEvent; import ml.docilealligator.infinityforreddit.markdown.RedditHeadingPlugin; +import ml.docilealligator.infinityforreddit.markdown.SpoilerAwareMovementMethod; import ml.docilealligator.infinityforreddit.markdown.SpoilerParserPlugin; import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.message.FetchMessage; @@ -138,6 +140,7 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter { + .usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod().setOnLinkLongClickListener((textView, url) -> { if (activity != null && !activity.isDestroyed() && !activity.isFinishing()) { UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); Bundle bundle = new Bundle(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PrivateMessagesDetailRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PrivateMessagesDetailRecyclerViewAdapter.java index 149eae5b..3dea4478 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PrivateMessagesDetailRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PrivateMessagesDetailRecyclerViewAdapter.java @@ -39,6 +39,7 @@ import io.noties.markwon.inlineparser.BangInlineProcessor; import io.noties.markwon.inlineparser.HtmlInlineProcessor; import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; import io.noties.markwon.linkify.LinkifyPlugin; +import io.noties.markwon.movement.MovementMethodPlugin; import jp.wasabeef.glide.transformations.RoundedCornersTransformation; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; @@ -46,6 +47,7 @@ import ml.docilealligator.infinityforreddit.activities.ViewPrivateMessagesActivi import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.markdown.RedditHeadingPlugin; +import ml.docilealligator.infinityforreddit.markdown.SpoilerAwareMovementMethod; import ml.docilealligator.infinityforreddit.markdown.SpoilerParserPlugin; import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.message.Message; @@ -121,6 +123,7 @@ public class PrivateMessagesDetailRecyclerViewAdapter extends RecyclerView.Adapt .usePlugin(StrikethroughPlugin.create()) .usePlugin(SpoilerParserPlugin.create(commentColor, commentColor | 0xFF000000)) .usePlugin(RedditHeadingPlugin.create()) + .usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod())) .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) .build(); mShowElapsedTime = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_ELAPSED_TIME_KEY, false); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java index 33c3dd81..a1109523 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java @@ -38,7 +38,6 @@ import io.noties.markwon.movement.MovementMethodPlugin; import io.noties.markwon.recycler.MarkwonAdapter; import io.noties.markwon.recycler.table.TableEntry; import io.noties.markwon.recycler.table.TableEntryPlugin; -import me.saket.bettermovementmethod.BetterLinkMovementMethod; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.Rule; import ml.docilealligator.infinityforreddit.activities.BaseActivity; @@ -48,6 +47,7 @@ import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager; import ml.docilealligator.infinityforreddit.markdown.RedditHeadingPlugin; +import ml.docilealligator.infinityforreddit.markdown.SpoilerAwareMovementMethod; import ml.docilealligator.infinityforreddit.markdown.SpoilerParserPlugin; import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.Utils; @@ -108,7 +108,7 @@ public class RulesRecyclerViewAdapter extends RecyclerView.Adapter { + .usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod().setOnLinkLongClickListener((textView, url) -> { if (activity != null && !activity.isDestroyed() && !activity.isFinishing()) { UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); Bundle bundle = new Bundle(); @@ -122,6 +122,7 @@ public class RulesRecyclerViewAdapter extends RecyclerView.Adapter