From d5770599f56f8ba1b7119de3b193d1daca7bb766 Mon Sep 17 00:00:00 2001 From: scria1000 <91804886+scria1000@users.noreply.github.com> Date: Tue, 16 Nov 2021 22:53:56 +0300 Subject: Refactor spoiler parsing into its own class Reuse spoiler pattern otherwise we match markdown like: `>!` lots of new lines and text "); + mCommentContent = getIntent().getStringExtra(EXTRA_CONTENT).replaceAll(">!",">!"); contentEditText.setText(mCommentContent); if (savedInstanceState != null) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditPostActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditPostActivity.java index 16e91ebc..2de2a47b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditPostActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditPostActivity.java @@ -141,7 +141,7 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled mFullName = getIntent().getStringExtra(EXTRA_FULLNAME); mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); titleTextView.setText(getIntent().getStringExtra(EXTRA_TITLE)); - mPostContent = getIntent().getStringExtra(EXTRA_CONTENT).replaceAll(">",">");; + mPostContent = getIntent().getStringExtra(EXTRA_CONTENT).replaceAll(">!",">!");; contentEditText.setText(mPostContent); if (savedInstanceState != null) { 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 32a5f452..acd1713c 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java @@ -61,8 +61,10 @@ 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.SpoilerParserPlugin; +import ml.docilealligator.infinityforreddit.markdown.SpoilerSpan; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.utils.SuperscriptInlineProcessor; +import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.Utils; public class FullMarkdownActivity extends BaseActivity { @@ -150,51 +152,6 @@ public class FullMarkdownActivity extends BaseActivity { public String processMarkdown(@NonNull String markdown) { return super.processMarkdown(Utils.fixSuperScript(markdown)); } - - @Override - public void afterSetText(@NonNull TextView textView) { - textView.setHighlightColor(Color.TRANSPARENT); - SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText()); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]+?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - int start = 0; - boolean find = false; - while (matcher.find(start)) { - if (markdownStringBuilder.length() < 4 - || matcher.start() < 0 - || matcher.end() > markdownStringBuilder.length()) { - break; - } - find = true; - markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); - markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); - ClickableSpan clickableSpan = new ClickableSpan() { - private boolean isShowing = false; - @Override - public void updateDrawState(@NonNull TextPaint ds) { - if (isShowing) { - super.updateDrawState(ds); - ds.setColor(markdownColor); - } else { - ds.bgColor = spoilerBackgroundColor; - ds.setColor(markdownColor); - } - ds.setUnderlineText(false); - } - - @Override - public void onClick(@NonNull View view) { - isShowing = !isShowing; - view.invalidate(); - } - }; - markdownStringBuilder.setSpan(clickableSpan, matcher.start(), matcher.end() - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - start = matcher.end() - 4; - } - if (find) { - textView.setText(markdownStringBuilder); - } - } @Override public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { @@ -217,6 +174,7 @@ public class FullMarkdownActivity extends BaseActivity { builder.linkColor(linkColor); } }) + .usePlugin(SpoilerParserPlugin.create(markdownColor, spoilerBackgroundColor)) .usePlugin(StrikethroughPlugin.create()) .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) .usePlugin(TableEntryPlugin.create(this)) 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 1a353a7f..b44f5d4f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java @@ -66,9 +66,11 @@ 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.SpoilerParserPlugin; +import ml.docilealligator.infinityforreddit.markdown.SpoilerSpan; import ml.docilealligator.infinityforreddit.utils.JSONUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.utils.SuperscriptInlineProcessor; +import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.Utils; import retrofit2.Call; import retrofit2.Callback; @@ -176,51 +178,6 @@ public class WikiActivity extends BaseActivity { return super.processMarkdown(Utils.fixSuperScript(markdown)); } - @Override - public void afterSetText(@NonNull TextView textView) { - textView.setHighlightColor(Color.TRANSPARENT); - SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText()); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]+?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - int start = 0; - boolean find = false; - while (matcher.find(start)) { - if (markdownStringBuilder.length() < 4 - || matcher.start() < 0 - || matcher.end() > markdownStringBuilder.length()) { - break; - } - find = true; - markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); - markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); - ClickableSpan clickableSpan = new ClickableSpan() { - private boolean isShowing = false; - @Override - public void updateDrawState(@NonNull TextPaint ds) { - if (isShowing) { - super.updateDrawState(ds); - ds.setColor(markdownColor); - } else { - ds.bgColor = spoilerBackgroundColor; - ds.setColor(markdownColor); - } - ds.setUnderlineText(false); - } - - @Override - public void onClick(@NonNull View view) { - isShowing = !isShowing; - view.invalidate(); - } - }; - markdownStringBuilder.setSpan(clickableSpan, matcher.start(), matcher.end() - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - start = matcher.end() - 4; - } - if (find) { - textView.setText(markdownStringBuilder); - } - } - @Override public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { textView.setTextColor(markdownColor); @@ -241,6 +198,7 @@ public class WikiActivity extends BaseActivity { builder.linkColor(linkColor); } }) + .usePlugin(SpoilerParserPlugin.create(markdownColor, spoilerBackgroundColor)) .usePlugin(StrikethroughPlugin.create()) .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) .usePlugin(TableEntryPlugin.create(this)) 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 616b9c1b..40bce0d6 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java @@ -63,9 +63,11 @@ import ml.docilealligator.infinityforreddit.comment.Comment; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.customviews.CommentIndentationView; import ml.docilealligator.infinityforreddit.customviews.SpoilerOnClickTextView; +import ml.docilealligator.infinityforreddit.markdown.SpoilerParserPlugin; +import ml.docilealligator.infinityforreddit.markdown.SpoilerSpan; import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.utils.SuperscriptInlineProcessor; +import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.Utils; import retrofit2.Retrofit; @@ -136,56 +138,6 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter![\\S\\s]+?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - int start = 0; - boolean find = false; - while (matcher.find(start)) { - if (markdownStringBuilder.length() < 4 - || matcher.start() < 0 - || matcher.end() > markdownStringBuilder.length()) { - break; - } - find = true; - markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); - markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); - int matcherStart = matcher.start(); - int matcherEnd = matcher.end(); - ClickableSpan clickableSpan = new ClickableSpan() { - private boolean isShowing = false; - @Override - public void updateDrawState(@NonNull TextPaint ds) { - if (isShowing) { - super.updateDrawState(ds); - ds.setColor(mCommentColor); - } else { - ds.bgColor = commentSpoilerBackgroundColor; - ds.setColor(mCommentColor); - } - ds.setUnderlineText(false); - } - - @Override - public void onClick(@NonNull View view) { - if (textView instanceof SpoilerOnClickTextView) { - ((SpoilerOnClickTextView) textView).setSpoilerOnClick(true); - } - isShowing = !isShowing; - view.invalidate(); - } - }; - markdownStringBuilder.setSpan(clickableSpan, matcherStart, matcherEnd - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - start = matcherEnd - 4; - } - if (find) { - textView.setText(markdownStringBuilder); - } - } - @Override public void configureTheme(@NonNull MarkwonTheme.Builder builder) { builder.linkColor(customThemeWrapper.getLinkColor()); @@ -202,6 +154,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter![\\S\\s]+?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - int start = 0; - boolean find = false; - while (matcher.find(start)) { - if (markdownStringBuilder.length() < 4 - || matcher.start() < 0 - || matcher.end() > markdownStringBuilder.length()) { - break; - } - find = true; - markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); - markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); - ClickableSpan clickableSpan = new ClickableSpan() { - private boolean isShowing = false; - @Override - public void updateDrawState(@NonNull TextPaint ds) { - if (isShowing) { - super.updateDrawState(ds); - } else { - ds.bgColor = commentSpoilerBackgroundColor; - } - ds.setColor(mCommentTextColor); - ds.setUnderlineText(false); - } - - @Override - public void onClick(@NonNull View view) { - if (textView instanceof SpoilerOnClickTextView) { - ((SpoilerOnClickTextView) textView).setSpoilerOnClick(true); - } - isShowing = !isShowing; - view.invalidate(); - } - }; - markdownStringBuilder.setSpan(clickableSpan, matcher.start(), matcher.end() - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - start = matcher.end() - 4; - } - if (find) { - textView.setText(markdownStringBuilder); - } - } - @Override public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { builder.linkResolver((view, link) -> { @@ -243,6 +197,7 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter { if (!activity.isDestroyed() && !activity.isFinishing()) { 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 095a36f7..7560aab4 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MessageRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MessageRecyclerViewAdapter.java @@ -46,10 +46,12 @@ import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; import ml.docilealligator.infinityforreddit.activities.ViewPrivateMessagesActivity; import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.markdown.SpoilerParserPlugin; +import ml.docilealligator.infinityforreddit.markdown.SpoilerSpan; import ml.docilealligator.infinityforreddit.message.FetchMessage; import ml.docilealligator.infinityforreddit.message.Message; import ml.docilealligator.infinityforreddit.message.ReadMessage; -import ml.docilealligator.infinityforreddit.utils.SuperscriptInlineProcessor; +import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.Utils; import retrofit2.Retrofit; @@ -120,53 +122,6 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter![\\S\\s]+?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - int start = 0; - boolean find = false; - while (matcher.find(start)) { - if (markdownStringBuilder.length() < 4 - || matcher.start() < 0 - || matcher.end() > markdownStringBuilder.length()) { - break; - } - find = true; - markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); - markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); - int matcherStart = matcher.start(); - int matcherEnd = matcher.end(); - ClickableSpan clickableSpan = new ClickableSpan() { - private boolean isShowing = false; - @Override - public void updateDrawState(@NonNull TextPaint ds) { - if (isShowing) { - super.updateDrawState(ds); - ds.setColor(mSecondaryTextColor); - } else { - ds.bgColor = spoilerBackgroundColor; - ds.setColor(mSecondaryTextColor); - } - ds.setUnderlineText(false); - } - - @Override - public void onClick(@NonNull View view) { - isShowing = !isShowing; - view.invalidate(); - } - }; - markdownStringBuilder.setSpan(clickableSpan, matcherStart, matcherEnd - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - start = matcherEnd - 4; - } - if (find) { - textView.setText(markdownStringBuilder); - } - } - @Override public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { builder.linkResolver((view, link) -> { @@ -182,6 +137,7 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter![\\S\\s]+?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - int start = 0; - boolean find = false; - while (matcher.find(start)) { - if (markdownStringBuilder.length() < 4 - || matcher.start() < 0 - || matcher.end() > markdownStringBuilder.length()) { - break; - } - find = true; - markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); - markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); - ClickableSpan clickableSpan = new ClickableSpan() { - private boolean isShowing = false; - @Override - public void updateDrawState(@NonNull TextPaint ds) { - if (isShowing) { - super.updateDrawState(ds); - ds.setColor(markdownColor); - } else { - ds.bgColor = postSpoilerBackgroundColor; - ds.setColor(markdownColor); - } - ds.setUnderlineText(false); - } - - @Override - public void onClick(@NonNull View view) { - isShowing = !isShowing; - view.invalidate(); - } - }; - markdownStringBuilder.setSpan(clickableSpan, matcher.start(), matcher.end() - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - start = matcher.end() - 4; - } - if (find) { - textView.setText(markdownStringBuilder); - } - } - @Override public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { textView.setTextColor(markdownColor); @@ -323,6 +280,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { if (activity != null && !activity.isDestroyed() && !activity.isFinishing()) { 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 e357771b..180b74be 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PrivateMessagesDetailRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PrivateMessagesDetailRecyclerViewAdapter.java @@ -41,7 +41,7 @@ import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.message.Message; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.utils.SuperscriptInlineProcessor; +import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.Utils; public class PrivateMessagesDetailRecyclerViewAdapter extends RecyclerView.Adapter { 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 294733a1..d82fcf8d 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java @@ -35,7 +35,7 @@ import ml.docilealligator.infinityforreddit.Rule; import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; import ml.docilealligator.infinityforreddit.bottomsheetfragments.UrlMenuBottomSheetFragment; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.utils.SuperscriptInlineProcessor; +import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.Utils; public class RulesRecyclerViewAdapter extends RecyclerView.Adapter { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CopyTextBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CopyTextBottomSheetFragment.java index 4264f36a..1e458fc7 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CopyTextBottomSheetFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CopyTextBottomSheetFragment.java @@ -74,7 +74,7 @@ public class CopyTextBottomSheetFragment extends LandscapeExpandedRoundedBottomS if (markdownText != null) { //markdownText = markdownText.replaceAll("", "^").replaceAll("", ""); - markdownText = markdownText.replaceAll(">", ">"); + markdownText = markdownText.replaceAll(">!", ">!"); copyMarkdownTextView.setOnClickListener(view -> { showCopyDialog(markdownText); dismiss(); 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 3f22a64e..bea0c4ed 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java @@ -58,7 +58,7 @@ import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFi import ml.docilealligator.infinityforreddit.subreddit.FetchSubredditData; import ml.docilealligator.infinityforreddit.subreddit.SubredditData; import ml.docilealligator.infinityforreddit.subreddit.SubredditViewModel; -import ml.docilealligator.infinityforreddit.utils.SuperscriptInlineProcessor; +import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.Utils; import retrofit2.Retrofit; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SpoilerParserPlugin.java b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SpoilerParserPlugin.java new file mode 100644 index 00000000..47c484c9 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SpoilerParserPlugin.java @@ -0,0 +1,65 @@ +package ml.docilealligator.infinityforreddit.markdown; + +import android.graphics.Color; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import io.noties.markwon.AbstractMarkwonPlugin; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; + +public class SpoilerParserPlugin extends AbstractMarkwonPlugin { + private final int textColor; + private final int backgroundColor; + + SpoilerParserPlugin(int textColor, int backgroundColor) { + this.textColor = textColor; + this.backgroundColor = backgroundColor; + } + + public static SpoilerParserPlugin create(@NonNull int textColor, @NonNull int backgroundColor) { + return new SpoilerParserPlugin(textColor, backgroundColor); + } + + @Override + public void afterSetText(@NonNull TextView textView) { + textView.setHighlightColor(Color.TRANSPARENT); + SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText()); + Pattern spoilerPattern = Pattern.compile(">!(\\n?(?:.+?(?:\\n?.+?)?)\\n?)!<"); + Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); + int start = 0; + boolean find = false; + while (matcher.find(start)) { + if (markdownStringBuilder.length() < 4 + || matcher.start() < 0 + || matcher.end() > markdownStringBuilder.length()) { + break; + } + find = true; + markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); + markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); + SpoilerSpan spoilerSpan = new SpoilerSpan(textColor, backgroundColor); + markdownStringBuilder.setSpan(spoilerSpan, matcher.start(), matcher.end() - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + start = matcher.end() - 4; + } + /*Pattern escapedSpoilerOpenerPattern = Pattern.compile(">!"); + Matcher escapedSpoilerOpenerMatcher = escapedSpoilerOpenerPattern.matcher(markdownStringBuilder); + ArrayList matched = new ArrayList<>(); + while (escapedSpoilerOpenerMatcher.find()) { + matched.add(escapedSpoilerOpenerMatcher.start()); + find = true; + } + for (int i = matched.size() - 1; i >= 0; i--) { + markdownStringBuilder.replace(matched.get(i), matched.get(i) + 4, ">"); + }*/ + if (find) { + textView.setText(markdownStringBuilder); + } + } + +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SpoilerSpan.java b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SpoilerSpan.java new file mode 100644 index 00000000..5be3797c --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SpoilerSpan.java @@ -0,0 +1,63 @@ +package ml.docilealligator.infinityforreddit.markdown; + +import android.text.Layout; +import android.text.Spannable; +import android.text.TextPaint; +import android.text.style.ClickableSpan; +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.transition.AutoTransition; +import androidx.transition.TransitionManager; + +import ml.docilealligator.infinityforreddit.customviews.SpoilerOnClickTextView; + +public class SpoilerSpan extends ClickableSpan { + final int textColor; + final int backgroundColor; + private boolean isShowing = false; + + public SpoilerSpan(@NonNull int textColor, @NonNull int backgroundColor) { + this.textColor = textColor; + this.backgroundColor = backgroundColor; + } + + @Override + public void onClick(@NonNull View widget) { + if (!(widget instanceof TextView)) { + return; + } + + final TextView textView = (TextView) widget; + final Spannable spannable = (Spannable) textView.getText(); + + final int end = spannable.getSpanEnd(this); + + if (end < 0) { + return; + } + + final Layout layout = textView.getLayout(); + if (layout == null) { + return; + } + + if (widget instanceof SpoilerOnClickTextView) { + ((SpoilerOnClickTextView) textView).setSpoilerOnClick(true); + } + isShowing = !isShowing; + widget.invalidate(); + } + + @Override + public void updateDrawState(@NonNull TextPaint ds) { + if (isShowing) { + super.updateDrawState(ds); + } else { + ds.bgColor = backgroundColor; + } + ds.setColor(textColor); + ds.setUnderlineText(false); + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SuperscriptInlineProcessor.java b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SuperscriptInlineProcessor.java new file mode 100644 index 00000000..27f4d1e4 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SuperscriptInlineProcessor.java @@ -0,0 +1,32 @@ +package ml.docilealligator.infinityforreddit.markdown; + +import androidx.annotation.Nullable; + +import org.commonmark.node.HtmlInline; +import org.commonmark.node.Node; + +import java.util.regex.Pattern; + +import io.noties.markwon.inlineparser.InlineProcessor; + +public class SuperscriptInlineProcessor extends InlineProcessor { + private static final Pattern HTML_TAG = Pattern.compile("", Pattern.CASE_INSENSITIVE); + + @Override + public char specialCharacter() { + return '<'; + } + + @Nullable + @Override + protected Node parse() { + String m = match(HTML_TAG); + if (m != null) { + HtmlInline node = new HtmlInline(); + node.setLiteral(m); + return node; + } else { + return null; + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SuperscriptInlineProcessor.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SuperscriptInlineProcessor.java deleted file mode 100644 index 136a69d4..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SuperscriptInlineProcessor.java +++ /dev/null @@ -1,32 +0,0 @@ -package ml.docilealligator.infinityforreddit.utils; - -import androidx.annotation.Nullable; - -import org.commonmark.node.HtmlInline; -import org.commonmark.node.Node; - -import java.util.regex.Pattern; - -import io.noties.markwon.inlineparser.InlineProcessor; - -public class SuperscriptInlineProcessor extends InlineProcessor { - private static final Pattern HTML_TAG = Pattern.compile("", Pattern.CASE_INSENSITIVE); - - @Override - public char specialCharacter() { - return '<'; - } - - @Nullable - @Override - protected Node parse() { - String m = match(HTML_TAG); - if (m != null) { - HtmlInline node = new HtmlInline(); - node.setLiteral(m); - return node; - } else { - return null; - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/Utils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/Utils.java index 15bcefa0..2963a58f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/Utils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/Utils.java @@ -65,7 +65,7 @@ public class Utils { .replaceAll("((?<=[\\s])|^)/[rRuU]/[\\w-]+/{0,1}", "[$0](https://www.reddit.com$0)") .replaceAll("((?<=[\\s])|^)[rRuU]/[\\w-]+/{0,1}", "[$0](https://www.reddit.com/$0)") .replaceAll("\\^{2,}", "^") - .replaceAll(">!(\\n?(?:[\\S\\h]+?(?:\\n?[\\S\\h]+?)?)\\n?)!<", ">!$1!<") // html entity remains escaped inside an inline block + .replaceAll(">!(\\n?(?:.+?(?:\\n?.+?)?)\\n?)!<", ">!$1!<") // html entity remains escaped inside an inline block .replaceAll("(^|^ *|\\n *)#(?!($|\\s|#))", "$0 ") .replaceAll("(^|^ *|\\n *)##(?!($|\\s|#))", "$0 ") .replaceAll("(^|^ *|\\n *)###(?!($|\\s|#))", "$0 ") -- cgit v1.2.3