diff options
23 files changed, 264 insertions, 78 deletions
diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser Binary files differindex 9ae71cf7..d5246306 100644 --- a/.idea/caches/build_file_checksums.ser +++ b/.idea/caches/build_file_checksums.ser diff --git a/.idea/caches/gradle_models.ser b/.idea/caches/gradle_models.ser Binary files differindex 941f4d61..798ac03c 100644 --- a/.idea/caches/gradle_models.ser +++ b/.idea/caches/gradle_models.ser diff --git a/app/build.gradle b/app/build.gradle index 0f78862a..3ddc20d7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -67,10 +67,10 @@ dependencies { annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0' implementation 'com.github.santalu:aspect-ratio-imageview:1.0.6' implementation 'androidx.paging:paging-runtime:2.1.0' - implementation "com.lsjwzh:materialloadingprogressbar:0.5.8-RELEASE" - implementation "ru.noties:markwon:2.0.1" - implementation "ru.noties:markwon-syntax-highlight:2.0.1" - implementation "ru.noties:markwon-view:2.0.1" + implementation 'com.lsjwzh:materialloadingprogressbar:0.5.8-RELEASE' + implementation 'io.noties.markwon:core:4.1.0' + implementation 'io.noties.markwon:linkify:4.1.0' + implementation 'io.noties.markwon:ext-strikethrough:4.1.0' implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.16' implementation 'com.github.Ferfalk:SimpleSearchView:0.1.3' implementation 'org.greenrobot:eventbus:3.1.1' @@ -79,6 +79,7 @@ dependencies { implementation 'com.github.livefront:bridge:v1.2.0' implementation 'com.evernote:android-state:1.4.1' annotationProcessor 'com.evernote:android-state-processor:1.4.1' - implementation "androidx.work:work-runtime:2.2.0" - implementation "androidx.preference:preference:1.1.0-rc01" + implementation 'androidx.work:work-runtime:2.2.0' + implementation 'androidx.preference:preference:1.1.0-rc01' + implementation 'org.sufficientlysecure:html-textview:3.6' } diff --git a/app/src/main/java/CustomView/CustomMarkwonView.java b/app/src/main/java/CustomView/CustomMarkwonView.java index 940b6b76..c89ff405 100644 --- a/app/src/main/java/CustomView/CustomMarkwonView.java +++ b/app/src/main/java/CustomView/CustomMarkwonView.java @@ -1,38 +1,73 @@ package CustomView; import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.util.AttributeSet; +import android.text.Spanned; +import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import ml.docilealligator.infinityforreddit.LinkResolverActivity; -import ru.noties.markwon.SpannableConfiguration; -import ru.noties.markwon.view.MarkwonView; +import org.commonmark.node.Node; -public class CustomMarkwonView extends MarkwonView { +import java.util.List; + +import io.noties.markwon.Markwon; +import io.noties.markwon.MarkwonPlugin; + +public class CustomMarkwonView extends Markwon { + + public void setMarkdown(@Nullable String markdown, Context context) { - public CustomMarkwonView(Context context) { - super(context); } - public CustomMarkwonView(Context context, AttributeSet attrs) { - super(context, attrs); + @NonNull + @Override + public Node parse(@NonNull String input) { + return null; } - public void setMarkdown(@Nullable String markdown, Context context) { - SpannableConfiguration configuration = SpannableConfiguration.builder(context).linkResolver((view, link) -> { - Intent intent = new Intent(context, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - if(uri.getScheme() == null && uri.getHost() == null) { - intent.setData(LinkResolverActivity.getRedditUriByPath(link)); - } else { - intent.setData(uri); - } - context.startActivity(intent); - }).build(); - - super.setMarkdown(configuration, markdown); + @NonNull + @Override + public Spanned render(@NonNull Node node) { + return null; + } + + @NonNull + @Override + public Spanned toMarkdown(@NonNull String input) { + return null; + } + + @Override + public void setMarkdown(@NonNull TextView textView, @NonNull String markdown) { + + } + + @Override + public void setParsedMarkdown(@NonNull TextView textView, @NonNull Spanned markdown) { + + } + + @Override + public boolean hasPlugin(@NonNull Class<? extends MarkwonPlugin> plugin) { + return false; + } + + @Nullable + @Override + public <P extends MarkwonPlugin> P getPlugin(@NonNull Class<P> type) { + return null; + } + + @NonNull + @Override + public <P extends MarkwonPlugin> P requirePlugin(@NonNull Class<P> type) { + return null; + } + + @NonNull + @Override + public List<? extends MarkwonPlugin> getPlugins() { + return null; } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentActivity.java index 5b5cd0ab..17e4061c 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentActivity.java @@ -4,14 +4,17 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; +import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.text.util.Linkify; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.Window; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -31,8 +34,11 @@ 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.linkify.LinkifyPlugin; import retrofit2.Retrofit; -import ru.noties.markwon.view.MarkwonView; import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY; import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; @@ -54,7 +60,7 @@ public class CommentActivity extends AppCompatActivity { @BindView(R.id.coordinator_layout_comment_activity) CoordinatorLayout coordinatorLayout; @BindView(R.id.toolbar_comment_activity) Toolbar toolbar; - @BindView(R.id.comment_parent_markwon_view_comment_activity) MarkwonView commentParentMarkwonView; + @BindView(R.id.comment_parent_markwon_view_comment_activity) TextView commentParentMarkwonView; @BindView(R.id.comment_edit_text_comment_activity) EditText commentEditText; private boolean mNullAccessToken = false; @@ -122,7 +128,25 @@ public class CommentActivity extends AppCompatActivity { } Intent intent = getIntent(); - commentParentMarkwonView.setMarkdown(intent.getExtras().getString(EXTRA_COMMENT_PARENT_TEXT_KEY)); + Markwon markwon = Markwon.builder(this) + .usePlugin(new AbstractMarkwonPlugin() { + @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); + if(uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(link)); + } else { + intent.setData(uri); + } + startActivity(intent); + }); + } + }) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .build(); + markwon.setMarkdown(commentParentMarkwonView, intent.getExtras().getString(EXTRA_COMMENT_PARENT_TEXT_KEY)); parentFullname = intent.getExtras().getString(EXTRA_PARENT_FULLNAME_KEY); parentDepth = intent.getExtras().getInt(EXTRA_PARENT_DEPTH_KEY); parentPosition = intent.getExtras().getInt(EXTRA_PARENT_POSITION_KEY); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentAndPostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentAndPostRecyclerViewAdapter.java index 996ba720..0f29b823 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentAndPostRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentAndPostRecyclerViewAdapter.java @@ -7,6 +7,7 @@ import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; +import android.text.util.Linkify; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -40,9 +41,14 @@ import java.util.ArrayList; import java.util.Locale; import CustomView.AspectRatioGifImageView; -import CustomView.CustomMarkwonView; 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.ext.strikethrough.StrikethroughPlugin; +import io.noties.markwon.linkify.LinkifyPlugin; +import io.noties.markwon.urlprocessor.UrlProcessorRelativeToAbsolute; import jp.wasabeef.glide.transformations.BlurTransformation; import jp.wasabeef.glide.transformations.RoundedCornersTransformation; import retrofit2.Retrofit; @@ -63,6 +69,7 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie private Retrofit mOauthRetrofit; private RedditDataRoomDatabase mRedditDataRoomDatabase; private RequestManager mGlide; + private Markwon mMarkwon; private String mAccessToken; private String mAccountName; private Post mPost; @@ -84,14 +91,33 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie CommentAndPostRecyclerViewAdapter(Activity activity, Retrofit retrofit, Retrofit oauthRetrofit, RedditDataRoomDatabase redditDataRoomDatabase, RequestManager glide, - String accessToken, String accountName, Post post, Locale locale, - String singleCommentId, boolean isSingleCommentThreadMode, + String accessToken, String accountName, Post post, + Locale locale, String singleCommentId, boolean isSingleCommentThreadMode, CommentRecyclerViewAdapterCallback commentRecyclerViewAdapterCallback) { mActivity = activity; mRetrofit = retrofit; mOauthRetrofit = oauthRetrofit; mRedditDataRoomDatabase = redditDataRoomDatabase; mGlide = glide; + mMarkwon = Markwon.builder(mActivity) + .usePlugin(new AbstractMarkwonPlugin() { + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(mActivity, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + if(uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(link)); + } else { + intent.setData(uri); + } + mActivity.startActivity(intent); + }).urlProcessor(new UrlProcessorRelativeToAbsolute("https://www.reddit.com")); + } + }) + .usePlugin(StrikethroughPlugin.create()) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .build(); mAccessToken = accessToken; mAccountName = accountName; mPost = post; @@ -422,8 +448,9 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie if(!mPost.getSelfText().equals("")) { ((PostDetailViewHolder) holder).mContentMarkdownView.setVisibility(View.VISIBLE); - ((PostDetailViewHolder) holder).mContentMarkdownView.setMarkdown(mPost.getSelfText(), mActivity); + mMarkwon.setMarkdown(((PostDetailViewHolder) holder).mContentMarkdownView, mPost.getSelfText()); } + ((PostDetailViewHolder) holder).mNoPreviewLinkImageView.setVisibility(View.VISIBLE); ((PostDetailViewHolder) holder).mNoPreviewLinkImageView.setOnClickListener(view -> { CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); @@ -447,7 +474,7 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie if(!mPost.getSelfText().equals("")) { ((PostDetailViewHolder) holder).mContentMarkdownView.setVisibility(View.VISIBLE); - ((PostDetailViewHolder) holder).mContentMarkdownView.setMarkdown(mPost.getSelfText(), mActivity); + mMarkwon.setMarkdown(((PostDetailViewHolder) holder).mContentMarkdownView, mPost.getSelfText()); } break; } @@ -469,7 +496,7 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie ((CommentViewHolder) holder).commentTimeTextView.setText(comment.getCommentTime()); - ((CommentViewHolder) holder).commentMarkdownView.setMarkdown(comment.getCommentContent(), mActivity); + mMarkwon.setMarkdown(((CommentViewHolder) holder).commentMarkdownView, comment.getCommentContent()); ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(comment.getScore())); ViewGroup.LayoutParams params = ((CommentViewHolder) holder).verticalBlock.getLayoutParams(); @@ -956,7 +983,7 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie @BindView(R.id.user_text_view_item_post_detail) TextView mUserTextView; @BindView(R.id.post_time_text_view_item_post_detail) TextView mPostTimeTextView; @BindView(R.id.title_text_view_item_post_detail) TextView mTitleTextView; - @BindView(R.id.content_markdown_view_item_post_detail) CustomMarkwonView mContentMarkdownView; + @BindView(R.id.content_markdown_view_item_post_detail) TextView mContentMarkdownView; @BindView(R.id.type_text_view_item_post_detail) Chip mTypeChip; @BindView(R.id.gilded_image_view_item_post_detail) ImageView mGildedImageView; @BindView(R.id.gilded_number_text_view_item_post_detail) TextView mGildedNumberTextView; @@ -1143,7 +1170,7 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie class CommentViewHolder extends RecyclerView.ViewHolder { @BindView(R.id.author_text_view_item_post_comment) TextView authorTextView; @BindView(R.id.comment_time_text_view_item_post_comment) TextView commentTimeTextView; - @BindView(R.id.comment_markdown_view_item_post_comment) CustomMarkwonView commentMarkdownView; + @BindView(R.id.comment_markdown_view_item_post_comment) TextView commentMarkdownView; @BindView(R.id.up_vote_button_item_post_comment) ImageView upVoteButton; @BindView(R.id.score_text_view_item_post_comment) TextView scoreTextView; @BindView(R.id.down_vote_button_item_post_comment) ImageView downVoteButton; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentsListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentsListingRecyclerViewAdapter.java index adab3ba3..c7979c63 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentsListingRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentsListingRecyclerViewAdapter.java @@ -2,7 +2,9 @@ package ml.docilealligator.infinityforreddit; import android.content.Context; import android.content.Intent; +import android.net.Uri; import android.os.Bundle; +import android.text.util.Linkify; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -19,14 +21,19 @@ import androidx.paging.PagedListAdapter; import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.RecyclerView; -import CustomView.CustomMarkwonView; 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.ext.strikethrough.StrikethroughPlugin; +import io.noties.markwon.linkify.LinkifyPlugin; import retrofit2.Retrofit; class CommentsListingRecyclerViewAdapter extends PagedListAdapter<CommentData, RecyclerView.ViewHolder> { private Context mContext; private Retrofit mOauthRetrofit; + private Markwon mMarkwon; private String mAccessToken; private String mAccountName; private int mTextColorPrimaryDark; @@ -43,11 +50,31 @@ class CommentsListingRecyclerViewAdapter extends PagedListAdapter<CommentData, R void retryLoadingMore(); } - protected CommentsListingRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, String accessToken, - String accountName, RetryLoadingMoreCallback retryLoadingMoreCallback) { + protected CommentsListingRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, + String accessToken, String accountName, + RetryLoadingMoreCallback retryLoadingMoreCallback) { super(DIFF_CALLBACK); mContext = context; mOauthRetrofit = oauthRetrofit; + mMarkwon = Markwon.builder(mContext) + .usePlugin(new AbstractMarkwonPlugin() { + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(mContext, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + if(uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(link)); + } else { + intent.setData(uri); + } + mContext.startActivity(intent); + }); + } + }) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .usePlugin(StrikethroughPlugin.create()) + .build(); mAccessToken = accessToken; mAccountName = accountName; mRetryLoadingMoreCallback = retryLoadingMoreCallback; @@ -104,7 +131,8 @@ class CommentsListingRecyclerViewAdapter extends PagedListAdapter<CommentData, R ((DataViewHolder) holder).commentTimeTextView.setText(comment.getCommentTime()); - ((DataViewHolder) holder).commentMarkdownView.setMarkdown(comment.getCommentContent(), mContext); + mMarkwon.setMarkdown(((DataViewHolder) holder).commentMarkdownView, comment.getCommentContent()); + ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(comment.getScore())); switch (comment.getVoteType()) { @@ -182,7 +210,7 @@ class CommentsListingRecyclerViewAdapter extends PagedListAdapter<CommentData, R @BindView(R.id.vertical_block_item_post_comment) View verticalBlock; @BindView(R.id.author_text_view_item_post_comment) TextView authorTextView; @BindView(R.id.comment_time_text_view_item_post_comment) TextView commentTimeTextView; - @BindView(R.id.comment_markdown_view_item_post_comment) CustomMarkwonView commentMarkdownView; + @BindView(R.id.comment_markdown_view_item_post_comment) TextView commentMarkdownView; @BindView(R.id.up_vote_button_item_post_comment) ImageView upvoteButton; @BindView(R.id.score_text_view_item_post_comment) TextView scoreTextView; @BindView(R.id.down_vote_button_item_post_comment) ImageView downvoteButton; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchMessages.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchMessages.java index 424c1c83..f2fc9b3a 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchMessages.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchMessages.java @@ -76,7 +76,7 @@ class FetchMessages { String author = rawMessageJSON.getString(JSONUtils.AUTHOR_KEY); String parentFullname = rawMessageJSON.getString(JSONUtils.PARENT_ID_KEY); String title = rawMessageJSON.has(JSONUtils.LINK_TITLE_KEY) ? rawMessageJSON.getString(JSONUtils.LINK_TITLE_KEY) : null; - String body = rawMessageJSON.getString(JSONUtils.BODY_KEY); + String body = Utils.addSubredditAndUserLink(rawMessageJSON.getString(JSONUtils.BODY_KEY)); String context = rawMessageJSON.getString(JSONUtils.CONTEXT_KEY); String distinguished = rawMessageJSON.getString(JSONUtils.DISTINGUISHED_KEY); boolean wasComment = rawMessageJSON.getBoolean(JSONUtils.WAS_COMMENT_KEY); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java index 235ba621..91d67096 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java @@ -73,7 +73,7 @@ public class JSONUtils { static final String SPOILER_KEY = "spoiler"; static final String RULES_KEY = "rules"; static final String SHORT_NAME_KEY = "short_name"; - static final String DESCRIPTION_HTML_KEY = "description_html"; + static final String DESCRIPTION_KEY = "description"; static final String ARCHIVED_KEY = "archived"; static final String LOCKEC_KEY = "locked"; static final String SAVED_KEY = "saved"; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/LinkResolverActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/LinkResolverActivity.java index 81fed5d1..f520ba24 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/LinkResolverActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/LinkResolverActivity.java @@ -32,7 +32,8 @@ public class LinkResolverActivity extends AppCompatActivity { private static final String POST_PATTERN = "/r/\\w+/comments/\\w+/{0,1}\\w+/{0,1}"; private static final String COMMENT_PATTERN = "/r/\\w+/comments/\\w+/{0,1}\\w+/\\w+/{0,1}"; private static final String SUBREDDIT_PATTERN = "/r/\\w+/*"; - private static final String USER_PATTERN = "/user/\\w+/*"; + private static final String USER_PATTERN_1 = "/user/\\w+/*"; + private static final String USER_PATTERN_2 = "/u/\\w+/*"; @Inject SharedPreferences mSharedPreferences; @@ -117,12 +118,18 @@ public class LinkResolverActivity extends AppCompatActivity { intent.putExtra(ViewSubredditDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); startActivity(intent); } - } else if(path.matches(USER_PATTERN)) { + } else if(path.matches(USER_PATTERN_1)) { Intent intent = new Intent(this, ViewUserDetailActivity.class); intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, path.substring(6)); intent.putExtra(ViewUserDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); intent.putExtra(ViewUserDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); startActivity(intent); + } else if(path.matches(USER_PATTERN_2)) { + Intent intent = new Intent(this, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, path.substring(3)); + intent.putExtra(ViewUserDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); + intent.putExtra(ViewUserDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); + startActivity(intent); } else { deepLinkError(uri); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MessageRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MessageRecyclerViewAdapter.java index 9ade4b03..3c627760 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MessageRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/MessageRecyclerViewAdapter.java @@ -4,6 +4,7 @@ import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.net.Uri; +import android.text.util.Linkify; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -15,9 +16,13 @@ import androidx.paging.PagedListAdapter; import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.RecyclerView; -import CustomView.CustomMarkwonView; 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.ext.strikethrough.StrikethroughPlugin; +import io.noties.markwon.linkify.LinkifyPlugin; import retrofit2.Retrofit; class MessageRecyclerViewAdapter extends PagedListAdapter<Message, RecyclerView.ViewHolder> { @@ -27,20 +32,42 @@ class MessageRecyclerViewAdapter extends PagedListAdapter<Message, RecyclerView. private Context mContext; private Retrofit mOauthRetrofit; + private Markwon mMarkwon; private String mAccessToken; private Resources mResources; private NetworkState networkState; - private CommentsListingRecyclerViewAdapter.RetryLoadingMoreCallback mRetryLoadingMoreCallback; + private RetryLoadingMoreCallback mRetryLoadingMoreCallback; interface RetryLoadingMoreCallback { void retryLoadingMore(); } - MessageRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, String accessToken) { + MessageRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, String accessToken, + RetryLoadingMoreCallback retryLoadingMoreCallback) { super(DIFF_CALLBACK); mContext = context; mOauthRetrofit = oauthRetrofit; + mRetryLoadingMoreCallback = retryLoadingMoreCallback; + mMarkwon = Markwon.builder(mContext) + .usePlugin(new AbstractMarkwonPlugin() { + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(mContext, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + if(uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(link)); + } else { + intent.setData(uri); + } + mContext.startActivity(intent); + }); + } + }) + .usePlugin(StrikethroughPlugin.create()) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .build(); mAccessToken = accessToken; mResources = context.getResources(); } @@ -89,7 +116,7 @@ class MessageRecyclerViewAdapter extends PagedListAdapter<Message, RecyclerView. ((DataViewHolder) holder).authorTextView.setText(message.getAuthor()); String subject = message.getSubject().substring(0, 1).toUpperCase() + message.getSubject().substring(1); ((DataViewHolder) holder).subjectTextView.setText(subject); - ((DataViewHolder) holder).contentCustomMarkwonView.setMarkdown(message.getBody(), mContext); + mMarkwon.setMarkdown(((DataViewHolder) holder).contentCustomMarkwonView, message.getBody()); ((DataViewHolder) holder).itemView.setOnClickListener(view -> { if(message.getContext() != null && !message.getContext().equals("")) { @@ -185,7 +212,7 @@ class MessageRecyclerViewAdapter extends PagedListAdapter<Message, RecyclerView. @BindView(R.id.author_text_view_item_message) TextView authorTextView; @BindView(R.id.subject_text_view_item_message) TextView subjectTextView; @BindView(R.id.title_text_view_item_message) TextView titleTextView; - @BindView(R.id.content_custom_markwon_view_item_message) CustomMarkwonView contentCustomMarkwonView; + @BindView(R.id.content_custom_markwon_view_item_message) TextView contentCustomMarkwonView; DataViewHolder(View itemView) { super(itemView); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseComment.java index aeddffc0..275acb6c 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseComment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseComment.java @@ -225,7 +225,7 @@ class ParseComment { boolean isSubmitter = singleCommentData.getBoolean(JSONUtils.IS_SUBMITTER_KEY); String commentContent = ""; if(!singleCommentData.isNull(JSONUtils.BODY_KEY)) { - commentContent = singleCommentData.getString(JSONUtils.BODY_KEY).trim(); + commentContent = Utils.addSubredditAndUserLink(singleCommentData.getString(JSONUtils.BODY_KEY).trim()); } String permalink = Html.fromHtml(singleCommentData.getString(JSONUtils.PERMALINK_KEY)).toString(); int score = singleCommentData.getInt(JSONUtils.SCORE_KEY); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java index cac74e40..009bcb18 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java @@ -234,7 +234,7 @@ class ParsePost { if(data.isNull(JSONUtils.SELFTEXT_KEY)) { post.setSelfText(""); } else { - post.setSelfText(data.getString(JSONUtils.SELFTEXT_KEY).trim()); + post.setSelfText(Utils.addSubredditAndUserLink(data.getString(JSONUtils.SELFTEXT_KEY).trim())); } } else { //No preview link post @@ -246,7 +246,7 @@ class ParsePost { if(data.isNull(JSONUtils.SELFTEXT_KEY)) { post.setSelfText(""); } else { - post.setSelfText(data.getString(JSONUtils.SELFTEXT_KEY).trim()); + post.setSelfText(Utils.addSubredditAndUserLink(data.getString(JSONUtils.SELFTEXT_KEY).trim())); } } } else { @@ -329,7 +329,7 @@ class ParsePost { if(data.isNull(JSONUtils.SELFTEXT_KEY)) { post.setSelfText(""); } else { - post.setSelfText(data.getString(JSONUtils.SELFTEXT_KEY).trim()); + post.setSelfText(Utils.addSubredditAndUserLink(data.getString(JSONUtils.SELFTEXT_KEY).trim())); } } else { //Link post @@ -342,7 +342,7 @@ class ParsePost { if(data.isNull(JSONUtils.SELFTEXT_KEY)) { post.setSelfText(""); } else { - post.setSelfText(data.getString(JSONUtils.SELFTEXT_KEY).trim()); + post.setSelfText(Utils.addSubredditAndUserLink(data.getString(JSONUtils.SELFTEXT_KEY).trim())); } post.setPreviewWidth(previewWidth); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RulesActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RulesActivity.java index 4a30c1d6..39ab8d42 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RulesActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/RulesActivity.java @@ -6,6 +6,7 @@ import android.content.res.Resources; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; +import android.util.Log; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; @@ -237,11 +238,12 @@ public class RulesActivity extends AppCompatActivity { ArrayList<Rule> rules = new ArrayList<>(); for(int i = 0; i < rulesArray.length(); i++) { String shortName = rulesArray.getJSONObject(i).getString(JSONUtils.SHORT_NAME_KEY); - String descriptionHtml = null; - if(rulesArray.getJSONObject(i).has(JSONUtils.DESCRIPTION_HTML_KEY)) { - descriptionHtml = rulesArray.getJSONObject(i).getString(JSONUtils.DESCRIPTION_HTML_KEY); + String description = null; + if(rulesArray.getJSONObject(i).has(JSONUtils.DESCRIPTION_KEY)) { + Log.i("asdfasdf", "" + rulesArray.getJSONObject(i).getString(JSONUtils.DESCRIPTION_KEY)); + description = Utils.addSubredditAndUserLink(rulesArray.getJSONObject(i).getString(JSONUtils.DESCRIPTION_KEY)); } - rules.add(new Rule(shortName, descriptionHtml)); + rules.add(new Rule(shortName, description)); } return rules; } catch (JSONException e) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RulesRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RulesRecyclerViewAdapter.java index 941b0316..4ab0f201 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RulesRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/RulesRecyclerViewAdapter.java @@ -1,6 +1,9 @@ package ml.docilealligator.infinityforreddit; import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.text.util.Linkify; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -11,16 +14,38 @@ import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; -import CustomView.CustomMarkwonView; 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.ext.strikethrough.StrikethroughPlugin; +import io.noties.markwon.linkify.LinkifyPlugin; class RulesRecyclerViewAdapter extends RecyclerView.Adapter<RulesRecyclerViewAdapter.RuleViewHolder> { - private Context context; + private Markwon markwon; private ArrayList<Rule> rules; RulesRecyclerViewAdapter(Context context) { - this.context = context; + markwon = Markwon.builder(context) + .usePlugin(new AbstractMarkwonPlugin() { + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(context, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + if(uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(link)); + } else { + intent.setData(uri); + } + context.startActivity(intent); + }); + } + }) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .usePlugin(StrikethroughPlugin.create()) + .build(); } @NonNull @@ -35,7 +60,7 @@ class RulesRecyclerViewAdapter extends RecyclerView.Adapter<RulesRecyclerViewAda if(rules.get(holder.getAdapterPosition()).getDescriptionHtml() == null) { holder.descriptionMarkwonView.setVisibility(View.GONE); } else { - holder.descriptionMarkwonView.setMarkdown(rules.get(holder.getAdapterPosition()).getDescriptionHtml(), context); + markwon.setMarkdown(holder.descriptionMarkwonView, rules.get(holder.getAdapterPosition()).getDescriptionHtml()); } } @@ -57,7 +82,7 @@ class RulesRecyclerViewAdapter extends RecyclerView.Adapter<RulesRecyclerViewAda class RuleViewHolder extends RecyclerView.ViewHolder { @BindView(R.id.short_name_text_view_item_rule) TextView shortNameTextView; - @BindView(R.id.description_markwon_view_item_rule) CustomMarkwonView descriptionMarkwonView; + @BindView(R.id.description_markwon_view_item_rule) TextView descriptionMarkwonView; RuleViewHolder(@NonNull View itemView) { super(itemView); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Utils.java new file mode 100644 index 00000000..9833702d --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Utils.java @@ -0,0 +1,8 @@ +package ml.docilealligator.infinityforreddit; + +class Utils { + static String addSubredditAndUserLink(String markdown) { + return markdown.replaceAll("(?<!\\w)/+u/\\w+/*", "[$0]($0)") + .replaceAll("(?<!\\w)/+r/\\w+/*", "[$0]($0)"); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewMessageActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewMessageActivity.java index 8ca6ec16..629440f1 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewMessageActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewMessageActivity.java @@ -213,7 +213,8 @@ public class ViewMessageActivity extends AppCompatActivity { } private void bindView() { - mAdapter = new MessageRecyclerViewAdapter(this, mOauthRetrofit, mAccessToken); + mAdapter = new MessageRecyclerViewAdapter(this, mOauthRetrofit, mAccessToken, + () -> mMessageViewModel.retryLoadingMore()); LinearLayoutManager layoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(layoutManager); recyclerView.setAdapter(mAdapter); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java index 9659d620..a170275c 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java @@ -433,9 +433,10 @@ public class ViewPostDetailActivity extends AppCompatActivity implements FlairBo mMenu.findItem(R.id.action_delete_view_post_detail_activity).setVisible(true); } - mAdapter = new CommentAndPostRecyclerViewAdapter(ViewPostDetailActivity.this, mRetrofit, - mOauthRetrofit, mRedditDataRoomDatabase, mGlide, mAccessToken, mAccountName, mPost, - mLocale, mSingleCommentId, isSingleCommentThreadMode, + mAdapter = new CommentAndPostRecyclerViewAdapter(ViewPostDetailActivity.this, + mRetrofit, mOauthRetrofit, mRedditDataRoomDatabase, mGlide, + mAccessToken, mAccountName, mPost, mLocale, mSingleCommentId, + isSingleCommentThreadMode, new CommentAndPostRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() { @Override public void updatePost(Post post) { diff --git a/app/src/main/res/layout/activity_comment.xml b/app/src/main/res/layout/activity_comment.xml index 76a053bf..494872ce 100644 --- a/app/src/main/res/layout/activity_comment.xml +++ b/app/src/main/res/layout/activity_comment.xml @@ -32,7 +32,7 @@ android:orientation="vertical" android:padding="16dp"> - <ru.noties.markwon.view.MarkwonView + <TextView android:id="@+id/comment_parent_markwon_view_comment_activity" android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/app/src/main/res/layout/item_comment.xml b/app/src/main/res/layout/item_comment.xml index 53613bc8..a9489d0a 100644 --- a/app/src/main/res/layout/item_comment.xml +++ b/app/src/main/res/layout/item_comment.xml @@ -42,7 +42,7 @@ </LinearLayout> - <CustomView.CustomMarkwonView + <TextView android:id="@+id/comment_markdown_view_item_post_comment" android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/app/src/main/res/layout/item_message.xml b/app/src/main/res/layout/item_message.xml index 12fd25c4..9fe9e0d4 100644 --- a/app/src/main/res/layout/item_message.xml +++ b/app/src/main/res/layout/item_message.xml @@ -26,7 +26,7 @@ android:layout_marginBottom="8dp" android:textColor="@color/primaryTextColor" /> - <CustomView.CustomMarkwonView + <TextView android:id="@+id/content_custom_markwon_view_item_message" android:layout_width="match_parent" android:layout_height="wrap_content" /> diff --git a/app/src/main/res/layout/item_post_detail.xml b/app/src/main/res/layout/item_post_detail.xml index a1fc7776..886f169f 100644 --- a/app/src/main/res/layout/item_post_detail.xml +++ b/app/src/main/res/layout/item_post_detail.xml @@ -71,7 +71,7 @@ android:textColor="@color/primaryTextColor" android:textSize="18sp" /> - <CustomView.CustomMarkwonView + <TextView android:id="@+id/content_markdown_view_item_post_detail" android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/app/src/main/res/layout/item_rule.xml b/app/src/main/res/layout/item_rule.xml index 1124a548..2c4a845b 100644 --- a/app/src/main/res/layout/item_rule.xml +++ b/app/src/main/res/layout/item_rule.xml @@ -11,7 +11,7 @@ android:textColor="@color/primaryTextColor" android:textSize="16sp" /> - <CustomView.CustomMarkwonView + <TextView android:id="@+id/description_markwon_view_item_rule" android:layout_width="match_parent" android:layout_height="wrap_content" |