From 01071e2a526119c703e4a8b11e03949cfb115934 Mon Sep 17 00:00:00 2001 From: Sergei Kozelko Date: Sat, 8 Oct 2022 11:22:22 +0700 Subject: Refactor and de-duplicate markdown code (#1086) * Add todos to places that need more markdown fixes * Parse spoilers and headings in sidebar * Assign anonymous MarkwonPlugin to a variable Prepare code for a future refactoring * Assign click listener lambda to a variable Prepare code for a future refactoring * Add function for creating Markwon with full markdown All the builders had the same plugins applied to them, except for BetterLinkMovement. But it is safe to add the plugin as it just adjusts link interactions. Also some plugins are now applied in a different order but it doesn't change anything in this case. * Add function for creating Markwon with only links support * Extract UrlMenuBottomSheetFragment creation * Add functions for creating MarkwonAdapters * Replace linkify with newInstance for BetterLinkMovementMethod Because varargs weren't used, the two methods are identical --- .../activities/CommentActivity.java | 110 ++++++---------- .../activities/FullMarkdownActivity.java | 108 ++++++---------- .../activities/ViewSubredditDetailActivity.java | 61 ++++----- .../activities/ViewUserDetailActivity.java | 61 ++++----- .../infinityforreddit/activities/WikiActivity.java | 107 ++++++---------- .../CommentsListingRecyclerViewAdapter.java | 118 ++++++------------ .../adapters/CommentsRecyclerViewAdapter.java | 120 +++++++----------- .../adapters/MessageRecyclerViewAdapter.java | 2 + .../adapters/PostDetailRecyclerViewAdapter.java | 138 ++++++++------------- .../PrivateMessagesDetailRecyclerViewAdapter.java | 2 + .../adapters/RulesRecyclerViewAdapter.java | 118 ++++++------------ .../UrlMenuBottomSheetFragment.java | 10 ++ .../fragments/SidebarFragment.java | 125 +++++++------------ .../ViewRedditGalleryImageOrGifFragment.java | 7 +- .../infinityforreddit/markdown/MarkdownUtils.java | 104 ++++++++++++++++ 15 files changed, 502 insertions(+), 689 deletions(-) create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/markdown/MarkdownUtils.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 07df4287..c9474bb2 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java @@ -12,7 +12,6 @@ import android.os.Handler; import android.provider.MediaStore; import android.text.Spanned; import android.text.TextUtils; -import android.text.util.Linkify; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -31,7 +30,6 @@ import com.bumptech.glide.request.RequestOptions; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.snackbar.Snackbar; -import org.commonmark.ext.gfm.tables.TableBlock; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; @@ -47,19 +45,9 @@ import javax.inject.Named; import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon; import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.MarkwonPlugin; import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.html.HtmlPlugin; -import io.noties.markwon.html.tag.SuperScriptHandler; -import io.noties.markwon.inlineparser.AutolinkInlineProcessor; -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; import jp.wasabeef.glide.transformations.RoundedCornersTransformation; import ml.docilealligator.infinityforreddit.AnyAccountAccessTokenAuthenticator; import ml.docilealligator.infinityforreddit.Infinity; @@ -78,10 +66,7 @@ import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; 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.markdown.MarkdownUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.Utils; import okhttp3.ConnectionPool; @@ -192,64 +177,45 @@ public class CommentActivity extends BaseActivity implements UploadImageEnabledA binding.commentContentMarkdownView.setVisibility(View.VISIBLE); binding.commentContentMarkdownView.setNestedScrollingEnabled(false); int linkColor = mCustomThemeWrapper.getLinkColor(); - Markwon postBodyMarkwon = Markwon.builder(this) - .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { - plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); - plugin.excludeInlineProcessor(HtmlInlineProcessor.class); - plugin.excludeInlineProcessor(BangInlineProcessor.class); - plugin.addInlineProcessor(new SuperscriptInlineProcessor()); - })) - .usePlugin(HtmlPlugin.create(plugin -> { - plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); - })) - .usePlugin(new AbstractMarkwonPlugin() { - @NonNull - @Override - public String processMarkdown(@NonNull String markdown) { - return Utils.fixSuperScript(markdown); - } + MarkwonPlugin miscPlugin = new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + return Utils.fixSuperScript(markdown); + } - @Override - public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { - if (contentTypeface != null) { - textView.setTypeface(contentTypeface); - } - textView.setTextColor(parentTextColor); - textView.setOnLongClickListener(view -> { - Utils.hideKeyboard(CommentActivity.this); - CopyTextBottomSheetFragment.show(getSupportFragmentManager(), - parentBody, parentBodyMarkdown); - return true; - }); - } + @Override + public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { + if (contentTypeface != null) { + textView.setTypeface(contentTypeface); + } + textView.setTextColor(parentTextColor); + textView.setOnLongClickListener(view -> { + Utils.hideKeyboard(CommentActivity.this); + CopyTextBottomSheetFragment.show(getSupportFragmentManager(), + parentBody, parentBodyMarkdown); + return true; + }); + } - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(CommentActivity.this, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - intent.setData(uri); - startActivity(intent); - }); - } + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(CommentActivity.this, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + intent.setData(uri); + startActivity(intent); + }); + } - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(linkColor); - } - }) - .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(); - MarkwonAdapter markwonAdapter = MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text) - .include(TableBlock.class, TableEntry.create(builder -> builder - .tableLayout(R.layout.adapter_table_block, R.id.table_layout) - .textLayoutIsRoot(R.layout.view_table_entry_cell))) - .build(); + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(linkColor); + } + }; + Markwon postBodyMarkwon = MarkdownUtils.createFullRedditMarkwon(this, + miscPlugin, parentTextColor, parentSpoilerBackgroundColor, null); + MarkwonAdapter markwonAdapter = MarkdownUtils.createTablesAdapter(); binding.commentContentMarkdownView.setLayoutManager(new LinearLayoutManagerBugFixed(this)); binding.commentContentMarkdownView.setAdapter(markwonAdapter); markwonAdapter.setMarkdown(postBodyMarkwon, parentBodyMarkdown); 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 59e964a3..782441dc 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java @@ -7,7 +7,6 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.text.Spanned; -import android.text.util.Linkify; import android.view.Menu; import android.view.MenuItem; import android.view.Window; @@ -24,7 +23,6 @@ import com.google.android.material.appbar.CollapsingToolbarLayout; import com.r0adkll.slidr.Slidr; import com.r0adkll.slidr.model.SlidrInterface; -import org.commonmark.ext.gfm.tables.TableBlock; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; @@ -36,29 +34,16 @@ import butterknife.ButterKnife; import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon; import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.MarkwonPlugin; import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.html.HtmlPlugin; -import io.noties.markwon.html.tag.SuperScriptHandler; -import io.noties.markwon.inlineparser.AutolinkInlineProcessor; -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; import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; 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.markdown.MarkdownUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.Utils; @@ -130,60 +115,41 @@ public class FullMarkdownActivity extends BaseActivity { int markdownColor = mCustomThemeWrapper.getCommentColor(); int spoilerBackgroundColor = markdownColor | 0xFF000000; int linkColor = mCustomThemeWrapper.getLinkColor(); - Markwon markwon = Markwon.builder(this) - .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { - plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); - plugin.excludeInlineProcessor(HtmlInlineProcessor.class); - plugin.excludeInlineProcessor(BangInlineProcessor.class); - plugin.addInlineProcessor(new SuperscriptInlineProcessor()); - })) - .usePlugin(HtmlPlugin.create(plugin -> { - plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); - })) - .usePlugin(new AbstractMarkwonPlugin() { - @NonNull - @Override - public String processMarkdown(@NonNull String markdown) { - return Utils.fixSuperScript(markdown); - } - - @Override - public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { - if (typeface != null) { - textView.setTypeface(typeface); - } - textView.setTextColor(markdownColor); - } - - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(FullMarkdownActivity.this, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - intent.setData(uri); - intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, isNsfw); - startActivity(intent); - }); - } - - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(linkColor); - } - }) - .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(); - - MarkwonAdapter markwonAdapter = MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text) - .include(TableBlock.class, TableEntry.create(builder -> builder - .tableLayout(R.layout.adapter_table_block, R.id.table_layout) - .textLayoutIsRoot(R.layout.view_table_entry_cell))) - .build(); + MarkwonPlugin miscPlugin = new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + return Utils.fixSuperScript(markdown); + } + + @Override + public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { + if (typeface != null) { + textView.setTypeface(typeface); + } + textView.setTextColor(markdownColor); + } + + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(FullMarkdownActivity.this, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + intent.setData(uri); + intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, isNsfw); + startActivity(intent); + }); + } + + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(linkColor); + } + }; + Markwon markwon = MarkdownUtils.createFullRedditMarkwon(this, + miscPlugin, markdownColor, spoilerBackgroundColor, null); + + MarkwonAdapter markwonAdapter = MarkdownUtils.createTablesAdapter(); LinearLayoutManagerBugFixed linearLayoutManager = new MarkwonLinearLayoutManager(this, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() { @Override public void onScrolledLeft() { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java index 64501048..e22d1538 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java @@ -10,7 +10,6 @@ import android.os.Bundle; import android.os.Handler; import android.text.Editable; import android.text.TextWatcher; -import android.text.util.Linkify; import android.view.Gravity; import android.view.KeyEvent; import android.view.Menu; @@ -67,13 +66,8 @@ import butterknife.ButterKnife; import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon; import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.MarkwonPlugin; import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.inlineparser.AutolinkInlineProcessor; -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 me.saket.bettermovementmethod.BetterLinkMovementMethod; import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; @@ -106,6 +100,7 @@ import ml.docilealligator.infinityforreddit.events.GoBackToMainPageEvent; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.fragments.PostFragment; import ml.docilealligator.infinityforreddit.fragments.SidebarFragment; +import ml.docilealligator.infinityforreddit.markdown.MarkdownUtils; import ml.docilealligator.infinityforreddit.message.ReadMessage; import ml.docilealligator.infinityforreddit.multireddit.MultiReddit; import ml.docilealligator.infinityforreddit.post.Post; @@ -370,37 +365,29 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp glide = Glide.with(this); Locale locale = getResources().getConfiguration().locale; - Markwon markwon = Markwon.builder(this) - .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { - plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); - plugin.excludeInlineProcessor(HtmlInlineProcessor.class); - plugin.excludeInlineProcessor(BangInlineProcessor.class); - })) - .usePlugin(new AbstractMarkwonPlugin() { - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(ViewSubredditDetailActivity.this, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - intent.setData(uri); - startActivity(intent); - }); - } + MarkwonPlugin miscPlugin = new AbstractMarkwonPlugin() { + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(ViewSubredditDetailActivity.this, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + intent.setData(uri); + startActivity(intent); + }); + } - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(mCustomThemeWrapper.getLinkColor()); - } - }) - .usePlugin(MovementMethodPlugin.create(BetterLinkMovementMethod.linkify(Linkify.WEB_URLS).setOnLinkLongClickListener((textView, url) -> { - UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putString(UrlMenuBottomSheetFragment.EXTRA_URL, url); - urlMenuBottomSheetFragment.setArguments(bundle); - urlMenuBottomSheetFragment.show(getSupportFragmentManager(), urlMenuBottomSheetFragment.getTag()); - return true; - }))) - .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)).build(); + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(mCustomThemeWrapper.getLinkColor()); + } + }; + BetterLinkMovementMethod.OnLinkLongClickListener onLinkLongClickListener = (textView, url) -> { + UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = UrlMenuBottomSheetFragment.newInstance(url); + urlMenuBottomSheetFragment.show(getSupportFragmentManager(), null); + return true; + }; + Markwon markwon = MarkdownUtils.createLinksOnlyMarkwon(this, + miscPlugin, onLinkLongClickListener); descriptionTextView.setOnLongClickListener(view -> { if (description != null && !description.equals("") && descriptionTextView.getSelectionStart() == -1 && descriptionTextView.getSelectionEnd() == -1) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java index d07b8244..eeafcbd8 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java @@ -12,7 +12,6 @@ import android.os.Bundle; import android.os.Handler; import android.text.Editable; import android.text.TextWatcher; -import android.text.util.Linkify; import android.view.Gravity; import android.view.KeyEvent; import android.view.Menu; @@ -69,13 +68,8 @@ import butterknife.ButterKnife; import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon; import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.MarkwonPlugin; import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.inlineparser.AutolinkInlineProcessor; -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 me.saket.bettermovementmethod.BetterLinkMovementMethod; import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; @@ -109,6 +103,7 @@ import ml.docilealligator.infinityforreddit.events.GoBackToMainPageEvent; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.fragments.CommentsListingFragment; import ml.docilealligator.infinityforreddit.fragments.PostFragment; +import ml.docilealligator.infinityforreddit.markdown.MarkdownUtils; import ml.docilealligator.infinityforreddit.message.ReadMessage; import ml.docilealligator.infinityforreddit.multireddit.MultiReddit; import ml.docilealligator.infinityforreddit.post.Post; @@ -366,37 +361,29 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele glide = Glide.with(this); Locale locale = getResources().getConfiguration().locale; - Markwon markwon = Markwon.builder(this) - .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { - plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); - plugin.excludeInlineProcessor(HtmlInlineProcessor.class); - plugin.excludeInlineProcessor(BangInlineProcessor.class); - })) - .usePlugin(new AbstractMarkwonPlugin() { - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(ViewUserDetailActivity.this, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - intent.setData(uri); - startActivity(intent); - }); - } + MarkwonPlugin miscPlugin = new AbstractMarkwonPlugin() { + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(ViewUserDetailActivity.this, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + intent.setData(uri); + startActivity(intent); + }); + } - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(mCustomThemeWrapper.getLinkColor()); - } - }) - .usePlugin(MovementMethodPlugin.create(BetterLinkMovementMethod.linkify(Linkify.WEB_URLS).setOnLinkLongClickListener((textView, url) -> { - UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putString(UrlMenuBottomSheetFragment.EXTRA_URL, url); - urlMenuBottomSheetFragment.setArguments(bundle); - urlMenuBottomSheetFragment.show(getSupportFragmentManager(), urlMenuBottomSheetFragment.getTag()); - return true; - }))) - .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)).build(); + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(mCustomThemeWrapper.getLinkColor()); + } + }; + BetterLinkMovementMethod.OnLinkLongClickListener onLinkLongClickListener = (textView, url) -> { + UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = UrlMenuBottomSheetFragment.newInstance(url); + urlMenuBottomSheetFragment.show(getSupportFragmentManager(), null); + return true; + }; + Markwon markwon = MarkdownUtils.createLinksOnlyMarkwon(this, + miscPlugin, onLinkLongClickListener); descriptionTextView.setOnLongClickListener(view -> { if (description != null && !description.equals("") && descriptionTextView.getSelectionStart() == -1 && descriptionTextView.getSelectionEnd() == -1) { 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 f8ef602b..8f8e902b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java @@ -6,7 +6,6 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.text.Spanned; -import android.text.util.Linkify; import android.view.MenuItem; import android.view.View; import android.view.Window; @@ -28,7 +27,6 @@ import com.google.android.material.appbar.CollapsingToolbarLayout; import com.r0adkll.slidr.Slidr; import com.r0adkll.slidr.model.SlidrInterface; -import org.commonmark.ext.gfm.tables.TableBlock; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.json.JSONException; @@ -42,19 +40,10 @@ import butterknife.ButterKnife; import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon; import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.MarkwonPlugin; import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.html.HtmlPlugin; -import io.noties.markwon.html.tag.SuperScriptHandler; -import io.noties.markwon.inlineparser.AutolinkInlineProcessor; -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; +import me.saket.bettermovementmethod.BetterLinkMovementMethod; import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.apis.RedditAPI; @@ -63,10 +52,7 @@ import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; 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.markdown.MarkdownUtils; import ml.docilealligator.infinityforreddit.utils.JSONUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.Utils; @@ -161,63 +147,42 @@ public class WikiActivity extends BaseActivity { int markdownColor = mCustomThemeWrapper.getPrimaryTextColor(); int spoilerBackgroundColor = markdownColor | 0xFF000000; int linkColor = mCustomThemeWrapper.getLinkColor(); - markwon = Markwon.builder(this) - .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { - plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); - plugin.excludeInlineProcessor(HtmlInlineProcessor.class); - plugin.excludeInlineProcessor(BangInlineProcessor.class); - plugin.addInlineProcessor(new SuperscriptInlineProcessor()); - })) - .usePlugin(HtmlPlugin.create(plugin -> { - plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); - })) - .usePlugin(new AbstractMarkwonPlugin() { - @NonNull - @Override - public String processMarkdown(@NonNull String markdown) { - return Utils.fixSuperScript(markdown); - } + MarkwonPlugin miscPlugin = new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + return Utils.fixSuperScript(markdown); + } - @Override - public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { - textView.setTextColor(markdownColor); - } + @Override + public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { + textView.setTextColor(markdownColor); + } - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(WikiActivity.this, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - intent.setData(uri); - startActivity(intent); - }); - } + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(WikiActivity.this, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + intent.setData(uri); + startActivity(intent); + }); + } - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(linkColor); - } - }) - .usePlugin(SpoilerParserPlugin.create(markdownColor, spoilerBackgroundColor)) - .usePlugin(RedditHeadingPlugin.create()) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod().setOnLinkLongClickListener((textView, url) -> { - UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putString(UrlMenuBottomSheetFragment.EXTRA_URL, url); - urlMenuBottomSheetFragment.setArguments(bundle); - urlMenuBottomSheetFragment.show(getSupportFragmentManager(), urlMenuBottomSheetFragment.getTag()); - return true; - }))) - .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) - .usePlugin(TableEntryPlugin.create(this)) - .build(); - - markwonAdapter = MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text) - .include(TableBlock.class, TableEntry.create(builder -> builder - .tableLayout(R.layout.adapter_table_block, R.id.table_layout) - .textLayoutIsRoot(R.layout.view_table_entry_cell))) - .build(); + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(linkColor); + } + }; + BetterLinkMovementMethod.OnLinkLongClickListener onLinkLongClickListener = (textView, url) -> { + UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = UrlMenuBottomSheetFragment.newInstance(url); + urlMenuBottomSheetFragment.show(getSupportFragmentManager(), null); + return true; + }; + markwon = MarkdownUtils.createFullRedditMarkwon(this, + miscPlugin, markdownColor, spoilerBackgroundColor, onLinkLongClickListener); + + markwonAdapter = MarkdownUtils.createTablesAdapter(); LinearLayoutManagerBugFixed linearLayoutManager = new MarkwonLinearLayoutManager(this, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() { @Override public void onScrolledLeft() { 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 6b8ad84f..0259361f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java @@ -8,7 +8,6 @@ import android.graphics.PorterDuff; import android.net.Uri; import android.os.Bundle; import android.text.Spanned; -import android.text.util.Linkify; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -27,8 +26,6 @@ import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.RecyclerView; -import org.commonmark.ext.gfm.tables.TableBlock; - import java.util.Locale; import butterknife.BindView; @@ -36,18 +33,9 @@ import butterknife.ButterKnife; import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon; import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.MarkwonPlugin; import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.html.HtmlPlugin; -import io.noties.markwon.html.tag.SuperScriptHandler; -import io.noties.markwon.inlineparser.AutolinkInlineProcessor; -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.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; @@ -67,10 +55,7 @@ import ml.docilealligator.infinityforreddit.customviews.CustomMarkwonAdapter; import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; 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.markdown.MarkdownUtils; import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.Utils; @@ -151,63 +136,46 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter { - plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); - plugin.excludeInlineProcessor(HtmlInlineProcessor.class); - plugin.excludeInlineProcessor(BangInlineProcessor.class); - plugin.addInlineProcessor(new SuperscriptInlineProcessor()); - })) - .usePlugin(HtmlPlugin.create(plugin -> { - plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); - })) - .usePlugin(new AbstractMarkwonPlugin() { - @NonNull - @Override - public String processMarkdown(@NonNull String markdown) { - return Utils.fixSuperScript(markdown); - } + MarkwonPlugin miscPlugin = new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + return Utils.fixSuperScript(markdown); + } - @Override - public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { - if (mActivity.contentTypeface != null) { - textView.setTypeface(mActivity.contentTypeface); - } - textView.setTextColor(mCommentColor); - textView.setHighlightColor(Color.TRANSPARENT); - } + @Override + public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { + if (mActivity.contentTypeface != null) { + textView.setTypeface(mActivity.contentTypeface); + } + textView.setTextColor(mCommentColor); + textView.setHighlightColor(Color.TRANSPARENT); + } - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(mActivity, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - intent.setData(uri); - mActivity.startActivity(intent); - }); - } + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(mActivity, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + intent.setData(uri); + mActivity.startActivity(intent); + }); + } - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(linkColor); - } - }) - .usePlugin(SpoilerParserPlugin.create(mCommentColor, commentSpoilerBackgroundColor)) - .usePlugin(RedditHeadingPlugin.create()) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod().setOnLinkLongClickListener((textView, url) -> { - if (!activity.isDestroyed() && !activity.isFinishing()) { - UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putString(UrlMenuBottomSheetFragment.EXTRA_URL, url); - urlMenuBottomSheetFragment.setArguments(bundle); - urlMenuBottomSheetFragment.show(activity.getSupportFragmentManager(), urlMenuBottomSheetFragment.getTag()); - } - return true; - }))) - .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) - .usePlugin(TableEntryPlugin.create(mActivity)) - .build(); + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(linkColor); + } + }; + BetterLinkMovementMethod.OnLinkLongClickListener onLinkLongClickListener = (textView, url) -> { + if (!activity.isDestroyed() && !activity.isFinishing()) { + UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = UrlMenuBottomSheetFragment.newInstance(url); + urlMenuBottomSheetFragment.show(activity.getSupportFragmentManager(), null); + } + return true; + }; + mMarkwon = MarkdownUtils.createFullRedditMarkwon(mActivity, + miscPlugin, mCommentColor, commentSpoilerBackgroundColor, onLinkLongClickListener); recycledViewPool = new RecyclerView.RecycledViewPool(); } @@ -553,11 +521,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter builder - .tableLayout(R.layout.adapter_table_block, R.id.table_layout) - .textLayoutIsRoot(R.layout.view_table_entry_cell))) - .build(); + markwonAdapter = MarkdownUtils.createCustomTablesAdapter(); markwonAdapter.setOnClickListener(view -> { if (view instanceof SpoilerOnClickTextView) { if (((SpoilerOnClickTextView) view).isSpoilerOnClick()) { 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 7fc55c01..bac83b14 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java @@ -10,7 +10,6 @@ import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.text.Spanned; -import android.text.util.Linkify; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -34,8 +33,6 @@ import com.bumptech.glide.RequestManager; import com.bumptech.glide.request.RequestOptions; import com.lsjwzh.widget.materialloadingprogressbar.CircleProgressBar; -import org.commonmark.ext.gfm.tables.TableBlock; - import java.util.ArrayList; import java.util.Locale; import java.util.concurrent.Executor; @@ -45,19 +42,10 @@ import butterknife.ButterKnife; import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon; import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.MarkwonPlugin; import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.html.HtmlPlugin; -import io.noties.markwon.html.tag.SuperScriptHandler; -import io.noties.markwon.inlineparser.AutolinkInlineProcessor; -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.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; @@ -77,10 +65,7 @@ import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFi import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager; 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.markdown.MarkdownUtils; import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; @@ -182,64 +167,47 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter { - plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); - plugin.excludeInlineProcessor(HtmlInlineProcessor.class); - plugin.excludeInlineProcessor(BangInlineProcessor.class); - plugin.addInlineProcessor(new SuperscriptInlineProcessor()); - })) - .usePlugin(HtmlPlugin.create(plugin -> { - plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); - })) - .usePlugin(new AbstractMarkwonPlugin() { - @NonNull - @Override - public String processMarkdown(@NonNull String markdown) { - return Utils.fixSuperScript(markdown); - } + MarkwonPlugin miscPlugin = new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + return Utils.fixSuperScript(markdown); + } - @Override - public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { - if (mActivity.contentTypeface != null) { - textView.setTypeface(mActivity.contentTypeface); - } - textView.setTextColor(mCommentTextColor); - textView.setHighlightColor(Color.TRANSPARENT); - } + @Override + public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { + if (mActivity.contentTypeface != null) { + textView.setTypeface(mActivity.contentTypeface); + } + textView.setTextColor(mCommentTextColor); + textView.setHighlightColor(Color.TRANSPARENT); + } - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(mActivity, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - intent.setData(uri); - intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, mPost.isNSFW()); - mActivity.startActivity(intent); - }); - } + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(mActivity, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + intent.setData(uri); + intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, mPost.isNSFW()); + mActivity.startActivity(intent); + }); + } - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(linkColor); - } - }) - .usePlugin(SpoilerParserPlugin.create(mCommentTextColor, commentSpoilerBackgroundColor)) - .usePlugin(RedditHeadingPlugin.create()) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod().setOnLinkLongClickListener((textView, url) -> { - if (!activity.isDestroyed() && !activity.isFinishing()) { - UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putString(UrlMenuBottomSheetFragment.EXTRA_URL, url); - urlMenuBottomSheetFragment.setArguments(bundle); - urlMenuBottomSheetFragment.show(activity.getSupportFragmentManager(), urlMenuBottomSheetFragment.getTag()); - } - return true; - }))) - .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) - .usePlugin(TableEntryPlugin.create(mActivity)) - .build(); + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(linkColor); + } + }; + BetterLinkMovementMethod.OnLinkLongClickListener onLinkLongClickListener = (textView, url) -> { + if (!activity.isDestroyed() && !activity.isFinishing()) { + UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = UrlMenuBottomSheetFragment.newInstance(url); + urlMenuBottomSheetFragment.show(activity.getSupportFragmentManager(), null); + } + return true; + }; + mCommentMarkwon = MarkdownUtils.createFullRedditMarkwon(mActivity, + miscPlugin, mCommentTextColor, commentSpoilerBackgroundColor, onLinkLongClickListener); recycledViewPool = new RecyclerView.RecycledViewPool(); mAccessToken = accessToken; mAccountName = accountName; @@ -1277,11 +1245,7 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter builder - .tableLayout(R.layout.adapter_table_block, R.id.table_layout) - .textLayoutIsRoot(R.layout.view_table_entry_cell))) - .build(); + mMarkwonAdapter = MarkdownUtils.createCustomTablesAdapter(); commentMarkdownView.setAdapter(mMarkwonAdapter); itemView.setBackgroundColor(mCommentBackgroundColor); 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 8a2aa51d..12c24df8 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MessageRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MessageRecyclerViewAdapter.java @@ -105,6 +105,8 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter { plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostDetailRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostDetailRecyclerViewAdapter.java index d332166a..05deb6fb 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostDetailRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostDetailRecyclerViewAdapter.java @@ -15,7 +15,6 @@ import android.os.Bundle; import android.os.Handler; import android.text.Spanned; import android.text.TextUtils; -import android.text.util.Linkify; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -46,8 +45,6 @@ import com.google.android.exoplayer2.ui.PlayerView; import com.google.common.collect.ImmutableList; import com.libRG.CustomTextView; -import org.commonmark.ext.gfm.tables.TableBlock; - import java.util.ArrayList; import java.util.Locale; import java.util.concurrent.Executor; @@ -57,21 +54,12 @@ import butterknife.ButterKnife; import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon; import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.MarkwonPlugin; import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.html.HtmlPlugin; -import io.noties.markwon.html.tag.SuperScriptHandler; -import io.noties.markwon.inlineparser.AutolinkInlineProcessor; -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; import jp.wasabeef.glide.transformations.BlurTransformation; import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import me.saket.bettermovementmethod.BetterLinkMovementMethod; import ml.docilealligator.infinityforreddit.FetchGfycatOrRedgifsVideoLinks; import ml.docilealligator.infinityforreddit.FetchStreamableVideo; import ml.docilealligator.infinityforreddit.R; @@ -102,10 +90,7 @@ import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.customviews.AspectRatioGifImageView; import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager; 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.markdown.MarkdownUtils; import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.post.PostPagingSource; import ml.docilealligator.infinityforreddit.utils.APIUtils; @@ -244,77 +229,60 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { - plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); - plugin.excludeInlineProcessor(HtmlInlineProcessor.class); - plugin.excludeInlineProcessor(BangInlineProcessor.class); - plugin.addInlineProcessor(new SuperscriptInlineProcessor()); - })) - .usePlugin(HtmlPlugin.create(plugin -> { - plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); - })) - .usePlugin(new AbstractMarkwonPlugin() { - @NonNull - @Override - public String processMarkdown(@NonNull String markdown) { - return Utils.fixSuperScript(markdown); - } + MarkwonPlugin miscPlugin = new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + return Utils.fixSuperScript(markdown); + } - @Override - public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { - if (mActivity.contentTypeface != null) { - textView.setTypeface(mActivity.contentTypeface); - } - textView.setTextColor(markdownColor); - textView.setOnLongClickListener(view -> { - if (textView.getSelectionStart() == -1 && textView.getSelectionEnd() == -1) { - CopyTextBottomSheetFragment.show( - mActivity.getSupportFragmentManager(), - mPost.getSelfTextPlain(), mPost.getSelfText() - ); - } - return true; - }); + @Override + public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { + if (mActivity.contentTypeface != null) { + textView.setTypeface(mActivity.contentTypeface); + } + textView.setTextColor(markdownColor); + textView.setOnLongClickListener(view -> { + if (textView.getSelectionStart() == -1 && textView.getSelectionEnd() == -1) { + CopyTextBottomSheetFragment.show( + mActivity.getSupportFragmentManager(), + mPost.getSelfTextPlain(), mPost.getSelfText() + ); } + return true; + }); + } - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(mActivity, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - intent.setData(uri); - intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, mPost.isNSFW()); - mActivity.startActivity(intent); - }); - } + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(mActivity, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + intent.setData(uri); + intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, mPost.isNSFW()); + mActivity.startActivity(intent); + }); + } + + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(linkColor); + } + }; + BetterLinkMovementMethod.OnLinkLongClickListener onLinkLongClickListener = (textView, url) -> { + if (activity != null && !activity.isDestroyed() && !activity.isFinishing()) { + UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putString(UrlMenuBottomSheetFragment.EXTRA_URL, url); + urlMenuBottomSheetFragment.setArguments(bundle); + urlMenuBottomSheetFragment.show(activity.getSupportFragmentManager(), urlMenuBottomSheetFragment.getTag()); + } + return true; + }; + mPostDetailMarkwon = MarkdownUtils.createFullRedditMarkwon(mActivity, + miscPlugin, markdownColor, postSpoilerBackgroundColor, onLinkLongClickListener); + mMarkwonAdapter = MarkdownUtils.createTablesAdapter(); - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(linkColor); - } - }) - .usePlugin(SpoilerParserPlugin.create(markdownColor, postSpoilerBackgroundColor)) - .usePlugin(RedditHeadingPlugin.create()) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod().setOnLinkLongClickListener((textView, url) -> { - if (activity != null && !activity.isDestroyed() && !activity.isFinishing()) { - UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putString(UrlMenuBottomSheetFragment.EXTRA_URL, url); - urlMenuBottomSheetFragment.setArguments(bundle); - urlMenuBottomSheetFragment.show(activity.getSupportFragmentManager(), urlMenuBottomSheetFragment.getTag()); - } - return true; - }))) - .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) - .usePlugin(TableEntryPlugin.create(mActivity)) - .build(); - mMarkwonAdapter = MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text) - .include(TableBlock.class, TableEntry.create(builder -> builder - .tableLayout(R.layout.adapter_table_block, R.id.table_layout) - .textLayoutIsRoot(R.layout.view_table_entry_cell))) - .build(); mSeparatePostAndComments = separatePostAndComments; mLegacyAutoplayVideoControllerUI = sharedPreferences.getBoolean(SharedPreferencesUtils.LEGACY_AUTOPLAY_VIDEO_CONTROLLER_UI, false); mEasierToWatchInFullScreen = sharedPreferences.getBoolean(SharedPreferencesUtils.EASIER_TO_WATCH_IN_FULL_SCREEN, false); 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 3dea4478..5893d79e 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PrivateMessagesDetailRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PrivateMessagesDetailRecyclerViewAdapter.java @@ -81,6 +81,8 @@ public class PrivateMessagesDetailRecyclerViewAdapter extends RecyclerView.Adapt mLocale = locale; mAccountName = accountName; int commentColor = customThemeWrapper.getCommentColor(); + // todo:https://github.com/Docile-Alligator/Infinity-For-Reddit/issues/1027 + // add tables support and replace with MarkdownUtils#commonPostMarkwonBuilder mMarkwon = Markwon.builder(viewPrivateMessagesActivity) .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); 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 a1109523..ad173262 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java @@ -2,9 +2,7 @@ package ml.docilealligator.infinityforreddit.adapters; import android.content.Intent; import android.net.Uri; -import android.os.Bundle; import android.text.Spanned; -import android.text.util.Linkify; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -16,8 +14,6 @@ import androidx.recyclerview.widget.RecyclerView; import com.r0adkll.slidr.model.SlidrInterface; -import org.commonmark.ext.gfm.tables.TableBlock; - import java.util.ArrayList; import butterknife.BindView; @@ -25,19 +21,10 @@ import butterknife.ButterKnife; import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon; import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.MarkwonPlugin; import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.html.HtmlPlugin; -import io.noties.markwon.html.tag.SuperScriptHandler; -import io.noties.markwon.inlineparser.AutolinkInlineProcessor; -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; +import me.saket.bettermovementmethod.BetterLinkMovementMethod; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.Rule; import ml.docilealligator.infinityforreddit.activities.BaseActivity; @@ -46,10 +33,7 @@ import ml.docilealligator.infinityforreddit.bottomsheetfragments.UrlMenuBottomSh 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.markdown.MarkdownUtils; import ml.docilealligator.infinityforreddit.utils.Utils; public class RulesRecyclerViewAdapter extends RecyclerView.Adapter { @@ -67,64 +51,46 @@ public class RulesRecyclerViewAdapter extends RecyclerView.Adapter { - plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); - plugin.excludeInlineProcessor(HtmlInlineProcessor.class); - plugin.excludeInlineProcessor(BangInlineProcessor.class); - plugin.addInlineProcessor(new SuperscriptInlineProcessor()); - })) - .usePlugin(HtmlPlugin.create(plugin -> { - plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); - })) - .usePlugin(new AbstractMarkwonPlugin() { - @NonNull - @Override - public String processMarkdown(@NonNull String markdown) { - return Utils.fixSuperScript(markdown); - } + MarkwonPlugin miscPlugin = new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + return Utils.fixSuperScript(markdown); + } - @Override - public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { - if (activity.typeface != null) { - textView.setTypeface(activity.typeface); - } + @Override + public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { + if (activity.typeface != null) { + textView.setTypeface(activity.typeface); + } - textView.setTextColor(mPrimaryTextColor); - } + textView.setTextColor(mPrimaryTextColor); + } - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(activity, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - intent.setData(uri); - activity.startActivity(intent); - }); - } + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(activity, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + intent.setData(uri); + activity.startActivity(intent); + }); + } - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(customThemeWrapper.getLinkColor()); - } - }) - .usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod().setOnLinkLongClickListener((textView, url) -> { - if (activity != null && !activity.isDestroyed() && !activity.isFinishing()) { - UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putString(UrlMenuBottomSheetFragment.EXTRA_URL, url); - urlMenuBottomSheetFragment.setArguments(bundle); - urlMenuBottomSheetFragment.show(activity.getSupportFragmentManager(), urlMenuBottomSheetFragment.getTag()); - } - return true; - }))) - .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) - .usePlugin(SpoilerParserPlugin.create(mPrimaryTextColor, spoilerBackgroundColor)) - .usePlugin(RedditHeadingPlugin.create()) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod())) - .usePlugin(TableEntryPlugin.create(activity)) - .build(); + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(customThemeWrapper.getLinkColor()); + } + }; + BetterLinkMovementMethod.OnLinkLongClickListener onLinkLongClickListener = (textView, url) -> { + if (activity != null && !activity.isDestroyed() && !activity.isFinishing()) { + UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = UrlMenuBottomSheetFragment.newInstance(url); + urlMenuBottomSheetFragment.show(activity.getSupportFragmentManager(), null); + } + return true; + }; + markwon = MarkdownUtils.createFullRedditMarkwon(activity, + miscPlugin, mPrimaryTextColor, spoilerBackgroundColor, onLinkLongClickListener); } @NonNull @@ -178,11 +144,7 @@ public class RulesRecyclerViewAdapter extends RecyclerView.Adapter builder - .tableLayout(R.layout.adapter_table_block, R.id.table_layout) - .textLayoutIsRoot(R.layout.view_table_entry_cell))) - .build(); + markwonAdapter = MarkdownUtils.createTablesAdapter(); LinearLayoutManagerBugFixed linearLayoutManager = new MarkwonLinearLayoutManager(activity, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() { @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/UrlMenuBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/UrlMenuBottomSheetFragment.java index aaf8783b..85da693c 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/UrlMenuBottomSheetFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/UrlMenuBottomSheetFragment.java @@ -15,6 +15,7 @@ import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentManager; import butterknife.BindView; import butterknife.ButterKnife; @@ -43,6 +44,15 @@ public class UrlMenuBottomSheetFragment extends LandscapeExpandedRoundedBottomSh // Required empty public constructor } + @NonNull + public static UrlMenuBottomSheetFragment newInstance(String url) { + UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putString(UrlMenuBottomSheetFragment.EXTRA_URL, url); + urlMenuBottomSheetFragment.setArguments(bundle); + return urlMenuBottomSheetFragment; + } + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java index 1b701bfa..bc1a0ddd 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java @@ -6,7 +6,6 @@ import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.text.Spanned; -import android.text.util.Linkify; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -19,8 +18,6 @@ import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; -import org.commonmark.ext.gfm.tables.TableBlock; - import java.util.concurrent.Executor; import javax.inject.Inject; @@ -31,19 +28,9 @@ import butterknife.ButterKnife; import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon; import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.MarkwonPlugin; import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.html.HtmlPlugin; -import io.noties.markwon.html.tag.SuperScriptHandler; -import io.noties.markwon.inlineparser.AutolinkInlineProcessor; -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; import me.saket.bettermovementmethod.BetterLinkMovementMethod; import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; @@ -55,7 +42,7 @@ import ml.docilealligator.infinityforreddit.bottomsheetfragments.CopyTextBottomS import ml.docilealligator.infinityforreddit.bottomsheetfragments.UrlMenuBottomSheetFragment; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; -import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; +import ml.docilealligator.infinityforreddit.markdown.MarkdownUtils; import ml.docilealligator.infinityforreddit.subreddit.FetchSubredditData; import ml.docilealligator.infinityforreddit.subreddit.SubredditData; import ml.docilealligator.infinityforreddit.subreddit.SubredditViewModel; @@ -114,74 +101,56 @@ public class SidebarFragment extends Fragment { swipeRefreshLayout.setProgressBackgroundColorSchemeColor(mCustomThemeWrapper.getCircularProgressBarBackground()); swipeRefreshLayout.setColorSchemeColors(mCustomThemeWrapper.getColorAccent()); markdownColor = mCustomThemeWrapper.getPrimaryTextColor(); + int spoilerBackgroundColor = markdownColor | 0xFF000000; - Markwon markwon = Markwon.builder(activity) - .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { - plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); - plugin.excludeInlineProcessor(HtmlInlineProcessor.class); - plugin.excludeInlineProcessor(BangInlineProcessor.class); - plugin.addInlineProcessor(new SuperscriptInlineProcessor()); - })) - .usePlugin(HtmlPlugin.create(plugin -> { - plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); - })) - .usePlugin(new AbstractMarkwonPlugin() { - @NonNull - @Override - public String processMarkdown(@NonNull String markdown) { - return Utils.fixSuperScript(markdown); - } + MarkwonPlugin miscPlugin = new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + return Utils.fixSuperScript(markdown); + } - @Override - public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { - if (activity.contentTypeface != null) { - textView.setTypeface(activity.contentTypeface); - } - textView.setTextColor(markdownColor); - textView.setOnLongClickListener(view -> { - if (sidebarDescription != null && !sidebarDescription.equals("") && textView.getSelectionStart() == -1 && textView.getSelectionEnd() == -1) { - Bundle bundle = new Bundle(); - bundle.putString(CopyTextBottomSheetFragment.EXTRA_MARKDOWN, sidebarDescription); - CopyTextBottomSheetFragment copyTextBottomSheetFragment = new CopyTextBottomSheetFragment(); - copyTextBottomSheetFragment.setArguments(bundle); - copyTextBottomSheetFragment.show(getChildFragmentManager(), copyTextBottomSheetFragment.getTag()); - } - return true; - }); + @Override + public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { + if (activity.contentTypeface != null) { + textView.setTypeface(activity.contentTypeface); + } + textView.setTextColor(markdownColor); + textView.setOnLongClickListener(view -> { + if (sidebarDescription != null && !sidebarDescription.equals("") && textView.getSelectionStart() == -1 && textView.getSelectionEnd() == -1) { + Bundle bundle = new Bundle(); + bundle.putString(CopyTextBottomSheetFragment.EXTRA_MARKDOWN, sidebarDescription); + CopyTextBottomSheetFragment copyTextBottomSheetFragment = new CopyTextBottomSheetFragment(); + copyTextBottomSheetFragment.setArguments(bundle); + copyTextBottomSheetFragment.show(getChildFragmentManager(), copyTextBottomSheetFragment.getTag()); } + return true; + }); + } - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(mCustomThemeWrapper.getLinkColor()); - } + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(mCustomThemeWrapper.getLinkColor()); + } - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(activity, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - intent.setData(uri); - startActivity(intent); - }); - } - }) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) - .usePlugin(MovementMethodPlugin.create(BetterLinkMovementMethod.linkify(Linkify.WEB_URLS).setOnLinkLongClickListener((textView, url) -> { - UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putString(UrlMenuBottomSheetFragment.EXTRA_URL, url); - urlMenuBottomSheetFragment.setArguments(bundle); - urlMenuBottomSheetFragment.show(getChildFragmentManager(), urlMenuBottomSheetFragment.getTag()); - return true; - }))) - .usePlugin(TableEntryPlugin.create(activity)) - .build(); - MarkwonAdapter markwonAdapter = MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text) - .include(TableBlock.class, TableEntry.create(builder -> builder - .tableLayout(R.layout.adapter_table_block, R.id.table_layout) - .textLayoutIsRoot(R.layout.view_table_entry_cell))) - .build(); + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(activity, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + intent.setData(uri); + startActivity(intent); + }); + } + }; + BetterLinkMovementMethod.OnLinkLongClickListener onLinkLongClickListener = (textView, url) -> { + UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = UrlMenuBottomSheetFragment.newInstance(url); + urlMenuBottomSheetFragment.show(getChildFragmentManager(), null); + return true; + }; + Markwon markwon = MarkdownUtils.createFullRedditMarkwon(activity, + miscPlugin, markdownColor, spoilerBackgroundColor, onLinkLongClickListener); + MarkwonAdapter markwonAdapter = MarkdownUtils.createTablesAdapter(); linearLayoutManager = new LinearLayoutManagerBugFixed(activity); recyclerView.setLayoutManager(linearLayoutManager); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryImageOrGifFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryImageOrGifFragment.java index 527dd40d..839b47ec 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryImageOrGifFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryImageOrGifFragment.java @@ -308,11 +308,8 @@ public class ViewRedditGalleryImageOrGifFragment extends Fragment { BetterLinkMovementMethod.linkify(Linkify.WEB_URLS, captionUrlTextView).setOnLinkLongClickListener((textView, url) -> { if (activity != null && !activity.isDestroyed() && !activity.isFinishing()) { - UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putString(UrlMenuBottomSheetFragment.EXTRA_URL, captionUrl); - urlMenuBottomSheetFragment.setArguments(bundle); - urlMenuBottomSheetFragment.show(activity.getSupportFragmentManager(), urlMenuBottomSheetFragment.getTag()); + UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = UrlMenuBottomSheetFragment.newInstance(captionUrl); + urlMenuBottomSheetFragment.show(activity.getSupportFragmentManager(), null); } return true; }); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/MarkdownUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/MarkdownUtils.java new file mode 100644 index 00000000..68640220 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/MarkdownUtils.java @@ -0,0 +1,104 @@ +package ml.docilealligator.infinityforreddit.markdown; + +import android.content.Context; +import android.text.util.Linkify; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.commonmark.ext.gfm.tables.TableBlock; + +import io.noties.markwon.Markwon; +import io.noties.markwon.MarkwonPlugin; +import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; +import io.noties.markwon.html.HtmlPlugin; +import io.noties.markwon.html.tag.SuperScriptHandler; +import io.noties.markwon.inlineparser.AutolinkInlineProcessor; +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; +import me.saket.bettermovementmethod.BetterLinkMovementMethod; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.customviews.CustomMarkwonAdapter; + +public class MarkdownUtils { + /** + * Creates a Markwon instance with all the plugins required for processing Reddit's markdown. + * @return configured Markwon instance + */ + @NonNull + public static Markwon createFullRedditMarkwon(@NonNull Context context, + @NonNull MarkwonPlugin miscPlugin, + int markdownColor, + int spoilerBackgroundColor, + @Nullable BetterLinkMovementMethod.OnLinkLongClickListener onLinkLongClickListener) { + return Markwon.builder(context) + .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { + plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); + plugin.excludeInlineProcessor(HtmlInlineProcessor.class); + plugin.excludeInlineProcessor(BangInlineProcessor.class); + plugin.addInlineProcessor(new SuperscriptInlineProcessor()); + })) + .usePlugin(HtmlPlugin.create(plugin -> { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); + })) + .usePlugin(miscPlugin) + .usePlugin(SpoilerParserPlugin.create(markdownColor, spoilerBackgroundColor)) + .usePlugin(RedditHeadingPlugin.create()) + .usePlugin(StrikethroughPlugin.create()) + .usePlugin(MovementMethodPlugin.create(new SpoilerAwareMovementMethod() + .setOnLinkLongClickListener(onLinkLongClickListener))) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .usePlugin(TableEntryPlugin.create(context)) + .build(); + } + + /** + * Creates a Markwon instance that processes only the links. + * @return configured Markwon instance + */ + @NonNull + public static Markwon createLinksOnlyMarkwon(@NonNull Context context, + @NonNull MarkwonPlugin miscPlugin, + @Nullable BetterLinkMovementMethod.OnLinkLongClickListener onLinkLongClickListener) { + return Markwon.builder(context) + .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { + plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); + plugin.excludeInlineProcessor(HtmlInlineProcessor.class); + plugin.excludeInlineProcessor(BangInlineProcessor.class); + })) + .usePlugin(miscPlugin) + .usePlugin(MovementMethodPlugin.create(BetterLinkMovementMethod.newInstance().setOnLinkLongClickListener(onLinkLongClickListener))) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .build(); + } + + /** + * Creates a MarkwonAdapter configured with support for tables. + */ + @NonNull + public static MarkwonAdapter createTablesAdapter() { + return MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text) + .include(TableBlock.class, TableEntry.create(builder -> builder + .tableLayout(R.layout.adapter_table_block, R.id.table_layout) + .textLayoutIsRoot(R.layout.view_table_entry_cell))) + .build(); + } + + /** + * Creates a CustomMarkwonAdapter configured with support for tables. + */ + @NonNull + public static CustomMarkwonAdapter createCustomTablesAdapter() { + return CustomMarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text) + .include(TableBlock.class, TableEntry.create(builder -> builder + .tableLayout(R.layout.adapter_table_block, R.id.table_layout) + .textLayoutIsRoot(R.layout.view_table_entry_cell))) + .build(); + } +} -- cgit v1.2.3