diff options
Diffstat (limited to 'app/src')
-rw-r--r-- | app/src/main/java/ml/docilealligator/infinityforreddit/CommentRecyclerViewAdapter.java | 644 | ||||
-rw-r--r-- | app/src/main/java/ml/docilealligator/infinityforreddit/FetchComment.java | 2 | ||||
-rw-r--r-- | app/src/main/java/ml/docilealligator/infinityforreddit/LoadSubredditIconAsyncTask.java | 4 | ||||
-rw-r--r-- | app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java | 2 | ||||
-rw-r--r-- | app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java | 499 | ||||
-rw-r--r-- | app/src/main/res/drawable/no_comment_placeholder.png (renamed from app/src/main/res/drawable/no_comment_indicator.png) | bin | 60561 -> 60561 bytes | |||
-rw-r--r-- | app/src/main/res/layout/activity_view_post_detail.xml | 335 | ||||
-rw-r--r-- | app/src/main/res/layout/item_load_comments.xml | 19 | ||||
-rw-r--r-- | app/src/main/res/layout/item_load_comments_failed_placeholder.xml | 8 | ||||
-rw-r--r-- | app/src/main/res/layout/item_no_comment_placeholder.xml | 8 | ||||
-rw-r--r-- | app/src/main/res/layout/item_post_detail.xml | 252 |
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 Binary files differindex 62a3668f..62a3668f 100644 --- a/app/src/main/res/drawable/no_comment_indicator.png +++ b/app/src/main/res/drawable/no_comment_placeholder.png 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 |