aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.idea/caches/build_file_checksums.serbin533 -> 533 bytes
-rw-r--r--.idea/caches/gradle_models.serbin268197 -> 268319 bytes
-rw-r--r--app/build.gradle2
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/CommentAdapter.java343
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/CommentDataSource.java195
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/CommentDataSourceFactory.java49
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/CommentMultiLevelRecyclerViewAdapter.java8
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/CommentViewModel.java90
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java3
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/ParseComment.java170
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java2
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/RedditAPI.java10
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/RedditUtils.java2
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java50
-rw-r--r--app/src/main/res/layout/activity_view_post_detail.xml2
-rw-r--r--build.gradle2
16 files changed, 867 insertions, 61 deletions
diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
index 164c2f2d..62203ae9 100644
--- a/.idea/caches/build_file_checksums.ser
+++ b/.idea/caches/build_file_checksums.ser
Binary files differ
diff --git a/.idea/caches/gradle_models.ser b/.idea/caches/gradle_models.ser
index 60459acd..62d6a116 100644
--- a/.idea/caches/gradle_models.ser
+++ b/.idea/caches/gradle_models.ser
Binary files differ
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