From 70cbadfb3bf1727f7cfaa89917d1c7577cc3b660 Mon Sep 17 00:00:00 2001 From: Alex Ning Date: Tue, 9 Nov 2021 21:12:31 +0800 Subject: Fix clicking spoiler invokes OnClickListener on TextView in comments. Render profile description in markdown. --- .../activities/ViewUserDetailActivity.java | 52 +++++++++++++++++++++- .../CommentsListingRecyclerViewAdapter.java | 14 ++++-- .../adapters/CommentsRecyclerViewAdapter.java | 33 ++++++++++---- .../customviews/SpoilerOnClickTextView.java | 30 +++++++++++++ 4 files changed, 116 insertions(+), 13 deletions(-) create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/customviews/SpoilerOnClickTextView.java (limited to 'app/src/main/java/ml') 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 2c41ba96..d12290ee 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java @@ -12,6 +12,7 @@ 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; @@ -68,7 +69,14 @@ import javax.inject.Named; import butterknife.BindView; import butterknife.ButterKnife; +import io.noties.markwon.AbstractMarkwonPlugin; +import io.noties.markwon.Markwon; +import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.core.MarkwonTheme; +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; import ml.docilealligator.infinityforreddit.AppBarStateChangeListener; import ml.docilealligator.infinityforreddit.DeleteThing; @@ -84,11 +92,13 @@ import ml.docilealligator.infinityforreddit.apis.RedditAPI; import ml.docilealligator.infinityforreddit.asynctasks.AddSubredditOrUserToMultiReddit; import ml.docilealligator.infinityforreddit.asynctasks.CheckIsFollowingUser; import ml.docilealligator.infinityforreddit.asynctasks.SwitchAccount; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.CopyTextBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.FABMoreOptionsBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.PostLayoutBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.PostTypeBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.RandomBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.SortTimeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.UrlMenuBottomSheetFragment; import ml.docilealligator.infinityforreddit.bottomsheetfragments.UserThingSortTypeBottomSheetFragment; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.events.ChangeNSFWEvent; @@ -217,6 +227,7 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele private String mAccessToken; private String mAccountName; private String username; + private String description; private boolean subscriptionReady = false; private boolean mFetchUserInfoSuccess = false; private int expandedTabTextColor; @@ -364,6 +375,44 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele glide = Glide.with(this); Locale locale = getResources().getConfiguration().locale; + Markwon markwon = Markwon.builder(this) + .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); + }); + } + + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(mCustomThemeWrapper.getLinkColor()); + } + }) + .usePlugin(MovementMethodPlugin.create(BetterLinkMovementMethod.linkify(Linkify.WEB_URLS, descriptionTextView).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(); + + descriptionTextView.setOnLongClickListener(view -> { + if (description != null && !description.equals("") && descriptionTextView.getSelectionStart() == -1 && descriptionTextView.getSelectionEnd() == -1) { + Bundle bundle = new Bundle(); + bundle.putString(CopyTextBottomSheetFragment.EXTRA_RAW_TEXT, description); + CopyTextBottomSheetFragment copyTextBottomSheetFragment = new CopyTextBottomSheetFragment(); + copyTextBottomSheetFragment.setArguments(bundle); + copyTextBottomSheetFragment.show(getSupportFragmentManager(), copyTextBottomSheetFragment.getTag()); + } + return true; + }); + userViewModel = new ViewModelProvider(this, new UserViewModel.Factory(getApplication(), mRedditDataRoomDatabase, username)) .get(UserViewModel.class); userViewModel.getUserLiveData().observe(this, userData -> { @@ -516,7 +565,8 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele descriptionTextView.setVisibility(View.GONE); } else { descriptionTextView.setVisibility(View.VISIBLE); - descriptionTextView.setText(userData.getDescription()); + description = userData.getDescription(); + markwon.setMarkdown(descriptionTextView, description); } /*if (userData.isNSFW()) { 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 78fb5796..4174b714 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java @@ -57,6 +57,7 @@ import ml.docilealligator.infinityforreddit.bottomsheetfragments.UrlMenuBottomSh 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.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.Utils; @@ -163,6 +164,9 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter { - if (commentMarkdownView.getSelectionStart() == -1 && commentMarkdownView.getSelectionEnd() == -1) { - itemView.callOnClick(); + if (commentMarkdownView.isSpoilerOnClick()) { + commentMarkdownView.setSpoilerOnClick(false); + return; } + itemView.callOnClick(); }); - commentMarkdownView.setMovementMethod(BetterLinkMovementMethod.linkify(Linkify.WEB_URLS, commentMarkdownView).setOnLinkLongClickListener((textView, url) -> { + commentMarkdownView.setMovementMethod(BetterLinkMovementMethod.newInstance().setOnLinkLongClickListener((textView, url) -> { if (mActivity != null && !mActivity.isDestroyed() && !mActivity.isFinishing()) { UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); Bundle bundle = new Bundle(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java index 14f53a2d..6147f3df 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java @@ -64,6 +64,7 @@ import ml.docilealligator.infinityforreddit.comment.Comment; import ml.docilealligator.infinityforreddit.comment.FetchComment; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.customviews.CommentIndentationView; +import ml.docilealligator.infinityforreddit.customviews.SpoilerOnClickTextView; import ml.docilealligator.infinityforreddit.fragments.ViewPostDetailFragment; import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.utils.APIUtils; @@ -195,16 +196,18 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter { + .usePlugin(MovementMethodPlugin.create(BetterLinkMovementMethod.newInstance().setOnLinkLongClickListener((textView, url) -> { if (!activity.isDestroyed() && !activity.isFinishing()) { UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); Bundle bundle = new Bundle(); @@ -1100,7 +1103,7 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter { + if (!mActivity.isDestroyed() && !mActivity.isFinishing()) { + UrlMenuBottomSheetFragment urlMenuBottomSheetFragment = new UrlMenuBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putString(UrlMenuBottomSheetFragment.EXTRA_URL, url); + urlMenuBottomSheetFragment.setArguments(bundle); + urlMenuBottomSheetFragment.show(mActivity.getSupportFragmentManager(), urlMenuBottomSheetFragment.getTag()); + } + return true; + }));*/ if (mSwapTapAndLong) { if (mCommentToolbarHideOnClick) { View.OnLongClickListener hideToolbarOnLongClickListener = view -> hideToolbar(); @@ -1485,17 +1498,21 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter { - if (commentMarkdownView.getSelectionStart() == -1 && commentMarkdownView.getSelectionEnd() == -1) { - expandComments(); + if (commentMarkdownView.isSpoilerOnClick()) { + commentMarkdownView.setSpoilerOnClick(false); + return; } + expandComments(); }); itemView.setOnClickListener(view -> expandComments()); } else { if (mCommentToolbarHideOnClick) { commentMarkdownView.setOnClickListener(view -> { - if (commentMarkdownView.getSelectionStart() == -1 && commentMarkdownView.getSelectionEnd() == -1) { - hideToolbar(); + if (commentMarkdownView.isSpoilerOnClick()) { + commentMarkdownView.setSpoilerOnClick(false); + return; } + hideToolbar(); }); View.OnClickListener hideToolbarOnClickListener = view -> hideToolbar(); itemView.setOnClickListener(hideToolbarOnClickListener); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/SpoilerOnClickTextView.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/SpoilerOnClickTextView.java new file mode 100644 index 00000000..a34f644a --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/SpoilerOnClickTextView.java @@ -0,0 +1,30 @@ +package ml.docilealligator.infinityforreddit.customviews; + +import android.content.Context; +import android.util.AttributeSet; + +import androidx.annotation.Nullable; + +public class SpoilerOnClickTextView extends androidx.appcompat.widget.AppCompatTextView { + private boolean isSpoilerOnClick; + + public SpoilerOnClickTextView(Context context) { + super(context); + } + + public SpoilerOnClickTextView(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public SpoilerOnClickTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public boolean isSpoilerOnClick() { + return isSpoilerOnClick; + } + + public void setSpoilerOnClick(boolean spoilerOnClick) { + isSpoilerOnClick = spoilerOnClick; + } +} -- cgit v1.2.3