diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java index 48ae7d93..cd4e7fdb 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java @@ -70,6 +70,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele public static final String EXTRA_POST_ID = "EPI"; public static final String EXTRA_POST_LIST_POSITION = "EPLP"; public static final String EXTRA_SINGLE_COMMENT_ID = "ESCI"; + public static final String EXTRA_CONTEXT_NUMBER = "ECN"; public static final String EXTRA_MESSAGE_FULLNAME = "ENI"; public static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; public static final String EXTRA_POST_FRAGMENT_ID = "EPFI"; @@ -510,6 +511,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele bundle.putParcelable(ViewPostDetailFragment.EXTRA_POST_DATA, post); bundle.putInt(ViewPostDetailFragment.EXTRA_POST_LIST_POSITION, position); bundle.putString(ViewPostDetailFragment.EXTRA_SINGLE_COMMENT_ID, getIntent().getStringExtra(EXTRA_SINGLE_COMMENT_ID)); + bundle.putString(ViewPostDetailFragment.EXTRA_CONTEXT_NUMBER, getIntent().getStringExtra(EXTRA_CONTEXT_NUMBER)); bundle.putString(ViewPostDetailFragment.EXTRA_MESSAGE_FULLNAME, getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME)); } else { bundle.putParcelable(ViewPostDetailFragment.EXTRA_POST_DATA, posts.get(position)); @@ -523,6 +525,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele bundle.putInt(ViewPostDetailFragment.EXTRA_POST_LIST_POSITION, postListPosition); } bundle.putString(ViewPostDetailFragment.EXTRA_SINGLE_COMMENT_ID, getIntent().getStringExtra(EXTRA_SINGLE_COMMENT_ID)); + bundle.putString(ViewPostDetailFragment.EXTRA_CONTEXT_NUMBER, getIntent().getStringExtra(EXTRA_CONTEXT_NUMBER)); bundle.putString(ViewPostDetailFragment.EXTRA_MESSAGE_FULLNAME, getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME)); } fragment.setArguments(bundle); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentAndPostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentAndPostRecyclerViewAdapter.java index 802150fc..a3e8dbb4 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentAndPostRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentAndPostRecyclerViewAdapter.java @@ -637,7 +637,7 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter depthThreshold) { - ((CommentViewHolder) holder).saveButton.setVisibility(View.GONE); - ((CommentViewHolder) holder).replyButton.setVisibility(View.GONE); - } else { - ((CommentViewHolder) holder).saveButton.setVisibility(View.VISIBLE); - ((CommentViewHolder) holder).replyButton.setVisibility(View.VISIBLE); - } - - if (comment.hasReply()) { - if (comment.isExpanded()) { - ((CommentViewHolder) holder).expandButton.setImageResource(R.drawable.ic_expand_less_grey_24dp); - } else { - ((CommentViewHolder) holder).expandButton.setImageResource(R.drawable.ic_expand_more_grey_24dp); + Comment comment = getCurrentComment(position); + if (comment != null) { + if (mIsSingleCommentThreadMode && comment.getId().equals(mSingleCommentId)) { + ((CommentViewHolder) holder).itemView.setBackgroundColor(mSingleCommentThreadBackgroundColor); + } else if (comment.getAwards() != null && !comment.getAwards().equals("")) { + ((CommentViewHolder) holder).itemView.setBackgroundColor(mAwardedCommentBackgroundColor); } - ((CommentViewHolder) holder).expandButton.setVisibility(View.VISIBLE); - } - switch (comment.getVoteType()) { - case Comment.VOTE_TYPE_UPVOTE: + String authorPrefixed = "u/" + comment.getAuthor(); + ((CommentViewHolder) holder).authorTextView.setText(authorPrefixed); + + if (comment.getAuthorFlairHTML() != null && !comment.getAuthorFlairHTML().equals("")) { + ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.VISIBLE); + Utils.setHTMLWithImageToTextView(((CommentViewHolder) holder).authorFlairTextView, comment.getAuthorFlairHTML(), true); + } else if (comment.getAuthorFlair() != null && !comment.getAuthorFlair().equals("")) { + ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.VISIBLE); + ((CommentViewHolder) holder).authorFlairTextView.setText(comment.getAuthorFlair()); + } + + if (comment.isSubmitter()) { + ((CommentViewHolder) holder).authorTextView.setTextColor(mSubmitterColor); + Drawable submitterDrawable = Utils.getTintedDrawable(mActivity, R.drawable.ic_mic_14dp, mSubmitterColor); + ((CommentViewHolder) holder).authorTextView.setCompoundDrawablesWithIntrinsicBounds( + submitterDrawable, null, null, null); + } else if (comment.isModerator()) { + ((CommentViewHolder) holder).authorTextView.setTextColor(mModeratorColor); + Drawable moderatorDrawable = Utils.getTintedDrawable(mActivity, R.drawable.ic_verified_user_14dp, mModeratorColor); + ((CommentViewHolder) holder).authorTextView.setCompoundDrawablesWithIntrinsicBounds( + moderatorDrawable, null, null, null); + } else if (comment.getAuthor().equals(mAccountName)) { + ((CommentViewHolder) holder).authorTextView.setTextColor(mCurrentUserColor); + Drawable currentUserDrawable = Utils.getTintedDrawable(mActivity, R.drawable.ic_current_user_14dp, mCurrentUserColor); + ((CommentViewHolder) holder).authorTextView.setCompoundDrawablesWithIntrinsicBounds( + currentUserDrawable, null, null, null); + } + + if (mShowElapsedTime) { + ((CommentViewHolder) holder).commentTimeTextView.setText( + Utils.getElapsedTime(mActivity, comment.getCommentTimeMillis())); + } else { + ((CommentViewHolder) holder).commentTimeTextView.setText(Utils.getFormattedTime(mLocale, comment.getCommentTimeMillis(), mTimeFormatPattern)); + } + + if (mCommentToolbarHidden) { + ((CommentViewHolder) holder).bottomConstraintLayout.getLayoutParams().height = 0; + ((CommentViewHolder) holder).topScoreTextView.setVisibility(View.VISIBLE); + } else { + ((CommentViewHolder) holder).bottomConstraintLayout.getLayoutParams().height = LinearLayout.LayoutParams.WRAP_CONTENT; + ((CommentViewHolder) holder).topScoreTextView.setVisibility(View.GONE); + } + + if (comment.getAwards() != null && !comment.getAwards().equals("")) { + ((CommentViewHolder) holder).awardsTextView.setVisibility(View.VISIBLE); + Utils.setHTMLWithImageToTextView(((CommentViewHolder) holder).awardsTextView, comment.getAwards(), true); + } + + mCommentMarkwon.setMarkdown(((CommentViewHolder) holder).commentMarkdownView, comment.getCommentMarkdown()); + ((CommentViewHolder) holder).scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType())); + ((CommentViewHolder) holder).topScoreTextView.setText(mActivity.getString(R.string.top_score, + Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType()))); + + ((CommentViewHolder) holder).commentIndentationView.setLevelAndColors(comment.getDepth(), verticalBlockColors); + if (comment.getDepth() > depthThreshold) { + ((CommentViewHolder) holder).saveButton.setVisibility(View.GONE); + ((CommentViewHolder) holder).replyButton.setVisibility(View.GONE); + } else { + ((CommentViewHolder) holder).saveButton.setVisibility(View.VISIBLE); + ((CommentViewHolder) holder).replyButton.setVisibility(View.VISIBLE); + } + + if (comment.hasReply()) { + if (comment.isExpanded()) { + ((CommentViewHolder) holder).expandButton.setImageResource(R.drawable.ic_expand_less_grey_24dp); + } else { + ((CommentViewHolder) holder).expandButton.setImageResource(R.drawable.ic_expand_more_grey_24dp); + } + ((CommentViewHolder) holder).expandButton.setVisibility(View.VISIBLE); + } + + switch (comment.getVoteType()) { + case Comment.VOTE_TYPE_UPVOTE: + ((CommentViewHolder) holder).upvoteButton + .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor); + ((CommentViewHolder) holder).topScoreTextView.setTextColor(mUpvotedColor); + break; + case Comment.VOTE_TYPE_DOWNVOTE: + ((CommentViewHolder) holder).downvoteButton + .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor); + ((CommentViewHolder) holder).topScoreTextView.setTextColor(mDownvotedColor); + break; + } + + if (mPost.isArchived()) { + ((CommentViewHolder) holder).replyButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, + android.graphics.PorterDuff.Mode.SRC_IN); ((CommentViewHolder) holder).upvoteButton - .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor); - ((CommentViewHolder) holder).topScoreTextView.setTextColor(mUpvotedColor); - break; - case Comment.VOTE_TYPE_DOWNVOTE: + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, + android.graphics.PorterDuff.Mode.SRC_IN); ((CommentViewHolder) holder).downvoteButton - .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor); - ((CommentViewHolder) holder).topScoreTextView.setTextColor(mDownvotedColor); - break; - } + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, + android.graphics.PorterDuff.Mode.SRC_IN); + } - if (mPost.isArchived()) { - ((CommentViewHolder) holder).replyButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).upvoteButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).downvoteButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - android.graphics.PorterDuff.Mode.SRC_IN); - } + if (mPost.isLocked()) { + ((CommentViewHolder) holder).replyButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, + android.graphics.PorterDuff.Mode.SRC_IN); + } - if (mPost.isLocked()) { - ((CommentViewHolder) holder).replyButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - android.graphics.PorterDuff.Mode.SRC_IN); - } - - if (comment.isSaved()) { - ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - } else { - ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + if (comment.isSaved()) { + ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + } else { + ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + } } } else if (holder instanceof CommentFullyCollapsedViewHolder) { - Comment comment; - if (mIsSingleCommentThreadMode) { - comment = mVisibleComments.get(holder.getBindingAdapterPosition() - 2); - } else { - comment = mVisibleComments.get(holder.getBindingAdapterPosition() - 1); + Comment comment = getCurrentComment(position); + if (comment != null) { + String authorWithPrefix = "u/" + comment.getAuthor(); + ((CommentFullyCollapsedViewHolder) holder).usernameTextView.setText(authorWithPrefix); + if (mShowElapsedTime) { + ((CommentFullyCollapsedViewHolder) holder).commentTimeTextView.setText(Utils.getElapsedTime(mActivity, comment.getCommentTimeMillis())); + } else { + ((CommentFullyCollapsedViewHolder) holder).commentTimeTextView.setText(Utils.getFormattedTime(mLocale, comment.getCommentTimeMillis(), mTimeFormatPattern)); + } + ((CommentFullyCollapsedViewHolder) holder).scoreTextView.setText(mActivity.getString(R.string.top_score, + Utils.getNVotes(mShowAbsoluteNumberOfVotes, comment.getScore() + comment.getVoteType()))); + ((CommentFullyCollapsedViewHolder) holder).commentIndentationView.setLevelAndColors(comment.getDepth(), verticalBlockColors); } - - String authorWithPrefix = "u/" + comment.getAuthor(); - ((CommentFullyCollapsedViewHolder) holder).usernameTextView.setText(authorWithPrefix); - if (mShowElapsedTime) { - ((CommentFullyCollapsedViewHolder) holder).commentTimeTextView.setText(Utils.getElapsedTime(mActivity, comment.getCommentTimeMillis())); - } else { - ((CommentFullyCollapsedViewHolder) holder).commentTimeTextView.setText(Utils.getFormattedTime(mLocale, comment.getCommentTimeMillis(), mTimeFormatPattern)); - } - ((CommentFullyCollapsedViewHolder) holder).scoreTextView.setText(mActivity.getString(R.string.top_score, - Utils.getNVotes(mShowAbsoluteNumberOfVotes, comment.getScore() + comment.getVoteType()))); - ((CommentFullyCollapsedViewHolder) holder).commentIndentationView.setLevelAndColors(comment.getDepth(), verticalBlockColors); } else if (holder instanceof LoadMoreChildCommentsViewHolder) { Comment placeholder; placeholder = mIsSingleCommentThreadMode ? mVisibleComments.get(holder.getBindingAdapterPosition() - 2) @@ -1184,111 +1176,53 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter { - int commentPosition = mIsSingleCommentThreadMode ? holder.getBindingAdapterPosition() - 2 : holder.getBindingAdapterPosition() - 1; - int parentPosition = getParentPosition(commentPosition); - if (parentPosition >= 0) { - Comment parentComment = mVisibleComments.get(parentPosition); + if (placeholder.getPlaceholderType() == Comment.PLACEHOLDER_LOAD_MORE_COMMENTS) { + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setOnClickListener(view -> { + int commentPosition = mIsSingleCommentThreadMode ? holder.getBindingAdapterPosition() - 2 : holder.getBindingAdapterPosition() - 1; + int parentPosition = getParentPosition(commentPosition); + if (parentPosition >= 0) { + Comment parentComment = mVisibleComments.get(parentPosition); - mVisibleComments.get(commentPosition).setLoadingMoreChildren(true); - mVisibleComments.get(commentPosition).setLoadMoreChildrenFailed(false); - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.loading); + mVisibleComments.get(commentPosition).setLoadingMoreChildren(true); + mVisibleComments.get(commentPosition).setLoadMoreChildrenFailed(false); + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.loading); - Retrofit retrofit = mAccessToken == null ? mRetrofit : mOauthRetrofit; - FetchComment.fetchMoreComment(retrofit, mAccessToken, parentComment.getMoreChildrenFullnames(), - parentComment.getMoreChildrenStartingIndex(), parentComment.getDepth() + 1, - mExpandChildren, mLocale, - new FetchComment.FetchMoreCommentListener() { - @Override - public void onFetchMoreCommentSuccess(ArrayList expandedComments, - int childrenStartingIndex) { - if (mVisibleComments.size() > parentPosition - && parentComment.getFullName().equals(mVisibleComments.get(parentPosition).getFullName())) { - if (mVisibleComments.get(parentPosition).isExpanded()) { - if (mVisibleComments.get(parentPosition).getChildren().size() > childrenStartingIndex) { - mVisibleComments.get(parentPosition).setMoreChildrenStartingIndex(childrenStartingIndex); - mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) - .setLoadingMoreChildren(false); - mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) - .setLoadMoreChildrenFailed(false); + Retrofit retrofit = mAccessToken == null ? mRetrofit : mOauthRetrofit; + FetchComment.fetchMoreComment(retrofit, mAccessToken, parentComment.getMoreChildrenFullnames(), + parentComment.getMoreChildrenStartingIndex(), parentComment.getDepth() + 1, + mExpandChildren, mLocale, + new FetchComment.FetchMoreCommentListener() { + @Override + public void onFetchMoreCommentSuccess(ArrayList expandedComments, + int childrenStartingIndex) { + if (mVisibleComments.size() > parentPosition + && parentComment.getFullName().equals(mVisibleComments.get(parentPosition).getFullName())) { + if (mVisibleComments.get(parentPosition).isExpanded()) { + if (mVisibleComments.get(parentPosition).getChildren().size() > childrenStartingIndex) { + mVisibleComments.get(parentPosition).setMoreChildrenStartingIndex(childrenStartingIndex); + mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) + .setLoadingMoreChildren(false); + mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) + .setLoadMoreChildrenFailed(false); - int placeholderPosition = commentPosition; - if (mVisibleComments.get(commentPosition).getFullName().equals(parentComment.getFullName())) { - for (int i = parentPosition + 1; i < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { - placeholderPosition = i; - break; - } - } - } - - mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); - mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(false); - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments); - - mVisibleComments.addAll(placeholderPosition, expandedComments); - if (mIsSingleCommentThreadMode) { - notifyItemRangeInserted(placeholderPosition + 2, expandedComments.size()); - } else { - notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size()); - } - } else { - mVisibleComments.get(parentPosition).getChildren() - .remove(mVisibleComments.get(parentPosition).getChildren().size() - 1); - mVisibleComments.get(parentPosition).removeMoreChildrenFullnames(); - - int placeholderPosition = commentPosition; - if (mVisibleComments.get(commentPosition).getFullName().equals(parentComment.getFullName())) { - for (int i = parentPosition + 1; i < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { - placeholderPosition = i; - break; - } - } - } - - mVisibleComments.remove(placeholderPosition); - if (mIsSingleCommentThreadMode) { - notifyItemRemoved(placeholderPosition + 2); - } else { - notifyItemRemoved(placeholderPosition + 1); - } - - mVisibleComments.addAll(placeholderPosition, expandedComments); - if (mIsSingleCommentThreadMode) { - notifyItemRangeInserted(placeholderPosition + 2, expandedComments.size()); - } else { - notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size()); - } - } - } else { - if (mVisibleComments.get(parentPosition).hasReply() && mVisibleComments.get(parentPosition).getChildren().size() <= childrenStartingIndex) { - mVisibleComments.get(parentPosition).getChildren() - .remove(mVisibleComments.get(parentPosition).getChildren().size() - 1); - mVisibleComments.get(parentPosition).removeMoreChildrenFullnames(); - } - } - - mVisibleComments.get(parentPosition).addChildren(expandedComments); - } else { - for (int i = 0; i < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { - if (mVisibleComments.get(i).isExpanded()) { - int placeholderPosition = i + mVisibleComments.get(i).getChildren().size(); - - if (!mVisibleComments.get(i).getFullName() - .equals(mVisibleComments.get(placeholderPosition).getFullName())) { - for (int j = i + 1; j < mVisibleComments.size(); j++) { - if (mVisibleComments.get(j).getFullName().equals(mVisibleComments.get(i).getFullName())) { - placeholderPosition = j; + int placeholderPosition = commentPosition; + if (mVisibleComments.get(commentPosition).getFullName().equals(parentComment.getFullName())) { + for (int i = parentPosition + 1; i < mVisibleComments.size(); i++) { + if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { + placeholderPosition = i; + break; } } } @@ -1303,75 +1237,150 @@ public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter= mVisibleComments.size() || commentPosition < 0 || !mVisibleComments.get(commentPosition).getFullName().equals(parentComment.getFullName())) { - for (int i = parentPosition + 1; i < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { - placeholderPosition = i; - break; - } - } - } - - mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); - mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(true); - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments_failed); - } - - mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) - .setLoadingMoreChildren(false); - mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) - .setLoadMoreChildrenFailed(true); - } else { - for (int i = 0; i < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { - if (mVisibleComments.get(i).isExpanded()) { - int placeholderPosition = i + mVisibleComments.get(i).getChildren().size(); - if (!mVisibleComments.get(placeholderPosition).getFullName().equals(mVisibleComments.get(i).getFullName())) { - for (int j = i + 1; j < mVisibleComments.size(); j++) { - if (mVisibleComments.get(j).getFullName().equals(mVisibleComments.get(i).getFullName())) { - placeholderPosition = j; + int placeholderPosition = commentPosition; + if (mVisibleComments.get(commentPosition).getFullName().equals(parentComment.getFullName())) { + for (int i = parentPosition + 1; i < mVisibleComments.size(); i++) { + if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { + placeholderPosition = i; break; } } } - mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); - mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(true); - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments_failed); + mVisibleComments.remove(placeholderPosition); + if (mIsSingleCommentThreadMode) { + notifyItemRemoved(placeholderPosition + 2); + } else { + notifyItemRemoved(placeholderPosition + 1); + } + + mVisibleComments.addAll(placeholderPosition, expandedComments); + if (mIsSingleCommentThreadMode) { + notifyItemRangeInserted(placeholderPosition + 2, expandedComments.size()); + } else { + notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size()); + } } + } else { + if (mVisibleComments.get(parentPosition).hasReply() && mVisibleComments.get(parentPosition).getChildren().size() <= childrenStartingIndex) { + mVisibleComments.get(parentPosition).getChildren() + .remove(mVisibleComments.get(parentPosition).getChildren().size() - 1); + mVisibleComments.get(parentPosition).removeMoreChildrenFullnames(); + } + } - mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1).setLoadingMoreChildren(false); - mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1).setLoadMoreChildrenFailed(true); + mVisibleComments.get(parentPosition).addChildren(expandedComments); + } else { + for (int i = 0; i < mVisibleComments.size(); i++) { + if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { + if (mVisibleComments.get(i).isExpanded()) { + int placeholderPosition = i + mVisibleComments.get(i).getChildren().size(); - break; + if (!mVisibleComments.get(i).getFullName() + .equals(mVisibleComments.get(placeholderPosition).getFullName())) { + for (int j = i + 1; j < mVisibleComments.size(); j++) { + if (mVisibleComments.get(j).getFullName().equals(mVisibleComments.get(i).getFullName())) { + placeholderPosition = j; + } + } + } + + mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); + mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(false); + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments); + + mVisibleComments.addAll(placeholderPosition, expandedComments); + if (mIsSingleCommentThreadMode) { + notifyItemRangeInserted(placeholderPosition + 2, expandedComments.size()); + } else { + notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size()); + } + } + + mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1) + .setLoadingMoreChildren(false); + mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1) + .setLoadMoreChildrenFailed(false); + mVisibleComments.get(i).addChildren(expandedComments); + + break; + } } } } - } - }); - } - }); + + @Override + public void onFetchMoreCommentFailed() { + if (parentPosition < mVisibleComments.size() + && parentComment.getFullName().equals(mVisibleComments.get(parentPosition).getFullName())) { + if (mVisibleComments.get(parentPosition).isExpanded()) { + int commentPosition = mIsSingleCommentThreadMode ? holder.getBindingAdapterPosition() - 2 : holder.getBindingAdapterPosition() - 1; + int placeholderPosition = commentPosition; + if (commentPosition >= mVisibleComments.size() || commentPosition < 0 || !mVisibleComments.get(commentPosition).getFullName().equals(parentComment.getFullName())) { + for (int i = parentPosition + 1; i < mVisibleComments.size(); i++) { + if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { + placeholderPosition = i; + break; + } + } + } + + mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); + mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(true); + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments_failed); + } + + mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) + .setLoadingMoreChildren(false); + mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) + .setLoadMoreChildrenFailed(true); + } else { + for (int i = 0; i < mVisibleComments.size(); i++) { + if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { + if (mVisibleComments.get(i).isExpanded()) { + int placeholderPosition = i + mVisibleComments.get(i).getChildren().size(); + if (!mVisibleComments.get(placeholderPosition).getFullName().equals(mVisibleComments.get(i).getFullName())) { + for (int j = i + 1; j < mVisibleComments.size(); j++) { + if (mVisibleComments.get(j).getFullName().equals(mVisibleComments.get(i).getFullName())) { + placeholderPosition = j; + break; + } + } + } + + mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); + mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(true); + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments_failed); + } + + mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1).setLoadingMoreChildren(false); + mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1).setLoadMoreChildrenFailed(true); + + break; + } + } + } + } + }); + } + }); + } else { + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setOnClickListener(view -> { + Comment comment = getCurrentComment(position); + if (comment != null) { + Intent intent = new Intent(mActivity, ViewPostDetailActivity.class); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, mPost); + intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, comment.getParentId()); + intent.putExtra(ViewPostDetailActivity.EXTRA_CONTEXT_NUMBER, "0"); + mActivity.startActivity(intent); + } + }); + } } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java index b9220278..f3a9c582 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java @@ -243,7 +243,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter { - int position = getAdapterPosition(); + int position = getBindingAdapterPosition(); if (position < 0) { return; } - Comment comment = getItem(getAdapterPosition()); + Comment comment = getItem(getBindingAdapterPosition()); if (comment != null) { if (comment.getSubredditName().substring(2).equals(comment.getLinkAuthor())) { Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); @@ -496,11 +496,11 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter { - int position = getAdapterPosition(); + int position = getBindingAdapterPosition(); if (position < 0) { return; } - Comment comment = getItem(getAdapterPosition()); + Comment comment = getItem(getBindingAdapterPosition()); if (comment != null) { Bundle bundle = new Bundle(); if (comment.getAuthor().equals(mAccountName)) { @@ -508,7 +508,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter { - int position = getAdapterPosition(); + int position = getBindingAdapterPosition(); if (position < 0) { return; } - Comment comment = getItem(getAdapterPosition()); + Comment comment = getItem(getBindingAdapterPosition()); if (comment != null) { Intent intent = new Intent(mActivity, ViewPostDetailActivity.class); intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, comment.getLinkId()); @@ -542,11 +542,11 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter { - int position = getAdapterPosition(); + int position = getBindingAdapterPosition(); if (position < 0) { return; } @@ -682,7 +682,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter getRules(@Path("subredditName") String subredditName); - @GET("/comments/{id}/placeholder/{singleCommentId}.json?context=8&raw_json=1") + @GET("/comments/{id}/placeholder/{singleCommentId}.json?raw_json=1") Call getPostAndCommentsSingleThreadByIdOauth(@Path("id") String id, @Path("singleCommentId") String singleCommentId, - @Query("sort") String sortType, + @Query("sort") String sortType, @Query("context") String contextNumber, @HeaderMap Map headers); @GET("/comments/{id}.json?raw_json=1") Call getPostAndCommentsByIdOauth(@Path("id") String id, @Query("sort") String sortType, @HeaderMap Map headers); - @GET("/comments/{id}/placeholder/{singleCommentId}.json?context=8&raw_json=1") + @GET("/comments/{id}/placeholder/{singleCommentId}.json?raw_json=1") Call getPostAndCommentsSingleThreadById(@Path("id") String id, @Path("singleCommentId") String singleCommentId, - @Query("sort") String sortType); + @Query("sort") String sortType, @Query("context") String contextNumber); @GET("/comments/{id}.json?raw_json=1") Call getPostAndCommentsById(@Path("id") String id, @Query("sort") String sortType); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/Comment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/Comment.java index aa915171..fcbd58c1 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/Comment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/Comment.java @@ -11,6 +11,9 @@ public class Comment implements Parcelable { public static final int VOTE_TYPE_NO_VOTE = 0; public static final int VOTE_TYPE_UPVOTE = 1; public static final int VOTE_TYPE_DOWNVOTE = -1; + public static final int NOT_PLACEHOLDER = 0; + public static final int PLACEHOLDER_LOAD_MORE_COMMENTS = 1; + public static final int PLACEHOLDER_CONTINUE_THREAD = 2; public static final Creator CREATOR = new Creator() { @Override public Comment createFromParcel(Parcel in) { @@ -50,7 +53,7 @@ public class Comment implements Parcelable { private ArrayList children; private ArrayList moreChildrenFullnames; private int moreChildrenStartingIndex; - private boolean isPlaceHolder; + private int placeholderType; private boolean isLoadingMoreChildren; private boolean loadMoreChildrenFailed; @@ -87,17 +90,25 @@ public class Comment implements Parcelable { this.isExpanded = false; this.hasExpandedBefore = false; moreChildrenStartingIndex = 0; - isPlaceHolder = false; + placeholderType = NOT_PLACEHOLDER; } - public Comment(String parentFullName, int depth) { - this.fullName = parentFullName; + public Comment(String parentFullName, int depth, int placeholderType) { + if (placeholderType == PLACEHOLDER_LOAD_MORE_COMMENTS) { + this.fullName = parentFullName; + } else { + this.parentId = parentFullName.substring(3); + } this.depth = depth; - isPlaceHolder = true; + this.placeholderType = placeholderType; isLoadingMoreChildren = false; loadMoreChildrenFailed = false; } + public Comment(String parentFullName) { + + } + protected Comment(Parcel in) { id = in.readString(); fullName = in.readString(); @@ -126,7 +137,7 @@ public class Comment implements Parcelable { children = in.readArrayList(Comment.class.getClassLoader()); moreChildrenFullnames = in.readArrayList(Comment.class.getClassLoader()); moreChildrenStartingIndex = in.readInt(); - isPlaceHolder = in.readByte() != 0; + placeholderType = in.readInt(); isLoadingMoreChildren = in.readByte() != 0; loadMoreChildrenFailed = in.readByte() != 0; } @@ -286,7 +297,7 @@ public class Comment implements Parcelable { if (children == null || children.size() == 0) { setChildren(moreChildren); } else { - if (children.size() > 1 && children.get(children.size() - 1).isPlaceHolder) { + if (children.size() > 1 && children.get(children.size() - 1).placeholderType == PLACEHOLDER_LOAD_MORE_COMMENTS) { children.addAll(children.size() - 2, moreChildren); } else { children.addAll(moreChildren); @@ -329,8 +340,8 @@ public class Comment implements Parcelable { this.moreChildrenStartingIndex = moreChildrenStartingIndex; } - public boolean isPlaceHolder() { - return isPlaceHolder; + public int getPlaceholderType() { + return placeholderType; } public boolean isLoadingMoreChildren() { @@ -383,7 +394,7 @@ public class Comment implements Parcelable { parcel.writeList(children); parcel.writeList(moreChildrenFullnames); parcel.writeInt(moreChildrenStartingIndex); - parcel.writeByte((byte) (isPlaceHolder ? 1 : 0)); + parcel.writeInt(placeholderType); parcel.writeByte((byte) (isLoadingMoreChildren ? 1 : 0)); parcel.writeByte((byte) (loadMoreChildrenFailed ? 1 : 0)); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/CommentDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/CommentDataSource.java index 42aeaf9e..3ea679f2 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/CommentDataSource.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/CommentDataSource.java @@ -245,7 +245,7 @@ public class CommentDataSource extends PageKeyedDataSource { for (int i = 0; i < commentsJSONArray.length(); i++) { try { JSONObject commentJSON = commentsJSONArray.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); - comments.add(ParseComment.parseSingleComment(commentJSON, 0, locale)); + comments.add(ParseComment.parseSingleComment(commentJSON, 0)); } catch (JSONException ignored) { } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/FetchComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/FetchComment.java index a21335f4..14849870 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/FetchComment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/FetchComment.java @@ -15,7 +15,7 @@ import retrofit2.Retrofit; public class FetchComment { public static void fetchComments(Retrofit retrofit, @Nullable String accessToken, String article, - String commentId, String sortType, boolean expandChildren, + String commentId, String sortType, String contextNumber, boolean expandChildren, Locale locale, FetchCommentListener fetchCommentListener) { RedditAPI api = retrofit.create(RedditAPI.class); Call comments; @@ -23,13 +23,13 @@ public class FetchComment { if (commentId == null) { comments = api.getPostAndCommentsById(article, sortType); } else { - comments = api.getPostAndCommentsSingleThreadById(article, commentId, sortType); + comments = api.getPostAndCommentsSingleThreadById(article, commentId, sortType, contextNumber); } } else { if (commentId == null) { comments = api.getPostAndCommentsByIdOauth(article, sortType, APIUtils.getOAuthHeader(accessToken)); } else { - comments = api.getPostAndCommentsSingleThreadByIdOauth(article, commentId, sortType, + comments = api.getPostAndCommentsSingleThreadByIdOauth(article, commentId, sortType, contextNumber, APIUtils.getOAuthHeader(accessToken)); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/ParseComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/ParseComment.java index d5a41dd1..ace36940 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/ParseComment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/ParseComment.java @@ -70,13 +70,18 @@ public class ParseComment { } actualCommentLength = comments.length() - 1; + + if (moreChildrenFullnames.isEmpty() && comments.getJSONObject(comments.length() - 1).getString(JSONUtils.KIND_KEY).equals(JSONUtils.KIND_VALUE_MORE)) { + newCommentData.add(new Comment(more.getString(JSONUtils.PARENT_ID_KEY), more.getInt(JSONUtils.DEPTH_KEY), Comment.PLACEHOLDER_CONTINUE_THREAD)); + return; + } } else { actualCommentLength = comments.length(); } for (int i = 0; i < actualCommentLength; i++) { JSONObject data = comments.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); - Comment singleComment = parseSingleComment(data, depth, locale); + Comment singleComment = parseSingleComment(data, depth); if (data.get(JSONUtils.REPLIES_KEY) instanceof JSONObject) { JSONArray childrenArray = data.getJSONObject(JSONUtils.REPLIES_KEY) @@ -107,14 +112,14 @@ public class ParseComment { } if (c.hasMoreChildrenFullnames() && c.getMoreChildrenFullnames().size() > c.getMoreChildrenStartingIndex()) { //Add a load more placeholder - Comment placeholder = new Comment(c.getFullName(), c.getDepth() + 1); + Comment placeholder = new Comment(c.getFullName(), c.getDepth() + 1, Comment.PLACEHOLDER_LOAD_MORE_COMMENTS); visibleComments.add(placeholder); c.addChild(placeholder, c.getChildren().size()); } } } - static Comment parseSingleComment(JSONObject singleCommentData, int depth, Locale locale) throws JSONException { + static Comment parseSingleComment(JSONObject singleCommentData, int depth) throws JSONException { String id = singleCommentData.getString(JSONUtils.ID_KEY); String fullName = singleCommentData.getString(JSONUtils.NAME_KEY); String author = singleCommentData.getString(JSONUtils.AUTHOR_KEY); @@ -262,6 +267,7 @@ public class ParseComment { expandChildren(newComments, expandedNewComments, expandChildren); } catch (JSONException e) { parseFailed = true; + e.printStackTrace(); } return null; } @@ -302,7 +308,7 @@ public class ParseComment { protected Void doInBackground(Void... voids) { try { JSONObject sentCommentData = new JSONObject(response); - comment = parseSingleComment(sentCommentData, depth, locale); + comment = parseSingleComment(sentCommentData, depth); } catch (JSONException e) { e.printStackTrace(); errorMessage = parseSentCommentErrorMessage(response); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewPostDetailFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewPostDetailFragment.java index 6c960a2d..c8400b31 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewPostDetailFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewPostDetailFragment.java @@ -117,6 +117,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic public static final String EXTRA_POST_DATA = "EPD"; public static final String EXTRA_POST_ID = "EPI"; public static final String EXTRA_SINGLE_COMMENT_ID = "ESCI"; + public static final String EXTRA_CONTEXT_NUMBER = "ECN"; public static final String EXTRA_MESSAGE_FULLNAME = "EMF"; public static final String EXTRA_POST_LIST_POSITION = "EPLP"; private static final int EDIT_POST_REQUEST_CODE = 2; @@ -202,6 +203,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic private String mAccountName; private int postListPosition = -1; private String mSingleCommentId; + private String mContextNumber; private boolean showToast = false; private boolean isSortingComments = false; private boolean mIsSmoothScrolling = false; @@ -461,6 +463,8 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic }; mSingleCommentId = getArguments().getString(EXTRA_SINGLE_COMMENT_ID); + mContextNumber = getArguments().getString(EXTRA_CONTEXT_NUMBER, "8"); + if (savedInstanceState == null) { if (mSingleCommentId != null) { isSingleCommentThreadMode = true; @@ -1055,7 +1059,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic if (mAccessToken == null) { if (isSingleCommentThreadMode && mSingleCommentId != null) { postAndComments = mRetrofit.create(RedditAPI.class).getPostAndCommentsSingleThreadById( - subredditId, mSingleCommentId, sortType); + subredditId, mSingleCommentId, sortType, mContextNumber); } else { postAndComments = mRetrofit.create(RedditAPI.class).getPostAndCommentsById(subredditId, sortType); @@ -1063,7 +1067,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic } else { if (isSingleCommentThreadMode && mSingleCommentId != null) { postAndComments = mOauthRetrofit.create(RedditAPI.class).getPostAndCommentsSingleThreadByIdOauth(subredditId, - mSingleCommentId, sortType, APIUtils.getOAuthHeader(mAccessToken)); + mSingleCommentId, sortType, mContextNumber, APIUtils.getOAuthHeader(mAccessToken)); } else { postAndComments = mOauthRetrofit.create(RedditAPI.class).getPostAndCommentsByIdOauth(subredditId, sortType, APIUtils.getOAuthHeader(mAccessToken)); @@ -1240,8 +1244,8 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic } Retrofit retrofit = mAccessToken == null ? mRetrofit : mOauthRetrofit; - FetchComment.fetchComments(retrofit, mAccessToken, mPost.getId(), commentId, sortType, mExpandChildren, - mLocale, new FetchComment.FetchCommentListener() { + FetchComment.fetchComments(retrofit, mAccessToken, mPost.getId(), commentId, sortType, + mContextNumber, mExpandChildren, mLocale, new FetchComment.FetchCommentListener() { @Override public void onFetchCommentSuccess(ArrayList expandedComments, String parentId, ArrayList children) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/JSONUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/JSONUtils.java index 48bf1e4c..8ba23bf4 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/JSONUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/JSONUtils.java @@ -6,6 +6,7 @@ package ml.docilealligator.infinityforreddit.utils; public class JSONUtils { public static final String KIND_KEY = "kind"; + public static final String KIND_VALUE_MORE = "more"; public static final String DATA_KEY = "data"; public static final String AFTER_KEY = "after"; public static final String CHILDREN_KEY = "children"; diff --git a/app/src/main/res/layout/item_load_more_comments_placeholder.xml b/app/src/main/res/layout/item_load_more_comments_placeholder.xml index db050cfb..48dd15e3 100644 --- a/app/src/main/res/layout/item_load_more_comments_placeholder.xml +++ b/app/src/main/res/layout/item_load_more_comments_placeholder.xml @@ -20,7 +20,6 @@ android:layout_height="wrap_content" android:gravity="center" android:padding="8dp" - android:text="@string/comment_load_more_comments" android:textColor="?attr/primaryTextColor" android:textSize="?attr/font_default" android:fontFamily="?attr/font_family" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f671784b..492d8376 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -193,6 +193,7 @@ Load more comments Load failed. Tap to retry. + Continue thread Loading