aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/CommentRecyclerViewAdapter.java644
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/FetchComment.java2
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/LoadSubredditIconAsyncTask.java4
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java2
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java499
-rw-r--r--app/src/main/res/drawable/no_comment_placeholder.png (renamed from app/src/main/res/drawable/no_comment_indicator.png)bin60561 -> 60561 bytes
-rw-r--r--app/src/main/res/layout/activity_view_post_detail.xml335
-rw-r--r--app/src/main/res/layout/item_load_comments.xml19
-rw-r--r--app/src/main/res/layout/item_load_comments_failed_placeholder.xml8
-rw-r--r--app/src/main/res/layout/item_no_comment_placeholder.xml8
-rw-r--r--app/src/main/res/layout/item_post_detail.xml252
11 files changed, 927 insertions, 846 deletions
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentRecyclerViewAdapter.java
index d2b34ecd..d987a6b7 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentRecyclerViewAdapter.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentRecyclerViewAdapter.java
@@ -3,55 +3,113 @@ package ml.docilealligator.infinityforreddit;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.graphics.ColorFilter;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.RelativeLayout;
import android.widget.TextView;
+import android.widget.Toast;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.browser.customtabs.CustomTabsIntent;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
+import com.bumptech.glide.RequestBuilder;
+import com.bumptech.glide.RequestManager;
+import com.bumptech.glide.load.DataSource;
+import com.bumptech.glide.load.engine.GlideException;
+import com.bumptech.glide.request.RequestListener;
+import com.bumptech.glide.request.RequestOptions;
+import com.bumptech.glide.request.target.Target;
+import com.google.android.material.chip.Chip;
+import com.santalu.aspectratioimageview.AspectRatioImageView;
+
import java.util.ArrayList;
import java.util.Locale;
+import CustomView.AspectRatioGifImageView;
+import SubredditDatabase.SubredditRoomDatabase;
import butterknife.BindView;
import butterknife.ButterKnife;
+import jp.wasabeef.glide.transformations.BlurTransformation;
+import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
import retrofit2.Retrofit;
import ru.noties.markwon.SpannableConfiguration;
import ru.noties.markwon.view.MarkwonView;
class CommentRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
- private static final int VIEW_TYPE_COMMENT = 0;
- private static final int VIEW_TYPE_LOAD_MORE_COMMENT = 1;
+ private static final int VIEW_TYPE_POST_DETAIL = 0;
+ private static final int VIEW_TYPE_FIRST_LOADING = 1;
+ private static final int VIEW_TYPE_FIRST_LOADING_FAILED = 2;
+ private static final int VIEW_TYPE_NO_COMMENT_PLACEHOLDER = 3;
+ private static final int VIEW_TYPE_COMMENT = 4;
+ private static final int VIEW_TYPE_LOAD_MORE_COMMENT = 5;
private Activity mActivity;
private Retrofit mRetrofit;
private Retrofit mOauthRetrofit;
+ private RequestManager mGlide;
private SharedPreferences mSharedPreferences;
+ private Post mPost;
+ private ArrayList<CommentData> mVisibleComments;
private String mSubredditNamePrefixed;
private Locale mLocale;
+ private UpdatePostInPostFragmentCallback mUpdatePostInPostFragmentCallback;
+ private LoadSubredditIconAsyncTask mLoadSubredditIconAsyncTask;
+ private boolean isInitiallyLoading;
+ private boolean isInitiallyLoadingFailed;
- private ArrayList<CommentData> mVisibleComments;
+ interface UpdatePostInPostFragmentCallback {
+ void updatePost(Post post);
+ }
- CommentRecyclerViewAdapter(Activity activity, Retrofit retrofit, Retrofit oauthRetrofit,
- SharedPreferences sharedPreferences, ArrayList<CommentData> expandedComments,
- String subredditNamePrefixed, Locale locale) {
+ CommentRecyclerViewAdapter(Activity activity, Retrofit retrofit, Retrofit oauthRetrofit, RequestManager glide,
+ SharedPreferences sharedPreferences, Post post, String subredditNamePrefixed,
+ Locale locale, LoadSubredditIconAsyncTask loadSubredditIconAsyncTask,
+ UpdatePostInPostFragmentCallback updatePostInPostFragmentCallback) {
mActivity = activity;
mRetrofit = retrofit;
mOauthRetrofit = oauthRetrofit;
+ mGlide = glide;
mSharedPreferences = sharedPreferences;
+ mPost = post;
+ mVisibleComments = new ArrayList<>();
mSubredditNamePrefixed = subredditNamePrefixed;
mLocale = locale;
- mVisibleComments = expandedComments;
+ mLoadSubredditIconAsyncTask = loadSubredditIconAsyncTask;
+ mUpdatePostInPostFragmentCallback = updatePostInPostFragmentCallback;
+ isInitiallyLoading = true;
+ isInitiallyLoadingFailed = false;
}
@Override
public int getItemViewType(int position) {
- CommentData comment = mVisibleComments.get(position);
+ if(position == 0) {
+ return VIEW_TYPE_POST_DETAIL;
+ }
+
+ if(mVisibleComments.size() == 0) {
+ if(position == 1) {
+ if(isInitiallyLoading) {
+ return VIEW_TYPE_FIRST_LOADING;
+ } else if(isInitiallyLoadingFailed) {
+ return VIEW_TYPE_FIRST_LOADING_FAILED;
+ } else {
+ return VIEW_TYPE_NO_COMMENT_PLACEHOLDER;
+ }
+ }
+ }
+
+ CommentData comment = mVisibleComments.get(position - 1);
if(!comment.isPlaceHolder()) {
return VIEW_TYPE_COMMENT;
} else {
@@ -62,7 +120,15 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
- if(viewType == VIEW_TYPE_COMMENT) {
+ if(viewType == VIEW_TYPE_POST_DETAIL) {
+ return new PostDetailViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail, parent, false));
+ } else if(viewType == VIEW_TYPE_FIRST_LOADING) {
+ return new LoadCommentsViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_load_comments, parent, false));
+ } else if(viewType == VIEW_TYPE_FIRST_LOADING_FAILED) {
+ return new LoadCommentsFailedViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_load_comments_failed_placeholder, parent, false));
+ } else if(viewType == VIEW_TYPE_NO_COMMENT_PLACEHOLDER) {
+ return new NoCommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_no_comment_placeholder, parent, false));
+ } else if(viewType == VIEW_TYPE_COMMENT) {
return new CommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment, parent, false));
} else {
return new LoadMoreCommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_load_more_comments_placeholder, parent, false));
@@ -71,8 +137,196 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
- if(holder.getItemViewType() == VIEW_TYPE_COMMENT) {
- CommentData commentItem = mVisibleComments.get(holder.getAdapterPosition());
+ if(holder.getItemViewType() == VIEW_TYPE_POST_DETAIL) {
+ ((PostDetailViewHolder) holder).mTitleTextView.setText(mPost.getTitle());
+
+ if(mPost.getSubredditIconUrl() == null) {
+ if(mLoadSubredditIconAsyncTask != null) {
+ mLoadSubredditIconAsyncTask.cancel(true);
+ } else {
+ mLoadSubredditIconAsyncTask = new LoadSubredditIconAsyncTask(
+ SubredditRoomDatabase.getDatabase(mActivity).subredditDao(), mPost.getSubredditNamePrefixed().substring(2),
+ iconImageUrl -> {
+ if(!iconImageUrl.equals("")) {
+ mGlide.load(iconImageUrl)
+ .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
+ .error(mGlide.load(R.drawable.subreddit_default_icon)
+ .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))))
+ .into(((PostDetailViewHolder) holder).mSubredditIconGifImageView);
+ } else {
+ mGlide.load(R.drawable.subreddit_default_icon)
+ .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
+ .into(((PostDetailViewHolder) holder).mSubredditIconGifImageView);
+ }
+
+ mPost.setSubredditIconUrl(iconImageUrl);
+ });
+ }
+
+ mLoadSubredditIconAsyncTask.execute();
+ } else if(!mPost.getSubredditIconUrl().equals("")) {
+ mGlide.load(mPost.getSubredditIconUrl())
+ .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
+ .error(mGlide.load(R.drawable.subreddit_default_icon)
+ .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))))
+ .into(((PostDetailViewHolder) holder).mSubredditIconGifImageView);
+ } else {
+ mGlide.load(R.drawable.subreddit_default_icon)
+ .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
+ .into(((PostDetailViewHolder) holder).mSubredditIconGifImageView);
+ }
+
+ switch (mPost.getVoteType()) {
+ case 1:
+ //Upvote
+ ((PostDetailViewHolder) holder).mUpvoteButton.setColorFilter(ContextCompat.getColor(mActivity, R.color.backgroundColorPrimaryDark), PorterDuff.Mode.SRC_IN);
+ break;
+ case -1:
+ //Downvote
+ ((PostDetailViewHolder) holder).mDownvoteButton.setColorFilter(ContextCompat.getColor(mActivity, R.color.minusButtonColor), PorterDuff.Mode.SRC_IN);
+ break;
+ case 0:
+ ((PostDetailViewHolder) holder).mUpvoteButton.clearColorFilter();
+ ((PostDetailViewHolder) holder).mDownvoteButton.clearColorFilter();
+ }
+
+ if(mPost.getPostType() != Post.TEXT_TYPE && mPost.getPostType() != Post.NO_PREVIEW_LINK_TYPE) {
+ ((PostDetailViewHolder) holder).mRelativeLayout.setVisibility(View.VISIBLE);
+ ((PostDetailViewHolder) holder).mImageView.setVisibility(View.VISIBLE);
+ ((PostDetailViewHolder) holder).mImageView.setRatio((float) mPost.getPreviewHeight() / (float) mPost.getPreviewWidth());
+ loadImage((PostDetailViewHolder) holder);
+ } else {
+ ((PostDetailViewHolder) holder).mRelativeLayout.setVisibility(View.GONE);
+ ((PostDetailViewHolder) holder).mImageView.setVisibility(View.GONE);
+ }
+
+ if(mPost.isCrosspost()) {
+ ((PostDetailViewHolder) holder).mCrosspostImageView.setVisibility(View.VISIBLE);
+ }
+
+ ((PostDetailViewHolder) holder).mSubredditTextView.setText(mPost.getSubredditNamePrefixed());
+
+ ((PostDetailViewHolder) holder).mPostTimeTextView.setText(mPost.getPostTime());
+
+ if(mPost.getGilded() > 0) {
+ ((PostDetailViewHolder) holder).mGildedImageView.setVisibility(View.VISIBLE);
+ mGlide.load(R.drawable.gold).into(((PostDetailViewHolder) holder).mGildedImageView);
+ ((PostDetailViewHolder) holder).mGildedNumberTextView.setVisibility(View.VISIBLE);
+ String gildedNumber = mActivity.getResources().getString(R.string.gilded, mPost.getGilded());
+ ((PostDetailViewHolder) holder).mGildedNumberTextView.setText(gildedNumber);
+ }
+
+ if(mPost.isNSFW()) {
+ ((PostDetailViewHolder) holder).mNSFWChip.setVisibility(View.VISIBLE);
+ } else {
+ ((PostDetailViewHolder) holder).mNSFWChip.setVisibility(View.GONE);
+ }
+
+ String scoreWithVote = Integer.toString(mPost.getScore() + mPost.getVoteType());
+ ((PostDetailViewHolder) holder).mScoreTextView.setText(scoreWithVote);
+
+ switch (mPost.getPostType()) {
+ case Post.IMAGE_TYPE:
+ ((PostDetailViewHolder) holder).mTypeChip.setText("IMAGE");
+
+ ((PostDetailViewHolder) holder).mImageView.setOnClickListener(view -> {
+ Intent intent = new Intent(mActivity, ViewImageActivity.class);
+ intent.putExtra(ViewImageActivity.IMAGE_URL_KEY, mPost.getUrl());
+ intent.putExtra(ViewImageActivity.TITLE_KEY, mPost.getTitle());
+ intent.putExtra(ViewImageActivity.FILE_NAME_KEY, mPost.getSubredditNamePrefixed().substring(2)
+ + "-" + mPost.getId().substring(3));
+ mActivity.startActivity(intent);
+ });
+ break;
+ case Post.LINK_TYPE:
+ ((PostDetailViewHolder) holder).mTypeChip.setText("LINK");
+
+ ((PostDetailViewHolder) holder).linkTextView.setVisibility(View.VISIBLE);
+ String domain = Uri.parse(mPost.getUrl()).getHost();
+ ((PostDetailViewHolder) holder).linkTextView.setText(domain);
+
+ ((PostDetailViewHolder) holder).mImageView.setOnClickListener(view -> {
+ CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
+ // add share action to menu list
+ builder.addDefaultShareMenuItem();
+ builder.setToolbarColor(mActivity.getResources().getColor(R.color.colorPrimary));
+ CustomTabsIntent customTabsIntent = builder.build();
+ customTabsIntent.launchUrl(mActivity, Uri.parse(mPost.getUrl()));
+ });
+ break;
+ case Post.GIF_VIDEO_TYPE:
+ ((PostDetailViewHolder) holder).mTypeChip.setText("GIF");
+
+ final Uri gifVideoUri = Uri.parse(mPost.getVideoUrl());
+ ((PostDetailViewHolder) holder).mImageView.setOnClickListener(view -> {
+ Intent intent = new Intent(mActivity, ViewVideoActivity.class);
+ intent.setData(gifVideoUri);
+ intent.putExtra(ViewVideoActivity.TITLE_KEY, mPost.getTitle());
+ intent.putExtra(ViewVideoActivity.IS_DASH_VIDEO_KEY, mPost.isDashVideo());
+ intent.putExtra(ViewVideoActivity.IS_DOWNLOADABLE_KEY, mPost.isDownloadableGifOrVideo());
+ if(mPost.isDownloadableGifOrVideo()) {
+ intent.putExtra(ViewVideoActivity.DOWNLOAD_URL_KEY, mPost.getGifOrVideoDownloadUrl());
+ intent.putExtra(ViewVideoActivity.SUBREDDIT_KEY, mPost.getSubredditNamePrefixed());
+ intent.putExtra(ViewVideoActivity.ID_KEY, mPost.getId());
+ }
+ mActivity.startActivity(intent);
+ });
+ break;
+ case Post.VIDEO_TYPE:
+ ((PostDetailViewHolder) holder).mTypeChip.setText("VIDEO");
+
+ final Uri videoUri = Uri.parse(mPost.getVideoUrl());
+ ((PostDetailViewHolder) holder).mImageView.setOnClickListener(view -> {
+ Intent intent = new Intent(mActivity, ViewVideoActivity.class);
+ intent.setData(videoUri);
+ intent.putExtra(ViewVideoActivity.TITLE_KEY, mPost.getTitle());
+ intent.putExtra(ViewVideoActivity.IS_DASH_VIDEO_KEY, mPost.isDashVideo());
+ intent.putExtra(ViewVideoActivity.IS_DOWNLOADABLE_KEY, mPost.isDownloadableGifOrVideo());
+ if(mPost.isDownloadableGifOrVideo()) {
+ intent.putExtra(ViewVideoActivity.DOWNLOAD_URL_KEY, mPost.getGifOrVideoDownloadUrl());
+ intent.putExtra(ViewVideoActivity.SUBREDDIT_KEY, mPost.getSubredditNamePrefixed());
+ intent.putExtra(ViewVideoActivity.ID_KEY, mPost.getId());
+ }
+ mActivity.startActivity(intent);
+ });
+ break;
+ case Post.NO_PREVIEW_LINK_TYPE:
+ ((PostDetailViewHolder) holder).mTypeChip.setText("LINK");
+
+ ((PostDetailViewHolder) holder).linkTextView.setVisibility(View.VISIBLE);
+ String noPreviewLinkDomain = Uri.parse(mPost.getUrl()).getHost();
+ ((PostDetailViewHolder) holder).linkTextView.setText(noPreviewLinkDomain);
+
+ if(!mPost.getSelfText().equals("")) {
+ ((PostDetailViewHolder) holder).mContentMarkdownView.setVisibility(View.VISIBLE);
+ ((PostDetailViewHolder) holder).mContentMarkdownView.setMarkdown(getCustomSpannableConfiguration(), mPost.getSelfText());
+ }
+ ((PostDetailViewHolder) holder).mNoPreviewLinkImageView.setVisibility(View.VISIBLE);
+ ((PostDetailViewHolder) holder).mNoPreviewLinkImageView.setOnClickListener(view -> {
+ CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
+ // add share action to menu list
+ builder.addDefaultShareMenuItem();
+ builder.setToolbarColor(mActivity.getResources().getColor(R.color.colorPrimary));
+ CustomTabsIntent customTabsIntent = builder.build();
+ customTabsIntent.launchUrl(mActivity, Uri.parse(mPost.getUrl()));
+ });
+ break;
+ case Post.TEXT_TYPE:
+ ((PostDetailViewHolder) holder).mTypeChip.setText("TEXT");
+
+ if(!mPost.getSelfText().equals("")) {
+ ((PostDetailViewHolder) holder).mContentMarkdownView.setVisibility(View.VISIBLE);
+ ((PostDetailViewHolder) holder).mContentMarkdownView.setMarkdown(getCustomSpannableConfiguration(), mPost.getSelfText());
+ }
+ break;
+ }
+ } else if(holder.getItemViewType() == VIEW_TYPE_COMMENT) {
+ CommentData commentItem;
+ if(isInitiallyLoading || isInitiallyLoadingFailed) {
+ commentItem = mVisibleComments.get(holder.getAdapterPosition() - 2);
+ } else {
+ commentItem = mVisibleComments.get(holder.getAdapterPosition() - 1);
+ }
String authorPrefixed = "u/" + commentItem.getAuthor();
((CommentViewHolder) holder).authorTextView.setText(authorPrefixed);
@@ -122,11 +376,17 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
.setColorFilter(ContextCompat.getColor(mActivity, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN);
break;
}
- } else {
- ((LoadMoreCommentViewHolder) holder).verticalBlock.getLayoutParams().width = mVisibleComments.get(holder.getAdapterPosition()).getDepth() * 16;
- if(mVisibleComments.get(holder.getAdapterPosition()).isLoadingMoreChildren()) {
+ } else if(holder instanceof LoadMoreCommentViewHolder) {
+ CommentData placeholder;
+ if(isInitiallyLoading || isInitiallyLoadingFailed) {
+ placeholder = mVisibleComments.get(holder.getAdapterPosition() - 2);
+ } else {
+ placeholder = mVisibleComments.get(holder.getAdapterPosition() - 1);
+ }
+ ((LoadMoreCommentViewHolder) holder).verticalBlock.getLayoutParams().width = placeholder.getDepth() * 16;
+ if(placeholder.isLoadingMoreChildren()) {
((LoadMoreCommentViewHolder) holder).placeholderTextView.setText(R.string.loading);
- } else if(mVisibleComments.get(holder.getAdapterPosition()).isLoadMoreChildrenFailed()) {
+ } else if(placeholder.isLoadMoreChildrenFailed()) {
((LoadMoreCommentViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments_failed);
} else {
((LoadMoreCommentViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments);
@@ -134,6 +394,63 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
}
}
+ private void loadImage(PostDetailViewHolder holder) {
+ RequestBuilder imageRequestBuilder = mGlide.load(mPost.getPreviewUrl())
+ .apply(new RequestOptions().override(mPost.getPreviewWidth(), mPost.getPreviewHeight()))
+ .listener(new RequestListener<Drawable>() {
+ @Override
+ public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
+ holder.mLoadImageProgressBar.setVisibility(View.GONE);
+ holder.mLoadImageErrorTextView.setVisibility(View.VISIBLE);
+ holder.mLoadImageErrorTextView.setOnClickListener(view -> {
+ holder.mLoadImageProgressBar.setVisibility(View.VISIBLE);
+ holder.mLoadImageErrorTextView.setVisibility(View.GONE);
+ loadImage(holder);
+ });
+ return false;
+ }
+
+ @Override
+ public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
+ holder.mLoadWrapper.setVisibility(View.GONE);
+ return false;
+ }
+ });
+
+ if(mPost.isNSFW()) {
+ imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 2)))
+ .into(holder.mImageView);
+ } else {
+ imageRequestBuilder.into(holder.mImageView);
+ }
+ }
+
+ private SpannableConfiguration getCustomSpannableConfiguration() {
+ return SpannableConfiguration.builder(mActivity).linkResolver((view, link) -> {
+ if(link.startsWith("/u/") || link.startsWith("u/")) {
+ Intent intent = new Intent(mActivity, ViewUserDetailActivity.class);
+ intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, link.substring(3));
+ mActivity.startActivity(intent);
+ } else if(link.startsWith("/r/") || link.startsWith("r/")) {
+ Intent intent = new Intent(mActivity, ViewSubredditDetailActivity.class);
+ intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, link.substring(3));
+ mActivity.startActivity(intent);
+ } else {
+ CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
+ // add share action to menu list
+ builder.addDefaultShareMenuItem();
+ builder.setToolbarColor(mActivity.getResources().getColor(R.color.colorPrimary));
+ CustomTabsIntent customTabsIntent = builder.build();
+ customTabsIntent.launchUrl(mActivity, Uri.parse(link));
+ }
+ }).build();
+ }
+
+ void updatePost(Post post) {
+ mPost = post;
+ notifyItemChanged(0);
+ }
+
private int getParentPosition(int position) {
int childDepth = mVisibleComments.get(position).getDepth();
for(int i = position; i >= 0; i--) {
@@ -176,9 +493,19 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
}
void addComments(ArrayList<CommentData> comments) {
+ if(mVisibleComments.size() == 0) {
+ isInitiallyLoading = false;
+ isInitiallyLoadingFailed = false;
+ if(comments.size() == 0) {
+ notifyItemChanged(1);
+ } else {
+ notifyItemRemoved(1);
+ }
+ }
+
int sizeBefore = mVisibleComments.size();
mVisibleComments.addAll(comments);
- notifyItemRangeInserted(sizeBefore, comments.size());
+ notifyItemRangeInserted(sizeBefore + 1, comments.size());
}
void addComment(CommentData comment) {
@@ -207,9 +534,36 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
}
}
- void clearData() {
- mVisibleComments.clear();
- notifyDataSetChanged();
+ void initiallyLoading() {
+ if(mLoadSubredditIconAsyncTask != null) {
+ mLoadSubredditIconAsyncTask.cancel(true);
+ }
+
+ if(isInitiallyLoading || isInitiallyLoadingFailed) {
+ isInitiallyLoading = true;
+ isInitiallyLoadingFailed = false;
+ notifyItemChanged(1);
+ } else {
+ isInitiallyLoading = true;
+ isInitiallyLoadingFailed = false;
+ notifyItemInserted(1);
+ }
+
+ clearComments();
+ }
+
+ void initiallyLoadCommentsFailed() {
+ isInitiallyLoading = false;
+ isInitiallyLoadingFailed = true;
+ notifyItemChanged(1);
+ }
+
+ private void clearComments() {
+ if(mVisibleComments.size() != 0) {
+ int previousSize = mVisibleComments.size();
+ mVisibleComments.clear();
+ notifyItemRangeRemoved(1, previousSize);
+ }
}
@Override
@@ -221,7 +575,164 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
@Override
public int getItemCount() {
- return mVisibleComments.size();
+ if(isInitiallyLoading || isInitiallyLoadingFailed) {
+ return 2;
+ }
+
+ return mVisibleComments.size() + 1;
+ }
+
+ class PostDetailViewHolder extends RecyclerView.ViewHolder {
+ @BindView(R.id.subreddit_icon_name_linear_layout_item_post_detail) LinearLayout mSubredditIconNameLinearLayout;
+ @BindView(R.id.subreddit_icon_circle_image_view_item_post_detail) AspectRatioGifImageView mSubredditIconGifImageView;
+ @BindView(R.id.subreddit_text_view_item_post_detail) TextView mSubredditTextView;
+ @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) MarkwonView 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;
+ @BindView(R.id.crosspost_image_view_item_post_detail) ImageView mCrosspostImageView;
+ @BindView(R.id.nsfw_text_view_item_post_detail) Chip mNSFWChip;
+ @BindView(R.id.link_text_view_item_post_detail) TextView linkTextView;
+ @BindView(R.id.image_view_wrapper_item_post_detail) RelativeLayout mRelativeLayout;
+ @BindView(R.id.load_wrapper_item_post_detail) RelativeLayout mLoadWrapper;
+ @BindView(R.id.progress_bar_item_post_detail) ProgressBar mLoadImageProgressBar;
+ @BindView(R.id.load_image_error_text_view_item_post_detail) TextView mLoadImageErrorTextView;
+ @BindView(R.id.image_view_item_post_detail) AspectRatioImageView mImageView;
+ @BindView(R.id.image_view_no_preview_link_item_post_detail) ImageView mNoPreviewLinkImageView;
+ @BindView(R.id.plus_button_item_post_detail) ImageView mUpvoteButton;
+ @BindView(R.id.score_text_view_item_post_detail) TextView mScoreTextView;
+ @BindView(R.id.minus_button_item_post_detail) ImageView mDownvoteButton;
+ @BindView(R.id.share_button_item_post_detail) ImageView mShareButton;
+
+ public PostDetailViewHolder(@NonNull View itemView) {
+ super(itemView);
+ ButterKnife.bind(this, itemView);
+
+ mSubredditIconNameLinearLayout.setOnClickListener(view -> {
+ Intent intent = new Intent(mActivity, ViewSubredditDetailActivity.class);
+ intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY,
+ mPost.getSubredditNamePrefixed().substring(2));
+ mActivity.startActivity(intent);
+ });
+
+ mShareButton.setOnClickListener(view -> {
+ Intent intent = new Intent(Intent.ACTION_SEND);
+ intent.setType("text/plain");
+ String extraText = mPost.getTitle() + "\n" + mPost.getPermalink();
+ intent.putExtra(Intent.EXTRA_TEXT, extraText);
+ mActivity.startActivity(Intent.createChooser(intent, "Share"));
+ });
+
+ mUpvoteButton.setOnClickListener(view -> {
+ ColorFilter previousUpvoteButtonColorFilter = mUpvoteButton.getColorFilter();
+ ColorFilter previousDownvoteButtonColorFilter = mDownvoteButton.getColorFilter();
+ int previousVoteType = mPost.getVoteType();
+ String newVoteType;
+
+ mDownvoteButton.clearColorFilter();
+
+ if(previousUpvoteButtonColorFilter == null) {
+ //Not upvoted before
+ mPost.setVoteType(1);
+ newVoteType = RedditUtils.DIR_UPVOTE;
+ mUpvoteButton.setColorFilter(ContextCompat.getColor(mActivity, R.color.backgroundColorPrimaryDark), android.graphics.PorterDuff.Mode.SRC_IN);
+ } else {
+ //Upvoted before
+ mPost.setVoteType(0);
+ newVoteType = RedditUtils.DIR_UNVOTE;
+ mUpvoteButton.clearColorFilter();
+ }
+
+ mScoreTextView.setText(Integer.toString(mPost.getScore() + mPost.getVoteType()));
+
+ mUpdatePostInPostFragmentCallback.updatePost(mPost);
+
+ VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingWithoutPositionListener() {
+ @Override
+ public void onVoteThingSuccess() {
+ if(newVoteType.equals(RedditUtils.DIR_UPVOTE)) {
+ mPost.setVoteType(1);
+ mUpvoteButton.setColorFilter(ContextCompat.getColor(mActivity, R.color.backgroundColorPrimaryDark), android.graphics.PorterDuff.Mode.SRC_IN);
+ } else {
+ mPost.setVoteType(0);
+ mUpvoteButton.clearColorFilter();
+ }
+
+ mDownvoteButton.clearColorFilter();
+ mScoreTextView.setText(Integer.toString(mPost.getScore() + mPost.getVoteType()));
+
+ mUpdatePostInPostFragmentCallback.updatePost(mPost);
+ }
+
+ @Override
+ public void onVoteThingFail() {
+ Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show();
+ mPost.setVoteType(previousVoteType);
+ mScoreTextView.setText(Integer.toString(mPost.getScore() + previousVoteType));
+ mUpvoteButton.setColorFilter(previousUpvoteButtonColorFilter);
+ mDownvoteButton.setColorFilter(previousDownvoteButtonColorFilter);
+
+ mUpdatePostInPostFragmentCallback.updatePost(mPost);
+ }
+ }, mPost.getFullName(), newVoteType);
+ });
+
+ mDownvoteButton.setOnClickListener(view -> {
+ ColorFilter previousUpvoteButtonColorFilter = mUpvoteButton.getColorFilter();
+ ColorFilter previousDownvoteButtonColorFilter = mDownvoteButton.getColorFilter();
+ int previousVoteType = mPost.getVoteType();
+ String newVoteType;
+
+ mUpvoteButton.clearColorFilter();
+
+ if(previousDownvoteButtonColorFilter == null) {
+ //Not upvoted before
+ mPost.setVoteType(-1);
+ newVoteType = RedditUtils.DIR_DOWNVOTE;
+ mDownvoteButton.setColorFilter(ContextCompat.getColor(mActivity, R.color.colorAccent), android.graphics.PorterDuff.Mode.SRC_IN);
+ } else {
+ //Upvoted before
+ mPost.setVoteType(0);
+ newVoteType = RedditUtils.DIR_UNVOTE;
+ mDownvoteButton.clearColorFilter();
+ }
+
+ mScoreTextView.setText(Integer.toString(mPost.getScore() + mPost.getVoteType()));
+
+ mUpdatePostInPostFragmentCallback.updatePost(mPost);
+
+ VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingWithoutPositionListener() {
+ @Override
+ public void onVoteThingSuccess() {
+ if(newVoteType.equals(RedditUtils.DIR_DOWNVOTE)) {
+ mPost.setVoteType(-1);
+ mDownvoteButton.setColorFilter(ContextCompat.getColor(mActivity, R.color.colorAccent), android.graphics.PorterDuff.Mode.SRC_IN);
+ } else {
+ mPost.setVoteType(0);
+ mDownvoteButton.clearColorFilter();
+ }
+
+ mUpvoteButton.clearColorFilter();
+ mScoreTextView.setText(Integer.toString(mPost.getScore() + mPost.getVoteType()));
+
+ mUpdatePostInPostFragmentCallback.updatePost(mPost);
+ }
+
+ @Override
+ public void onVoteThingFail() {
+ Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show();
+ mPost.setVoteType(previousVoteType);
+ mScoreTextView.setText(Integer.toString(mPost.getScore() + previousVoteType));
+ mUpvoteButton.setColorFilter(previousUpvoteButtonColorFilter);
+ mDownvoteButton.setColorFilter(previousDownvoteButtonColorFilter);
+
+ mUpdatePostInPostFragmentCallback.updatePost(mPost);
+ }
+ }, mPost.getFullName(), newVoteType);
+ });
+ }
}
class CommentViewHolder extends RecyclerView.ViewHolder {
@@ -242,117 +753,117 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
authorTextView.setOnClickListener(view -> {
Intent intent = new Intent(mActivity, ViewUserDetailActivity.class);
- intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mVisibleComments.get(getAdapterPosition()).getAuthor());
+ intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mVisibleComments.get(getAdapterPosition() - 1).getAuthor());
mActivity.startActivity(intent);
});
shareButton.setOnClickListener(view -> {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
- String extraText = mVisibleComments.get(getAdapterPosition()).getPermalink();
+ String extraText = mVisibleComments.get(getAdapterPosition() - 1).getPermalink();
intent.putExtra(Intent.EXTRA_TEXT, extraText);
mActivity.startActivity(Intent.createChooser(intent, "Share"));
});
expandButton.setOnClickListener(view -> {
- if(mVisibleComments.get(getAdapterPosition()).isExpanded()) {
+ if(mVisibleComments.get(getAdapterPosition() - 1).isExpanded()) {
collapseChildren(getAdapterPosition());
expandButton.setImageResource(R.drawable.ic_expand_more_black_20dp);
} else {
expandChildren(getAdapterPosition());
- mVisibleComments.get(getAdapterPosition()).setExpanded(true);
+ mVisibleComments.get(getAdapterPosition() - 1).setExpanded(true);
expandButton.setImageResource(R.drawable.ic_expand_less_black_20dp);
}
});
replyButton.setOnClickListener(view -> {
Intent intent = new Intent(mActivity, CommentActivity.class);
- intent.putExtra(CommentActivity.EXTRA_PARENT_DEPTH_KEY, mVisibleComments.get(getAdapterPosition()).getDepth() + 1);
- intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_KEY, mVisibleComments.get(getAdapterPosition()).getCommentContent());
- intent.putExtra(CommentActivity.EXTRA_PARENT_FULLNAME_KEY, mVisibleComments.get(getAdapterPosition()).getFullName());
+ intent.putExtra(CommentActivity.EXTRA_PARENT_DEPTH_KEY, mVisibleComments.get(getAdapterPosition() - 1).getDepth() + 1);
+ intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_KEY, mVisibleComments.get(getAdapterPosition() - 1).getCommentContent());
+ intent.putExtra(CommentActivity.EXTRA_PARENT_FULLNAME_KEY, mVisibleComments.get(getAdapterPosition() - 1).getFullName());
intent.putExtra(CommentActivity.EXTRA_IS_REPLYING_KEY, true);
intent.putExtra(CommentActivity.EXTRA_PARENT_POSITION_KEY, getAdapterPosition());
mActivity.startActivityForResult(intent, CommentActivity.WRITE_COMMENT_REQUEST_CODE);
});
upvoteButton.setOnClickListener(view -> {
- int previousVoteType = mVisibleComments.get(getAdapterPosition()).getVoteType();
+ int previousVoteType = mVisibleComments.get(getAdapterPosition() - 1).getVoteType();
String newVoteType;
downvoteButton.clearColorFilter();
if(previousVoteType != CommentData.VOTE_TYPE_UPVOTE) {
//Not upvoted before
- mVisibleComments.get(getAdapterPosition()).setVoteType(CommentData.VOTE_TYPE_UPVOTE);
+ mVisibleComments.get(getAdapterPosition() - 1).setVoteType(CommentData.VOTE_TYPE_UPVOTE);
newVoteType = RedditUtils.DIR_UPVOTE;
upvoteButton.setColorFilter(ContextCompat.getColor(mActivity, R.color.backgroundColorPrimaryDark), android.graphics.PorterDuff.Mode.SRC_IN);
} else {
//Upvoted before
- mVisibleComments.get(getAdapterPosition()).setVoteType(CommentData.VOTE_TYPE_NO_VOTE);
+ mVisibleComments.get(getAdapterPosition() - 1).setVoteType(CommentData.VOTE_TYPE_NO_VOTE);
newVoteType = RedditUtils.DIR_UNVOTE;
upvoteButton.clearColorFilter();
}
- scoreTextView.setText(Integer.toString(mVisibleComments.get(getAdapterPosition()).getScore() + mVisibleComments.get(getAdapterPosition()).getVoteType()));
+ scoreTextView.setText(Integer.toString(mVisibleComments.get(getAdapterPosition() - 1).getScore() + mVisibleComments.get(getAdapterPosition() - 1).getVoteType()));
VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() {
@Override
public void onVoteThingSuccess(int position) {
if(newVoteType.equals(RedditUtils.DIR_UPVOTE)) {
- mVisibleComments.get(getAdapterPosition()).setVoteType(CommentData.VOTE_TYPE_UPVOTE);
+ mVisibleComments.get(getAdapterPosition() - 1).setVoteType(CommentData.VOTE_TYPE_UPVOTE);
upvoteButton.setColorFilter(ContextCompat.getColor(mActivity, R.color.backgroundColorPrimaryDark), android.graphics.PorterDuff.Mode.SRC_IN);
} else {
- mVisibleComments.get(getAdapterPosition()).setVoteType(CommentData.VOTE_TYPE_NO_VOTE);
+ mVisibleComments.get(getAdapterPosition() - 1).setVoteType(CommentData.VOTE_TYPE_NO_VOTE);
upvoteButton.clearColorFilter();
}
downvoteButton.clearColorFilter();
- scoreTextView.setText(Integer.toString(mVisibleComments.get(getAdapterPosition()).getScore() + mVisibleComments.get(getAdapterPosition()).getVoteType()));
+ scoreTextView.setText(Integer.toString(mVisibleComments.get(getAdapterPosition() - 1).getScore() + mVisibleComments.get(getAdapterPosition() - 1).getVoteType()));
}
@Override
public void onVoteThingFail(int position) { }
- }, mVisibleComments.get(getAdapterPosition()).getFullName(), newVoteType, getAdapterPosition());
+ }, mVisibleComments.get(getAdapterPosition() - 1).getFullName(), newVoteType, getAdapterPosition());
});
downvoteButton.setOnClickListener(view -> {
- int previousVoteType = mVisibleComments.get(getAdapterPosition()).getVoteType();
+ int previousVoteType = mVisibleComments.get(getAdapterPosition() - 1).getVoteType();
String newVoteType;
upvoteButton.clearColorFilter();
if(previousVoteType != CommentData.VOTE_TYPE_DOWNVOTE) {
//Not downvoted before
- mVisibleComments.get(getAdapterPosition()).setVoteType(CommentData.VOTE_TYPE_DOWNVOTE);
+ mVisibleComments.get(getAdapterPosition() - 1).setVoteType(CommentData.VOTE_TYPE_DOWNVOTE);
newVoteType = RedditUtils.DIR_DOWNVOTE;
downvoteButton.setColorFilter(ContextCompat.getColor(mActivity, R.color.colorAccent), android.graphics.PorterDuff.Mode.SRC_IN);
} else {
//Downvoted before
- mVisibleComments.get(getAdapterPosition()).setVoteType(CommentData.VOTE_TYPE_NO_VOTE);
+ mVisibleComments.get(getAdapterPosition() - 1).setVoteType(CommentData.VOTE_TYPE_NO_VOTE);
newVoteType = RedditUtils.DIR_UNVOTE;
downvoteButton.clearColorFilter();
}
- scoreTextView.setText(Integer.toString(mVisibleComments.get(getAdapterPosition()).getScore() + mVisibleComments.get(getAdapterPosition()).getVoteType()));
+ scoreTextView.setText(Integer.toString(mVisibleComments.get(getAdapterPosition() - 1).getScore() + mVisibleComments.get(getAdapterPosition() - 1).getVoteType()));
VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() {
@Override
public void onVoteThingSuccess(int position1) {
if(newVoteType.equals(RedditUtils.DIR_DOWNVOTE)) {
- mVisibleComments.get(getAdapterPosition()).setVoteType(CommentData.VOTE_TYPE_DOWNVOTE);
+ mVisibleComments.get(getAdapterPosition() - 1).setVoteType(CommentData.VOTE_TYPE_DOWNVOTE);
downvoteButton.setColorFilter(ContextCompat.getColor(mActivity, R.color.colorAccent), android.graphics.PorterDuff.Mode.SRC_IN);
} else {
- mVisibleComments.get(getAdapterPosition()).setVoteType(CommentData.VOTE_TYPE_NO_VOTE);
+ mVisibleComments.get(getAdapterPosition() - 1).setVoteType(CommentData.VOTE_TYPE_NO_VOTE);
downvoteButton.clearColorFilter();
}
upvoteButton.clearColorFilter();
- scoreTextView.setText(Integer.toString(mVisibleComments.get(getAdapterPosition()).getScore() + mVisibleComments.get(getAdapterPosition()).getVoteType()));
+ scoreTextView.setText(Integer.toString(mVisibleComments.get(getAdapterPosition() - 1).getScore() + mVisibleComments.get(getAdapterPosition() - 1).getVoteType()));
}
@Override
public void onVoteThingFail(int position1) { }
- }, mVisibleComments.get(getAdapterPosition()).getFullName(), newVoteType, getAdapterPosition());
+ }, mVisibleComments.get(getAdapterPosition() - 1).getFullName(), newVoteType, getAdapterPosition());
});
}
}
@@ -366,11 +877,11 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
ButterKnife.bind(this, itemView);
placeholderTextView.setOnClickListener(view -> {
- int parentPosition = getParentPosition(getAdapterPosition());
+ int parentPosition = getParentPosition(getAdapterPosition() - 1);
CommentData parentComment = mVisibleComments.get(parentPosition);
- mVisibleComments.get(getAdapterPosition()).setLoadingMoreChildren(true);
- mVisibleComments.get(getAdapterPosition()).setLoadMoreChildrenFailed(false);
+ mVisibleComments.get(getAdapterPosition() - 1).setLoadingMoreChildren(true);
+ mVisibleComments.get(getAdapterPosition() - 1).setLoadMoreChildrenFailed(false);
placeholderTextView.setText(R.string.loading);
FetchComment.fetchMoreComment(mRetrofit, mSubredditNamePrefixed, parentComment.getMoreChildrenFullnames(),
@@ -389,8 +900,8 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1)
.setLoadMoreChildrenFailed(false);
- int placeholderPosition = getAdapterPosition();
- if(mVisibleComments.get(getAdapterPosition()).getFullName().equals(parentComment.getFullName())) {
+ int placeholderPosition = getAdapterPosition() - 1;
+ if(mVisibleComments.get(getAdapterPosition() - 1).getFullName().equals(parentComment.getFullName())) {
for(int i = parentPosition + 1; i < mVisibleComments.size(); i++) {
if(mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) {
placeholderPosition = i;
@@ -404,14 +915,14 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
placeholderTextView.setText(R.string.comment_load_more_comments);
mVisibleComments.addAll(placeholderPosition, expandedComments);
- notifyItemRangeInserted(placeholderPosition, expandedComments.size());
+ notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size());
} else {
mVisibleComments.get(parentPosition).getChildren()
.remove(mVisibleComments.get(parentPosition).getChildren().size() - 1);
mVisibleComments.get(parentPosition).removeMoreChildrenFullnames();
- int placeholderPosition = getAdapterPosition();
- if(mVisibleComments.get(getAdapterPosition()).getFullName().equals(parentComment.getFullName())) {
+ int placeholderPosition = getAdapterPosition() - 1;
+ if(mVisibleComments.get(getAdapterPosition() - 1).getFullName().equals(parentComment.getFullName())) {
for(int i = parentPosition + 1; i < mVisibleComments.size(); i++) {
if(mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) {
placeholderPosition = i;
@@ -421,10 +932,10 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
}
mVisibleComments.remove(placeholderPosition);
- notifyItemRemoved(placeholderPosition);
+ notifyItemRemoved(placeholderPosition + 1);
mVisibleComments.addAll(placeholderPosition, expandedComments);
- notifyItemRangeInserted(placeholderPosition, expandedComments.size());
+ notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size());
}
} else {
if(mVisibleComments.get(parentPosition).hasReply() && mVisibleComments.get(parentPosition).getChildren().size() <= childrenStartingIndex) {
@@ -455,7 +966,7 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
placeholderTextView.setText(R.string.comment_load_more_comments);
mVisibleComments.addAll(placeholderPosition, expandedComments);
- notifyItemRangeInserted(placeholderPosition, expandedComments.size());
+ notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size());
}
mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1)
@@ -475,8 +986,8 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
if(parentPosition < mVisibleComments.size()
&& parentComment.getFullName().equals(mVisibleComments.get(parentPosition).getFullName())) {
if(mVisibleComments.get(parentPosition).isExpanded()) {
- int placeholderPosition = getAdapterPosition();
- if(!mVisibleComments.get(getAdapterPosition()).getFullName().equals(parentComment.getFullName())) {
+ int placeholderPosition = getAdapterPosition() - 1;
+ if(!mVisibleComments.get(getAdapterPosition() - 1).getFullName().equals(parentComment.getFullName())) {
for(int i = parentPosition + 1; i < mVisibleComments.size(); i++) {
if(mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) {
placeholderPosition = i;
@@ -525,4 +1036,25 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
});
}
}
+
+ class LoadCommentsViewHolder extends RecyclerView.ViewHolder {
+
+ public LoadCommentsViewHolder(@NonNull View itemView) {
+ super(itemView);
+ }
+ }
+
+ class LoadCommentsFailedViewHolder extends RecyclerView.ViewHolder {
+
+ public LoadCommentsFailedViewHolder(@NonNull View itemView) {
+ super(itemView);
+ }
+ }
+
+ class NoCommentViewHolder extends RecyclerView.ViewHolder {
+
+ public NoCommentViewHolder(@NonNull View itemView) {
+ super(itemView);
+ }
+ }
}
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchComment.java
index b2a0db3f..fb1aec1f 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchComment.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchComment.java
@@ -106,7 +106,7 @@ class FetchComment {
}
@Override
- public void onFailure(Call<String> call, Throwable t) {
+ public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
Log.i("more comment failed", t.getMessage());
fetchMoreCommentListener.onFetchMoreCommentFailed();
}
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/LoadSubredditIconAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/LoadSubredditIconAsyncTask.java
index f7f0fdcd..923e657f 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/LoadSubredditIconAsyncTask.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/LoadSubredditIconAsyncTask.java
@@ -34,6 +34,8 @@ class LoadSubredditIconAsyncTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
- loadSubredditIconAsyncTaskListener.loadIconSuccess(iconImageUrl);
+ if(!isCancelled()) {
+ loadSubredditIconAsyncTaskListener.loadIconSuccess(iconImageUrl);
+ }
}
}
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java
index 72f8c4a3..a10579c1 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java
@@ -16,7 +16,7 @@ public interface RedditAPI {
@POST("api/v1/access_token")
Call<String> getAccessToken(@HeaderMap Map<String, String> headers, @FieldMap Map<String, String> params);
- @GET("{subredditNamePrefixed}/comments/{article}.json?raw_json=1")
+ @GET("{subredditNamePrefixed}/comments/{article}.json?&raw_json=1")
Call<String> getComments(@Path("subredditNamePrefixed") String subredditNamePrefixed,
@Path("article") String article);
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java
index 8ab0b3f5..0eb99830 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java
@@ -3,46 +3,23 @@ package ml.docilealligator.infinityforreddit;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
-import android.graphics.ColorFilter;
-import android.graphics.PorterDuff;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.ProgressBar;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
-import androidx.browser.customtabs.CustomTabsIntent;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
-import androidx.core.content.ContextCompat;
-import androidx.core.widget.NestedScrollView;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
-import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.RequestManager;
-import com.bumptech.glide.load.DataSource;
-import com.bumptech.glide.load.engine.GlideException;
-import com.bumptech.glide.request.RequestListener;
-import com.bumptech.glide.request.RequestOptions;
-import com.bumptech.glide.request.target.Target;
-import com.google.android.material.card.MaterialCardView;
-import com.google.android.material.chip.Chip;
import com.google.android.material.snackbar.Snackbar;
-import com.lsjwzh.widget.materialloadingprogressbar.CircleProgressBar;
-import com.santalu.aspectratioimageview.AspectRatioImageView;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
@@ -53,15 +30,9 @@ import java.util.Locale;
import javax.inject.Inject;
import javax.inject.Named;
-import CustomView.AspectRatioGifImageView;
-import SubredditDatabase.SubredditRoomDatabase;
import butterknife.BindView;
import butterknife.ButterKnife;
-import jp.wasabeef.glide.transformations.BlurTransformation;
-import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
import retrofit2.Retrofit;
-import ru.noties.markwon.SpannableConfiguration;
-import ru.noties.markwon.view.MarkwonView;
import static ml.docilealligator.infinityforreddit.CommentActivity.EXTRA_COMMENT_DATA_KEY;
import static ml.docilealligator.infinityforreddit.CommentActivity.WRITE_COMMENT_REQUEST_CODE;
@@ -93,34 +64,7 @@ public class ViewPostDetailActivity extends AppCompatActivity {
@BindView(R.id.coordinator_layout_view_post_detail) CoordinatorLayout mCoordinatorLayout;
@BindView(R.id.toolbar_view_post_detail_activity) Toolbar toolbar;
- @BindView(R.id.nested_scroll_view_view_post_detail_activity) NestedScrollView mNestedScrollView;
- @BindView(R.id.subreddit_icon_name_linear_layout_view_post_detail) LinearLayout mSubredditIconNameLinearLayout;
- @BindView(R.id.subreddit_icon_circle_image_view_view_post_detail) AspectRatioGifImageView mSubredditIconGifImageView;
- @BindView(R.id.subreddit_text_view_view_post_detail) TextView mSubredditTextView;
- @BindView(R.id.post_time_text_view_view_post_detail) TextView mPostTimeTextView;
- @BindView(R.id.title_text_view_view_post_detail) TextView mTitleTextView;
- @BindView(R.id.content_markdown_view_view_post_detail) MarkwonView mContentMarkdownView;
- @BindView(R.id.type_text_view_view_post_detail) Chip mTypeChip;
- @BindView(R.id.gilded_image_view_view_post_detail) ImageView mGildedImageView;
- @BindView(R.id.gilded_number_text_view_view_post_detail) TextView mGildedNumberTextView;
- @BindView(R.id.crosspost_image_view_view_post_detail) ImageView mCrosspostImageView;
- @BindView(R.id.nsfw_text_view_view_post_detail) Chip mNSFWChip;
- @BindView(R.id.link_text_view_view_post_detail) TextView linkTextView;
- @BindView(R.id.image_view_wrapper_view_post_detail) RelativeLayout mRelativeLayout;
- @BindView(R.id.load_wrapper_view_post_detail) RelativeLayout mLoadWrapper;
- @BindView(R.id.progress_bar_view_post_detail) ProgressBar mLoadImageProgressBar;
- @BindView(R.id.load_image_error_text_view_view_post_detail) TextView mLoadImageErrorTextView;
- @BindView(R.id.image_view_view_post_detail) AspectRatioImageView mImageView;
- @BindView(R.id.image_view_no_preview_link_view_post_detail) ImageView mNoPreviewLinkImageView;
- @BindView(R.id.plus_button_view_post_detail) ImageView mUpvoteButton;
- @BindView(R.id.score_text_view_view_post_detail) TextView mScoreTextView;
- @BindView(R.id.minus_button_view_post_detail) ImageView mDownvoteButton;
- @BindView(R.id.share_button_view_post_detail) ImageView mShareButton;
- @BindView(R.id.comment_progress_bar_view_post_detail) CircleProgressBar mCommentProgressbar;
- @BindView(R.id.comment_card_view_view_post_detail) MaterialCardView mCommentCardView;
@BindView(R.id.recycler_view_view_post_detail) RecyclerView mRecyclerView;
- @BindView(R.id.no_comment_wrapper_linear_layout_view_post_detail) LinearLayout mNoCommentWrapperLinearLayout;
- @BindView(R.id.no_comment_image_view_view_post_detail) ImageView mNoCommentImageView;
@Inject @Named("no_oauth")
Retrofit mRetrofit;
@@ -148,14 +92,26 @@ public class ViewPostDetailActivity extends AppCompatActivity {
mGlide = Glide.with(this);
mLocale = getResources().getConfiguration().locale;
+ mRecyclerView.setNestedScrollingEnabled(false);
+ mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
+ mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
+
if(savedInstanceState == null) {
orientation = getResources().getConfiguration().orientation;
mPost = getIntent().getExtras().getParcelable(EXTRA_POST_DATA);
} else {
orientation = savedInstanceState.getInt(ORIENTATION_STATE);
mPost = savedInstanceState.getParcelable(POST_STATE);
- isRefreshing = savedInstanceState.getBoolean(IS_REFRESHING_STATE);
+ }
+
+ mAdapter = new CommentRecyclerViewAdapter(ViewPostDetailActivity.this, mRetrofit,
+ mOauthRetrofit, mGlide, mSharedPreferences, mPost,
+ mPost.getSubredditNamePrefixed(), mLocale, mLoadSubredditIconAsyncTask,
+ post -> EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)));
+ mRecyclerView.setAdapter(mAdapter);
+ if(savedInstanceState != null) {
+ isRefreshing = savedInstanceState.getBoolean(IS_REFRESHING_STATE);
if(isRefreshing) {
isRefreshing = false;
refresh();
@@ -166,336 +122,11 @@ public class ViewPostDetailActivity extends AppCompatActivity {
postListPosition = getIntent().getExtras().getInt(EXTRA_POST_LIST_POSITION);
}
- mRecyclerView.setNestedScrollingEnabled(false);
- mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
- mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
-
fetchComment();
- bindView();
- initializeButtonOnClickListener();
- }
-
- private void bindView() {
- mTitleTextView.setText(mPost.getTitle());
-
- if(mPost.getSubredditIconUrl() == null) {
- mLoadSubredditIconAsyncTask = new LoadSubredditIconAsyncTask(
- SubredditRoomDatabase.getDatabase(this).subredditDao(), mPost.getSubredditNamePrefixed().substring(2),
- iconImageUrl -> {
- if(!iconImageUrl.equals("")) {
- mGlide.load(iconImageUrl)
- .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
- .error(mGlide.load(R.drawable.subreddit_default_icon)
- .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))))
- .into(mSubredditIconGifImageView);
- } else {
- mGlide.load(R.drawable.subreddit_default_icon)
- .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
- .into(mSubredditIconGifImageView);
- }
-
- mPost.setSubredditIconUrl(iconImageUrl);
- });
- mLoadSubredditIconAsyncTask.execute();
- } else if(!mPost.getSubredditIconUrl().equals("")) {
- mGlide.load(mPost.getSubredditIconUrl())
- .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
- .error(mGlide.load(R.drawable.subreddit_default_icon)
- .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))))
- .into(mSubredditIconGifImageView);
- } else {
- mGlide.load(R.drawable.subreddit_default_icon)
- .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
- .into(mSubredditIconGifImageView);
- }
-
- switch (mPost.getVoteType()) {
- case 1:
- //Upvote
- mUpvoteButton.setColorFilter(ContextCompat.getColor(this, R.color.backgroundColorPrimaryDark), PorterDuff.Mode.SRC_IN);
- break;
- case -1:
- //Downvote
- mDownvoteButton.setColorFilter(ContextCompat.getColor(this, R.color.minusButtonColor), PorterDuff.Mode.SRC_IN);
- break;
- case 0:
- mUpvoteButton.clearColorFilter();
- mDownvoteButton.clearColorFilter();
- }
-
- if(mPost.getPostType() != Post.TEXT_TYPE && mPost.getPostType() != Post.NO_PREVIEW_LINK_TYPE) {
- mRelativeLayout.setVisibility(View.VISIBLE);
- mImageView.setVisibility(View.VISIBLE);
- mImageView.setRatio((float) mPost.getPreviewHeight() / (float) mPost.getPreviewWidth());
- loadImage();
- } else {
- mRelativeLayout.setVisibility(View.GONE);
- mImageView.setVisibility(View.GONE);
- }
-
- if(mPost.isCrosspost()) {
- mCrosspostImageView.setVisibility(View.VISIBLE);
- }
-
- mSubredditTextView.setText(mPost.getSubredditNamePrefixed());
-
- mPostTimeTextView.setText(mPost.getPostTime());
-
- if(mPost.getGilded() > 0) {
- mGildedImageView.setVisibility(View.VISIBLE);
- mGlide.load(R.drawable.gold).into(mGildedImageView);
- mGildedNumberTextView.setVisibility(View.VISIBLE);
- String gildedNumber = getResources().getString(R.string.gilded, mPost.getGilded());
- mGildedNumberTextView.setText(gildedNumber);
- }
-
- if(mPost.isNSFW()) {
- mNSFWChip.setVisibility(View.VISIBLE);
- } else {
- mNSFWChip.setVisibility(View.GONE);
- }
-
- String scoreWithVote = Integer.toString(mPost.getScore() + mPost.getVoteType());
- mScoreTextView.setText(scoreWithVote);
-
- switch (mPost.getPostType()) {
- case Post.IMAGE_TYPE:
- mTypeChip.setText("IMAGE");
-
- mImageView.setOnClickListener(view -> {
- Intent intent = new Intent(ViewPostDetailActivity.this, ViewImageActivity.class);
- intent.putExtra(ViewImageActivity.IMAGE_URL_KEY, mPost.getUrl());
- intent.putExtra(ViewImageActivity.TITLE_KEY, mPost.getTitle());
- intent.putExtra(ViewImageActivity.FILE_NAME_KEY, mPost.getSubredditNamePrefixed().substring(2)
- + "-" + mPost.getId().substring(3));
- startActivity(intent);
- });
- break;
- case Post.LINK_TYPE:
- mTypeChip.setText("LINK");
-
- linkTextView.setVisibility(View.VISIBLE);
- String domain = Uri.parse(mPost.getUrl()).getHost();
- linkTextView.setText(domain);
-
- mImageView.setOnClickListener(view -> {
- CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
- // add share action to menu list
- builder.addDefaultShareMenuItem();
- builder.setToolbarColor(getResources().getColor(R.color.colorPrimary));
- CustomTabsIntent customTabsIntent = builder.build();
- customTabsIntent.launchUrl(ViewPostDetailActivity.this, Uri.parse(mPost.getUrl()));
- });
- break;
- case Post.GIF_VIDEO_TYPE:
- mTypeChip.setText("GIF");
-
- final Uri gifVideoUri = Uri.parse(mPost.getVideoUrl());
- mImageView.setOnClickListener(view -> {
- Intent intent = new Intent(ViewPostDetailActivity.this, ViewVideoActivity.class);
- intent.setData(gifVideoUri);
- intent.putExtra(ViewVideoActivity.TITLE_KEY, mPost.getTitle());
- intent.putExtra(ViewVideoActivity.IS_DASH_VIDEO_KEY, mPost.isDashVideo());
- intent.putExtra(ViewVideoActivity.IS_DOWNLOADABLE_KEY, mPost.isDownloadableGifOrVideo());
- if(mPost.isDownloadableGifOrVideo()) {
- intent.putExtra(ViewVideoActivity.DOWNLOAD_URL_KEY, mPost.getGifOrVideoDownloadUrl());
- intent.putExtra(ViewVideoActivity.SUBREDDIT_KEY, mPost.getSubredditNamePrefixed());
- intent.putExtra(ViewVideoActivity.ID_KEY, mPost.getId());
- }
- startActivity(intent);
- });
- break;
- case Post.VIDEO_TYPE:
- mTypeChip.setText("VIDEO");
-
- final Uri videoUri = Uri.parse(mPost.getVideoUrl());
- mImageView.setOnClickListener(view -> {
- Intent intent = new Intent(ViewPostDetailActivity.this, ViewVideoActivity.class);
- intent.setData(videoUri);
- intent.putExtra(ViewVideoActivity.TITLE_KEY, mPost.getTitle());
- intent.putExtra(ViewVideoActivity.IS_DASH_VIDEO_KEY, mPost.isDashVideo());
- intent.putExtra(ViewVideoActivity.IS_DOWNLOADABLE_KEY, mPost.isDownloadableGifOrVideo());
- if(mPost.isDownloadableGifOrVideo()) {
- intent.putExtra(ViewVideoActivity.DOWNLOAD_URL_KEY, mPost.getGifOrVideoDownloadUrl());
- intent.putExtra(ViewVideoActivity.SUBREDDIT_KEY, mPost.getSubredditNamePrefixed());
- intent.putExtra(ViewVideoActivity.ID_KEY, mPost.getId());
- }
- startActivity(intent);
- });
- break;
- case Post.NO_PREVIEW_LINK_TYPE:
- mTypeChip.setText("LINK");
-
- linkTextView.setVisibility(View.VISIBLE);
- String noPreviewLinkDomain = Uri.parse(mPost.getUrl()).getHost();
- linkTextView.setText(noPreviewLinkDomain);
-
- if(!mPost.getSelfText().equals("")) {
- mContentMarkdownView.setVisibility(View.VISIBLE);
- mContentMarkdownView.setMarkdown(getCustomSpannableConfiguration(), mPost.getSelfText());
- }
- mNoPreviewLinkImageView.setVisibility(View.VISIBLE);
- mNoPreviewLinkImageView.setOnClickListener(view -> {
- CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
- // add share action to menu list
- builder.addDefaultShareMenuItem();
- builder.setToolbarColor(getResources().getColor(R.color.colorPrimary));
- CustomTabsIntent customTabsIntent = builder.build();
- customTabsIntent.launchUrl(ViewPostDetailActivity.this, Uri.parse(mPost.getUrl()));
- });
- break;
- case Post.TEXT_TYPE:
- mTypeChip.setText("TEXT");
-
- if(!mPost.getSelfText().equals("")) {
- mContentMarkdownView.setVisibility(View.VISIBLE);
- mContentMarkdownView.setMarkdown(getCustomSpannableConfiguration(), mPost.getSelfText());
- }
- break;
- }
- }
-
- private void initializeButtonOnClickListener() {
- mSubredditIconNameLinearLayout.setOnClickListener(view -> {
- Intent intent = new Intent(ViewPostDetailActivity.this, ViewSubredditDetailActivity.class);
- intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY,
- mPost.getSubredditNamePrefixed().substring(2));
- startActivity(intent);
- });
-
- mShareButton.setOnClickListener(view -> {
- Intent intent = new Intent(Intent.ACTION_SEND);
- intent.setType("text/plain");
- String extraText = mPost.getTitle() + "\n" + mPost.getPermalink();
- intent.putExtra(Intent.EXTRA_TEXT, extraText);
- startActivity(Intent.createChooser(intent, "Share"));
- });
-
- mUpvoteButton.setOnClickListener(view -> {
- ColorFilter previousUpvoteButtonColorFilter = mUpvoteButton.getColorFilter();
- ColorFilter previousDownvoteButtonColorFilter = mDownvoteButton.getColorFilter();
- int previousVoteType = mPost.getVoteType();
- String newVoteType;
-
- mDownvoteButton.clearColorFilter();
-
- if(previousUpvoteButtonColorFilter == null) {
- //Not upvoted before
- mPost.setVoteType(1);
- newVoteType = RedditUtils.DIR_UPVOTE;
- mUpvoteButton.setColorFilter(ContextCompat.getColor(this, R.color.backgroundColorPrimaryDark), android.graphics.PorterDuff.Mode.SRC_IN);
- } else {
- //Upvoted before
- mPost.setVoteType(0);
- newVoteType = RedditUtils.DIR_UNVOTE;
- mUpvoteButton.clearColorFilter();
- }
-
- mScoreTextView.setText(Integer.toString(mPost.getScore() + mPost.getVoteType()));
-
- if(postListPosition != -1) {
- EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition));
- }
-
- VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingWithoutPositionListener() {
- @Override
- public void onVoteThingSuccess() {
- if(newVoteType.equals(RedditUtils.DIR_UPVOTE)) {
- mPost.setVoteType(1);
- mUpvoteButton.setColorFilter(ContextCompat.getColor(ViewPostDetailActivity.this, R.color.backgroundColorPrimaryDark), android.graphics.PorterDuff.Mode.SRC_IN);
- } else {
- mPost.setVoteType(0);
- mUpvoteButton.clearColorFilter();
- }
-
- mDownvoteButton.clearColorFilter();
- mScoreTextView.setText(Integer.toString(mPost.getScore() + mPost.getVoteType()));
-
- if(postListPosition != -1) {
- EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition));
- }
- }
-
- @Override
- public void onVoteThingFail() {
- Toast.makeText(ViewPostDetailActivity.this, R.string.vote_failed, Toast.LENGTH_SHORT).show();
- mPost.setVoteType(previousVoteType);
- mScoreTextView.setText(Integer.toString(mPost.getScore() + previousVoteType));
- mUpvoteButton.setColorFilter(previousUpvoteButtonColorFilter);
- mDownvoteButton.setColorFilter(previousDownvoteButtonColorFilter);
-
- if(postListPosition != -1) {
- EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition));
- }
- }
- }, mPost.getFullName(), newVoteType);
- });
-
- mDownvoteButton.setOnClickListener(view -> {
- ColorFilter previousUpvoteButtonColorFilter = mUpvoteButton.getColorFilter();
- ColorFilter previousDownvoteButtonColorFilter = mDownvoteButton.getColorFilter();
- int previousVoteType = mPost.getVoteType();
- String newVoteType;
-
- mUpvoteButton.clearColorFilter();
-
- if(previousDownvoteButtonColorFilter == null) {
- //Not upvoted before
- mPost.setVoteType(-1);
- newVoteType = RedditUtils.DIR_DOWNVOTE;
- mDownvoteButton.setColorFilter(ContextCompat.getColor(this, R.color.colorAccent), android.graphics.PorterDuff.Mode.SRC_IN);
- } else {
- //Upvoted before
- mPost.setVoteType(0);
- newVoteType = RedditUtils.DIR_UNVOTE;
- mDownvoteButton.clearColorFilter();
- }
-
- mScoreTextView.setText(Integer.toString(mPost.getScore() + mPost.getVoteType()));
-
- if(postListPosition != -1) {
- EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition));
- }
-
- VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingWithoutPositionListener() {
- @Override
- public void onVoteThingSuccess() {
- if(newVoteType.equals(RedditUtils.DIR_DOWNVOTE)) {
- mPost.setVoteType(-1);
- mDownvoteButton.setColorFilter(ContextCompat.getColor(ViewPostDetailActivity.this, R.color.colorAccent), android.graphics.PorterDuff.Mode.SRC_IN);
- } else {
- mPost.setVoteType(0);
- mDownvoteButton.clearColorFilter();
- }
-
- mUpvoteButton.clearColorFilter();
- mScoreTextView.setText(Integer.toString(mPost.getScore() + mPost.getVoteType()));
-
- if(postListPosition != -1) {
- EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition));
- }
- }
-
- @Override
- public void onVoteThingFail() {
- Toast.makeText(ViewPostDetailActivity.this, R.string.vote_failed, Toast.LENGTH_SHORT).show();
- mPost.setVoteType(previousVoteType);
- mScoreTextView.setText(Integer.toString(mPost.getScore() + previousVoteType));
- mUpvoteButton.setColorFilter(previousUpvoteButtonColorFilter);
- mDownvoteButton.setColorFilter(previousDownvoteButtonColorFilter);
-
- if(postListPosition != -1) {
- EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition));
- }
- }
- }, mPost.getFullName(), newVoteType);
- });
}
private void fetchComment() {
- mCommentCardView.setVisibility(View.GONE);
- mCommentProgressbar.setVisibility(View.VISIBLE);
- mNoCommentWrapperLinearLayout.setVisibility(View.GONE);
+ mAdapter.initiallyLoading();
FetchComment.fetchComment(mRetrofit, mPost.getSubredditNamePrefixed(), mPost.getId(),
mLocale, new FetchComment.FetchCommentListener() {
@@ -503,7 +134,19 @@ public class ViewPostDetailActivity extends AppCompatActivity {
public void onFetchCommentSuccess(ArrayList<CommentData> expandedComments,
String parentId, ArrayList<String> children) {
ViewPostDetailActivity.this.children = children;
- mCommentProgressbar.setVisibility(View.GONE);
+
+ mAdapter.addComments(expandedComments);
+
+ mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
+ @Override
+ public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
+ super.onScrolled(recyclerView, dx, dy);
+
+
+ }
+ });
+
+ /*mCommentProgressbar.setVisibility(View.GONE);
if (expandedComments.size() > 0) {
if(mAdapter == null) {
@@ -520,26 +163,34 @@ public class ViewPostDetailActivity extends AppCompatActivity {
}
mAdapter = new CommentRecyclerViewAdapter(ViewPostDetailActivity.this, mRetrofit,
- mOauthRetrofit, mSharedPreferences, expandedComments,
- mPost.getSubredditNamePrefixed(), mLocale);
+ mOauthRetrofit, mGlide, mSharedPreferences, mPost,
+ mPost.getSubredditNamePrefixed(), mLocale, new CommentRecyclerViewAdapter.UpdatePostInPostFragmentCallback() {
+ @Override
+ public void updatePost(Post post) {
+ EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition));
+ }
+ });
mRecyclerView.setAdapter(mAdapter);
- mCommentCardView.setVisibility(View.VISIBLE);
+ //mCommentCardView.setVisibility(View.VISIBLE);
} else {
mNoCommentWrapperLinearLayout.setVisibility(View.VISIBLE);
- mGlide.load(R.drawable.no_comment_indicator).into(mNoCommentImageView);
- }
+ mGlide.load(R.drawable.no_comment_placeholder).into(mNoCommentImageView);
+ }*/
}
@Override
public void onFetchCommentFailed() {
- mCommentProgressbar.setVisibility(View.GONE);
- showRetrySnackbar();
+ mAdapter.initiallyLoadCommentsFailed();
}
});
}
private void fetchMoreComment(int startingIndex) {
+ if(isLoadingMoreChildren) {
+ return;
+ }
+
isLoadingMoreChildren = true;
FetchComment.fetchMoreComment(mRetrofit, mPost.getSubredditNamePrefixed(), children, startingIndex,
0, mLocale, new FetchComment.FetchMoreCommentListener() {
@@ -560,73 +211,11 @@ public class ViewPostDetailActivity extends AppCompatActivity {
});
}
- private void loadImage() {
- RequestBuilder imageRequestBuilder = mGlide.load(mPost.getPreviewUrl())
- .apply(new RequestOptions().override(mPost.getPreviewWidth(), mPost.getPreviewHeight()))
- .listener(new RequestListener<Drawable>() {
- @Override
- public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
- mLoadImageProgressBar.setVisibility(View.GONE);
- mLoadImageErrorTextView.setVisibility(View.VISIBLE);
- mLoadImageErrorTextView.setOnClickListener(view -> {
- mLoadImageProgressBar.setVisibility(View.VISIBLE);
- mLoadImageErrorTextView.setVisibility(View.GONE);
- loadImage();
- });
- return false;
- }
-
- @Override
- public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
- mLoadWrapper.setVisibility(View.GONE);
- return false;
- }
- });
-
- if(mPost.isNSFW()) {
- imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 2)))
- .into(mImageView);
- } else {
- imageRequestBuilder.into(mImageView);
- }
- }
-
- private SpannableConfiguration getCustomSpannableConfiguration() {
- return SpannableConfiguration.builder(this).linkResolver((view, link) -> {
- if(link.startsWith("/u/") || link.startsWith("u/")) {
- Intent intent = new Intent(ViewPostDetailActivity.this, ViewUserDetailActivity.class);
- intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, link.substring(3));
- startActivity(intent);
- } else if(link.startsWith("/r/") || link.startsWith("r/")) {
- Intent intent = new Intent(ViewPostDetailActivity.this, ViewSubredditDetailActivity.class);
- intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, link.substring(3));
- startActivity(intent);
- } else {
- CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
- // add share action to menu list
- builder.addDefaultShareMenuItem();
- builder.setToolbarColor(getResources().getColor(R.color.colorPrimary));
- CustomTabsIntent customTabsIntent = builder.build();
- customTabsIntent.launchUrl(ViewPostDetailActivity.this, Uri.parse(link));
- }
- }).build();
- }
-
- private void showRetrySnackbar() {
- Snackbar snackbar = Snackbar.make(mCoordinatorLayout, R.string.post_load_comments_failed, Snackbar.LENGTH_INDEFINITE);
- snackbar.setAction(R.string.retry, view -> fetchComment());
- snackbar.show();
- }
-
private void refresh() {
if(!isRefreshing) {
isRefreshing = true;
mChildrenStartingIndex = 0;
- if(mAdapter != null) {
- mAdapter.clearData();
- }
-
fetchComment();
String accessToken = getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE)
@@ -636,7 +225,7 @@ public class ViewPostDetailActivity extends AppCompatActivity {
@Override
public void fetchPostSuccess(Post post) {
mPost = post;
- bindView();
+ mAdapter.updatePost(mPost);
EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition));
isRefreshing = false;
}
@@ -654,7 +243,7 @@ public class ViewPostDetailActivity extends AppCompatActivity {
public void onPostUpdateEvent(PostUpdateEventToDetailActivity event) {
if(mPost.getId().equals(event.postId)) {
mPost.setVoteType(event.voteType);
- mScoreTextView.setText(Integer.toString(mPost.getScore() + event.voteType));
+ mAdapter.updatePost(mPost);
}
}
diff --git a/app/src/main/res/drawable/no_comment_indicator.png b/app/src/main/res/drawable/no_comment_placeholder.png
index 62a3668f..62a3668f 100644
--- a/app/src/main/res/drawable/no_comment_indicator.png
+++ b/app/src/main/res/drawable/no_comment_placeholder.png
Binary files differ
diff --git a/app/src/main/res/layout/activity_view_post_detail.xml b/app/src/main/res/layout/activity_view_post_detail.xml
index 0c9f6786..7416ed7a 100644
--- a/app/src/main/res/layout/activity_view_post_detail.xml
+++ b/app/src/main/res/layout/activity_view_post_detail.xml
@@ -21,339 +21,10 @@
</com.google.android.material.appbar.AppBarLayout>
- <androidx.core.widget.NestedScrollView
- android:id="@+id/nested_scroll_view_view_post_detail_activity"
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/recycler_view_view_post_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- app:layout_behavior="@string/appbar_scrolling_view_behavior">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:descendantFocusability="blocksDescendants">
-
- <com.google.android.material.card.MaterialCardView
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:id="@+id/relative_layout_view_post_detail"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <LinearLayout
- android:id="@+id/subreddit_icon_name_linear_layout_view_post_detail"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:padding="16dp"
- app:layout_constrainedWidth="true"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@id/post_time_text_view_view_post_detail"
- app:layout_constraintTop_toTopOf="parent">
-
- <CustomView.AspectRatioGifImageView
- android:id="@+id/subreddit_icon_circle_image_view_view_post_detail"
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:layout_gravity="center"/>
-
- <TextView
- android:id="@+id/subreddit_text_view_view_post_detail"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="16dp"
- android:layout_gravity="center"
- android:textColor="#E91E63" />
-
- </LinearLayout>
-
- <TextView
- android:id="@+id/post_time_text_view_view_post_detail"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_marginEnd="16dp"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toEndOf="@id/subreddit_icon_name_linear_layout_view_post_detail"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent"/>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- <TextView
- android:id="@+id/title_text_view_view_post_detail"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingStart="16dp"
- android:paddingEnd="16dp"
- android:textColor="@color/primaryTextColor"
- android:textSize="18sp" />
-
- <ru.noties.markwon.view.MarkwonView
- android:id="@+id/content_markdown_view_view_post_detail"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingStart="16dp"
- android:paddingEnd="16dp"
- android:layout_marginTop="16dp"
- android:visibility="gone" />
-
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingStart="16dp"
- android:paddingEnd="16dp"
- android:paddingTop="16dp">
-
- <com.google.android.material.chip.Chip
- android:id="@+id/type_text_view_view_post_detail"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="16dp"
- android:textColor="@android:color/white"
- android:layout_centerVertical="true"
- app:chipBackgroundColor="@color/backgroundColorPrimaryDark"/>
-
- <ImageView
- android:id="@+id/gilded_image_view_view_post_detail"
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:layout_toEndOf="@id/type_text_view_view_post_detail"
- android:layout_centerVertical="true"
- android:visibility="gone"/>
-
- <TextView
- android:id="@+id/gilded_number_text_view_view_post_detail"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="4dp"
- android:layout_marginEnd="8dp"
- android:layout_toEndOf="@id/gilded_image_view_view_post_detail"
- android:layout_centerVertical="true"
- android:visibility="gone"
- android:textSize="20sp"
- android:textColor="@color/gold"/>
-
- <ImageView
- android:id="@+id/crosspost_image_view_view_post_detail"
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:layout_toEndOf="@id/gilded_number_text_view_view_post_detail"
- android:layout_centerVertical="true"
- android:src="@drawable/crosspost"
- android:tint="@color/colorAccent"
- android:visibility="gone"/>
-
- <com.google.android.material.chip.Chip
- android:id="@+id/nsfw_text_view_view_post_detail"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/nsfw"
- android:layout_alignParentEnd="true"
- android:layout_marginStart="8dp"
- android:textColor="@android:color/white"
- android:visibility="gone"
- android:layout_centerVertical="true"
- app:chipBackgroundColor="@color/colorAccent"/>
-
- </RelativeLayout>
-
- <TextView
- android:id="@+id/link_text_view_view_post_detail"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingStart="16dp"
- android:paddingEnd="16dp"
- android:textSize="12sp"
- android:visibility="gone"/>
-
- <RelativeLayout
- android:id="@+id/image_view_wrapper_view_post_detail"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="16dp"
- android:visibility="gone">
-
- <com.santalu.aspectratioimageview.AspectRatioImageView
- android:id="@+id/image_view_view_post_detail"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:adjustViewBounds="true"
- android:scaleType="fitStart"/>
-
- <RelativeLayout
- android:id="@+id/load_wrapper_view_post_detail"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true">
-
- <ProgressBar
- android:id="@+id/progress_bar_view_post_detail"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true" />
-
- <TextView
- android:id="@+id/load_image_error_text_view_view_post_detail"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:drawableTop="@drawable/ic_error_outline_black_24dp"
- android:layout_centerInParent="true"
- android:gravity="center"
- android:text="@string/tap_to_retry"
- android:visibility="gone" />
-
- </RelativeLayout>
-
- </RelativeLayout>
-
- <ImageView
- android:id="@+id/image_view_no_preview_link_view_post_detail"
- android:layout_width="match_parent"
- android:layout_height="150dp"
- android:layout_marginTop="16dp"
- android:background="@color/grey"
- android:scaleType="center"
- android:src="@drawable/ic_link"
- android:tint="@android:color/tab_indicator_text"
- android:visibility="gone" />
-
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <ImageView
- android:id="@+id/plus_button_view_post_detail"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentStart="true"
- android:layout_centerVertical="true"
- android:background="?actionBarItemBackground"
- android:clickable="true"
- android:focusable="true"
- android:padding="16dp"
- android:src="@drawable/ic_arrow_upward_black_24dp"
- android:tint="@android:color/tab_indicator_text" />
-
- <TextView
- android:id="@+id/score_text_view_view_post_detail"
- android:layout_width="64dp"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_toEndOf="@id/plus_button_view_post_detail"
- android:gravity="center" />
-
- <ImageView
- android:id="@+id/minus_button_view_post_detail"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_toEndOf="@id/score_text_view_view_post_detail"
- android:background="?actionBarItemBackground"
- android:clickable="true"
- android:focusable="true"
- android:padding="16dp"
- android:src="@drawable/ic_arrow_downward_black_24dp"
- android:tint="@android:color/tab_indicator_text" />
-
- <ImageView
- android:id="@+id/share_button_view_post_detail"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentEnd="true"
- android:layout_centerVertical="true"
- android:background="?actionBarItemBackground"
- android:clickable="true"
- android:focusable="true"
- android:padding="16dp"
- android:src="@drawable/ic_outline_share_24px"
- android:tint="@android:color/tab_indicator_text" />
-
- </RelativeLayout>
-
- </LinearLayout>
-
- </com.google.android.material.card.MaterialCardView>
-
- <com.lsjwzh.widget.materialloadingprogressbar.CircleProgressBar
- android:id="@+id/comment_progress_bar_view_post_detail"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="16dp"
- android:layout_marginBottom="16dp"
- app:mlpb_progress_stoke_width="3dp"
- app:mlpb_progress_color="@color/colorAccent"
- app:mlpb_background_color="@color/circularProgressBarBackground"
- android:layout_gravity="center_horizontal"/>
-
- <com.google.android.material.card.MaterialCardView
- android:id="@+id/comment_card_view_view_post_detail"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="16dp"
- android:visibility="gone">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingEnd="16dp"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:paddingStart="16dp"
- android:paddingTop="16dp"
- android:text="@string/comments"
- android:textColor="@color/primaryTextColor"
- android:textSize="18sp" />
-
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/recycler_view_view_post_detail"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
- </LinearLayout>
-
- </com.google.android.material.card.MaterialCardView>
-
- <LinearLayout
- android:id="@+id/no_comment_wrapper_linear_layout_view_post_detail"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="48dp"
- android:layout_marginBottom="48dp"
- android:orientation="vertical"
- android:visibility="gone">
-
- <ImageView
- android:id="@+id/no_comment_image_view_view_post_detail"
- android:layout_width="150dp"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal" />
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="16dp"
- android:layout_gravity="center_horizontal"
- android:text="@string/no_comments_yet"/>
-
- </LinearLayout>
-
- </LinearLayout>
-
- </androidx.core.widget.NestedScrollView>
+ app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/item_load_comments.xml b/app/src/main/res/layout/item_load_comments.xml
new file mode 100644
index 00000000..06bc8c38
--- /dev/null
+++ b/app/src/main/res/layout/item_load_comments.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <com.lsjwzh.widget.materialloadingprogressbar.CircleProgressBar
+ android:id="@+id/comment_progress_bar_view_post_detail"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:layout_marginBottom="16dp"
+ app:mlpb_progress_stoke_width="3dp"
+ app:mlpb_progress_color="@color/colorAccent"
+ app:mlpb_background_color="@color/circularProgressBarBackground"
+ android:layout_gravity="center_horizontal"/>
+
+</LinearLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/item_load_comments_failed_placeholder.xml b/app/src/main/res/layout/item_load_comments_failed_placeholder.xml
new file mode 100644
index 00000000..476d3d2d
--- /dev/null
+++ b/app/src/main/res/layout/item_load_comments_failed_placeholder.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:padding="36dp"
+ android:text="@string/post_load_comments_failed"
+ android:drawableTop="@drawable/load_post_error_indicator"/> \ No newline at end of file
diff --git a/app/src/main/res/layout/item_no_comment_placeholder.xml b/app/src/main/res/layout/item_no_comment_placeholder.xml
new file mode 100644
index 00000000..becf93d4
--- /dev/null
+++ b/app/src/main/res/layout/item_no_comment_placeholder.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/no_comments_yet"
+ android:gravity="center"
+ android:padding="36dp"
+ android:drawableTop="@drawable/no_comment_placeholder"/> \ No newline at end of file
diff --git a/app/src/main/res/layout/item_post_detail.xml b/app/src/main/res/layout/item_post_detail.xml
new file mode 100644
index 00000000..870d21ef
--- /dev/null
+++ b/app/src/main/res/layout/item_post_detail.xml
@@ -0,0 +1,252 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:id="@+id/relative_layout_item_post_detail"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <LinearLayout
+ android:id="@+id/subreddit_icon_name_linear_layout_item_post_detail"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:padding="16dp"
+ app:layout_constrainedWidth="true"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/post_time_text_view_item_post_detail"
+ app:layout_constraintTop_toTopOf="parent">
+
+ <CustomView.AspectRatioGifImageView
+ android:id="@+id/subreddit_icon_circle_image_view_item_post_detail"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_gravity="center"/>
+
+ <TextView
+ android:id="@+id/subreddit_text_view_item_post_detail"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:layout_gravity="center"
+ android:textColor="#E91E63" />
+
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/post_time_text_view_item_post_detail"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_marginEnd="16dp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toEndOf="@id/subreddit_icon_name_linear_layout_item_post_detail"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="parent"/>
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+ <TextView
+ android:id="@+id/title_text_view_item_post_detail"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp"
+ android:textColor="@color/primaryTextColor"
+ android:textSize="18sp" />
+
+ <ru.noties.markwon.view.MarkwonView
+ android:id="@+id/content_markdown_view_item_post_detail"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp"
+ android:layout_marginTop="16dp"
+ android:visibility="gone" />
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp"
+ android:paddingTop="16dp">
+
+ <com.google.android.material.chip.Chip
+ android:id="@+id/type_text_view_item_post_detail"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="16dp"
+ android:textColor="@android:color/white"
+ android:layout_centerVertical="true"
+ app:chipBackgroundColor="@color/backgroundColorPrimaryDark"/>
+
+ <ImageView
+ android:id="@+id/gilded_image_view_item_post_detail"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_toEndOf="@id/type_text_view_item_post_detail"
+ android:layout_centerVertical="true"
+ android:visibility="gone"/>
+
+ <TextView
+ android:id="@+id/gilded_number_text_view_item_post_detail"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="4dp"
+ android:layout_marginEnd="8dp"
+ android:layout_toEndOf="@id/gilded_image_view_item_post_detail"
+ android:layout_centerVertical="true"
+ android:visibility="gone"
+ android:textSize="20sp"
+ android:textColor="@color/gold"/>
+
+ <ImageView
+ android:id="@+id/crosspost_image_view_item_post_detail"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_marginStart="8dp"
+ android:layout_marginEnd="8dp"
+ android:layout_toEndOf="@id/gilded_number_text_view_item_post_detail"
+ android:layout_centerVertical="true"
+ android:src="@drawable/crosspost"
+ android:tint="@color/colorAccent"
+ android:visibility="gone"/>
+
+ <com.google.android.material.chip.Chip
+ android:id="@+id/nsfw_text_view_item_post_detail"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/nsfw"
+ android:layout_alignParentEnd="true"
+ android:layout_marginStart="8dp"
+ android:textColor="@android:color/white"
+ android:visibility="gone"
+ android:layout_centerVertical="true"
+ app:chipBackgroundColor="@color/colorAccent"/>
+
+ </RelativeLayout>
+
+ <TextView
+ android:id="@+id/link_text_view_item_post_detail"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp"
+ android:textSize="12sp"
+ android:visibility="gone"/>
+
+ <RelativeLayout
+ android:id="@+id/image_view_wrapper_item_post_detail"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:visibility="gone">
+
+ <com.santalu.aspectratioimageview.AspectRatioImageView
+ android:id="@+id/image_view_item_post_detail"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:adjustViewBounds="true"
+ android:scaleType="fitStart"/>
+
+ <RelativeLayout
+ android:id="@+id/load_wrapper_item_post_detail"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true">
+
+ <ProgressBar
+ android:id="@+id/progress_bar_item_post_detail"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true" />
+
+ <TextView
+ android:id="@+id/load_image_error_text_view_item_post_detail"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:drawableTop="@drawable/ic_error_outline_black_24dp"
+ android:layout_centerInParent="true"
+ android:gravity="center"
+ android:text="@string/tap_to_retry"
+ android:visibility="gone" />
+
+ </RelativeLayout>
+
+ </RelativeLayout>
+
+ <ImageView
+ android:id="@+id/image_view_no_preview_link_item_post_detail"
+ android:layout_width="match_parent"
+ android:layout_height="150dp"
+ android:layout_marginTop="16dp"
+ android:background="@color/grey"
+ android:scaleType="center"
+ android:src="@drawable/ic_link"
+ android:tint="@android:color/tab_indicator_text"
+ android:visibility="gone" />
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <ImageView
+ android:id="@+id/plus_button_item_post_detail"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentStart="true"
+ android:layout_centerVertical="true"
+ android:background="?actionBarItemBackground"
+ android:clickable="true"
+ android:focusable="true"
+ android:padding="16dp"
+ android:src="@drawable/ic_arrow_upward_black_24dp"
+ android:tint="@android:color/tab_indicator_text" />
+
+ <TextView
+ android:id="@+id/score_text_view_item_post_detail"
+ android:layout_width="64dp"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_toEndOf="@id/plus_button_item_post_detail"
+ android:gravity="center" />
+
+ <ImageView
+ android:id="@+id/minus_button_item_post_detail"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_toEndOf="@id/score_text_view_item_post_detail"
+ android:background="?actionBarItemBackground"
+ android:clickable="true"
+ android:focusable="true"
+ android:padding="16dp"
+ android:src="@drawable/ic_arrow_downward_black_24dp"
+ android:tint="@android:color/tab_indicator_text" />
+
+ <ImageView
+ android:id="@+id/share_button_item_post_detail"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentEnd="true"
+ android:layout_centerVertical="true"
+ android:background="?actionBarItemBackground"
+ android:clickable="true"
+ android:focusable="true"
+ android:padding="16dp"
+ android:src="@drawable/ic_outline_share_24px"
+ android:tint="@android:color/tab_indicator_text" />
+
+ </RelativeLayout>
+
+ </LinearLayout>
+
+</com.google.android.material.card.MaterialCardView> \ No newline at end of file