diff options
Diffstat (limited to 'app/src/main')
14 files changed, 599 insertions, 346 deletions
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<CommentData> children; - private ArrayList<String> moreChildrenIds; + private ArrayList<String> 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<CommentData> CREATOR = new Creator<CommentData>() { @@ -164,26 +182,70 @@ class CommentData implements Parcelable { } public void addChildren(ArrayList<CommentData> 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<String> getMoreChildrenFullnames() { + return moreChildrenFullnames; + } + + public void setMoreChildrenFullnames(ArrayList<String> 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 ArrayList<String> getMoreChildrenIds() { - return moreChildrenIds; + public boolean isLoadMoreChildrenFailed() { + return loadMoreChildrenFailed; } - public void setMoreChildrenIds(ArrayList<String> moreChildrenIds) { - this.moreChildrenIds = moreChildrenIds; + 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<String, Post> { @@ -62,7 +62,7 @@ public class CommentDataSource extends PageKeyedDataSource<String, Post> { RedditAPI api = retrofit.create(RedditAPI.class); - Call<String> comments = api.getComments(subredditNamePrefixed, article, comment); + //Call<String> comments = api.getComments(subredditNamePrefixed, article, comment); /*comments.enqueue(new Callback<String>() { @Override public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { @@ -119,7 +119,7 @@ public class CommentDataSource extends PageKeyedDataSource<String, Post> { RedditAPI api = retrofit.create(RedditAPI.class); - Call<String> moreChildrenBasicInfo = api.getMoreChildren(mParentId, params.key); + //Call<String> moreChildrenBasicInfo = api.getMoreChildren(mParentId, params.key); /*moreChildrenBasicInfo.enqueue(new Callback<String>() { @Override public void onResponse(Call<String> call, Response<String> 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<RecyclerView.ViewHolder> { + private static final int VIEW_TYPE_COMMENT = 0; + private static final int VIEW_TYPE_LOAD_MORE_COMMENT = 1; + private static final int VIEW_TYPE_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<RecyclerView.ViewH mLocale = locale; mVisibleComments = new ArrayList<>(); - new Handler().post(() -> { makeChildrenVisible(commentData, mVisibleComments); notifyDataSetChanged(); @@ -70,239 +74,387 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewH c.setExpanded(true); makeChildrenVisible(c.getChildren(), visibleComments); } + if(c.hasMoreChildrenFullnames() && c.getMoreChildrenFullnames().size() > 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()); - - 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); - }); + if(holder.getItemViewType() == VIEW_TYPE_COMMENT) { + CommentData commentItem = mVisibleComments.get(holder.getAdapterPosition()); - ((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)); - 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)); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, commentItem.getAuthor()); 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)); + }); + + ((CommentViewHolder) holder).commentTimeTextView.setText(commentItem.getCommentTime()); + + 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(); + + ((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); + } + ((CommentViewHolder) holder).expandButton.setVisibility(View.VISIBLE); } - }).build(); - - ((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).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).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).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")); - }); + ((CommentViewHolder) holder).upvoteButton.setOnClickListener(view -> { + ColorFilter previousUpvoteButtonColorFilter = ((CommentViewHolder) holder).upvoteButton.getColorFilter(); + ColorFilter previousDownvoteButtonColorFilter = ((CommentViewHolder) holder).downvoteButton.getColorFilter(); + int previousVoteType = commentItem.getVoteType(); + String newVoteType; - 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).downvoteButton.clearColorFilter(); - ((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>) commentData); - ((CommentViewHolder) holder).loadMoreCommentsProgressBar - .setVisibility(View.GONE); - expandChildren(holder.getAdapterPosition()); - ((CommentViewHolder) holder).expandButton - .setImageResource(R.drawable.ic_expand_less_black_20dp); - } + 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(); + } - @Override - public void onFetchAllCommentFailed() { - ((CommentViewHolder) holder).loadMoreCommentsProgressBar - .setVisibility(View.GONE); - } - }); - }*/ - }); + ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType())); - ((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); - }); + 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(); + } - 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).downvoteButton.clearColorFilter(); + ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType())); + } - ((CommentViewHolder) holder).upvoteButton.setOnClickListener(view -> { - ColorFilter previousUpvoteButtonColorFilter = ((CommentViewHolder) holder).upvoteButton.getColorFilter(); - ColorFilter previousDownvoteButtonColorFilter = ((CommentViewHolder) holder).downvoteButton.getColorFilter(); - int previousVoteType = commentItem.getVoteType(); - String newVoteType; + @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.clearColorFilter(); + ((CommentViewHolder) holder).downvoteButton.setOnClickListener(view -> { + ColorFilter previousUpvoteButtonColorFilter = ((CommentViewHolder) holder).upvoteButton.getColorFilter(); + ColorFilter previousDownvoteButtonColorFilter = ((CommentViewHolder) holder).downvoteButton.getColorFilter(); + int previousVoteType = commentItem.getVoteType(); + String newVoteType; - 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(); - } + 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())); } - @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())); - ((CommentViewHolder) holder).downvoteButton.setOnClickListener(view -> { - ColorFilter previousUpvoteButtonColorFilter = ((CommentViewHolder) holder).upvoteButton.getColorFilter(); - ColorFilter previousDownvoteButtonColorFilter = ((CommentViewHolder) holder).downvoteButton.getColorFilter(); - int previousVoteType = commentItem.getVoteType(); - String newVoteType; + 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).upvoteButton.clearColorFilter(); + ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType())); + } - 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()); + }); + } 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()); + }); + } + } - ((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(); + 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<CommentData> 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; + } + } + } } - ((CommentViewHolder) holder).upvoteButton.clearColorFilter(); - ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType())); - } + @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); + } - @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()); - }); + 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<CommentData> 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<CommentData> 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<RecyclerView.ViewH ButterKnife.bind(this, itemView); } } + + class LoadMoreCommentViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.vertical_block_item_load_more_comments) View verticalBlock; + @BindView(R.id.load_more_comments_text_view_item_load_more_comments) TextView textView; + + LoadMoreCommentViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + } + } + + class IsLoadingMoreCommentViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.vertical_block_item_is_loading_more_comments) View verticalBlock; + + IsLoadingMoreCommentViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + } + } + + class LoadMoreCommentFailedViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.vertical_block_item_load_more_comments_failed) View verticalBlock; + @BindView(R.id.retry_text_view_item_load_more_comments_failed) TextView retryTextView; + + LoadMoreCommentFailedViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + } + } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchComment.java index e2a5569f..281daf1d 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchComment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchComment.java @@ -24,13 +24,8 @@ class FetchComment { void onFetchMoreCommentFailed(); } - interface FetchAllCommentListener { - void onFetchAllCommentSuccess(ArrayList<CommentData> 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<String> comments = api.getComments(subredditNamePrefixed, article, comment); @@ -39,13 +34,13 @@ class FetchComment { public void onResponse(@NonNull Call<String> call, @NonNull Response<String> 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> commentData, - String parentId, ArrayList<String> moreChildrenIds) { + String parentId, ArrayList<String> moreChildrenFullnames) { fetchCommentListener.onFetchCommentSuccess(commentData, parentId, - moreChildrenIds); + moreChildrenFullnames); } @Override @@ -68,9 +63,9 @@ class FetchComment { }); } - static void fetchMoreComment(Retrofit retrofit, String subredditNamePrefixed, String mParentId, - ArrayList<String> allChildren, int startingIndex, Locale locale, - FetchMoreCommentListener fetchMoreCommentListener) { + static void fetchMoreComment(Retrofit retrofit, String subredditNamePrefixed, + ArrayList<String> 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<String> moreChildrenBasicInfo = api.getMoreChildren(mParentId, stringBuilder.toString()); - moreChildrenBasicInfo.enqueue(new Callback<String>() { + + Call<String> moreComments = api.getInfo(subredditNamePrefixed, stringBuilder.toString()); + moreComments.enqueue(new Callback<String>() { @Override public void onResponse(Call<String> call, Response<String> response) { if(response.isSuccessful()) { - ParseComment.parseMoreCommentBasicInfo(response.body(), new ParseComment.ParseMoreCommentBasicInfoListener() { - @Override - public void onParseMoreCommentBasicInfoSuccess(String commaSeparatedChildrenId) { - Call<String> moreComments = api.getInfo(subredditNamePrefixed, commaSeparatedChildrenId); - moreComments.enqueue(new Callback<String>() { + ParseComment.parseMoreComment(response.body(), new ArrayList<>(), locale, + depth, new ParseComment.ParseCommentListener() { @Override - public void onResponse(Call<String> call, Response<String> response) { - if(response.isSuccessful()) { - ParseComment.parseMoreComment(response.body(), new ArrayList<>(), locale, - 0, new ParseComment.ParseCommentListener() { - @Override - public void onParseCommentSuccess(ArrayList<CommentData> commentData, String parentId, - ArrayList<String> 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> commentData, String parentId, + ArrayList<String> moreChildrenFullnames) { + fetchMoreCommentListener.onFetchMoreCommentSuccess(commentData, startingIndex + 100); } @Override - public void onFailure(Call<String> 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<String> 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<CommentData> commentsData, String parentId, ArrayList<String> children) { - if(children.size() != 0) { - fetchMoreComment(retrofit, subredditNamePrefixed, parentId, children, - 0, locale, new FetchMoreCommentListener() { - @Override - public void onFetchMoreCommentSuccess(ArrayList<CommentData> commentsData, - int childrenStartingIndex) { - ((ArrayList<CommentData>) commentsData).addAll((ArrayList<CommentData>) 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> commentData, String parentId, ArrayList<String> moreChildrenIds); + void onParseCommentSuccess(ArrayList<CommentData> commentData, String parentId, ArrayList<String> moreChildrenFullnames); void onParseCommentFailed(); } @@ -31,7 +31,7 @@ class ParseComment { } static void parseComment(String response, ArrayList<CommentData> 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> 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<Void, Void, Void> { private JSONArray comments; private ArrayList<CommentData> commentData; private ArrayList<CommentData> newcommentData; - private ArrayList<String> moreChildrenIds; + private ArrayList<String> moreChildrenFullnames; private Locale locale; private String parentId; - private int parentDepth; + private int depth; private ParseCommentListener parseCommentListener; private boolean parseFailed; ParseCommentAsyncTask(JSONArray comments, ArrayList<CommentData> 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<CommentData> newCommentData, - ArrayList<String> moreChildrenIds, int parentDepth, Locale locale) throws JSONException { + ArrayList<String> 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<CommentData> children = new ArrayList<>(); - ArrayList<String> nextMoreChildrenIds = new ArrayList<>(); - parseCommentRecursion(childrenArray, children, nextMoreChildrenIds, singleComment.getDepth(), + ArrayList<String> 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<Void, Void, Void> { 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<String> subredditSubscription(@HeaderMap Map<String, String> headers, @FieldMap Map<String, String> params); - @GET("api/morechildren?api_type=json&raw_json=1") - Call<String> getMoreChildren(@Query("link_id") String linkId, @Query("children") String children); - @GET("{subredditNamePrefixed}/api/info.json?raw_json=1") Call<String> 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<Subred super(itemView); ButterKnife.bind(this, itemView); retryButton.setOnClickListener(view -> 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<UserData, R super(itemView); ButterKnife.bind(this, itemView); retryButton.setOnClickListener(view -> 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<CommentData> 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 @@ +<?xml version="1.0" encoding="utf-8"?> +<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <View + android:id="@+id/vertical_block_item_is_loading_more_comments" + android:layout_width="0dp" + android:layout_height="match_parent" + android:background="@color/textColorPrimaryDark" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center" + android:padding="8dp" + android:text="@string/loading" + android:textColor="@color/primaryTextColor" /> + + </LinearLayout> + +</com.google.android.material.card.MaterialCardView>
\ 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 @@ +<?xml version="1.0" encoding="utf-8"?> +<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <View + android:id="@+id/vertical_block_item_load_more_comments" + android:layout_width="0dp" + android:layout_height="match_parent" + android:background="@color/textColorPrimaryDark" /> + + <TextView + android:id="@+id/load_more_comments_text_view_item_load_more_comments" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center" + android:padding="8dp" + android:text="@string/comment_load_more_comments" + android:textColor="@color/primaryTextColor" /> + + </LinearLayout> + +</com.google.android.material.card.MaterialCardView>
\ 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 @@ +<?xml version="1.0" encoding="utf-8"?> +<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <View + android:id="@+id/vertical_block_item_load_more_comments_failed" + android:layout_width="0dp" + android:layout_height="match_parent" + android:background="@color/textColorPrimaryDark" /> + + <TextView + android:id="@+id/retry_text_view_item_load_more_comments_failed" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_gravity="center_vertical" + android:gravity="center" + android:padding="8dp" + android:text="@string/comment_load_more_comments_failed" + android:textColor="@color/primaryTextColor" /> + + </LinearLayout> + +</com.google.android.material.card.MaterialCardView>
\ 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 @@ <string name="no_storage_permission">No storage permission to save this file</string> <string name="load_posts_failed">Error loading posts</string> - <string name="load_comment_failed">Error loading comments</string> - <string name="load_more_comment_failed">Error loading more comments</string> + <string name="post_load_comments_failed">Error loading comments</string> + <string name="post_load_more_comments_failed">Error loading more comments</string> <string name="retry">Retry</string> <string name="comments">Comments</string> <string name="no_comments_yet">No comments yet. Write a comment?</string> @@ -80,4 +80,9 @@ <string name="download_completed">Download completed</string> <string name="download_failed">Download Failed</string> + + <string name="comment_load_more_comments">Load more comments</string> + <string name="comment_load_more_comments_failed">Load failed. Tap to retry.</string> + + <string name="loading">Loading</string> </resources> |