diff options
author | Alex Ning <chineseperson5@gmail.com> | 2019-02-12 06:37:36 +0000 |
---|---|---|
committer | Alex Ning <chineseperson5@gmail.com> | 2019-02-12 06:37:36 +0000 |
commit | 0d6296c1a4d3a17cf077eea371d91093d766b6cf (patch) | |
tree | 1fa97001c557c03c14ad7942dbea486a5c250952 | |
parent | 0e1abee883469a6345485499013c97c252361f33 (diff) | |
download | infinity-for-reddit-0d6296c1a4d3a17cf077eea371d91093d766b6cf.tar infinity-for-reddit-0d6296c1a4d3a17cf077eea371d91093d766b6cf.tar.gz infinity-for-reddit-0d6296c1a4d3a17cf077eea371d91093d766b6cf.tar.bz2 infinity-for-reddit-0d6296c1a4d3a17cf077eea371d91093d766b6cf.tar.lz infinity-for-reddit-0d6296c1a4d3a17cf077eea371d91093d766b6cf.tar.xz infinity-for-reddit-0d6296c1a4d3a17cf077eea371d91093d766b6cf.tar.zst infinity-for-reddit-0d6296c1a4d3a17cf077eea371d91093d766b6cf.zip |
Load All comments of a post using paging library. Loading comments of comments is now broken.
16 files changed, 867 insertions, 61 deletions
diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser Binary files differindex 164c2f2d..62203ae9 100644 --- a/.idea/caches/build_file_checksums.ser +++ b/.idea/caches/build_file_checksums.ser diff --git a/.idea/caches/gradle_models.ser b/.idea/caches/gradle_models.ser Binary files differindex 60459acd..62d6a116 100644 --- a/.idea/caches/gradle_models.ser +++ b/.idea/caches/gradle_models.ser diff --git a/app/build.gradle b/app/build.gradle index 43ead6ce..ec846c03 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,7 +59,7 @@ dependencies { annotationProcessor "android.arch.lifecycle:compiler:$rootProject.archLifecycleVersion" implementation 'io.reactivex.rxjava2:rxandroid:2.1.0' implementation 'io.reactivex.rxjava2:rxjava:2.2.0' - implementation 'com.squareup.retrofit2:retrofit:2.4.0' + implementation 'com.squareup.retrofit2:retrofit:2.5.0' implementation 'com.squareup.retrofit2:converter-scalars:2.4.0' implementation 'jp.wasabeef:glide-transformations:4.0.0' implementation 'com.muditsen.multilevelrecyclerview:multilevelview:1.0.0' diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentAdapter.java new file mode 100644 index 00000000..0f7e191c --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentAdapter.java @@ -0,0 +1,343 @@ +package ml.docilealligator.infinityforreddit; + +import android.arch.paging.PagedListAdapter; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.ColorFilter; +import android.net.Uri; +import android.support.annotation.NonNull; +import android.support.customtabs.CustomTabsIntent; +import android.support.v4.content.ContextCompat; +import android.support.v7.util.DiffUtil; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; + +import com.multilevelview.models.RecyclerViewItem; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.ButterKnife; +import retrofit2.Retrofit; +import ru.noties.markwon.SpannableConfiguration; +import ru.noties.markwon.view.MarkwonView; + +public class CommentAdapter extends PagedListAdapter<CommentData, RecyclerView.ViewHolder> { + private Context mContext; + private Retrofit mRetrofit; + private Retrofit mOauthRetrofit; + private SharedPreferences mSharedPreferences; + private RecyclerView mRecyclerView; + private String subredditNamePrefixed; + private String article; + private Locale locale; + + private NetworkState networkState; + private RetryLoadingMoreCallback retryLoadingMoreCallback; + + interface RetryLoadingMoreCallback { + void retryLoadingMore(); + } + + CommentAdapter(Context context, Retrofit retrofit, Retrofit oauthRetrofit, + SharedPreferences sharedPreferences, RecyclerView recyclerView, + String subredditNamePrefixed, String article, Locale locale) { + super(DIFF_CALLBACK); + mContext = context; + mRetrofit = retrofit; + mOauthRetrofit = oauthRetrofit; + mSharedPreferences = sharedPreferences; + mRecyclerView = recyclerView; + this.subredditNamePrefixed = subredditNamePrefixed; + this.article = article; + this.locale = locale; + } + + static final DiffUtil.ItemCallback<CommentData> DIFF_CALLBACK = new DiffUtil.ItemCallback<CommentData>() { + @Override + public boolean areItemsTheSame(@NonNull CommentData commentData, @NonNull CommentData t1) { + return commentData.getId().equals(t1.getId()); + } + + @Override + public boolean areContentsTheSame(@NonNull CommentData commentData, @NonNull CommentData t1) { + return commentData.getCommentContent().equals(t1.getCommentContent()); + } + }; + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) { + return new CommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_comment, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { + final CommentData commentItem = getItem(i); + + String authorPrefixed = "u/" + commentItem.getAuthor(); + ((CommentViewHolder) viewHolder).authorTextView.setText(authorPrefixed); + ((CommentViewHolder) viewHolder).authorTextView.setOnClickListener(view -> { + Intent intent = new Intent(mContext, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, commentItem.getAuthor()); + mContext.startActivity(intent); + }); + + ((CommentViewHolder) viewHolder).commentTimeTextView.setText(commentItem.getCommentTime()); + SpannableConfiguration spannableConfiguration = SpannableConfiguration.builder(mContext).linkResolver((view, link) -> { + if(link.startsWith("/u/")) { + Intent intent = new Intent(mContext, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, link.substring(3)); + mContext.startActivity(intent); + } else if(link.startsWith("/r/")) { + Intent intent = new Intent(mContext, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, link.substring(3)); + mContext.startActivity(intent); + } else { + CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); + // add share action to menu list + builder.addDefaultShareMenuItem(); + builder.setToolbarColor(mContext.getResources().getColor(R.color.colorPrimary)); + CustomTabsIntent customTabsIntent = builder.build(); + customTabsIntent.launchUrl(mContext, Uri.parse(link)); + } + }).build(); + + ((CommentViewHolder) viewHolder).commentMarkdownView.setMarkdown(spannableConfiguration, commentItem.getCommentContent()); + ((CommentViewHolder) viewHolder).scoreTextView.setText(Integer.toString(commentItem.getScore())); + + ((CommentViewHolder) viewHolder).verticalBlock.getLayoutParams().width = commentItem.getDepth() * 16; + if(commentItem.hasReply()) { + setExpandButton(((CommentViewHolder) viewHolder).expandButton, commentItem.isExpanded()); + } + + ((CommentViewHolder) viewHolder).expandButton.setOnClickListener(view -> { + if(commentItem.hasChildren() && commentItem.getChildren().size() > 0) { + //mRecyclerView.toggleItemsGroup(viewHolder.getAdapterPosition()); + setExpandButton(((CommentViewHolder) viewHolder).expandButton, commentItem.isExpanded()); + } else { + ((CommentViewHolder) viewHolder).loadMoreCommentsProgressBar.setVisibility(View.VISIBLE); + FetchComment.fetchComment(mRetrofit, subredditNamePrefixed, article, commentItem.getId(), + new FetchComment.FetchCommentListener() { + @Override + public void onFetchCommentSuccess(String response) { + ParseComment.parseComment(response, new ArrayList<CommentData>(), + locale, false, commentItem.getDepth(), 1, + new ParseComment.ParseCommentListener() { + @Override + public void onParseCommentSuccess(List<?> commentData, + String parentId, String commaSeparatedChildren) { + commentItem.addChildren((List<RecyclerViewItem>) commentData); + ((CommentViewHolder) viewHolder).loadMoreCommentsProgressBar + .setVisibility(View.GONE); + //mRecyclerView.toggleItemsGroup(viewHolder.getAdapterPosition()); + ((CommentViewHolder) viewHolder).expandButton + .setImageResource(R.drawable.ic_expand_less_black_20dp); + } + + @Override + public void onParseCommentFailed() { + ((CommentViewHolder) viewHolder).loadMoreCommentsProgressBar + .setVisibility(View.GONE); + } + }); + } + + @Override + public void onFetchCommentFail() { + + } + }); + } + }); + + switch (commentItem.getVoteType()) { + case 1: + ((CommentViewHolder) viewHolder).upvoteButton + .setColorFilter(ContextCompat.getColor(mContext, R.color.colorPrimary), android.graphics.PorterDuff.Mode.SRC_IN); + break; + case 2: + ((CommentViewHolder) viewHolder).downvoteButton + .setColorFilter(ContextCompat.getColor(mContext, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN); + break; + } + + ((CommentViewHolder) viewHolder).upvoteButton.setOnClickListener(view -> { + final boolean isDownvotedBefore = ((CommentViewHolder) viewHolder).downvoteButton.getColorFilter() != null; + final ColorFilter minusButtonColorFilter = ((CommentViewHolder) viewHolder).downvoteButton.getColorFilter(); + ((CommentViewHolder) viewHolder).downvoteButton.clearColorFilter(); + + if (((CommentViewHolder) viewHolder).upvoteButton.getColorFilter() == null) { + ((CommentViewHolder) viewHolder).upvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.colorPrimary), android.graphics.PorterDuff.Mode.SRC_IN); + if(isDownvotedBefore) { + ((CommentViewHolder) viewHolder).scoreTextView.setText(Integer.toString(commentItem.getScore() + 2)); + } else { + ((CommentViewHolder) viewHolder).scoreTextView.setText(Integer.toString(commentItem.getScore() + 1)); + } + + VoteThing.voteThing(mOauthRetrofit,mSharedPreferences, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position1) { + commentItem.setVoteType(1); + if(isDownvotedBefore) { + commentItem.setScore(commentItem.getScore() + 2); + } else { + commentItem.setScore(commentItem.getScore() + 1); + } + } + + @Override + public void onVoteThingFail(int position1) { + Toast.makeText(mContext, "Cannot upvote this comment", Toast.LENGTH_SHORT).show(); + ((CommentViewHolder) viewHolder).upvoteButton.clearColorFilter(); + ((CommentViewHolder) viewHolder).scoreTextView.setText(Integer.toString(commentItem.getScore())); + ((CommentViewHolder) viewHolder).downvoteButton.setColorFilter(minusButtonColorFilter); + } + }, commentItem.getFullName(), RedditUtils.DIR_UPVOTE, ((CommentViewHolder) viewHolder).getAdapterPosition()); + } else { + //Upvoted before + ((CommentViewHolder) viewHolder).upvoteButton.clearColorFilter(); + ((CommentViewHolder) viewHolder).scoreTextView.setText(Integer.toString(commentItem.getScore() - 1)); + + VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position1) { + commentItem.setVoteType(0); + commentItem.setScore(commentItem.getScore() - 1); + } + + @Override + public void onVoteThingFail(int position1) { + Toast.makeText(mContext, "Cannot unvote this comment", Toast.LENGTH_SHORT).show(); + ((CommentViewHolder) viewHolder).scoreTextView.setText(Integer.toString(commentItem.getScore() + 1)); + ((CommentViewHolder) viewHolder).upvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.colorPrimary), android.graphics.PorterDuff.Mode.SRC_IN); + commentItem.setScore(commentItem.getScore() + 1); + } + }, commentItem.getFullName(), RedditUtils.DIR_UNVOTE, ((CommentViewHolder) viewHolder).getAdapterPosition()); + } + }); + + ((CommentViewHolder) viewHolder).downvoteButton.setOnClickListener(view -> { + final boolean isUpvotedBefore = ((CommentViewHolder) viewHolder).upvoteButton.getColorFilter() != null; + + final ColorFilter upvoteButtonColorFilter = ((CommentViewHolder) viewHolder).upvoteButton.getColorFilter(); + ((CommentViewHolder) viewHolder).upvoteButton.clearColorFilter(); + + if (((CommentViewHolder) viewHolder).downvoteButton.getColorFilter() == null) { + ((CommentViewHolder) viewHolder).downvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN); + if (isUpvotedBefore) { + ((CommentViewHolder) viewHolder).scoreTextView.setText(Integer.toString(commentItem.getScore() - 2)); + } else { + ((CommentViewHolder) viewHolder).scoreTextView.setText(Integer.toString(commentItem.getScore() - 1)); + } + + VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position12) { + commentItem.setVoteType(-1); + if(isUpvotedBefore) { + commentItem.setScore(commentItem.getScore() - 2); + } else { + commentItem.setScore(commentItem.getScore() - 1); + } + } + + @Override + public void onVoteThingFail(int position12) { + Toast.makeText(mContext, "Cannot downvote this comment", Toast.LENGTH_SHORT).show(); + ((CommentViewHolder) viewHolder).downvoteButton.clearColorFilter(); + ((CommentViewHolder) viewHolder).scoreTextView.setText(Integer.toString(commentItem.getScore())); + ((CommentViewHolder) viewHolder).upvoteButton.setColorFilter(upvoteButtonColorFilter); + } + }, commentItem.getFullName(), RedditUtils.DIR_DOWNVOTE, viewHolder.getAdapterPosition()); + } else { + //Down voted before + ((CommentViewHolder) viewHolder).downvoteButton.clearColorFilter(); + ((CommentViewHolder) viewHolder).scoreTextView.setText(Integer.toString(commentItem.getScore() + 1)); + + VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position12) { + commentItem.setVoteType(0); + commentItem.setScore(commentItem.getScore()); + } + + @Override + public void onVoteThingFail(int position12) { + Toast.makeText(mContext, "Cannot unvote this comment", Toast.LENGTH_SHORT).show(); + ((CommentViewHolder) viewHolder).downvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) viewHolder).scoreTextView.setText(Integer.toString(commentItem.getScore())); + commentItem.setScore(commentItem.getScore()); + } + }, commentItem.getFullName(), RedditUtils.DIR_UNVOTE, viewHolder.getAdapterPosition()); + } + }); + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + ((CommentMultiLevelRecyclerViewAdapter.CommentViewHolder) holder).expandButton.setVisibility(View.GONE); + ((CommentMultiLevelRecyclerViewAdapter.CommentViewHolder) holder).loadMoreCommentsProgressBar.setVisibility(View.GONE); + } + + @Override + public int getItemCount() { + if(hasExtraRow()) { + return super.getItemCount() + 1; + } + return super.getItemCount(); + } + + private boolean hasExtraRow() { + return networkState != null && networkState.getStatus() != NetworkState.Status.SUCCESS; + } + + void setNetworkState(NetworkState newNetworkState) { + NetworkState previousState = this.networkState; + boolean previousExtraRow = hasExtraRow(); + this.networkState = newNetworkState; + boolean newExtraRow = hasExtraRow(); + if (previousExtraRow != newExtraRow) { + if (previousExtraRow) { + notifyItemRemoved(super.getItemCount()); + } else { + notifyItemInserted(super.getItemCount()); + } + } else if (newExtraRow && !previousState.equals(newNetworkState)) { + notifyItemChanged(getItemCount() - 1); + } + } + + private void setExpandButton(ImageView expandButton, boolean isExpanded) { + // set the icon based on the current state + expandButton.setVisibility(View.VISIBLE); + expandButton.setImageResource(isExpanded ? R.drawable.ic_expand_less_black_20dp : R.drawable.ic_expand_more_black_20dp); + } + + class CommentViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.author_text_view_item_post_comment) TextView authorTextView; + @BindView(R.id.comment_time_text_view_item_post_comment) TextView commentTimeTextView; + @BindView(R.id.comment_markdown_view_item_post_comment) MarkwonView commentMarkdownView; + @BindView(R.id.plus_button_item_post_comment) ImageView upvoteButton; + @BindView(R.id.score_text_view_item_post_comment) TextView scoreTextView; + @BindView(R.id.minus_button_item_post_comment) ImageView downvoteButton; + @BindView(R.id.expand_button_item_post_comment) ImageView expandButton; + @BindView(R.id.load_more_comments_progress_bar) ProgressBar loadMoreCommentsProgressBar; + @BindView(R.id.reply_button_item_post_comment) ImageView replyButton; + @BindView(R.id.vertical_block_item_post_comment) View verticalBlock; + + CommentViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentDataSource.java new file mode 100644 index 00000000..1c06ba04 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentDataSource.java @@ -0,0 +1,195 @@ +package ml.docilealligator.infinityforreddit; + +import android.arch.lifecycle.MutableLiveData; +import android.arch.paging.PageKeyedDataSource; +import android.support.annotation.NonNull; +import android.util.Log; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class CommentDataSource extends PageKeyedDataSource<String, Post> { + interface OnCommentFetchedCallback { + void hasComment(); + void noComment(); + } + + private Retrofit retrofit; + private Locale locale; + private String subredditNamePrefixed; + private String article; + private String comment; + private boolean isPost; + private OnCommentFetchedCallback onCommentFetchedCallback; + + private MutableLiveData<NetworkState> paginationNetworkStateLiveData; + private MutableLiveData<NetworkState> initialLoadStateLiveData; + + private LoadInitialParams<String> initialParams; + private LoadInitialCallback<String, Post> initialCallback; + private LoadParams<String> params; + private LoadCallback<String, Post> callback; + + private String mParentId; + + CommentDataSource(Retrofit retrofit, Locale locale, String subredditNamePrefixed, String article, + String comment, boolean isPost, OnCommentFetchedCallback onCommentFetchedCallback) { + this.retrofit = retrofit; + this.locale = locale; + this.subredditNamePrefixed = subredditNamePrefixed; + this.article = article; + this.comment = comment; + this.isPost = isPost; + paginationNetworkStateLiveData = new MutableLiveData(); + initialLoadStateLiveData = new MutableLiveData(); + this.onCommentFetchedCallback = onCommentFetchedCallback; + } + + MutableLiveData getPaginationNetworkStateLiveData() { + return paginationNetworkStateLiveData; + } + + MutableLiveData getInitialLoadStateLiveData() { + return initialLoadStateLiveData; + } + + @Override + public void loadInitial(@NonNull LoadInitialParams<String> params, @NonNull LoadInitialCallback<String, Post> callback) { + initialParams = params; + initialCallback = callback; + + initialLoadStateLiveData.postValue(NetworkState.LOADING); + + RedditAPI api = retrofit.create(RedditAPI.class); + + 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) { + if(response.isSuccessful()) { + ParseComment.parseComment(response.body(), new ArrayList<>(), locale, isPost, + 0, 1, new ParseComment.ParseCommentListener() { + @Override + public void onParseCommentSuccess(List<?> commentData, String parentId, + String commaSeparatedChildren) { + if(commentData.size() > 0) { + onCommentFetchedCallback.hasComment(); + mParentId = parentId; + } else { + onCommentFetchedCallback.noComment(); + } + + callback.onResult((List<Post>) commentData, null, commaSeparatedChildren); + initialLoadStateLiveData.postValue(NetworkState.LOADED); + } + + @Override + public void onParseCommentFailed() { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing comment")); + } + }); + } else { + Log.i("comment call failed", response.message()); + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing comment")); + } + } + + @Override + public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetching comment")); + } + }); + } + + @Override + public void loadBefore(@NonNull LoadParams<String> params, @NonNull LoadCallback<String, Post> callback) { + + } + + @Override + public void loadAfter(@NonNull LoadParams<String> params, @NonNull LoadCallback<String, Post> callback) { + this.params = params; + this.callback = callback; + + if(params.key.equals("null") || params.key.equals("")) { + return; + } + + paginationNetworkStateLiveData.postValue(NetworkState.LOADING); + + RedditAPI api = retrofit.create(RedditAPI.class); + + Call<String> moreChildrenBasicInfo = api.getMoreChildren(mParentId, params.key); + moreChildrenBasicInfo.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>() { + @Override + public void onResponse(Call<String> call, Response<String> response) { + if(response.isSuccessful()) { + ParseComment.parseMoreComment(response.body(), new ArrayList<>(), locale, isPost, + 0, 0, new ParseComment.ParseCommentListener() { + @Override + public void onParseCommentSuccess(List<?> commentData, String parentId, + String commaSeparatedChildren) { + callback.onResult((List<Post>) commentData, null); + paginationNetworkStateLiveData.postValue(NetworkState.LOADED); + } + + @Override + public void onParseCommentFailed() { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); + } + }); + } else { + Log.i("comment call failed", response.message()); + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); + } + } + + @Override + public void onFailure(Call<String> call, Throwable t) { + String errorMessage = t == null ? "unknown error" : t.getMessage(); + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); + } + }); + } + + @Override + public void onParseMoreCommentBasicInfoFailed() { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Parse more comments basic info failed")); + } + }); + } else { + Log.i("comment call failed", response.message()); + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); + } + } + + @Override + public void onFailure(Call<String> call, Throwable t) { + String errorMessage = t == null ? "unknown error" : t.getMessage(); + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); + } + }); + } + + void retry() { + loadInitial(initialParams, initialCallback); + } + + void retryLoadingMore() { + loadAfter(params, callback); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentDataSourceFactory.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentDataSourceFactory.java new file mode 100644 index 00000000..2c149dbe --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentDataSourceFactory.java @@ -0,0 +1,49 @@ +package ml.docilealligator.infinityforreddit; + +import android.arch.lifecycle.MutableLiveData; +import android.arch.paging.DataSource; + +import java.util.Locale; + +import retrofit2.Retrofit; + +public class CommentDataSourceFactory extends DataSource.Factory { + private Retrofit retrofit; + private Locale locale; + private String subredditNamePrefixed; + private String article; + private String comment; + private boolean isPost; + private CommentDataSource.OnCommentFetchedCallback onCommentFetchedCallback; + + private CommentDataSource commentDataSource; + private MutableLiveData<CommentDataSource> commentDataSourceMutableLiveData; + + CommentDataSourceFactory(Retrofit retrofit, Locale locale, String subredditNamePrefixed, + String article, String comment, boolean isPost, + CommentDataSource.OnCommentFetchedCallback onCommentFetchedCallback) { + this.retrofit = retrofit; + this.locale = locale; + this.subredditNamePrefixed = subredditNamePrefixed; + this.article = article; + this.comment = comment; + this.isPost = isPost; + commentDataSourceMutableLiveData = new MutableLiveData<>(); + this.onCommentFetchedCallback = onCommentFetchedCallback; + } + + @Override + public DataSource create() { + commentDataSource = new CommentDataSource(retrofit, locale, subredditNamePrefixed, article, comment, isPost, onCommentFetchedCallback); + commentDataSourceMutableLiveData.postValue(commentDataSource); + return commentDataSource; + } + + public MutableLiveData<CommentDataSource> getCommentDataSourceMutableLiveData() { + return commentDataSourceMutableLiveData; + } + + CommentDataSource getCommentDataSource() { + return commentDataSource; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentMultiLevelRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentMultiLevelRecyclerViewAdapter.java index 935826c6..719bd833 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentMultiLevelRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentMultiLevelRecyclerViewAdapter.java @@ -115,9 +115,11 @@ class CommentMultiLevelRecyclerViewAdapter extends MultiLevelAdapter { @Override public void onFetchCommentSuccess(String response) { ParseComment.parseComment(response, new ArrayList<CommentData>(), - locale, false, commentItem.getDepth(), new ParseComment.ParseCommentListener() { + locale, false, commentItem.getDepth(), 1, + new ParseComment.ParseCommentListener() { @Override - public void onParseCommentSuccess(List<?> commentData, int moreCommentCount) { + public void onParseCommentSuccess(List<?> commentData, + String parentId, String commaSeparatedChildren) { commentItem.addChildren((List<RecyclerViewItem>) commentData); ((CommentViewHolder) holder).loadMoreCommentsProgressBar .setVisibility(View.GONE); @@ -127,7 +129,7 @@ class CommentMultiLevelRecyclerViewAdapter extends MultiLevelAdapter { } @Override - public void onParseCommentFail() { + public void onParseCommentFailed() { ((CommentViewHolder) holder).loadMoreCommentsProgressBar .setVisibility(View.GONE); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentViewModel.java new file mode 100644 index 00000000..12d28818 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentViewModel.java @@ -0,0 +1,90 @@ +package ml.docilealligator.infinityforreddit; + +import android.arch.lifecycle.LiveData; +import android.arch.lifecycle.Transformations; +import android.arch.lifecycle.ViewModel; +import android.arch.lifecycle.ViewModelProvider; +import android.arch.paging.LivePagedListBuilder; +import android.arch.paging.PagedList; +import android.support.annotation.NonNull; + +import java.util.Locale; + +import retrofit2.Retrofit; + +public class CommentViewModel extends ViewModel { + private CommentDataSourceFactory commentDataSourceFactory; + private LiveData<NetworkState> paginationNetworkState; + private LiveData<NetworkState> initialLoadingState; + private LiveData<PagedList<CommentData>> comments; + + public CommentViewModel(Retrofit retrofit, Locale locale, String subredditNamePrefixed, + String article, String comment, boolean isPost, + CommentDataSource.OnCommentFetchedCallback onCommentFetchedCallback) { + commentDataSourceFactory = new CommentDataSourceFactory(retrofit, locale, subredditNamePrefixed, article, comment, isPost, onCommentFetchedCallback); + + initialLoadingState = Transformations.switchMap(commentDataSourceFactory.getCommentDataSourceMutableLiveData(), + dataSource -> dataSource.getInitialLoadStateLiveData()); + paginationNetworkState = Transformations.switchMap(commentDataSourceFactory.getCommentDataSourceMutableLiveData(), + dataSource -> dataSource.getPaginationNetworkStateLiveData()); + PagedList.Config pagedListConfig = + (new PagedList.Config.Builder()) + .setEnablePlaceholders(false) + .setPageSize(25) + .build(); + + comments = (new LivePagedListBuilder(commentDataSourceFactory, pagedListConfig)).build(); + } + + LiveData<PagedList<CommentData>> getComments() { + return comments; + } + + LiveData<NetworkState> getPaginationNetworkState() { + return paginationNetworkState; + } + + LiveData<NetworkState> getInitialLoadingState() { + return initialLoadingState; + } + + void refresh() { + commentDataSourceFactory.getCommentDataSource().invalidate(); + } + + void retry() { + commentDataSourceFactory.getCommentDataSource().retry(); + } + + void retryLoadingMore() { + commentDataSourceFactory.getCommentDataSource().retryLoadingMore(); + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + private Retrofit retrofit; + private Locale locale; + private String subredditNamePrefixed; + private String article; + private String comment; + private boolean isPost; + private CommentDataSource.OnCommentFetchedCallback onCommentFetchedCallback; + + public Factory(Retrofit retrofit, Locale locale, String subredditNamePrefixed, + String article, String comment, boolean isPost, + CommentDataSource.OnCommentFetchedCallback onCommentFetchedCallback) { + this.retrofit = retrofit; + this.locale = locale; + this.subredditNamePrefixed = subredditNamePrefixed; + this.article = article; + this.comment = comment; + this.isPost = isPost; + this.onCommentFetchedCallback = onCommentFetchedCallback; + } + + @NonNull + @Override + public <T extends ViewModel> T create(@NonNull Class<T> modelClass) { + return (T) new CommentViewModel(retrofit, locale, subredditNamePrefixed, article, comment, isPost, onCommentFetchedCallback); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java index c168e71a..1a219619 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java @@ -68,4 +68,7 @@ public class JSONUtils { public static final String IS_GOLD_KEY = "is_gold"; public static final String IS_FRIEND_KEY = "is_friend"; static final String KIND_KEY = "kind"; + static final String JSON_KEY = "json"; + static final String THINGS_KEY = "things"; + static final String PARENT_ID_KEY = "parent_id"; } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseComment.java index ff87536c..54b4af1d 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseComment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseComment.java @@ -15,73 +15,118 @@ import java.util.Locale; class ParseComment { interface ParseCommentListener { - void onParseCommentSuccess(List<?> commentData, int moreCommentCount); - void onParseCommentFail(); + void onParseCommentSuccess(List<?> commentData, String parentId, String commaSeparatedChildren); + void onParseCommentFailed(); + } + + interface ParseMoreCommentBasicInfoListener { + void onParseMoreCommentBasicInfoSuccess(String commaSeparatedChildrenId); + void onParseMoreCommentBasicInfoFailed(); } static void parseComment(String response, ArrayList<CommentData> commentData, Locale locale, - boolean isPost, int parentDepth, ParseCommentListener parseCommentListener) { - new ParseCommentAsyncTask(response, commentData, locale, isPost, parentDepth, parseCommentListener).execute(); + boolean isPost, int parentDepth, int childrenStartIndex, ParseCommentListener parseCommentListener) { + try { + JSONArray childrenArray = new JSONArray(response); + + if(isPost) { + childrenArray = childrenArray.getJSONObject(childrenStartIndex).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + } else { + childrenArray = childrenArray.getJSONObject(childrenStartIndex).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY) + .getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getJSONObject(JSONUtils.REPLIES_KEY) + .getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + } + new ParseCommentAsyncTask(childrenArray, commentData, locale, isPost, parentDepth, childrenStartIndex, parseCommentListener).execute(); + } catch (JSONException e) { + e.printStackTrace(); + Log.i("comment json error", e.getMessage()); + parseCommentListener.onParseCommentFailed(); + } + } + + static void parseMoreCommentBasicInfo(String response, ParseMoreCommentBasicInfoListener parseMoreCommentBasicInfoListener) { + new ParseMoreCommentBasicInfoAsyncTask(response, parseMoreCommentBasicInfoListener).execute(); + } + + static void parseMoreComment(String response, ArrayList<CommentData> commentData, Locale locale, + boolean isPost, int parentDepth, int childrenStartIndex, ParseCommentListener parseCommentListener) { + try { + JSONArray childrenArray = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + new ParseCommentAsyncTask(childrenArray, commentData, locale, isPost, parentDepth, childrenStartIndex, parseCommentListener).execute(); + } catch (JSONException e) { + e.printStackTrace(); + Log.i("comment json error", e.getMessage()); + parseCommentListener.onParseCommentFailed(); + } } private static class ParseCommentAsyncTask extends AsyncTask<Void, Void, Void> { - private JSONArray jsonResponse; + private JSONArray comments; private ArrayList<CommentData> commentData; private ArrayList<CommentData> newcommentData; + private StringBuilder commaSeparatedChildren; private Locale locale; private boolean isPost; private int parentDepth; + private int childrenStartIndex; private ParseCommentListener parseCommentListener; private boolean parseFailed; - private int moreCommentCount; - - ParseCommentAsyncTask(String response, ArrayList<CommentData> commentData, Locale locale, - boolean isPost, int parentDepth, ParseCommentListener parseCommentListener){ - try { - jsonResponse = new JSONArray(response); - this.commentData = commentData; - newcommentData = new ArrayList<>(); - this.locale = locale; - this.isPost = isPost; - this.parentDepth = parentDepth; - this.parseCommentListener = parseCommentListener; - parseFailed = false; - } catch (JSONException e) { - Log.i("comment json error", e.getMessage()); - parseCommentListener.onParseCommentFail(); - } + private String parentId; + + ParseCommentAsyncTask(JSONArray comments, ArrayList<CommentData> commentData, Locale locale, + boolean isPost, int parentDepth, int childrenStartIndex, ParseCommentListener parseCommentListener){ + this.comments = comments; + this.commentData = commentData; + newcommentData = new ArrayList<>(); + commaSeparatedChildren = new StringBuilder(); + this.locale = locale; + this.isPost = isPost; + this.parentDepth = parentDepth; + this.childrenStartIndex = childrenStartIndex; + parseFailed = false; + this.parseCommentListener = parseCommentListener; } @Override protected Void doInBackground(Void... voids) { try { - moreCommentCount = 0; int actualCommentLength; - JSONArray allComments; + ArrayList<String> children = new ArrayList<>(); - if(isPost) { - allComments = jsonResponse.getJSONObject(1).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + /*if(isPost) { + allComments = comments.getJSONObject(childrenStartIndex).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); } else { - allComments = jsonResponse.getJSONObject(1).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY) + allComments = comments.getJSONObject(childrenStartIndex).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY) .getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getJSONObject(JSONUtils.REPLIES_KEY) .getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); - } - if(allComments.length() == 0) { + }*/ + if(comments.length() == 0) { return null; } - JSONObject more = allComments.getJSONObject(allComments.length() - 1).getJSONObject(JSONUtils.DATA_KEY); + JSONObject more = comments.getJSONObject(comments.length() - 1).getJSONObject(JSONUtils.DATA_KEY); //Maybe children contain only comments and no more info if(more.has(JSONUtils.COUNT_KEY)) { - moreCommentCount = more.getInt(JSONUtils.COUNT_KEY); - actualCommentLength = allComments.length() - 1; + JSONArray childrenArray = more.getJSONArray(JSONUtils.CHILDREN_KEY); + + parentId = more.getString(JSONUtils.PARENT_ID_KEY); + for(int i = 0; i < childrenArray.length(); i++) { + children.add(childrenArray.getString(i)); + } + + for(String c : children) { + commaSeparatedChildren.append(c).append(","); + } + commaSeparatedChildren.deleteCharAt(commaSeparatedChildren.length() - 1); + + actualCommentLength = comments.length() - 1; } else { - actualCommentLength = allComments.length(); + actualCommentLength = comments.length(); } for (int i = 0; i < actualCommentLength; i++) { - JSONObject data = allComments.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); + JSONObject data = comments.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); String id = data.getString(JSONUtils.ID_KEY); String fullName = data.getString(JSONUtils.LINK_ID_KEY); String author = data.getString(JSONUtils.AUTHOR_KEY); @@ -100,7 +145,12 @@ class ParseComment { String formattedSubmitTime = new SimpleDateFormat("MMM d, YYYY, HH:mm", locale).format(submitTimeCalendar.getTime()); - int depth = data.getInt(JSONUtils.DEPTH_KEY) + parentDepth; + int depth; + if(data.has(JSONUtils.DEPTH_KEY)) { + depth = data.getInt(JSONUtils.DEPTH_KEY) + parentDepth; + } else { + depth = parentDepth; + } boolean collapsed = data.getBoolean(JSONUtils.COLLAPSED_KEY); boolean hasReply = !(data.get(JSONUtils.REPLIES_KEY) instanceof String); @@ -117,9 +167,55 @@ class ParseComment { protected void onPostExecute(Void aVoid) { if(!parseFailed) { commentData.addAll(newcommentData); - parseCommentListener.onParseCommentSuccess(commentData, moreCommentCount); + parseCommentListener.onParseCommentSuccess(commentData, parentId, commaSeparatedChildren.toString()); + } else { + parseCommentListener.onParseCommentFailed(); + } + } + } + + private static class ParseMoreCommentBasicInfoAsyncTask extends AsyncTask<Void, Void, Void> { + private JSONArray children; + private StringBuilder commaSeparatedChildren; + private ParseMoreCommentBasicInfoListener parseMoreCommentBasicInfoListener; + private boolean parseFailed; + + ParseMoreCommentBasicInfoAsyncTask(String response, ParseMoreCommentBasicInfoListener parseMoreCommentBasicInfoListener) { + this.parseMoreCommentBasicInfoListener = parseMoreCommentBasicInfoListener; + try { + children = new JSONObject(response).getJSONObject(JSONUtils.JSON_KEY) + .getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.THINGS_KEY); + commaSeparatedChildren = new StringBuilder(); + } catch (JSONException e) { + parseMoreCommentBasicInfoListener.onParseMoreCommentBasicInfoFailed(); + e.printStackTrace(); + } + } + + @Override + protected Void doInBackground(Void... voids) { + try { + for(int i = 0; i < children.length(); i++) { + commaSeparatedChildren.append(children.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.ID_KEY)); + commaSeparatedChildren.append(","); + } + commaSeparatedChildren.deleteCharAt(commaSeparatedChildren.length() - 1); + parseFailed = false; + } catch (JSONException e) { + parseMoreCommentBasicInfoListener.onParseMoreCommentBasicInfoFailed(); + parseFailed = true; + e.printStackTrace(); + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if(!parseFailed) { + parseMoreCommentBasicInfoListener.onParseMoreCommentBasicInfoSuccess(commaSeparatedChildren.toString()); } else { - parseCommentListener.onParseCommentFail(); + parseMoreCommentBasicInfoListener.onParseMoreCommentBasicInfoFailed(); } } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java index 9ff04e03..6f374fb9 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java @@ -120,7 +120,7 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { Call<String> bestPost = api.getBestPosts(null, RedditUtils.getOAuthHeader(accessToken)); bestPost.enqueue(new Callback<String>() { @Override - public void onResponse(Call<String> call, retrofit2.Response<String> response) { + public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) { if (response.isSuccessful()) { ParsePost.parsePost(response.body(), locale, new ParsePost.ParsePostListener() { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java index 3a697832..39344b73 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java @@ -53,9 +53,15 @@ public interface RedditAPI { @POST("api/subscribe") Call<String> subredditSubscription(@HeaderMap Map<String, String> headers, @FieldMap Map<String, String> params); - @PUT("/api/v1/me/friends/username") + @PUT("api/v1/me/friends/username") Call<String> subscribeUser(@HeaderMap Map<String, String> headers); - @DELETE("/api/v1/me/friends/username") + @DELETE("api/v1/me/friends/username") Call<String> unsubscribeUser(@HeaderMap Map<String, String> headers); + + @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/RedditUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditUtils.java index aa9f0ab3..d598f684 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditUtils.java @@ -12,7 +12,7 @@ import java.util.Map; public class RedditUtils { static final String OAUTH_URL ="https://www.reddit.com/api/v1/authorize.compact"; static final String OAUTH_API_BASE_URI = "https://oauth.reddit.com"; - static final String API_BASE_URI = "https://api.reddit.com"; + static final String API_BASE_URI = "https://www.reddit.com"; static final String CLIENT_ID_KEY = "client_id"; static final String CLIENT_ID = ""; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java index 34601c3d..854a75dd 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java @@ -1,5 +1,6 @@ package ml.docilealligator.infinityforreddit; +import android.arch.lifecycle.ViewModelProviders; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.ColorFilter; @@ -18,6 +19,7 @@ import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.CardView; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; import android.view.MenuItem; import android.view.View; import android.widget.ImageView; @@ -36,12 +38,8 @@ import com.bumptech.glide.request.RequestListener; import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.target.Target; import com.lsjwzh.widget.materialloadingprogressbar.CircleProgressBar; -import com.multilevelview.MultiLevelRecyclerView; import com.santalu.aspectratioimageview.AspectRatioImageView; -import java.util.ArrayList; -import java.util.List; - import javax.inject.Inject; import javax.inject.Named; @@ -65,7 +63,6 @@ public class ViewPostDetailActivity extends AppCompatActivity { private int orientation; private String orientationState = "OS"; - private int mMoreCommentCount; private Post mPost; @BindView(R.id.coordinator_layout_view_post_detail) CoordinatorLayout mCoordinatorLayout; @@ -94,7 +91,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { @BindView(R.id.comment_progress_bar_view_post_detail) CircleProgressBar mCommentProgressbar; @BindView(R.id.comment_card_view_view_post_detail) CardView mCommentCardView; - @BindView(R.id.recycler_view_view_post_detail) MultiLevelRecyclerView mRecyclerView; + @BindView(R.id.recycler_view_view_post_detail) RecyclerView mRecyclerView; @BindView(R.id.no_comment_wrapper_linear_layout_view_post_detail) LinearLayout mNoCommentWrapperLinearLayout; @BindView(R.id.no_comment_image_view_view_post_detail) ImageView mNoCommentImageView; @@ -330,7 +327,32 @@ public class ViewPostDetailActivity extends AppCompatActivity { } break; } - queryComment(); + //queryComment(); + + CommentAdapter adapter = new CommentAdapter(this, mRetrofit, mOauthRetrofit, mSharedPreferences, + mRecyclerView, mPost.getSubredditNamePrefixed(), mPost.getId(), getResources().getConfiguration().locale); + + CommentViewModel.Factory factory = new CommentViewModel.Factory(mRetrofit, getResources().getConfiguration().locale, + mPost.getSubredditNamePrefixed(), mPost.getId(), null, true, new CommentDataSource.OnCommentFetchedCallback() { + @Override + public void hasComment() { + mCommentProgressbar.setVisibility(View.GONE); + /*mRecyclerView.removeItemClickListeners(); + mRecyclerView.setToggleItemOnClick(false); + mRecyclerView.setAccordion(false);*/ + mRecyclerView.setAdapter(adapter); + mCommentCardView.setVisibility(View.VISIBLE); + } + + @Override + public void noComment() { + + } + }); + + CommentViewModel commentViewModel = ViewModelProviders.of(this, factory).get(CommentViewModel.class); + commentViewModel.getComments().observe(this, posts -> adapter.submitList(posts)); + mUpvoteButton.setOnClickListener(view -> { final boolean isDownvotedBefore = mDownvoteButton.getColorFilter() != null; @@ -445,7 +467,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { }); } - private void queryComment() { + /*private void queryComment() { mCommentProgressbar.setVisibility(View.VISIBLE); mNoCommentWrapperLinearLayout.setVisibility(View.GONE); FetchComment.fetchComment(mRetrofit, mPost.getSubredditNamePrefixed(), mPost.getId(), @@ -453,12 +475,12 @@ public class ViewPostDetailActivity extends AppCompatActivity { @Override public void onFetchCommentSuccess(String response) { ParseComment.parseComment(response, new ArrayList<CommentData>(), - getResources().getConfiguration().locale, true, 0, + getResources().getConfiguration().locale, true, 0, 1, new ParseComment.ParseCommentListener() { @Override - public void onParseCommentSuccess(List<?> commentData, int moreCommentCount) { + public void onParseCommentSuccess(List<?> commentData, + String parentId, String commaSeparatedChildren) { mCommentProgressbar.setVisibility(View.GONE); - mMoreCommentCount = moreCommentCount; if (commentData.size() > 0) { CommentMultiLevelRecyclerViewAdapter adapter = new CommentMultiLevelRecyclerViewAdapter( ViewPostDetailActivity.this, mRetrofit, mOauthRetrofit, @@ -477,7 +499,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { } @Override - public void onParseCommentFail() { + public void onParseCommentFailed() { mCommentProgressbar.setVisibility(View.GONE); showRetrySnackbar(); } @@ -490,7 +512,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { showRetrySnackbar(); } }); - } + }*/ private void loadImage() { RequestBuilder imageRequestBuilder = glide.load(mPost.getPreviewUrl()) @@ -549,7 +571,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { snackbar.setAction(R.string.retry, new View.OnClickListener() { @Override public void onClick(View view) { - queryComment(); + //queryComment(); } }); snackbar.show(); diff --git a/app/src/main/res/layout/activity_view_post_detail.xml b/app/src/main/res/layout/activity_view_post_detail.xml index 103edf40..e32ac9ab 100644 --- a/app/src/main/res/layout/activity_view_post_detail.xml +++ b/app/src/main/res/layout/activity_view_post_detail.xml @@ -293,7 +293,7 @@ android:textColor="#000000" android:textSize="18sp" /> - <com.multilevelview.MultiLevelRecyclerView + <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view_view_post_detail" android:layout_width="match_parent" android:layout_height="wrap_content" /> diff --git a/build.gradle b/build.gradle index c175ad82..af7d754f 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.3.0' + classpath 'com.android.tools.build:gradle:3.3.1' // NOTE: Do not place your application dependencies here; they belong |