Reimplement Markdown display due to update of Markwon library. Fixed RetryLoadingMoreCallback is null in MessageRecyclerViewAdapter.

This commit is contained in:
Alex Ning 2019-08-26 13:52:19 +08:00
parent 4d4e6165f0
commit 5e144c6de9
23 changed files with 264 additions and 78 deletions

Binary file not shown.

View File

@ -67,10 +67,10 @@ dependencies {
annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0' annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0'
implementation 'com.github.santalu:aspect-ratio-imageview:1.0.6' implementation 'com.github.santalu:aspect-ratio-imageview:1.0.6'
implementation 'androidx.paging:paging-runtime:2.1.0' implementation 'androidx.paging:paging-runtime:2.1.0'
implementation "com.lsjwzh:materialloadingprogressbar:0.5.8-RELEASE" implementation 'com.lsjwzh:materialloadingprogressbar:0.5.8-RELEASE'
implementation "ru.noties:markwon:2.0.1" implementation 'io.noties.markwon:core:4.1.0'
implementation "ru.noties:markwon-syntax-highlight:2.0.1" implementation 'io.noties.markwon:linkify:4.1.0'
implementation "ru.noties:markwon-view:2.0.1" implementation 'io.noties.markwon:ext-strikethrough:4.1.0'
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.16' implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.16'
implementation 'com.github.Ferfalk:SimpleSearchView:0.1.3' implementation 'com.github.Ferfalk:SimpleSearchView:0.1.3'
implementation 'org.greenrobot:eventbus:3.1.1' implementation 'org.greenrobot:eventbus:3.1.1'
@ -79,6 +79,7 @@ dependencies {
implementation 'com.github.livefront:bridge:v1.2.0' implementation 'com.github.livefront:bridge:v1.2.0'
implementation 'com.evernote:android-state:1.4.1' implementation 'com.evernote:android-state:1.4.1'
annotationProcessor 'com.evernote:android-state-processor:1.4.1' annotationProcessor 'com.evernote:android-state-processor:1.4.1'
implementation "androidx.work:work-runtime:2.2.0" implementation 'androidx.work:work-runtime:2.2.0'
implementation "androidx.preference:preference:1.1.0-rc01" implementation 'androidx.preference:preference:1.1.0-rc01'
implementation 'org.sufficientlysecure:html-textview:3.6'
} }

View File

@ -1,38 +1,73 @@
package CustomView; package CustomView;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.text.Spanned;
import android.net.Uri; import android.widget.TextView;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import ml.docilealligator.infinityforreddit.LinkResolverActivity; import org.commonmark.node.Node;
import ru.noties.markwon.SpannableConfiguration;
import ru.noties.markwon.view.MarkwonView;
public class CustomMarkwonView extends MarkwonView { import java.util.List;
public CustomMarkwonView(Context context) { import io.noties.markwon.Markwon;
super(context); import io.noties.markwon.MarkwonPlugin;
}
public CustomMarkwonView(Context context, AttributeSet attrs) { public class CustomMarkwonView extends Markwon {
super(context, attrs);
}
public void setMarkdown(@Nullable String markdown, Context context) { 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 Node parse(@NonNull String input) {
return null;
}
@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;
} }
} }

View File

@ -4,14 +4,17 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.util.Linkify;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.Window; import android.view.Window;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -31,8 +34,11 @@ import javax.inject.Named;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; 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 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_AUTO_BATTERY;
import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; 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.coordinator_layout_comment_activity) CoordinatorLayout coordinatorLayout;
@BindView(R.id.toolbar_comment_activity) Toolbar toolbar; @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; @BindView(R.id.comment_edit_text_comment_activity) EditText commentEditText;
private boolean mNullAccessToken = false; private boolean mNullAccessToken = false;
@ -122,7 +128,25 @@ public class CommentActivity extends AppCompatActivity {
} }
Intent intent = getIntent(); 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); parentFullname = intent.getExtras().getString(EXTRA_PARENT_FULLNAME_KEY);
parentDepth = intent.getExtras().getInt(EXTRA_PARENT_DEPTH_KEY); parentDepth = intent.getExtras().getInt(EXTRA_PARENT_DEPTH_KEY);
parentPosition = intent.getExtras().getInt(EXTRA_PARENT_POSITION_KEY); parentPosition = intent.getExtras().getInt(EXTRA_PARENT_POSITION_KEY);

View File

@ -7,6 +7,7 @@ import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.text.util.Linkify;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -40,9 +41,14 @@ import java.util.ArrayList;
import java.util.Locale; import java.util.Locale;
import CustomView.AspectRatioGifImageView; import CustomView.AspectRatioGifImageView;
import CustomView.CustomMarkwonView;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; 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.BlurTransformation;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation; import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
import retrofit2.Retrofit; import retrofit2.Retrofit;
@ -63,6 +69,7 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie
private Retrofit mOauthRetrofit; private Retrofit mOauthRetrofit;
private RedditDataRoomDatabase mRedditDataRoomDatabase; private RedditDataRoomDatabase mRedditDataRoomDatabase;
private RequestManager mGlide; private RequestManager mGlide;
private Markwon mMarkwon;
private String mAccessToken; private String mAccessToken;
private String mAccountName; private String mAccountName;
private Post mPost; private Post mPost;
@ -84,14 +91,33 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie
CommentAndPostRecyclerViewAdapter(Activity activity, Retrofit retrofit, Retrofit oauthRetrofit, CommentAndPostRecyclerViewAdapter(Activity activity, Retrofit retrofit, Retrofit oauthRetrofit,
RedditDataRoomDatabase redditDataRoomDatabase, RequestManager glide, RedditDataRoomDatabase redditDataRoomDatabase, RequestManager glide,
String accessToken, String accountName, Post post, Locale locale, String accessToken, String accountName, Post post,
String singleCommentId, boolean isSingleCommentThreadMode, Locale locale, String singleCommentId, boolean isSingleCommentThreadMode,
CommentRecyclerViewAdapterCallback commentRecyclerViewAdapterCallback) { CommentRecyclerViewAdapterCallback commentRecyclerViewAdapterCallback) {
mActivity = activity; mActivity = activity;
mRetrofit = retrofit; mRetrofit = retrofit;
mOauthRetrofit = oauthRetrofit; mOauthRetrofit = oauthRetrofit;
mRedditDataRoomDatabase = redditDataRoomDatabase; mRedditDataRoomDatabase = redditDataRoomDatabase;
mGlide = glide; 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; mAccessToken = accessToken;
mAccountName = accountName; mAccountName = accountName;
mPost = post; mPost = post;
@ -422,8 +448,9 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie
if(!mPost.getSelfText().equals("")) { if(!mPost.getSelfText().equals("")) {
((PostDetailViewHolder) holder).mContentMarkdownView.setVisibility(View.VISIBLE); ((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.setVisibility(View.VISIBLE);
((PostDetailViewHolder) holder).mNoPreviewLinkImageView.setOnClickListener(view -> { ((PostDetailViewHolder) holder).mNoPreviewLinkImageView.setOnClickListener(view -> {
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
@ -447,7 +474,7 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie
if(!mPost.getSelfText().equals("")) { if(!mPost.getSelfText().equals("")) {
((PostDetailViewHolder) holder).mContentMarkdownView.setVisibility(View.VISIBLE); ((PostDetailViewHolder) holder).mContentMarkdownView.setVisibility(View.VISIBLE);
((PostDetailViewHolder) holder).mContentMarkdownView.setMarkdown(mPost.getSelfText(), mActivity); mMarkwon.setMarkdown(((PostDetailViewHolder) holder).mContentMarkdownView, mPost.getSelfText());
} }
break; break;
} }
@ -469,7 +496,7 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVie
((CommentViewHolder) holder).commentTimeTextView.setText(comment.getCommentTime()); ((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())); ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(comment.getScore()));
ViewGroup.LayoutParams params = ((CommentViewHolder) holder).verticalBlock.getLayoutParams(); 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.user_text_view_item_post_detail) TextView mUserTextView;
@BindView(R.id.post_time_text_view_item_post_detail) TextView mPostTimeTextView; @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.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.type_text_view_item_post_detail) Chip mTypeChip;
@BindView(R.id.gilded_image_view_item_post_detail) ImageView mGildedImageView; @BindView(R.id.gilded_image_view_item_post_detail) ImageView mGildedImageView;
@BindView(R.id.gilded_number_text_view_item_post_detail) TextView mGildedNumberTextView; @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 { class CommentViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.author_text_view_item_post_comment) TextView authorTextView; @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_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.up_vote_button_item_post_comment) ImageView upVoteButton;
@BindView(R.id.score_text_view_item_post_comment) TextView scoreTextView; @BindView(R.id.score_text_view_item_post_comment) TextView scoreTextView;
@BindView(R.id.down_vote_button_item_post_comment) ImageView downVoteButton; @BindView(R.id.down_vote_button_item_post_comment) ImageView downVoteButton;

View File

@ -2,7 +2,9 @@ package ml.docilealligator.infinityforreddit;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.text.util.Linkify;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -19,14 +21,19 @@ import androidx.paging.PagedListAdapter;
import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import CustomView.CustomMarkwonView;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; 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; import retrofit2.Retrofit;
class CommentsListingRecyclerViewAdapter extends PagedListAdapter<CommentData, RecyclerView.ViewHolder> { class CommentsListingRecyclerViewAdapter extends PagedListAdapter<CommentData, RecyclerView.ViewHolder> {
private Context mContext; private Context mContext;
private Retrofit mOauthRetrofit; private Retrofit mOauthRetrofit;
private Markwon mMarkwon;
private String mAccessToken; private String mAccessToken;
private String mAccountName; private String mAccountName;
private int mTextColorPrimaryDark; private int mTextColorPrimaryDark;
@ -43,11 +50,31 @@ class CommentsListingRecyclerViewAdapter extends PagedListAdapter<CommentData, R
void retryLoadingMore(); void retryLoadingMore();
} }
protected CommentsListingRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, String accessToken, protected CommentsListingRecyclerViewAdapter(Context context, Retrofit oauthRetrofit,
String accountName, RetryLoadingMoreCallback retryLoadingMoreCallback) { String accessToken, String accountName,
RetryLoadingMoreCallback retryLoadingMoreCallback) {
super(DIFF_CALLBACK); super(DIFF_CALLBACK);
mContext = context; mContext = context;
mOauthRetrofit = oauthRetrofit; 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; mAccessToken = accessToken;
mAccountName = accountName; mAccountName = accountName;
mRetryLoadingMoreCallback = retryLoadingMoreCallback; mRetryLoadingMoreCallback = retryLoadingMoreCallback;
@ -104,7 +131,8 @@ class CommentsListingRecyclerViewAdapter extends PagedListAdapter<CommentData, R
((DataViewHolder) holder).commentTimeTextView.setText(comment.getCommentTime()); ((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())); ((DataViewHolder) holder).scoreTextView.setText(Integer.toString(comment.getScore()));
switch (comment.getVoteType()) { 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.vertical_block_item_post_comment) View verticalBlock;
@BindView(R.id.author_text_view_item_post_comment) TextView authorTextView; @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_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.up_vote_button_item_post_comment) ImageView upvoteButton;
@BindView(R.id.score_text_view_item_post_comment) TextView scoreTextView; @BindView(R.id.score_text_view_item_post_comment) TextView scoreTextView;
@BindView(R.id.down_vote_button_item_post_comment) ImageView downvoteButton; @BindView(R.id.down_vote_button_item_post_comment) ImageView downvoteButton;

View File

@ -76,7 +76,7 @@ class FetchMessages {
String author = rawMessageJSON.getString(JSONUtils.AUTHOR_KEY); String author = rawMessageJSON.getString(JSONUtils.AUTHOR_KEY);
String parentFullname = rawMessageJSON.getString(JSONUtils.PARENT_ID_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 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 context = rawMessageJSON.getString(JSONUtils.CONTEXT_KEY);
String distinguished = rawMessageJSON.getString(JSONUtils.DISTINGUISHED_KEY); String distinguished = rawMessageJSON.getString(JSONUtils.DISTINGUISHED_KEY);
boolean wasComment = rawMessageJSON.getBoolean(JSONUtils.WAS_COMMENT_KEY); boolean wasComment = rawMessageJSON.getBoolean(JSONUtils.WAS_COMMENT_KEY);

View File

@ -73,7 +73,7 @@ public class JSONUtils {
static final String SPOILER_KEY = "spoiler"; static final String SPOILER_KEY = "spoiler";
static final String RULES_KEY = "rules"; static final String RULES_KEY = "rules";
static final String SHORT_NAME_KEY = "short_name"; 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 ARCHIVED_KEY = "archived";
static final String LOCKEC_KEY = "locked"; static final String LOCKEC_KEY = "locked";
static final String SAVED_KEY = "saved"; static final String SAVED_KEY = "saved";

View File

@ -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 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 COMMENT_PATTERN = "/r/\\w+/comments/\\w+/{0,1}\\w+/\\w+/{0,1}";
private static final String SUBREDDIT_PATTERN = "/r/\\w+/*"; 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 @Inject
SharedPreferences mSharedPreferences; SharedPreferences mSharedPreferences;
@ -117,12 +118,18 @@ public class LinkResolverActivity extends AppCompatActivity {
intent.putExtra(ViewSubredditDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); intent.putExtra(ViewSubredditDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName);
startActivity(intent); startActivity(intent);
} }
} else if(path.matches(USER_PATTERN)) { } else if(path.matches(USER_PATTERN_1)) {
Intent intent = new Intent(this, ViewUserDetailActivity.class); Intent intent = new Intent(this, ViewUserDetailActivity.class);
intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, path.substring(6)); intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, path.substring(6));
intent.putExtra(ViewUserDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); intent.putExtra(ViewUserDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname);
intent.putExtra(ViewUserDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); intent.putExtra(ViewUserDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName);
startActivity(intent); 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 { } else {
deepLinkError(uri); deepLinkError(uri);
} }

View File

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.net.Uri; import android.net.Uri;
import android.text.util.Linkify;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -15,9 +16,13 @@ import androidx.paging.PagedListAdapter;
import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import CustomView.CustomMarkwonView;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; 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; import retrofit2.Retrofit;
class MessageRecyclerViewAdapter extends PagedListAdapter<Message, RecyclerView.ViewHolder> { class MessageRecyclerViewAdapter extends PagedListAdapter<Message, RecyclerView.ViewHolder> {
@ -27,20 +32,42 @@ class MessageRecyclerViewAdapter extends PagedListAdapter<Message, RecyclerView.
private Context mContext; private Context mContext;
private Retrofit mOauthRetrofit; private Retrofit mOauthRetrofit;
private Markwon mMarkwon;
private String mAccessToken; private String mAccessToken;
private Resources mResources; private Resources mResources;
private NetworkState networkState; private NetworkState networkState;
private CommentsListingRecyclerViewAdapter.RetryLoadingMoreCallback mRetryLoadingMoreCallback; private RetryLoadingMoreCallback mRetryLoadingMoreCallback;
interface RetryLoadingMoreCallback { interface RetryLoadingMoreCallback {
void retryLoadingMore(); void retryLoadingMore();
} }
MessageRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, String accessToken) { MessageRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, String accessToken,
RetryLoadingMoreCallback retryLoadingMoreCallback) {
super(DIFF_CALLBACK); super(DIFF_CALLBACK);
mContext = context; mContext = context;
mOauthRetrofit = oauthRetrofit; 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; mAccessToken = accessToken;
mResources = context.getResources(); mResources = context.getResources();
} }
@ -89,7 +116,7 @@ class MessageRecyclerViewAdapter extends PagedListAdapter<Message, RecyclerView.
((DataViewHolder) holder).authorTextView.setText(message.getAuthor()); ((DataViewHolder) holder).authorTextView.setText(message.getAuthor());
String subject = message.getSubject().substring(0, 1).toUpperCase() + message.getSubject().substring(1); String subject = message.getSubject().substring(0, 1).toUpperCase() + message.getSubject().substring(1);
((DataViewHolder) holder).subjectTextView.setText(subject); ((DataViewHolder) holder).subjectTextView.setText(subject);
((DataViewHolder) holder).contentCustomMarkwonView.setMarkdown(message.getBody(), mContext); mMarkwon.setMarkdown(((DataViewHolder) holder).contentCustomMarkwonView, message.getBody());
((DataViewHolder) holder).itemView.setOnClickListener(view -> { ((DataViewHolder) holder).itemView.setOnClickListener(view -> {
if(message.getContext() != null && !message.getContext().equals("")) { 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.author_text_view_item_message) TextView authorTextView;
@BindView(R.id.subject_text_view_item_message) TextView subjectTextView; @BindView(R.id.subject_text_view_item_message) TextView subjectTextView;
@BindView(R.id.title_text_view_item_message) TextView titleTextView; @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) { DataViewHolder(View itemView) {
super(itemView); super(itemView);

View File

@ -225,7 +225,7 @@ class ParseComment {
boolean isSubmitter = singleCommentData.getBoolean(JSONUtils.IS_SUBMITTER_KEY); boolean isSubmitter = singleCommentData.getBoolean(JSONUtils.IS_SUBMITTER_KEY);
String commentContent = ""; String commentContent = "";
if(!singleCommentData.isNull(JSONUtils.BODY_KEY)) { 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(); String permalink = Html.fromHtml(singleCommentData.getString(JSONUtils.PERMALINK_KEY)).toString();
int score = singleCommentData.getInt(JSONUtils.SCORE_KEY); int score = singleCommentData.getInt(JSONUtils.SCORE_KEY);

View File

@ -234,7 +234,7 @@ class ParsePost {
if(data.isNull(JSONUtils.SELFTEXT_KEY)) { if(data.isNull(JSONUtils.SELFTEXT_KEY)) {
post.setSelfText(""); post.setSelfText("");
} else { } else {
post.setSelfText(data.getString(JSONUtils.SELFTEXT_KEY).trim()); post.setSelfText(Utils.addSubredditAndUserLink(data.getString(JSONUtils.SELFTEXT_KEY).trim()));
} }
} else { } else {
//No preview link post //No preview link post
@ -246,7 +246,7 @@ class ParsePost {
if(data.isNull(JSONUtils.SELFTEXT_KEY)) { if(data.isNull(JSONUtils.SELFTEXT_KEY)) {
post.setSelfText(""); post.setSelfText("");
} else { } else {
post.setSelfText(data.getString(JSONUtils.SELFTEXT_KEY).trim()); post.setSelfText(Utils.addSubredditAndUserLink(data.getString(JSONUtils.SELFTEXT_KEY).trim()));
} }
} }
} else { } else {
@ -329,7 +329,7 @@ class ParsePost {
if(data.isNull(JSONUtils.SELFTEXT_KEY)) { if(data.isNull(JSONUtils.SELFTEXT_KEY)) {
post.setSelfText(""); post.setSelfText("");
} else { } else {
post.setSelfText(data.getString(JSONUtils.SELFTEXT_KEY).trim()); post.setSelfText(Utils.addSubredditAndUserLink(data.getString(JSONUtils.SELFTEXT_KEY).trim()));
} }
} else { } else {
//Link post //Link post
@ -342,7 +342,7 @@ class ParsePost {
if(data.isNull(JSONUtils.SELFTEXT_KEY)) { if(data.isNull(JSONUtils.SELFTEXT_KEY)) {
post.setSelfText(""); post.setSelfText("");
} else { } else {
post.setSelfText(data.getString(JSONUtils.SELFTEXT_KEY).trim()); post.setSelfText(Utils.addSubredditAndUserLink(data.getString(JSONUtils.SELFTEXT_KEY).trim()));
} }
post.setPreviewWidth(previewWidth); post.setPreviewWidth(previewWidth);

View File

@ -6,6 +6,7 @@ import android.content.res.Resources;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -237,11 +238,12 @@ public class RulesActivity extends AppCompatActivity {
ArrayList<Rule> rules = new ArrayList<>(); ArrayList<Rule> rules = new ArrayList<>();
for(int i = 0; i < rulesArray.length(); i++) { for(int i = 0; i < rulesArray.length(); i++) {
String shortName = rulesArray.getJSONObject(i).getString(JSONUtils.SHORT_NAME_KEY); String shortName = rulesArray.getJSONObject(i).getString(JSONUtils.SHORT_NAME_KEY);
String descriptionHtml = null; String description = null;
if(rulesArray.getJSONObject(i).has(JSONUtils.DESCRIPTION_HTML_KEY)) { if(rulesArray.getJSONObject(i).has(JSONUtils.DESCRIPTION_KEY)) {
descriptionHtml = rulesArray.getJSONObject(i).getString(JSONUtils.DESCRIPTION_HTML_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; return rules;
} catch (JSONException e) { } catch (JSONException e) {

View File

@ -1,6 +1,9 @@
package ml.docilealligator.infinityforreddit; package ml.docilealligator.infinityforreddit;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.text.util.Linkify;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -11,16 +14,38 @@ import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList; import java.util.ArrayList;
import CustomView.CustomMarkwonView;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; 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> { class RulesRecyclerViewAdapter extends RecyclerView.Adapter<RulesRecyclerViewAdapter.RuleViewHolder> {
private Context context; private Markwon markwon;
private ArrayList<Rule> rules; private ArrayList<Rule> rules;
RulesRecyclerViewAdapter(Context context) { 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 @NonNull
@ -35,7 +60,7 @@ class RulesRecyclerViewAdapter extends RecyclerView.Adapter<RulesRecyclerViewAda
if(rules.get(holder.getAdapterPosition()).getDescriptionHtml() == null) { if(rules.get(holder.getAdapterPosition()).getDescriptionHtml() == null) {
holder.descriptionMarkwonView.setVisibility(View.GONE); holder.descriptionMarkwonView.setVisibility(View.GONE);
} else { } 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 { class RuleViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.short_name_text_view_item_rule) TextView shortNameTextView; @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) { RuleViewHolder(@NonNull View itemView) {
super(itemView); super(itemView);

View File

@ -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)");
}
}

View File

@ -213,7 +213,8 @@ public class ViewMessageActivity extends AppCompatActivity {
} }
private void bindView() { private void bindView() {
mAdapter = new MessageRecyclerViewAdapter(this, mOauthRetrofit, mAccessToken); mAdapter = new MessageRecyclerViewAdapter(this, mOauthRetrofit, mAccessToken,
() -> mMessageViewModel.retryLoadingMore());
LinearLayoutManager layoutManager = new LinearLayoutManager(this); LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager); recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(mAdapter); recyclerView.setAdapter(mAdapter);

View File

@ -433,9 +433,10 @@ public class ViewPostDetailActivity extends AppCompatActivity implements FlairBo
mMenu.findItem(R.id.action_delete_view_post_detail_activity).setVisible(true); mMenu.findItem(R.id.action_delete_view_post_detail_activity).setVisible(true);
} }
mAdapter = new CommentAndPostRecyclerViewAdapter(ViewPostDetailActivity.this, mRetrofit, mAdapter = new CommentAndPostRecyclerViewAdapter(ViewPostDetailActivity.this,
mOauthRetrofit, mRedditDataRoomDatabase, mGlide, mAccessToken, mAccountName, mPost, mRetrofit, mOauthRetrofit, mRedditDataRoomDatabase, mGlide,
mLocale, mSingleCommentId, isSingleCommentThreadMode, mAccessToken, mAccountName, mPost, mLocale, mSingleCommentId,
isSingleCommentThreadMode,
new CommentAndPostRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() { new CommentAndPostRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() {
@Override @Override
public void updatePost(Post post) { public void updatePost(Post post) {

View File

@ -32,7 +32,7 @@
android:orientation="vertical" android:orientation="vertical"
android:padding="16dp"> android:padding="16dp">
<ru.noties.markwon.view.MarkwonView <TextView
android:id="@+id/comment_parent_markwon_view_comment_activity" android:id="@+id/comment_parent_markwon_view_comment_activity"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -42,7 +42,7 @@
</LinearLayout> </LinearLayout>
<CustomView.CustomMarkwonView <TextView
android:id="@+id/comment_markdown_view_item_post_comment" android:id="@+id/comment_markdown_view_item_post_comment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -26,7 +26,7 @@
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:textColor="@color/primaryTextColor" /> android:textColor="@color/primaryTextColor" />
<CustomView.CustomMarkwonView <TextView
android:id="@+id/content_custom_markwon_view_item_message" android:id="@+id/content_custom_markwon_view_item_message"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />

View File

@ -71,7 +71,7 @@
android:textColor="@color/primaryTextColor" android:textColor="@color/primaryTextColor"
android:textSize="18sp" /> android:textSize="18sp" />
<CustomView.CustomMarkwonView <TextView
android:id="@+id/content_markdown_view_item_post_detail" android:id="@+id/content_markdown_view_item_post_detail"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -11,7 +11,7 @@
android:textColor="@color/primaryTextColor" android:textColor="@color/primaryTextColor"
android:textSize="16sp" /> android:textSize="16sp" />
<CustomView.CustomMarkwonView <TextView
android:id="@+id/description_markwon_view_item_rule" android:id="@+id/description_markwon_view_item_rule"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"