diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentData.java index ac4b5823..7812a6c8 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentData.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentData.java @@ -22,7 +22,12 @@ class CommentData implements Parcelable { private boolean scoreHidden; private boolean isExpanded; private ArrayList children; - private ArrayList moreChildrenIds; + private ArrayList moreChildrenFullnames; + private int moreChildrenStartingIndex; + + private boolean isPlaceHolder; + private boolean isLoadingMoreChildren; + private boolean loadMoreChildrenFailed; CommentData(String id, String fullName, String author, String commentTime, String commentContent, String parentId, int score, boolean isSubmitter, String permalink, int depth, @@ -41,6 +46,15 @@ class CommentData implements Parcelable { this.hasReply = hasReply; this.scoreHidden = scoreHidden; this.isExpanded = false; + moreChildrenStartingIndex = 0; + isPlaceHolder = false; + } + + CommentData(int depth) { + this.depth = depth; + isPlaceHolder = true; + isLoadingMoreChildren = false; + loadMoreChildrenFailed = false; } protected CommentData(Parcel in) { @@ -60,7 +74,11 @@ class CommentData implements Parcelable { scoreHidden = in.readByte() != 0; isExpanded = in.readByte() != 0; children = in.readArrayList(null); - moreChildrenIds = in.readArrayList(null); + moreChildrenFullnames = in.readArrayList(null); + moreChildrenStartingIndex = in.readInt(); + isPlaceHolder = in.readByte() != 0; + isLoadingMoreChildren = in.readByte() != 0; + loadMoreChildrenFailed = in.readByte() != 0; } public static final Creator CREATOR = new Creator() { @@ -164,26 +182,70 @@ class CommentData implements Parcelable { } public void addChildren(ArrayList moreChildren) { - if(children == null) { + if(children == null || children.size() == 0) { setChildren(moreChildren); } else { - children.addAll(moreChildren); + if(children.get(children.size() - 1).isPlaceHolder) { + children.addAll(children.size() - 2, moreChildren); + } else { + children.addAll(moreChildren); + } } } public void addChild(CommentData comment) { + addChild(comment, 0); + } + + public void addChild(CommentData comment, int position) { if(children == null) { children = new ArrayList<>(); } - children.add(0, comment); + children.add(position, comment); } - public ArrayList getMoreChildrenIds() { - return moreChildrenIds; + public ArrayList getMoreChildrenFullnames() { + return moreChildrenFullnames; } - public void setMoreChildrenIds(ArrayList moreChildrenIds) { - this.moreChildrenIds = moreChildrenIds; + public void setMoreChildrenFullnames(ArrayList moreChildrenFullnames) { + this.moreChildrenFullnames = moreChildrenFullnames; + } + + public boolean hasMoreChildrenFullnames() { + return moreChildrenFullnames != null; + } + + public void removeMoreChildrenFullnames() { + moreChildrenFullnames.clear(); + } + + public int getMoreChildrenStartingIndex() { + return moreChildrenStartingIndex; + } + + public void setMoreChildrenStartingIndex(int moreChildrenStartingIndex) { + this.moreChildrenStartingIndex = moreChildrenStartingIndex; + } + + public boolean isPlaceHolder() { + return isPlaceHolder; + } + + public boolean isLoadingMoreChildren() { + return isLoadingMoreChildren; + } + + public void setLoadingMoreChildren(boolean isLoadingMoreChildren) { + this.isLoadingMoreChildren = isLoadingMoreChildren; + } + + public boolean isLoadMoreChildrenFailed() { + return loadMoreChildrenFailed; + } + + public void setLoadMoreChildrenFailed(boolean loadMoreChildrenFailed) { + this.loadMoreChildrenFailed = loadMoreChildrenFailed; } @Override @@ -209,6 +271,10 @@ class CommentData implements Parcelable { parcel.writeByte((byte) (scoreHidden ? 1 : 0)); parcel.writeByte((byte) (isExpanded ? 1 : 0)); parcel.writeList(children); - parcel.writeList(moreChildrenIds); + parcel.writeList(moreChildrenFullnames); + parcel.writeInt(moreChildrenStartingIndex); + parcel.writeByte((byte) (isPlaceHolder ? 1 : 0)); + parcel.writeByte((byte) (isLoadingMoreChildren ? 1 : 0)); + parcel.writeByte((byte) (loadMoreChildrenFailed ? 1 : 0)); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentDataSource.java index a7fd32cd..0e664ea2 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentDataSource.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentDataSource.java @@ -1,11 +1,11 @@ package ml.docilealligator.infinityforreddit; -import java.util.Locale; - import androidx.annotation.NonNull; import androidx.lifecycle.MutableLiveData; import androidx.paging.PageKeyedDataSource; -import retrofit2.Call; + +import java.util.Locale; + import retrofit2.Retrofit; public class CommentDataSource extends PageKeyedDataSource { @@ -62,7 +62,7 @@ public class CommentDataSource extends PageKeyedDataSource { RedditAPI api = retrofit.create(RedditAPI.class); - Call comments = api.getComments(subredditNamePrefixed, article, comment); + //Call comments = api.getComments(subredditNamePrefixed, article, comment); /*comments.enqueue(new Callback() { @Override public void onResponse(@NonNull Call call, @NonNull Response response) { @@ -119,7 +119,7 @@ public class CommentDataSource extends PageKeyedDataSource { RedditAPI api = retrofit.create(RedditAPI.class); - Call moreChildrenBasicInfo = api.getMoreChildren(mParentId, params.key); + //Call moreChildrenBasicInfo = api.getMoreChildren(mParentId, params.key); /*moreChildrenBasicInfo.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentRecyclerViewAdapter.java index dc2e49f0..f845bec0 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentRecyclerViewAdapter.java @@ -29,6 +29,11 @@ import ru.noties.markwon.SpannableConfiguration; import ru.noties.markwon.view.MarkwonView; class CommentRecyclerViewAdapter extends RecyclerView.Adapter { + private static final int VIEW_TYPE_COMMENT = 0; + private static final int VIEW_TYPE_LOAD_MORE_COMMENT = 1; + private static final int VIEW_TYPE_IS_LOADING_MORE_COMMENT = 2; + private static final int VIEW_TYPE_LOAD_MORE_COMMENT_FAILED = 3; + private Activity mActivity; private Retrofit mRetrofit; private Retrofit mOauthRetrofit; @@ -56,7 +61,6 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter(); - new Handler().post(() -> { makeChildrenVisible(commentData, mVisibleComments); notifyDataSetChanged(); @@ -70,239 +74,387 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter c.getMoreChildrenStartingIndex()) { + //Add a load more placeholder + visibleComments.add(new CommentData(c.getDepth() + 1)); + c.addChild(new CommentData(c.getDepth() + 1), c.getChildren().size()); + } + } + } + + @Override + public int getItemViewType(int position) { + CommentData comment = mVisibleComments.get(position); + if(!comment.isPlaceHolder()) { + return VIEW_TYPE_COMMENT; + } else { + if(comment.isLoadMoreChildrenFailed()) { + return VIEW_TYPE_LOAD_MORE_COMMENT_FAILED; + } else if(comment.isLoadingMoreChildren()) { + return VIEW_TYPE_IS_LOADING_MORE_COMMENT; + } else { + return VIEW_TYPE_LOAD_MORE_COMMENT; + } } } @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new CommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment, parent, false)); + switch (viewType) { + case VIEW_TYPE_COMMENT: + return new CommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment, parent, false)); + case VIEW_TYPE_LOAD_MORE_COMMENT: + return new LoadMoreCommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_load_more_comments, parent, false)); + case VIEW_TYPE_IS_LOADING_MORE_COMMENT: + return new IsLoadingMoreCommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_is_loading_more_comments, parent, false)); + default: + return new LoadMoreCommentFailedViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_load_more_comments_failed, parent, false)); + } } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - CommentData commentItem = mVisibleComments.get(holder.getAdapterPosition()); + if(holder.getItemViewType() == VIEW_TYPE_COMMENT) { + CommentData commentItem = mVisibleComments.get(holder.getAdapterPosition()); - String authorPrefixed = "u/" + commentItem.getAuthor(); - ((CommentViewHolder) holder).authorTextView.setText(authorPrefixed); - ((CommentViewHolder) holder).authorTextView.setOnClickListener(view -> { - Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, commentItem.getAuthor()); - mActivity.startActivity(intent); - }); - - ((CommentViewHolder) holder).commentTimeTextView.setText(commentItem.getCommentTime()); - - SpannableConfiguration spannableConfiguration = SpannableConfiguration.builder(mActivity).linkResolver((view, link) -> { - if (link.startsWith("/u/") || link.startsWith("u/")) { + String authorPrefixed = "u/" + commentItem.getAuthor(); + ((CommentViewHolder) holder).authorTextView.setText(authorPrefixed); + ((CommentViewHolder) holder).authorTextView.setOnClickListener(view -> { Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, link.substring(3)); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, commentItem.getAuthor()); 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(); + }); - ((CommentViewHolder) holder).commentMarkdownView.setMarkdown(spannableConfiguration, commentItem.getCommentContent()); - ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore())); + ((CommentViewHolder) holder).commentTimeTextView.setText(commentItem.getCommentTime()); - ((CommentViewHolder) holder).verticalBlock.getLayoutParams().width = commentItem.getDepth() * 16; - - ((CommentViewHolder) holder).shareButton.setOnClickListener(view -> { - Intent intent = new Intent(Intent.ACTION_SEND); - intent.setType("text/plain"); - String extraText = commentItem.getPermalink(); - intent.putExtra(Intent.EXTRA_TEXT, extraText); - mActivity.startActivity(Intent.createChooser(intent, "Share")); - }); - - if (commentItem.hasReply()) { - if(commentItem.isExpanded()) { - ((CommentViewHolder) holder).expandButton.setImageResource(R.drawable.ic_expand_less_black_20dp); - } else { - ((CommentViewHolder) holder).expandButton.setImageResource(R.drawable.ic_expand_more_black_20dp); - } - ((CommentViewHolder) holder).expandButton.setVisibility(View.VISIBLE); - } - - ((CommentViewHolder) holder).expandButton.setOnClickListener(view -> { - if(commentItem.isExpanded()) { - collapseChildren(holder.getAdapterPosition()); - ((CommentViewHolder) holder).expandButton - .setImageResource(R.drawable.ic_expand_more_black_20dp); - } else { - expandChildren(holder.getAdapterPosition()); - commentItem.setExpanded(true); - ((CommentViewHolder) holder).expandButton - .setImageResource(R.drawable.ic_expand_less_black_20dp); - } - /*if (commentItem.hasReply() && commentItem.getChildren().size() > 0) { - collapseChildren(holder.getAdapterPosition()); - ((CommentViewHolder) holder).expandButton - .setImageResource(R.drawable.ic_expand_more_black_20dp); - } else { - ((CommentViewHolder) holder).loadMoreCommentsProgressBar.setVisibility(View.VISIBLE); - FetchComment.fetchAllComment(mRetrofit, mSubredditNamePrefixed, article, commentItem.getId(), - locale, false, commentItem.getDepth(), new FetchComment.FetchAllCommentListener() { - @Override - public void onFetchAllCommentSuccess(List commentData) { - commentItem.addChildren((ArrayList) commentData); - ((CommentViewHolder) holder).loadMoreCommentsProgressBar - .setVisibility(View.GONE); - expandChildren(holder.getAdapterPosition()); - ((CommentViewHolder) holder).expandButton - .setImageResource(R.drawable.ic_expand_less_black_20dp); - } - - @Override - public void onFetchAllCommentFailed() { - ((CommentViewHolder) holder).loadMoreCommentsProgressBar - .setVisibility(View.GONE); - } - }); - }*/ - }); - - ((CommentViewHolder) holder).replyButton.setOnClickListener(view -> { - Intent intent = new Intent(mActivity, CommentActivity.class); - intent.putExtra(CommentActivity.EXTRA_PARENT_DEPTH_KEY, commentItem.getDepth() + 1); - intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_KEY, commentItem.getCommentContent()); - intent.putExtra(CommentActivity.EXTRA_PARENT_FULLNAME_KEY, commentItem.getFullName()); - intent.putExtra(CommentActivity.EXTRA_IS_REPLYING_KEY, true); - intent.putExtra(CommentActivity.EXTRA_PARENT_POSITION_KEY, holder.getAdapterPosition()); - mActivity.startActivityForResult(intent, CommentActivity.WRITE_COMMENT_REQUEST_CODE); - }); - - switch (commentItem.getVoteType()) { - case 1: - ((CommentViewHolder) holder).upvoteButton - .setColorFilter(ContextCompat.getColor(mActivity, R.color.colorPrimary), android.graphics.PorterDuff.Mode.SRC_IN); - break; - case 2: - ((CommentViewHolder) holder).downvoteButton - .setColorFilter(ContextCompat.getColor(mActivity, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN); - break; - } - - ((CommentViewHolder) holder).upvoteButton.setOnClickListener(view -> { - ColorFilter previousUpvoteButtonColorFilter = ((CommentViewHolder) holder).upvoteButton.getColorFilter(); - ColorFilter previousDownvoteButtonColorFilter = ((CommentViewHolder) holder).downvoteButton.getColorFilter(); - int previousVoteType = commentItem.getVoteType(); - String newVoteType; - - ((CommentViewHolder) holder).downvoteButton.clearColorFilter(); - - if(previousUpvoteButtonColorFilter == null) { - //Not upvoted before - commentItem.setVoteType(1); - newVoteType = RedditUtils.DIR_UPVOTE; - ((CommentViewHolder) holder).upvoteButton - .setColorFilter(ContextCompat.getColor(mActivity, R.color.backgroundColorPrimaryDark), android.graphics.PorterDuff.Mode.SRC_IN); - } else { - //Upvoted before - commentItem.setVoteType(0); - newVoteType = RedditUtils.DIR_UNVOTE; - ((CommentViewHolder) holder).upvoteButton.clearColorFilter(); - } - - ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType())); - - VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position1) { - if(newVoteType.equals(RedditUtils.DIR_UPVOTE)) { - commentItem.setVoteType(1); - ((CommentViewHolder) holder).upvoteButton - .setColorFilter(ContextCompat.getColor(mActivity, R.color.backgroundColorPrimaryDark), android.graphics.PorterDuff.Mode.SRC_IN); - } else { - commentItem.setVoteType(0); - ((CommentViewHolder) holder).upvoteButton.clearColorFilter(); - } - - ((CommentViewHolder) holder).downvoteButton.clearColorFilter(); - ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType())); + SpannableConfiguration spannableConfiguration = 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(); - @Override - public void onVoteThingFail(int position1) { - Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); - commentItem.setVoteType(previousVoteType); - ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + previousVoteType)); - ((CommentViewHolder) holder).upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); - ((CommentViewHolder) holder).downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); + ((CommentViewHolder) holder).commentMarkdownView.setMarkdown(spannableConfiguration, commentItem.getCommentContent()); + ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore())); + + ((CommentViewHolder) holder).verticalBlock.getLayoutParams().width = commentItem.getDepth() * 16; + + ((CommentViewHolder) holder).shareButton.setOnClickListener(view -> { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + String extraText = commentItem.getPermalink(); + intent.putExtra(Intent.EXTRA_TEXT, extraText); + mActivity.startActivity(Intent.createChooser(intent, "Share")); + }); + + if (commentItem.hasReply()) { + if(commentItem.isExpanded()) { + ((CommentViewHolder) holder).expandButton.setImageResource(R.drawable.ic_expand_less_black_20dp); + } else { + ((CommentViewHolder) holder).expandButton.setImageResource(R.drawable.ic_expand_more_black_20dp); } - }, commentItem.getFullName(), newVoteType, holder.getAdapterPosition()); - }); + ((CommentViewHolder) holder).expandButton.setVisibility(View.VISIBLE); + } - ((CommentViewHolder) holder).downvoteButton.setOnClickListener(view -> { - ColorFilter previousUpvoteButtonColorFilter = ((CommentViewHolder) holder).upvoteButton.getColorFilter(); - ColorFilter previousDownvoteButtonColorFilter = ((CommentViewHolder) holder).downvoteButton.getColorFilter(); - int previousVoteType = commentItem.getVoteType(); - String newVoteType; + ((CommentViewHolder) holder).expandButton.setOnClickListener(view -> { + if(commentItem.isExpanded()) { + collapseChildren(holder.getAdapterPosition()); + ((CommentViewHolder) holder).expandButton + .setImageResource(R.drawable.ic_expand_more_black_20dp); + } else { + expandChildren(holder.getAdapterPosition()); + commentItem.setExpanded(true); + ((CommentViewHolder) holder).expandButton + .setImageResource(R.drawable.ic_expand_less_black_20dp); + } + }); - ((CommentViewHolder) holder).upvoteButton.clearColorFilter(); + ((CommentViewHolder) holder).replyButton.setOnClickListener(view -> { + Intent intent = new Intent(mActivity, CommentActivity.class); + intent.putExtra(CommentActivity.EXTRA_PARENT_DEPTH_KEY, commentItem.getDepth() + 1); + intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_KEY, commentItem.getCommentContent()); + intent.putExtra(CommentActivity.EXTRA_PARENT_FULLNAME_KEY, commentItem.getFullName()); + intent.putExtra(CommentActivity.EXTRA_IS_REPLYING_KEY, true); + intent.putExtra(CommentActivity.EXTRA_PARENT_POSITION_KEY, holder.getAdapterPosition()); + mActivity.startActivityForResult(intent, CommentActivity.WRITE_COMMENT_REQUEST_CODE); + }); + + switch (commentItem.getVoteType()) { + case 1: + ((CommentViewHolder) holder).upvoteButton + .setColorFilter(ContextCompat.getColor(mActivity, R.color.colorPrimary), android.graphics.PorterDuff.Mode.SRC_IN); + break; + case 2: + ((CommentViewHolder) holder).downvoteButton + .setColorFilter(ContextCompat.getColor(mActivity, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN); + break; + } + + ((CommentViewHolder) holder).upvoteButton.setOnClickListener(view -> { + ColorFilter previousUpvoteButtonColorFilter = ((CommentViewHolder) holder).upvoteButton.getColorFilter(); + ColorFilter previousDownvoteButtonColorFilter = ((CommentViewHolder) holder).downvoteButton.getColorFilter(); + int previousVoteType = commentItem.getVoteType(); + String newVoteType; - if(previousDownvoteButtonColorFilter == null) { - //Not downvoted before - commentItem.setVoteType(-1); - newVoteType = RedditUtils.DIR_DOWNVOTE; - ((CommentViewHolder) holder).downvoteButton - .setColorFilter(ContextCompat.getColor(mActivity, R.color.colorAccent), android.graphics.PorterDuff.Mode.SRC_IN); - } else { - //Downvoted before - commentItem.setVoteType(0); - newVoteType = RedditUtils.DIR_UNVOTE; ((CommentViewHolder) holder).downvoteButton.clearColorFilter(); - } - ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType())); + if(previousUpvoteButtonColorFilter == null) { + //Not upvoted before + commentItem.setVoteType(1); + newVoteType = RedditUtils.DIR_UPVOTE; + ((CommentViewHolder) holder).upvoteButton + .setColorFilter(ContextCompat.getColor(mActivity, R.color.backgroundColorPrimaryDark), android.graphics.PorterDuff.Mode.SRC_IN); + } else { + //Upvoted before + commentItem.setVoteType(0); + newVoteType = RedditUtils.DIR_UNVOTE; + ((CommentViewHolder) holder).upvoteButton.clearColorFilter(); + } + + ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType())); + + VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position1) { + if(newVoteType.equals(RedditUtils.DIR_UPVOTE)) { + commentItem.setVoteType(1); + ((CommentViewHolder) holder).upvoteButton + .setColorFilter(ContextCompat.getColor(mActivity, R.color.backgroundColorPrimaryDark), android.graphics.PorterDuff.Mode.SRC_IN); + } else { + commentItem.setVoteType(0); + ((CommentViewHolder) holder).upvoteButton.clearColorFilter(); + } - VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position1) { - if(newVoteType.equals(RedditUtils.DIR_DOWNVOTE)) { - commentItem.setVoteType(-1); - ((CommentViewHolder) holder).downvoteButton - .setColorFilter(ContextCompat.getColor(mActivity, R.color.colorAccent), android.graphics.PorterDuff.Mode.SRC_IN); - } else { - commentItem.setVoteType(0); ((CommentViewHolder) holder).downvoteButton.clearColorFilter(); + ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType())); } - ((CommentViewHolder) holder).upvoteButton.clearColorFilter(); - ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType())); + @Override + public void onVoteThingFail(int position1) { + Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); + commentItem.setVoteType(previousVoteType); + ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + previousVoteType)); + ((CommentViewHolder) holder).upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); + ((CommentViewHolder) holder).downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); + } + }, commentItem.getFullName(), newVoteType, holder.getAdapterPosition()); + }); + + ((CommentViewHolder) holder).downvoteButton.setOnClickListener(view -> { + ColorFilter previousUpvoteButtonColorFilter = ((CommentViewHolder) holder).upvoteButton.getColorFilter(); + ColorFilter previousDownvoteButtonColorFilter = ((CommentViewHolder) holder).downvoteButton.getColorFilter(); + int previousVoteType = commentItem.getVoteType(); + String newVoteType; + + ((CommentViewHolder) holder).upvoteButton.clearColorFilter(); + + if(previousDownvoteButtonColorFilter == null) { + //Not downvoted before + commentItem.setVoteType(-1); + newVoteType = RedditUtils.DIR_DOWNVOTE; + ((CommentViewHolder) holder).downvoteButton + .setColorFilter(ContextCompat.getColor(mActivity, R.color.colorAccent), android.graphics.PorterDuff.Mode.SRC_IN); + } else { + //Downvoted before + commentItem.setVoteType(0); + newVoteType = RedditUtils.DIR_UNVOTE; + ((CommentViewHolder) holder).downvoteButton.clearColorFilter(); } - @Override - public void onVoteThingFail(int position1) { - Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); - commentItem.setVoteType(previousVoteType); - ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + previousVoteType)); - ((CommentViewHolder) holder).upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); - ((CommentViewHolder) holder).downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); - } - }, commentItem.getFullName(), newVoteType, holder.getAdapterPosition()); - }); + ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType())); + + VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position1) { + if(newVoteType.equals(RedditUtils.DIR_DOWNVOTE)) { + commentItem.setVoteType(-1); + ((CommentViewHolder) holder).downvoteButton + .setColorFilter(ContextCompat.getColor(mActivity, R.color.colorAccent), android.graphics.PorterDuff.Mode.SRC_IN); + } else { + commentItem.setVoteType(0); + ((CommentViewHolder) holder).downvoteButton.clearColorFilter(); + } + + ((CommentViewHolder) holder).upvoteButton.clearColorFilter(); + ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType())); + } + + @Override + public void onVoteThingFail(int position1) { + Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); + commentItem.setVoteType(previousVoteType); + ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + previousVoteType)); + ((CommentViewHolder) holder).upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); + ((CommentViewHolder) holder).downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); + } + }, commentItem.getFullName(), newVoteType, holder.getAdapterPosition()); + }); + } else if(holder.getItemViewType() == VIEW_TYPE_LOAD_MORE_COMMENT) { + ((LoadMoreCommentViewHolder) holder).verticalBlock.getLayoutParams().width = mVisibleComments.get(holder.getAdapterPosition()).getDepth() * 16; + + ((LoadMoreCommentViewHolder) holder).textView.setOnClickListener(view -> { + loadMoreComments(holder.getAdapterPosition()); + }); + } else if(holder.getItemViewType() == VIEW_TYPE_IS_LOADING_MORE_COMMENT){ + ((IsLoadingMoreCommentViewHolder) holder).verticalBlock.getLayoutParams().width = mVisibleComments.get(holder.getAdapterPosition()).getDepth() * 16; + } else if(holder.getItemViewType() == VIEW_TYPE_LOAD_MORE_COMMENT_FAILED) { + ((LoadMoreCommentFailedViewHolder) holder).verticalBlock.getLayoutParams().width = mVisibleComments.get(holder.getAdapterPosition()).getDepth() * 16; + + ((LoadMoreCommentFailedViewHolder) holder).retryTextView.setOnClickListener(view -> { + loadMoreComments(holder.getAdapterPosition()); + }); + } + } + + private void loadMoreComments(int position) { + int parentPosition = getParentPosition(position); + CommentData parentComment = mVisibleComments.get(parentPosition); + + mVisibleComments.get(position).setLoadingMoreChildren(true); + mVisibleComments.get(position).setLoadMoreChildrenFailed(false); + notifyItemChanged(position); + + FetchComment.fetchMoreComment(mRetrofit, mSubredditNamePrefixed, parentComment.getMoreChildrenFullnames(), + parentComment.getMoreChildrenStartingIndex(), parentComment.getDepth() + 1, mLocale, + new FetchComment.FetchMoreCommentListener() { + @Override + public void onFetchMoreCommentSuccess(ArrayList commentsData, 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(position).setLoadingMoreChildren(false); + mVisibleComments.get(position).setLoadMoreChildrenFailed(false); + notifyItemChanged(position); + + 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); + + mVisibleComments.addAll(parentPosition + + mVisibleComments.get(parentPosition).getChildren().size(), + commentsData); + notifyItemRangeInserted(parentPosition + mVisibleComments.get(parentPosition).getChildren().size(), + commentsData.size()); + } else { + mVisibleComments.get(parentPosition).getChildren() + .remove(mVisibleComments.get(parentPosition).getChildren().size() - 1); + mVisibleComments.remove(position); + notifyItemRemoved(position); + mVisibleComments.get(parentPosition).removeMoreChildrenFullnames(); + + mVisibleComments.addAll(parentPosition + + mVisibleComments.get(parentPosition).getChildren().size() + 1, + commentsData); + notifyItemRangeInserted(parentPosition + mVisibleComments.get(parentPosition).getChildren().size() + 1, + commentsData.size()); + } + } + + mVisibleComments.get(parentPosition).addChildren(commentsData); + } else { + for(int i = 0; i < mVisibleComments.size(); i++) { + if(mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { + mVisibleComments.get(i).setMoreChildrenStartingIndex(childrenStartingIndex); + + if(mVisibleComments.get(i).isExpanded()) { + mVisibleComments.get(i + mVisibleComments.get(i).getChildren().size()).setLoadingMoreChildren(false); + mVisibleComments.get(i + mVisibleComments.get(i).getChildren().size()).setLoadMoreChildrenFailed(false); + notifyItemChanged(i + mVisibleComments.get(i).getChildren().size()); + + mVisibleComments.addAll(i + mVisibleComments.get(i).getChildren().size(), + commentsData); + notifyItemRangeInserted(i + mVisibleComments.get(i).getChildren().size(), + commentsData.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(commentsData); + + break; + } + } + } + } + + @Override + public void onFetchMoreCommentFailed() { + if(parentPosition < mVisibleComments.size() + && parentComment.getFullName().equals(mVisibleComments.get(parentPosition).getFullName())) { + if(mVisibleComments.get(parentPosition).isExpanded()) { + mVisibleComments.get(position).setLoadingMoreChildren(false); + mVisibleComments.get(position).setLoadMoreChildrenFailed(true); + notifyItemChanged(position); + } + + 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()) { + mVisibleComments.get(i + mVisibleComments.get(i).getChildren().size()).setLoadingMoreChildren(false); + mVisibleComments.get(i + mVisibleComments.get(i).getChildren().size()).setLoadMoreChildrenFailed(true); + notifyItemChanged(i + mVisibleComments.get(i).getChildren().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(true); + + break; + } + } + } + } + }); + } + + private int getParentPosition(int position) { + int childDepth = mVisibleComments.get(position).getDepth(); + for(int i = position; i >= 0; i--) { + if(mVisibleComments.get(i).getDepth() < childDepth) { + return i; + } + } + return -1; } private void expandChildren(int position) { - mVisibleComments.get(position).setExpanded(true); - ArrayList children = mVisibleComments.get(position).getChildren(); - if(children != null && children.size() > 0) { - mVisibleComments.addAll(position + 1, children); - for(int i = position + 1; i <= position + children.size(); i++) { - mVisibleComments.get(i).setExpanded(false); + CommentData comment = mVisibleComments.get(position); + if(!comment.isExpanded()) { + comment.setExpanded(true); + ArrayList children = comment.getChildren(); + if(children != null && children.size() > 0) { + /*if(comment.hasMoreChildrenFullnames() && comment.getMoreChildrenFullnames().size() > comment.getMoreChildrenStartingIndex() + && !children.get(children.size() - 1).isPlaceHolder()) { + children.add(children.size(), new CommentData(children.get(0).getDepth())); + }*/ + mVisibleComments.addAll(position + 1, children); + for(int i = position + 1; i <= position + children.size(); i++) { + mVisibleComments.get(i).setExpanded(false); + } + notifyItemRangeInserted(position + 1, children.size()); } - notifyItemRangeInserted(position + 1, children.size()); } } @@ -392,4 +544,33 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter commentData); - void onFetchAllCommentFailed(); - } - static void fetchComment(Retrofit retrofit, String subredditNamePrefixed, String article, - String comment, Locale locale, boolean isPost, int parentDepth, + String comment, Locale locale, boolean isPost, int depth, final FetchCommentListener fetchCommentListener) { RedditAPI api = retrofit.create(RedditAPI.class); Call comments = api.getComments(subredditNamePrefixed, article, comment); @@ -39,13 +34,13 @@ class FetchComment { public void onResponse(@NonNull Call call, @NonNull Response response) { if(response.isSuccessful()) { ParseComment.parseComment(response.body(), new ArrayList<>(), - locale, isPost, parentDepth, + locale, isPost, depth, new ParseComment.ParseCommentListener() { @Override public void onParseCommentSuccess(ArrayList commentData, - String parentId, ArrayList moreChildrenIds) { + String parentId, ArrayList moreChildrenFullnames) { fetchCommentListener.onFetchCommentSuccess(commentData, parentId, - moreChildrenIds); + moreChildrenFullnames); } @Override @@ -68,9 +63,9 @@ class FetchComment { }); } - static void fetchMoreComment(Retrofit retrofit, String subredditNamePrefixed, String mParentId, - ArrayList allChildren, int startingIndex, Locale locale, - FetchMoreCommentListener fetchMoreCommentListener) { + static void fetchMoreComment(Retrofit retrofit, String subredditNamePrefixed, + ArrayList allChildren, int startingIndex, int depth, + Locale locale, FetchMoreCommentListener fetchMoreCommentListener) { StringBuilder stringBuilder = new StringBuilder(); for(int i = 0; i < 100; i++) { if(allChildren.size() <= startingIndex + i) { @@ -86,101 +81,37 @@ class FetchComment { stringBuilder.deleteCharAt(stringBuilder.length() - 1); RedditAPI api = retrofit.create(RedditAPI.class); - Call moreChildrenBasicInfo = api.getMoreChildren(mParentId, stringBuilder.toString()); - moreChildrenBasicInfo.enqueue(new Callback() { + + Call moreComments = api.getInfo(subredditNamePrefixed, stringBuilder.toString()); + moreComments.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { if(response.isSuccessful()) { - ParseComment.parseMoreCommentBasicInfo(response.body(), new ParseComment.ParseMoreCommentBasicInfoListener() { - @Override - public void onParseMoreCommentBasicInfoSuccess(String commaSeparatedChildrenId) { - Call moreComments = api.getInfo(subredditNamePrefixed, commaSeparatedChildrenId); - moreComments.enqueue(new Callback() { + ParseComment.parseMoreComment(response.body(), new ArrayList<>(), locale, + depth, new ParseComment.ParseCommentListener() { @Override - public void onResponse(Call call, Response response) { - if(response.isSuccessful()) { - ParseComment.parseMoreComment(response.body(), new ArrayList<>(), locale, - 0, new ParseComment.ParseCommentListener() { - @Override - public void onParseCommentSuccess(ArrayList commentData, String parentId, - ArrayList moreChildrenIds) { - fetchMoreCommentListener.onFetchMoreCommentSuccess(commentData, startingIndex + 100); - } - - @Override - public void onParseCommentFailed() { - fetchMoreCommentListener.onFetchMoreCommentFailed(); - Log.i("comment parse failed", "comment parse failed"); - } - }); - } else { - Log.i("more comment failed", response.message()); - fetchMoreCommentListener.onFetchMoreCommentFailed(); - } + public void onParseCommentSuccess(ArrayList commentData, String parentId, + ArrayList moreChildrenFullnames) { + fetchMoreCommentListener.onFetchMoreCommentSuccess(commentData, startingIndex + 100); } @Override - public void onFailure(Call call, Throwable t) { - Log.i("more comment failed", t.getMessage()); + public void onParseCommentFailed() { fetchMoreCommentListener.onFetchMoreCommentFailed(); + Log.i("comment parse failed", "comment parse failed"); } }); - } - - @Override - public void onParseMoreCommentBasicInfoFailed() { - Log.i("comment parse failed", "comment parse failed"); - fetchMoreCommentListener.onFetchMoreCommentFailed(); - } - }); } else { - Log.i("basic info failed", response.message()); + Log.i("more comment failed", response.message()); fetchMoreCommentListener.onFetchMoreCommentFailed(); } } @Override public void onFailure(Call call, Throwable t) { - Log.i("basic info failed", t.getMessage()); + Log.i("more comment failed", t.getMessage()); fetchMoreCommentListener.onFetchMoreCommentFailed(); } }); } - - static void fetchAllComment(Retrofit retrofit, String subredditNamePrefixed, String article, - String comment, Locale locale, boolean isPost, int parentDepth, - FetchAllCommentListener fetchAllCommentListener) { - fetchComment(retrofit, subredditNamePrefixed, article, comment, locale, isPost, parentDepth, - new FetchCommentListener() { - @Override - public void onFetchCommentSuccess(ArrayList commentsData, String parentId, ArrayList children) { - if(children.size() != 0) { - fetchMoreComment(retrofit, subredditNamePrefixed, parentId, children, - 0, locale, new FetchMoreCommentListener() { - @Override - public void onFetchMoreCommentSuccess(ArrayList commentsData, - int childrenStartingIndex) { - ((ArrayList) commentsData).addAll((ArrayList) commentsData); - fetchAllCommentListener.onFetchAllCommentSuccess(commentsData); - } - - @Override - public void onFetchMoreCommentFailed() { - Log.i("fetch more comment", "error"); - fetchAllCommentListener.onFetchAllCommentFailed(); - } - }); - } else { - fetchAllCommentListener.onFetchAllCommentSuccess(commentsData); - } - } - - @Override - public void onFetchCommentFailed() { - Log.i("fetch comment", "error"); - fetchAllCommentListener.onFetchAllCommentFailed(); - } - }); - - } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java index a099960b..0192acea 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java @@ -382,13 +382,10 @@ public class MainActivity extends AppCompatActivity { if (mFragment instanceof FragmentCommunicator) { switch (item.getItemId()) { case R.id.action_refresh_main_activity: - /*((FragmentCommunicator) mFragment).refresh(); + ((FragmentCommunicator) mFragment).refresh(); mFetchUserInfoSuccess = false; mInsertSuccess = false; - loadUserData();*/ - Intent intent = new Intent(this, CommentActivity.class); - intent.putExtra(CommentActivity.EXTRA_COMMENT_DATA_KEY, "asdfasdfas"); - startActivity(intent); + loadUserData(); return true; case R.id.action_lazy_mode_main_activity: MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_main_activity); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseComment.java index 05b9440a..d6ff6697 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseComment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseComment.java @@ -16,7 +16,7 @@ import java.util.Locale; class ParseComment { interface ParseCommentListener { - void onParseCommentSuccess(ArrayList commentData, String parentId, ArrayList moreChildrenIds); + void onParseCommentSuccess(ArrayList commentData, String parentId, ArrayList moreChildrenFullnames); void onParseCommentFailed(); } @@ -31,7 +31,7 @@ class ParseComment { } static void parseComment(String response, ArrayList commentData, Locale locale, - boolean isPost, int parentDepth, ParseCommentListener parseCommentListener) { + boolean isPost, int depth, ParseCommentListener parseCommentListener) { try { JSONArray childrenArray = new JSONArray(response); String parentId = childrenArray.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY) @@ -44,7 +44,7 @@ class ParseComment { .getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); } - new ParseCommentAsyncTask(childrenArray, commentData, locale, parentId, parentDepth, parseCommentListener).execute(); + new ParseCommentAsyncTask(childrenArray, commentData, locale, parentId, depth, parseCommentListener).execute(); } catch (JSONException e) { e.printStackTrace(); if(e.getMessage() != null) { @@ -54,15 +54,11 @@ class ParseComment { } } - static void parseMoreCommentBasicInfo(String response, ParseMoreCommentBasicInfoListener parseMoreCommentBasicInfoListener) { - new ParseMoreCommentBasicInfoAsyncTask(response, parseMoreCommentBasicInfoListener).execute(); - } - static void parseMoreComment(String response, ArrayList commentData, Locale locale, - int parentDepth, ParseCommentListener parseCommentListener) { + int depth, ParseCommentListener parseCommentListener) { try { JSONArray childrenArray = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); - new ParseCommentAsyncTask(childrenArray, commentData, locale, null, parentDepth, parseCommentListener).execute(); + new ParseCommentAsyncTask(childrenArray, commentData, locale, null, depth, parseCommentListener).execute(); } catch (JSONException e) { e.printStackTrace(); if(e.getMessage() != null) { @@ -72,31 +68,31 @@ class ParseComment { } } - static void parseSentComment(String response, int parentDepth, Locale locale, + static void parseSentComment(String response, int depth, Locale locale, ParseSentCommentListener parseSentCommentListener) { - new ParseSentCommentAsyncTask(response, parentDepth, locale, parseSentCommentListener).execute(); + new ParseSentCommentAsyncTask(response, depth, locale, parseSentCommentListener).execute(); } private static class ParseCommentAsyncTask extends AsyncTask { private JSONArray comments; private ArrayList commentData; private ArrayList newcommentData; - private ArrayList moreChildrenIds; + private ArrayList moreChildrenFullnames; private Locale locale; private String parentId; - private int parentDepth; + private int depth; private ParseCommentListener parseCommentListener; private boolean parseFailed; ParseCommentAsyncTask(JSONArray comments, ArrayList commentData, Locale locale, - @Nullable String parentId, int parentDepth, ParseCommentListener parseCommentListener){ + @Nullable String parentId, int depth, ParseCommentListener parseCommentListener){ this.comments = comments; this.commentData = commentData; newcommentData = new ArrayList<>(); - moreChildrenIds = new ArrayList<>(); + moreChildrenFullnames = new ArrayList<>(); this.locale = locale; this.parentId = parentId; - this.parentDepth = parentDepth; + this.depth = depth; parseFailed = false; this.parseCommentListener = parseCommentListener; } @@ -104,7 +100,7 @@ class ParseComment { @Override protected Void doInBackground(Void... voids) { try { - parseCommentRecursion(comments, newcommentData, moreChildrenIds, parentDepth, locale); + parseCommentRecursion(comments, newcommentData, moreChildrenFullnames, depth, locale); } catch (JSONException e) { parseFailed = true; if(e.getMessage() != null) { @@ -118,7 +114,7 @@ class ParseComment { protected void onPostExecute(Void aVoid) { if(!parseFailed) { commentData.addAll(newcommentData); - parseCommentListener.onParseCommentSuccess(commentData, parentId, moreChildrenIds); + parseCommentListener.onParseCommentSuccess(commentData, parentId, moreChildrenFullnames); } else { parseCommentListener.onParseCommentFailed(); } @@ -126,7 +122,7 @@ class ParseComment { } private static void parseCommentRecursion(JSONArray comments, ArrayList newCommentData, - ArrayList moreChildrenIds, int parentDepth, Locale locale) throws JSONException { + ArrayList moreChildrenFullnames, int depth, Locale locale) throws JSONException { int actualCommentLength; if(comments.length() == 0) { @@ -135,12 +131,12 @@ class ParseComment { JSONObject more = comments.getJSONObject(comments.length() - 1).getJSONObject(JSONUtils.DATA_KEY); - //Maybe moreChildrenIds contain only comments and no more info + //Maybe moreChildrenFullnames contain only comments and no more info if(more.has(JSONUtils.COUNT_KEY)) { JSONArray childrenArray = more.getJSONArray(JSONUtils.CHILDREN_KEY); for(int i = 0; i < childrenArray.length(); i++) { - moreChildrenIds.add(childrenArray.getString(i)); + moreChildrenFullnames.add("t1_" + childrenArray.getString(i)); } actualCommentLength = comments.length() - 1; @@ -150,17 +146,17 @@ class ParseComment { for (int i = 0; i < actualCommentLength; i++) { JSONObject data = comments.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); - CommentData singleComment = parseSingleComment(data, parentDepth, locale); + CommentData singleComment = parseSingleComment(data, depth, locale); if(data.get(JSONUtils.REPLIES_KEY) instanceof JSONObject) { JSONArray childrenArray = data.getJSONObject(JSONUtils.REPLIES_KEY) .getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); ArrayList children = new ArrayList<>(); - ArrayList nextMoreChildrenIds = new ArrayList<>(); - parseCommentRecursion(childrenArray, children, nextMoreChildrenIds, singleComment.getDepth(), + ArrayList nextMoreChildrenFullnames = new ArrayList<>(); + parseCommentRecursion(childrenArray, children, nextMoreChildrenFullnames, singleComment.getDepth(), locale); singleComment.addChildren(children); - singleComment.setMoreChildrenIds(nextMoreChildrenIds); + singleComment.setMoreChildrenFullnames(nextMoreChildrenFullnames); } newCommentData.add(singleComment); @@ -214,15 +210,15 @@ class ParseComment { private static class ParseSentCommentAsyncTask extends AsyncTask { private String response; - private int parentDepth; + private int depth; private Locale locale; private ParseSentCommentListener parseSentCommentListener; private boolean parseFailed; private CommentData commentData; - ParseSentCommentAsyncTask(String response, int parentDepth, Locale locale, ParseSentCommentListener parseSentCommentListener) { + ParseSentCommentAsyncTask(String response, int depth, Locale locale, ParseSentCommentListener parseSentCommentListener) { this.response = response; - this.parentDepth = parentDepth; + this.depth = depth; this.locale = locale; this.parseSentCommentListener = parseSentCommentListener; parseFailed = false; @@ -232,7 +228,7 @@ class ParseComment { protected Void doInBackground(Void... voids) { try { JSONObject sentCommentData = new JSONObject(response); - commentData = parseSingleComment(sentCommentData, parentDepth, locale); + commentData = parseSingleComment(sentCommentData, depth, locale); } catch (JSONException e) { e.printStackTrace(); parseFailed = true; @@ -250,7 +246,7 @@ class ParseComment { } } } - private static CommentData parseSingleComment(JSONObject singleCommentData, int parentDepth, Locale locale) throws JSONException { + private static CommentData parseSingleComment(JSONObject singleCommentData, int depth, Locale locale) throws JSONException { String id = singleCommentData.getString(JSONUtils.ID_KEY); String fullName = singleCommentData.getString(JSONUtils.NAME_KEY); String author = singleCommentData.getString(JSONUtils.AUTHOR_KEY); @@ -270,12 +266,10 @@ class ParseComment { String formattedSubmitTime = new SimpleDateFormat("MMM d, YYYY, HH:mm", locale).format(submitTimeCalendar.getTime()); - int depth; if(singleCommentData.has(JSONUtils.DEPTH_KEY)) { depth = singleCommentData.getInt(JSONUtils.DEPTH_KEY); - } else { - depth = parentDepth; } + boolean collapsed = singleCommentData.getBoolean(JSONUtils.COLLAPSED_KEY); boolean hasReply = !(singleCommentData.get(JSONUtils.REPLIES_KEY) instanceof String); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java index ebdb5f91..bced4f3f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java @@ -54,9 +54,6 @@ public interface RedditAPI { @POST("api/subscribe") Call subredditSubscription(@HeaderMap Map headers, @FieldMap Map params); - @GET("api/morechildren?api_type=json&raw_json=1") - Call getMoreChildren(@Query("link_id") String linkId, @Query("children") String children); - @GET("{subredditNamePrefixed}/api/info.json?raw_json=1") Call getInfo(@Path("subredditNamePrefixed") String subredditNamePrefixed, @Query("id") String id); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditListingRecyclerViewAdapter.java index ad27c1b9..b071d6f9 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditListingRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditListingRecyclerViewAdapter.java @@ -209,7 +209,7 @@ public class SubredditListingRecyclerViewAdapter extends PagedListAdapter retryLoadingMoreCallback.retryLoadingMore()); - errorTextView.setText(R.string.load_comment_failed); + errorTextView.setText(R.string.post_load_comments_failed); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/UserListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/UserListingRecyclerViewAdapter.java index 5a49f51f..91e6ae4e 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/UserListingRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/UserListingRecyclerViewAdapter.java @@ -209,7 +209,7 @@ public class UserListingRecyclerViewAdapter extends PagedListAdapter retryLoadingMoreCallback.retryLoadingMore()); - errorTextView.setText(R.string.load_comment_failed); + errorTextView.setText(R.string.post_load_comments_failed); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java index 58c4d571..94480f98 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java @@ -541,8 +541,8 @@ public class ViewPostDetailActivity extends AppCompatActivity { private void fetchMoreComment(int startingIndex) { isLoadingMoreChildren = true; - FetchComment.fetchMoreComment(mRetrofit, mPost.getSubredditNamePrefixed(), mPost.getFullName(), - children, startingIndex, mLocale, new FetchComment.FetchMoreCommentListener() { + FetchComment.fetchMoreComment(mRetrofit, mPost.getSubredditNamePrefixed(), children, startingIndex, + 0, mLocale, new FetchComment.FetchMoreCommentListener() { @Override public void onFetchMoreCommentSuccess(ArrayList commentsData, int childrenStartingIndex) { mAdapter.addComments(commentsData); @@ -553,7 +553,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { @Override public void onFetchMoreCommentFailed() { isLoadingMoreChildren = false; - Snackbar snackbar = Snackbar.make(mCoordinatorLayout, R.string.load_more_comment_failed, Snackbar.LENGTH_INDEFINITE); + Snackbar snackbar = Snackbar.make(mCoordinatorLayout, R.string.post_load_more_comments_failed, Snackbar.LENGTH_INDEFINITE); snackbar.setAction(R.string.retry, view -> fetchMoreComment(startingIndex)); snackbar.show(); } @@ -613,7 +613,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { } private void showRetrySnackbar() { - Snackbar snackbar = Snackbar.make(mCoordinatorLayout, R.string.load_comment_failed, Snackbar.LENGTH_INDEFINITE); + Snackbar snackbar = Snackbar.make(mCoordinatorLayout, R.string.post_load_comments_failed, Snackbar.LENGTH_INDEFINITE); snackbar.setAction(R.string.retry, view -> fetchComment()); snackbar.show(); } diff --git a/app/src/main/res/layout/item_is_loading_more_comments.xml b/app/src/main/res/layout/item_is_loading_more_comments.xml new file mode 100644 index 00000000..7dfdf5cb --- /dev/null +++ b/app/src/main/res/layout/item_is_loading_more_comments.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_load_more_comments.xml b/app/src/main/res/layout/item_load_more_comments.xml new file mode 100644 index 00000000..5b92d767 --- /dev/null +++ b/app/src/main/res/layout/item_load_more_comments.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_load_more_comments_failed.xml b/app/src/main/res/layout/item_load_more_comments_failed.xml new file mode 100644 index 00000000..eb1b4e4f --- /dev/null +++ b/app/src/main/res/layout/item_load_more_comments_failed.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6c9120c7..8cd06098 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -27,8 +27,8 @@ No storage permission to save this file Error loading posts - Error loading comments - Error loading more comments + Error loading comments + Error loading more comments Retry Comments No comments yet. Write a comment? @@ -80,4 +80,9 @@ Download completed Download Failed + + Load more comments + Load failed. Tap to retry. + + Loading