From 25f2a35d227b299ff202969f614eab914bf8f6ec Mon Sep 17 00:00:00 2001
From: Alex Ning <chineseperson5@gmail.com>
Date: Tue, 18 Jun 2019 00:01:15 +0800
Subject: Reimplemented parsing comments using recursion to parse all the child
 comments. Reimplemented CommentRecyclerView (some methods need proper
 implementation. Minor bugs fixed.

---
 .../infinityforreddit/CommentActivity.java         |   2 -
 .../infinityforreddit/CommentData.java             | 232 ++++++++++++-
 .../CommentMultiLevelRecyclerViewAdapter.java      | 322 -----------------
 .../CommentRecyclerViewAdapter.java                | 379 +++++++++++++++++++++
 .../infinityforreddit/FetchComment.java            |  21 +-
 .../infinityforreddit/ParseComment.java            |  99 +++---
 .../infinityforreddit/ViewPostDetailActivity.java  |  28 +-
 7 files changed, 687 insertions(+), 396 deletions(-)
 delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CommentMultiLevelRecyclerViewAdapter.java
 create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CommentRecyclerViewAdapter.java

(limited to 'app/src/main/java/ml/docilealligator')

diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentActivity.java
index 9bf4ebc7..eef1d810 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentActivity.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentActivity.java
@@ -3,7 +3,6 @@ package ml.docilealligator.infinityforreddit;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.os.Bundle;
-import android.util.Log;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.widget.EditText;
@@ -70,7 +69,6 @@ public class CommentActivity extends AppCompatActivity {
             toolbar.setTitle(getString(R.string.comment_activity_label_is_replying));
         }
 
-        Log.i("fullname", parentFullname);
         setSupportActionBar(toolbar);
     }
 
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentData.java
index 57e95bae..043c0071 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentData.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentData.java
@@ -3,14 +3,15 @@ package ml.docilealligator.infinityforreddit;
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import com.multilevelview.models.RecyclerViewItem;
+import java.util.ArrayList;
 
-class CommentData extends RecyclerViewItem implements Parcelable {
+class CommentData implements Parcelable {
     private String id;
     private String fullName;
     private String author;
     private String commentTime;
     private String commentContent;
+    private String parentId;
     private int score;
     private int voteType;
     private boolean isSubmitter;
@@ -19,16 +20,217 @@ class CommentData extends RecyclerViewItem implements Parcelable {
     private boolean collapsed;
     private boolean hasReply;
     private boolean scoreHidden;
+    private boolean isExpanded;
+    private ArrayList<CommentData> children;
+    private ArrayList<String> moreChildrenIds;
 
     CommentData(String id, String fullName, String author, String commentTime, String commentContent,
-                int score, boolean isSubmitter, String permalink, int depth, boolean collapsed,
-                boolean hasReply, boolean scoreHidden) {
+                String parentId, int score, boolean isSubmitter, String permalink, int depth,
+                boolean collapsed, boolean hasReply, boolean scoreHidden) {
+        this.id = id;
+        this.fullName = fullName;
+        this.author = author;
+        this.commentTime = commentTime;
+        this.commentContent = commentContent;
+        this.parentId = parentId;
+        this.score = score;
+        this.isSubmitter = isSubmitter;
+        this.permalink = RedditUtils.API_BASE_URI + permalink;
+        this.depth = depth;
+        this.collapsed = collapsed;
+        this.hasReply = hasReply;
+        this.scoreHidden = scoreHidden;
+        this.isExpanded = false;
+    }
+
+    protected CommentData(Parcel in) {
+        id = in.readString();
+        fullName = in.readString();
+        author = in.readString();
+        commentTime = in.readString();
+        commentContent = in.readString();
+        parentId = in.readString();
+        score = in.readInt();
+        voteType = in.readInt();
+        isSubmitter = in.readByte() != 0;
+        permalink = in.readString();
+        depth = in.readInt();
+        collapsed = in.readByte() != 0;
+        hasReply = in.readByte() != 0;
+        scoreHidden = in.readByte() != 0;
+        isExpanded = in.readByte() != 0;
+        in.readStringList(moreChildrenIds);
+    }
+
+    public static final Creator<CommentData> CREATOR = new Creator<CommentData>() {
+        @Override
+        public CommentData createFromParcel(Parcel in) {
+            return new CommentData(in);
+        }
+
+        @Override
+        public CommentData[] newArray(int size) {
+            return new CommentData[size];
+        }
+    };
+
+    public String getId() {
+        return id;
+    }
+
+    public String getFullName() {
+        return fullName;
+    }
+
+    public String getAuthor() {
+        return author;
+    }
+
+    public String getCommentTime() {
+        return commentTime;
+    }
+
+    public String getCommentContent() {
+        return commentContent;
+    }
+
+    public String getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(String parentId) {
+        this.parentId = parentId;
+    }
+
+    public int getScore() {
+        return score;
+    }
+
+    public void setScore(int score) {
+        this.score = score;
+    }
+
+    public boolean isSubmitter() {
+        return isSubmitter;
+    }
+
+    public String getPermalink() {
+        return permalink;
+    }
+
+    public int getDepth() {
+        return depth;
+    }
+
+    public boolean isCollapsed() {
+        return collapsed;
+    }
+
+    public boolean hasReply() {
+        return hasReply;
+    }
+
+    public void setHasReply(boolean hasReply) {
+        this.hasReply = hasReply;
+    }
+
+    public boolean isScoreHidden() {
+        return scoreHidden;
+    }
+
+    public boolean isExpanded() {
+        return isExpanded;
+    }
+
+    public void setExpanded(boolean isExpanded) {
+        this.isExpanded = isExpanded;
+    }
+
+    public int getVoteType() {
+        return voteType;
+    }
+
+    public void setVoteType(int voteType) {
+        this.voteType = voteType;
+    }
+
+    public ArrayList<CommentData> getChildren() {
+        return children;
+    }
+
+    public void setChildren(ArrayList<CommentData> children) {
+        this.children = children;
+    }
+
+    public void addChildren(ArrayList<CommentData> moreChildren) {
+        if(children == null) {
+            setChildren(moreChildren);
+        } else {
+            children.addAll(moreChildren);
+        }
+    }
+
+    public ArrayList<String> getMoreChildrenIds() {
+        return moreChildrenIds;
+    }
+
+    public void setMoreChildrenIds(ArrayList<String> moreChildrenIds) {
+        this.moreChildrenIds = moreChildrenIds;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int i) {
+        parcel.writeString(id);
+        parcel.writeString(fullName);
+        parcel.writeString(author);
+        parcel.writeString(commentTime);
+        parcel.writeString(commentContent);
+        parcel.writeString(parentId);
+        parcel.writeInt(score);
+        parcel.writeInt(voteType);
+        parcel.writeByte((byte) (isSubmitter ? 1 : 0));
+        parcel.writeString(permalink);
+        parcel.writeInt(depth);
+        parcel.writeByte((byte) (collapsed ? 1 : 0));
+        parcel.writeByte((byte) (hasReply ? 1 : 0));
+        parcel.writeByte((byte) (scoreHidden ? 1 : 0));
+        parcel.writeByte((byte) (isExpanded ? 1 : 0));
+        parcel.writeStringList(moreChildrenIds);
+    }
+}
+
+/*class CommentData extends RecyclerViewItem implements Parcelable {
+    private String id;
+    private String fullName;
+    private String author;
+    private String commentTime;
+    private String commentContent;
+    private String parentId;
+    private int score;
+    private int voteType;
+    private boolean isSubmitter;
+    private String permalink;
+    private int depth;
+    private boolean collapsed;
+    private boolean hasReply;
+    private boolean scoreHidden;
+    private ArrayList<String> moreChildrenIds;
+
+    CommentData(String id, String fullName, String author, String commentTime, String commentContent,
+                String parentId, int score, boolean isSubmitter, String permalink, int depth,
+                boolean collapsed, boolean hasReply, boolean scoreHidden) {
         super(depth);
         this.id = id;
         this.fullName = fullName;
         this.author = author;
         this.commentTime = commentTime;
         this.commentContent = commentContent;
+        this.parentId = parentId;
         this.score = score;
         this.isSubmitter = isSubmitter;
         this.permalink = RedditUtils.API_BASE_URI + permalink;
@@ -45,6 +247,7 @@ class CommentData extends RecyclerViewItem implements Parcelable {
         author = in.readString();
         commentTime = in.readString();
         commentContent = in.readString();
+        parentId = in.readString();
         score = in.readInt();
         voteType = in.readInt();
         isSubmitter = in.readByte() != 0;
@@ -53,6 +256,7 @@ class CommentData extends RecyclerViewItem implements Parcelable {
         collapsed = in.readByte() != 0;
         hasReply = in.readByte() != 0;
         scoreHidden = in.readByte() != 0;
+        in.readStringList(moreChildrenIds);
         super.setLevel(depth);
     }
 
@@ -88,6 +292,14 @@ class CommentData extends RecyclerViewItem implements Parcelable {
         return commentContent;
     }
 
+    public String getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(String parentId) {
+        this.parentId = parentId;
+    }
+
     public int getScore() {
         return score;
     }
@@ -132,6 +344,14 @@ class CommentData extends RecyclerViewItem implements Parcelable {
         this.voteType = voteType;
     }
 
+    public ArrayList<String> getMoreChildrenIds() {
+        return moreChildrenIds;
+    }
+
+    public void setMoreChildrenIds(ArrayList<String> moreChildrenIds) {
+        this.moreChildrenIds = moreChildrenIds;
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -144,6 +364,7 @@ class CommentData extends RecyclerViewItem implements Parcelable {
         parcel.writeString(author);
         parcel.writeString(commentTime);
         parcel.writeString(commentContent);
+        parcel.writeString(parentId);
         parcel.writeInt(score);
         parcel.writeInt(voteType);
         parcel.writeByte((byte) (isSubmitter ? 1 : 0));
@@ -152,5 +373,6 @@ class CommentData extends RecyclerViewItem implements Parcelable {
         parcel.writeByte((byte) (collapsed ? 1 : 0));
         parcel.writeByte((byte) (hasReply ? 1 : 0));
         parcel.writeByte((byte) (scoreHidden ? 1 : 0));
+        parcel.writeStringList(moreChildrenIds);
     }
-}
+}*/
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentMultiLevelRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentMultiLevelRecyclerViewAdapter.java
deleted file mode 100644
index 1f5795fe..00000000
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentMultiLevelRecyclerViewAdapter.java
+++ /dev/null
@@ -1,322 +0,0 @@
-package ml.docilealligator.infinityforreddit;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.graphics.ColorFilter;
-import android.net.Uri;
-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 androidx.annotation.NonNull;
-import androidx.browser.customtabs.CustomTabsIntent;
-import androidx.core.content.ContextCompat;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.multilevelview.MultiLevelAdapter;
-import com.multilevelview.MultiLevelRecyclerView;
-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;
-
-class CommentMultiLevelRecyclerViewAdapter extends MultiLevelAdapter {
-    private Activity mActivity;
-    private Retrofit mRetrofit;
-    private Retrofit mOauthRetrofit;
-    private SharedPreferences mSharedPreferences;
-    private ArrayList<CommentData> mCommentData;
-    private MultiLevelRecyclerView mMultiLevelRecyclerView;
-    private String subredditNamePrefixed;
-    private String article;
-    private Locale locale;
-
-    CommentMultiLevelRecyclerViewAdapter(Activity activity, Retrofit retrofit, Retrofit oauthRetrofit,
-                                         SharedPreferences sharedPreferences, ArrayList<CommentData> commentData,
-                                         MultiLevelRecyclerView multiLevelRecyclerView,
-                                         String subredditNamePrefixed, String article, Locale locale) {
-        super(commentData);
-        mActivity = activity;
-        mRetrofit = retrofit;
-        mOauthRetrofit = oauthRetrofit;
-        mSharedPreferences = sharedPreferences;
-        mCommentData = commentData;
-        mMultiLevelRecyclerView = multiLevelRecyclerView;
-        this.subredditNamePrefixed = subredditNamePrefixed;
-        this.article = article;
-        this.locale = locale;
-    }
-
-    @NonNull
-    @Override
-    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
-        return new CommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment, parent, false));
-    }
-
-    @Override
-    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
-        final CommentData commentItem = mCommentData.get(position);
-
-        String authorPrefixed = "u/" + commentItem.getAuthor();
-        ((CommentViewHolder) holder).authorTextView.setText(authorPrefixed);
-        ((CommentViewHolder) holder).authorTextView.setOnClickListener(view -> {
-            Intent intent = new Intent(mActivity, ViewUserDetailActivity.class);
-            intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, commentItem.getAuthor());
-            mActivity.startActivity(intent);
-        });
-
-        ((CommentViewHolder) holder).commentTimeTextView.setText(commentItem.getCommentTime());
-        SpannableConfiguration spannableConfiguration = SpannableConfiguration.builder(mActivity).linkResolver((view, link) -> {
-            if (link.startsWith("/u/") || link.startsWith("u/")) {
-                Intent intent = new Intent(mActivity, ViewUserDetailActivity.class);
-                intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, link.substring(3));
-                mActivity.startActivity(intent);
-            } else if (link.startsWith("/r/") || link.startsWith("r/")) {
-                Intent intent = new Intent(mActivity, ViewSubredditDetailActivity.class);
-                intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, link.substring(3));
-                mActivity.startActivity(intent);
-            } else {
-                CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
-                // add share action to menu list
-                builder.addDefaultShareMenuItem();
-                builder.setToolbarColor(mActivity.getResources().getColor(R.color.colorPrimary));
-                CustomTabsIntent customTabsIntent = builder.build();
-                customTabsIntent.launchUrl(mActivity, Uri.parse(link));
-            }
-        }).build();
-
-        ((CommentViewHolder) holder).commentMarkdownView.setMarkdown(spannableConfiguration, commentItem.getCommentContent());
-        ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore()));
-
-        ((CommentViewHolder) holder).verticalBlock.getLayoutParams().width = commentItem.getDepth() * 16;
-        if (commentItem.hasReply()) {
-            setExpandButton(((CommentViewHolder) holder).expandButton, commentItem.isExpanded());
-        }
-
-        ((CommentViewHolder) holder).shareButton.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View view) {
-                Intent intent = new Intent(Intent.ACTION_SEND);
-                intent.setType("text/plain");
-                String extraText = commentItem.getPermalink();
-                intent.putExtra(Intent.EXTRA_TEXT, extraText);
-                mActivity.startActivity(Intent.createChooser(intent, "Share"));
-            }
-        });
-
-        ((CommentViewHolder) holder).expandButton.setOnClickListener(view -> {
-            if (commentItem.hasChildren() && commentItem.getChildren().size() > 0) {
-                mMultiLevelRecyclerView.toggleItemsGroup(holder.getAdapterPosition());
-                setExpandButton(((CommentViewHolder) holder).expandButton, commentItem.isExpanded());
-            } else {
-                ((CommentViewHolder) holder).loadMoreCommentsProgressBar.setVisibility(View.VISIBLE);
-                FetchComment.fetchAllComment(mRetrofit, subredditNamePrefixed, article, commentItem.getId(),
-                        locale, false, commentItem.getDepth(), new FetchComment.FetchAllCommentListener() {
-                            @Override
-                            public void onFetchAllCommentSuccess(List<?> commentData) {
-                                commentItem.addChildren((List<RecyclerViewItem>) commentData);
-                                ((CommentViewHolder) holder).loadMoreCommentsProgressBar
-                                        .setVisibility(View.GONE);
-                                mMultiLevelRecyclerView.toggleItemsGroup(holder.getAdapterPosition());
-                                ((CommentViewHolder) holder).expandButton
-                                        .setImageResource(R.drawable.ic_expand_less_black_20dp);
-                            }
-
-                            @Override
-                            public void onFetchAllCommentFailed() {
-                                ((CommentViewHolder) holder).loadMoreCommentsProgressBar
-                                        .setVisibility(View.GONE);
-                            }
-                        });
-            }
-        });
-
-        ((CommentViewHolder) holder).replyButton.setOnClickListener(view -> {
-            Intent intent = new Intent(mActivity, CommentActivity.class);
-            intent.putExtra(CommentActivity.EXTRA_PARENT_DEPTH_KEY, commentItem.getDepth() + 1);
-            intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_KEY, commentItem.getCommentContent());
-            intent.putExtra(CommentActivity.EXTRA_PARENT_FULLNAME_KEY, commentItem.getFullName());
-            intent.putExtra(CommentActivity.EXTRA_IS_REPLYING_KEY, true);
-            mActivity.startActivityForResult(intent, CommentActivity.WRITE_COMMENT_REQUEST_CODE);
-        });
-
-        switch (commentItem.getVoteType()) {
-            case 1:
-                ((CommentViewHolder) holder).upvoteButton
-                        .setColorFilter(ContextCompat.getColor(mActivity, R.color.colorPrimary), android.graphics.PorterDuff.Mode.SRC_IN);
-                break;
-            case 2:
-                ((CommentViewHolder) holder).downvoteButton
-                        .setColorFilter(ContextCompat.getColor(mActivity, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN);
-                break;
-        }
-
-        ((CommentViewHolder) holder).upvoteButton.setOnClickListener(view -> {
-            ColorFilter previousUpvoteButtonColorFilter = ((CommentViewHolder) holder).upvoteButton.getColorFilter();
-            ColorFilter previousDownvoteButtonColorFilter = ((CommentViewHolder) holder).downvoteButton.getColorFilter();
-            int previousVoteType = commentItem.getVoteType();
-            String newVoteType;
-
-            ((CommentViewHolder) holder).downvoteButton.clearColorFilter();
-
-            if(previousUpvoteButtonColorFilter == null) {
-                //Not upvoted before
-                commentItem.setVoteType(1);
-                newVoteType = RedditUtils.DIR_UPVOTE;
-                ((CommentViewHolder) holder).upvoteButton
-                        .setColorFilter(ContextCompat.getColor(mActivity, R.color.backgroundColorPrimaryDark), android.graphics.PorterDuff.Mode.SRC_IN);
-            } else {
-                //Upvoted before
-                commentItem.setVoteType(0);
-                newVoteType = RedditUtils.DIR_UNVOTE;
-                ((CommentViewHolder) holder).upvoteButton.clearColorFilter();
-            }
-
-            ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType()));
-
-            VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() {
-                @Override
-                public void onVoteThingSuccess(int position1) {
-                    if(newVoteType.equals(RedditUtils.DIR_UPVOTE)) {
-                        commentItem.setVoteType(1);
-                        ((CommentViewHolder) holder).upvoteButton
-                                .setColorFilter(ContextCompat.getColor(mActivity, R.color.backgroundColorPrimaryDark), android.graphics.PorterDuff.Mode.SRC_IN);
-                    } else {
-                        commentItem.setVoteType(0);
-                        ((CommentViewHolder) holder).upvoteButton.clearColorFilter();
-                    }
-
-                    ((CommentViewHolder) holder).downvoteButton.clearColorFilter();
-                    ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType()));
-                }
-
-                @Override
-                public void onVoteThingFail(int position1) {
-                    Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show();
-                    commentItem.setVoteType(previousVoteType);
-                    ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + previousVoteType));
-                    ((CommentViewHolder) holder).upvoteButton.setColorFilter(previousUpvoteButtonColorFilter);
-                    ((CommentViewHolder) holder).downvoteButton.setColorFilter(previousDownvoteButtonColorFilter);
-                }
-            }, commentItem.getFullName(), newVoteType, holder.getAdapterPosition());
-        });
-
-        ((CommentViewHolder) holder).downvoteButton.setOnClickListener(view -> {
-            ColorFilter previousUpvoteButtonColorFilter = ((CommentViewHolder) holder).upvoteButton.getColorFilter();
-            ColorFilter previousDownvoteButtonColorFilter = ((CommentViewHolder) holder).downvoteButton.getColorFilter();
-            int previousVoteType = commentItem.getVoteType();
-            String newVoteType;
-
-            ((CommentViewHolder) holder).upvoteButton.clearColorFilter();
-
-            if(previousDownvoteButtonColorFilter == null) {
-                //Not downvoted before
-                commentItem.setVoteType(-1);
-                newVoteType = RedditUtils.DIR_DOWNVOTE;
-                ((CommentViewHolder) holder).downvoteButton
-                        .setColorFilter(ContextCompat.getColor(mActivity, R.color.colorAccent), android.graphics.PorterDuff.Mode.SRC_IN);
-            } else {
-                //Downvoted before
-                commentItem.setVoteType(0);
-                newVoteType = RedditUtils.DIR_UNVOTE;
-                ((CommentViewHolder) holder).downvoteButton.clearColorFilter();
-            }
-
-            ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType()));
-
-            VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() {
-                @Override
-                public void onVoteThingSuccess(int position1) {
-                    if(newVoteType.equals(RedditUtils.DIR_DOWNVOTE)) {
-                        commentItem.setVoteType(-1);
-                        ((CommentViewHolder) holder).downvoteButton
-                                .setColorFilter(ContextCompat.getColor(mActivity, R.color.colorAccent), android.graphics.PorterDuff.Mode.SRC_IN);
-                    } else {
-                        commentItem.setVoteType(0);
-                        ((CommentViewHolder) holder).downvoteButton.clearColorFilter();
-                    }
-
-                    ((CommentViewHolder) holder).upvoteButton.clearColorFilter();
-                    ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType()));
-                }
-
-                @Override
-                public void onVoteThingFail(int position1) {
-                    Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show();
-                    commentItem.setVoteType(previousVoteType);
-                    ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + previousVoteType));
-                    ((CommentViewHolder) holder).upvoteButton.setColorFilter(previousUpvoteButtonColorFilter);
-                    ((CommentViewHolder) holder).downvoteButton.setColorFilter(previousDownvoteButtonColorFilter);
-                }
-            }, commentItem.getFullName(), newVoteType, holder.getAdapterPosition());
-        });
-    }
-
-    @Override
-    public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
-        if (holder instanceof CommentViewHolder) {
-            ((CommentViewHolder) holder).expandButton.setVisibility(View.GONE);
-            ((CommentViewHolder) holder).loadMoreCommentsProgressBar.setVisibility(View.GONE);
-        }
-    }
-
-    void addComments(ArrayList<CommentData> comments) {
-        int sizeBefore = mCommentData.size();
-        mCommentData.addAll(comments);
-        notifyItemRangeInserted(sizeBefore, mCommentData.size() - sizeBefore);
-    }
-
-    void addComment(CommentData comment) {
-        mCommentData.add(0, comment);
-        notifyItemInserted(0);
-    }
-
-    void addChildComment(CommentData comment, int parentPosition) {
-        List<RecyclerViewItem> childComments = mCommentData.get(parentPosition).getChildren();
-        if(childComments == null) {
-            childComments = new ArrayList<>();
-        }
-        childComments.add(0, comment);
-        mCommentData.get(parentPosition).addChildren(childComments);
-        mCommentData.get(parentPosition).setHasReply(true);
-        notifyItemChanged(parentPosition);
-        mMultiLevelRecyclerView.toggleItemsGroup(parentPosition);
-    }
-
-    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.load_more_comments_progress_bar) ProgressBar loadMoreCommentsProgressBar;
-        @BindView(R.id.expand_button_item_post_comment) ImageView expandButton;
-        @BindView(R.id.share_button_item_post_comment) ImageView shareButton;
-        @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/CommentRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentRecyclerViewAdapter.java
new file mode 100644
index 00000000..e9da8bde
--- /dev/null
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentRecyclerViewAdapter.java
@@ -0,0 +1,379 @@
+package ml.docilealligator.infinityforreddit;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.graphics.ColorFilter;
+import android.net.Uri;
+import android.os.Handler;
+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 androidx.annotation.NonNull;
+import androidx.browser.customtabs.CustomTabsIntent;
+import androidx.core.content.ContextCompat;
+import androidx.recyclerview.widget.RecyclerView;
+
+import java.util.ArrayList;
+import java.util.Locale;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import retrofit2.Retrofit;
+import ru.noties.markwon.SpannableConfiguration;
+import ru.noties.markwon.view.MarkwonView;
+
+class CommentRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
+    private Activity mActivity;
+    private Retrofit mRetrofit;
+    private Retrofit mOauthRetrofit;
+    private SharedPreferences mSharedPreferences;
+    private ArrayList<CommentData> mCommentData;
+    private RecyclerView mRecyclerView;
+    private String mSubredditNamePrefixed;
+    private String mArticle;
+    private Locale mLocale;
+
+    private ArrayList<CommentData> mVisibleComments;
+
+    CommentRecyclerViewAdapter(Activity activity, Retrofit retrofit, Retrofit oauthRetrofit,
+                                         SharedPreferences sharedPreferences, ArrayList<CommentData> commentData,
+                                         RecyclerView recyclerView,
+                                         String subredditNamePrefixed, String article, Locale locale) {
+        mActivity = activity;
+        mRetrofit = retrofit;
+        mOauthRetrofit = oauthRetrofit;
+        mSharedPreferences = sharedPreferences;
+        mCommentData = commentData;
+        mRecyclerView = recyclerView;
+        mSubredditNamePrefixed = subredditNamePrefixed;
+        mArticle = article;
+        mLocale = locale;
+        mVisibleComments = new ArrayList<>();
+
+        new Handler().post(() -> {
+            makeChildrenVisible(commentData, mVisibleComments);
+            notifyDataSetChanged();
+        });
+    }
+
+    private void makeChildrenVisible(ArrayList<CommentData> comments, ArrayList<CommentData> visibleComments) {
+        for(CommentData c : comments) {
+            visibleComments.add(c);
+            if(c.hasReply()) {
+                c.setExpanded(true);
+                makeChildrenVisible(c.getChildren(), visibleComments);
+            }
+        }
+    }
+
+    @NonNull
+    @Override
+    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+        return new CommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment, parent, false));
+    }
+
+    @Override
+    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
+        final CommentData commentItem = mVisibleComments.get(position);
+
+        String authorPrefixed = "u/" + commentItem.getAuthor();
+        ((CommentViewHolder) holder).authorTextView.setText(authorPrefixed);
+        ((CommentViewHolder) holder).authorTextView.setOnClickListener(view -> {
+            Intent intent = new Intent(mActivity, ViewUserDetailActivity.class);
+            intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, commentItem.getAuthor());
+            mActivity.startActivity(intent);
+        });
+
+        ((CommentViewHolder) holder).commentTimeTextView.setText(commentItem.getCommentTime());
+
+        SpannableConfiguration spannableConfiguration = SpannableConfiguration.builder(mActivity).linkResolver((view, link) -> {
+            if (link.startsWith("/u/") || link.startsWith("u/")) {
+                Intent intent = new Intent(mActivity, ViewUserDetailActivity.class);
+                intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, link.substring(3));
+                mActivity.startActivity(intent);
+            } else if (link.startsWith("/r/") || link.startsWith("r/")) {
+                Intent intent = new Intent(mActivity, ViewSubredditDetailActivity.class);
+                intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, link.substring(3));
+                mActivity.startActivity(intent);
+            } else {
+                CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
+                // add share action to menu list
+                builder.addDefaultShareMenuItem();
+                builder.setToolbarColor(mActivity.getResources().getColor(R.color.colorPrimary));
+                CustomTabsIntent customTabsIntent = builder.build();
+                customTabsIntent.launchUrl(mActivity, Uri.parse(link));
+            }
+        }).build();
+
+        ((CommentViewHolder) holder).commentMarkdownView.setMarkdown(spannableConfiguration, commentItem.getCommentContent());
+        ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore()));
+
+        ((CommentViewHolder) holder).verticalBlock.getLayoutParams().width = commentItem.getDepth() * 16;
+
+        ((CommentViewHolder) holder).shareButton.setOnClickListener(view -> {
+            Intent intent = new Intent(Intent.ACTION_SEND);
+            intent.setType("text/plain");
+            String extraText = commentItem.getPermalink();
+            intent.putExtra(Intent.EXTRA_TEXT, extraText);
+            mActivity.startActivity(Intent.createChooser(intent, "Share"));
+        });
+
+        if (commentItem.hasReply()) {
+            if(commentItem.isExpanded()) {
+                ((CommentViewHolder) holder).expandButton.setImageResource(R.drawable.ic_expand_less_black_20dp);
+            } else {
+                ((CommentViewHolder) holder).expandButton.setImageResource(R.drawable.ic_expand_more_black_20dp);
+            }
+            ((CommentViewHolder) holder).expandButton.setVisibility(View.VISIBLE);
+        }
+
+        ((CommentViewHolder) holder).expandButton.setOnClickListener(view -> {
+            if(commentItem.isExpanded()) {
+                collapseChildren(holder.getAdapterPosition());
+                ((CommentViewHolder) holder).expandButton
+                        .setImageResource(R.drawable.ic_expand_more_black_20dp);
+            } else {
+                expandChildren(holder.getAdapterPosition());
+                commentItem.setExpanded(true);
+                ((CommentViewHolder) holder).expandButton
+                        .setImageResource(R.drawable.ic_expand_less_black_20dp);
+            }
+            /*if (commentItem.hasReply() && commentItem.getChildren().size() > 0) {
+                collapseChildren(holder.getAdapterPosition());
+                ((CommentViewHolder) holder).expandButton
+                        .setImageResource(R.drawable.ic_expand_more_black_20dp);
+            } else {
+                ((CommentViewHolder) holder).loadMoreCommentsProgressBar.setVisibility(View.VISIBLE);
+                FetchComment.fetchAllComment(mRetrofit, mSubredditNamePrefixed, article, commentItem.getId(),
+                        locale, false, commentItem.getDepth(), new FetchComment.FetchAllCommentListener() {
+                            @Override
+                            public void onFetchAllCommentSuccess(List<?> commentData) {
+                                commentItem.addChildren((ArrayList<CommentData>) commentData);
+                                ((CommentViewHolder) holder).loadMoreCommentsProgressBar
+                                        .setVisibility(View.GONE);
+                                expandChildren(holder.getAdapterPosition());
+                                ((CommentViewHolder) holder).expandButton
+                                        .setImageResource(R.drawable.ic_expand_less_black_20dp);
+                            }
+
+                            @Override
+                            public void onFetchAllCommentFailed() {
+                                ((CommentViewHolder) holder).loadMoreCommentsProgressBar
+                                        .setVisibility(View.GONE);
+                            }
+                        });
+            }*/
+        });
+
+        ((CommentViewHolder) holder).replyButton.setOnClickListener(view -> {
+            Intent intent = new Intent(mActivity, CommentActivity.class);
+            intent.putExtra(CommentActivity.EXTRA_PARENT_DEPTH_KEY, commentItem.getDepth() + 1);
+            intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_KEY, commentItem.getCommentContent());
+            intent.putExtra(CommentActivity.EXTRA_PARENT_FULLNAME_KEY, commentItem.getFullName());
+            intent.putExtra(CommentActivity.EXTRA_IS_REPLYING_KEY, true);
+            intent.putExtra(CommentActivity.EXTRA_PARENT_POSITION_KEY, holder.getAdapterPosition());
+            mActivity.startActivityForResult(intent, CommentActivity.WRITE_COMMENT_REQUEST_CODE);
+        });
+
+        switch (commentItem.getVoteType()) {
+            case 1:
+                ((CommentViewHolder) holder).upvoteButton
+                        .setColorFilter(ContextCompat.getColor(mActivity, R.color.colorPrimary), android.graphics.PorterDuff.Mode.SRC_IN);
+                break;
+            case 2:
+                ((CommentViewHolder) holder).downvoteButton
+                        .setColorFilter(ContextCompat.getColor(mActivity, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN);
+                break;
+        }
+
+        ((CommentViewHolder) holder).upvoteButton.setOnClickListener(view -> {
+            ColorFilter previousUpvoteButtonColorFilter = ((CommentViewHolder) holder).upvoteButton.getColorFilter();
+            ColorFilter previousDownvoteButtonColorFilter = ((CommentViewHolder) holder).downvoteButton.getColorFilter();
+            int previousVoteType = commentItem.getVoteType();
+            String newVoteType;
+
+            ((CommentViewHolder) holder).downvoteButton.clearColorFilter();
+
+            if(previousUpvoteButtonColorFilter == null) {
+                //Not upvoted before
+                commentItem.setVoteType(1);
+                newVoteType = RedditUtils.DIR_UPVOTE;
+                ((CommentViewHolder) holder).upvoteButton
+                        .setColorFilter(ContextCompat.getColor(mActivity, R.color.backgroundColorPrimaryDark), android.graphics.PorterDuff.Mode.SRC_IN);
+            } else {
+                //Upvoted before
+                commentItem.setVoteType(0);
+                newVoteType = RedditUtils.DIR_UNVOTE;
+                ((CommentViewHolder) holder).upvoteButton.clearColorFilter();
+            }
+
+            ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType()));
+
+            VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() {
+                @Override
+                public void onVoteThingSuccess(int position1) {
+                    if(newVoteType.equals(RedditUtils.DIR_UPVOTE)) {
+                        commentItem.setVoteType(1);
+                        ((CommentViewHolder) holder).upvoteButton
+                                .setColorFilter(ContextCompat.getColor(mActivity, R.color.backgroundColorPrimaryDark), android.graphics.PorterDuff.Mode.SRC_IN);
+                    } else {
+                        commentItem.setVoteType(0);
+                        ((CommentViewHolder) holder).upvoteButton.clearColorFilter();
+                    }
+
+                    ((CommentViewHolder) holder).downvoteButton.clearColorFilter();
+                    ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType()));
+                }
+
+                @Override
+                public void onVoteThingFail(int position1) {
+                    Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show();
+                    commentItem.setVoteType(previousVoteType);
+                    ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + previousVoteType));
+                    ((CommentViewHolder) holder).upvoteButton.setColorFilter(previousUpvoteButtonColorFilter);
+                    ((CommentViewHolder) holder).downvoteButton.setColorFilter(previousDownvoteButtonColorFilter);
+                }
+            }, commentItem.getFullName(), newVoteType, holder.getAdapterPosition());
+        });
+
+        ((CommentViewHolder) holder).downvoteButton.setOnClickListener(view -> {
+            ColorFilter previousUpvoteButtonColorFilter = ((CommentViewHolder) holder).upvoteButton.getColorFilter();
+            ColorFilter previousDownvoteButtonColorFilter = ((CommentViewHolder) holder).downvoteButton.getColorFilter();
+            int previousVoteType = commentItem.getVoteType();
+            String newVoteType;
+
+            ((CommentViewHolder) holder).upvoteButton.clearColorFilter();
+
+            if(previousDownvoteButtonColorFilter == null) {
+                //Not downvoted before
+                commentItem.setVoteType(-1);
+                newVoteType = RedditUtils.DIR_DOWNVOTE;
+                ((CommentViewHolder) holder).downvoteButton
+                        .setColorFilter(ContextCompat.getColor(mActivity, R.color.colorAccent), android.graphics.PorterDuff.Mode.SRC_IN);
+            } else {
+                //Downvoted before
+                commentItem.setVoteType(0);
+                newVoteType = RedditUtils.DIR_UNVOTE;
+                ((CommentViewHolder) holder).downvoteButton.clearColorFilter();
+            }
+
+            ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType()));
+
+            VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() {
+                @Override
+                public void onVoteThingSuccess(int position1) {
+                    if(newVoteType.equals(RedditUtils.DIR_DOWNVOTE)) {
+                        commentItem.setVoteType(-1);
+                        ((CommentViewHolder) holder).downvoteButton
+                                .setColorFilter(ContextCompat.getColor(mActivity, R.color.colorAccent), android.graphics.PorterDuff.Mode.SRC_IN);
+                    } else {
+                        commentItem.setVoteType(0);
+                        ((CommentViewHolder) holder).downvoteButton.clearColorFilter();
+                    }
+
+                    ((CommentViewHolder) holder).upvoteButton.clearColorFilter();
+                    ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + commentItem.getVoteType()));
+                }
+
+                @Override
+                public void onVoteThingFail(int position1) {
+                    Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show();
+                    commentItem.setVoteType(previousVoteType);
+                    ((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + previousVoteType));
+                    ((CommentViewHolder) holder).upvoteButton.setColorFilter(previousUpvoteButtonColorFilter);
+                    ((CommentViewHolder) holder).downvoteButton.setColorFilter(previousDownvoteButtonColorFilter);
+                }
+            }, commentItem.getFullName(), newVoteType, holder.getAdapterPosition());
+        });
+    }
+
+    private void expandChildren(int position) {
+        mVisibleComments.get(position).setExpanded(true);
+        ArrayList<CommentData> children = mVisibleComments.get(position).getChildren();
+        if(children != null && children.size() > 0) {
+            mVisibleComments.addAll(position + 1, children);
+            for(int i = position + 1; i <= position + children.size(); i++) {
+                mVisibleComments.get(i).setExpanded(false);
+            }
+            notifyItemRangeInserted(position + 1, children.size());
+        }
+    }
+
+    private void collapseChildren(int position) {
+        mVisibleComments.get(position).setExpanded(false);
+        int depth = mVisibleComments.get(position).getDepth();
+        int allChildrenSize = 0;
+        for(int i = position + 1; i < mVisibleComments.size(); i++) {
+            if(mVisibleComments.get(i).getDepth() > depth) {
+                allChildrenSize++;
+            } else {
+                break;
+            }
+        }
+
+        mVisibleComments.subList(position + 1, position + 1 + allChildrenSize).clear();
+        notifyItemRangeRemoved(position + 1, allChildrenSize);
+    }
+
+    void addComments(ArrayList<CommentData> comments) {
+        int sizeBefore = mVisibleComments.size();
+        mVisibleComments.addAll(comments);
+        notifyItemRangeInserted(sizeBefore, comments.size());
+    }
+
+    //Need proper implementation
+    void addComment(CommentData comment) {
+        mCommentData.add(0, comment);
+        notifyItemInserted(0);
+    }
+
+    //Need proper implementation
+    void addChildComment(CommentData comment, int parentPosition) {
+        ArrayList<CommentData> childComments = mCommentData.get(parentPosition).getChildren();
+        if(childComments == null) {
+            childComments = new ArrayList<>();
+        }
+        childComments.add(0, comment);
+        mCommentData.get(parentPosition).addChildren(childComments);
+        mCommentData.get(parentPosition).setHasReply(true);
+        notifyItemChanged(parentPosition);
+    }
+
+    @Override
+    public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
+        if (holder instanceof CommentViewHolder) {
+            ((CommentViewHolder) holder).expandButton.setVisibility(View.GONE);
+            ((CommentViewHolder) holder).loadMoreCommentsProgressBar.setVisibility(View.GONE);
+        }
+    }
+
+    @Override
+    public int getItemCount() {
+        return mVisibleComments.size();
+    }
+
+    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.load_more_comments_progress_bar) ProgressBar loadMoreCommentsProgressBar;
+        @BindView(R.id.expand_button_item_post_comment) ImageView expandButton;
+        @BindView(R.id.share_button_item_post_comment) ImageView shareButton;
+        @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/FetchComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchComment.java
index c4b1958e..7f582214 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchComment.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchComment.java
@@ -5,7 +5,6 @@ import android.util.Log;
 import androidx.annotation.NonNull;
 
 import java.util.ArrayList;
-import java.util.List;
 import java.util.Locale;
 
 import retrofit2.Call;
@@ -15,18 +14,18 @@ import retrofit2.Retrofit;
 
 class FetchComment {
     interface FetchCommentListener {
-        void onFetchCommentSuccess(List<?> commentsData,
+        void onFetchCommentSuccess(ArrayList<CommentData> commentsData,
                                    String parentId, ArrayList<String> children);
         void onFetchCommentFailed();
     }
 
     interface FetchMoreCommentListener {
-        void onFetchMoreCommentSuccess(List<?> commentsData, int childrenStartingIndex);
+        void onFetchMoreCommentSuccess(ArrayList<CommentData> commentsData, int childrenStartingIndex);
         void onFetchMoreCommentFailed();
     }
 
     interface FetchAllCommentListener {
-        void onFetchAllCommentSuccess(List<?> commentData);
+        void onFetchAllCommentSuccess(ArrayList<CommentData> commentData);
         void onFetchAllCommentFailed();
     }
 
@@ -43,10 +42,10 @@ class FetchComment {
                             locale, isPost, parentDepth,
                             new ParseComment.ParseCommentListener() {
                                 @Override
-                                public void onParseCommentSuccess(List<?> commentData,
-                                                                  String parentId, ArrayList<String> children) {
+                                public void onParseCommentSuccess(ArrayList<CommentData> commentData,
+                                                                  String parentId, ArrayList<String> moreChildrenIds) {
                                     fetchCommentListener.onFetchCommentSuccess(commentData, parentId,
-                                            children);
+                                            moreChildrenIds);
                                 }
 
                                 @Override
@@ -104,8 +103,8 @@ class FetchComment {
                                         ParseComment.parseMoreComment(response.body(), new ArrayList<>(), locale,
                                                 0, new ParseComment.ParseCommentListener() {
                                                     @Override
-                                                    public void onParseCommentSuccess(List<?> commentData, String parentId,
-                                                                                      ArrayList<String> children) {
+                                                    public void onParseCommentSuccess(ArrayList<CommentData> commentData, String parentId,
+                                                                                      ArrayList<String> moreChildrenIds) {
                                                         fetchMoreCommentListener.onFetchMoreCommentSuccess(commentData, startingIndex + 100);
                                                     }
 
@@ -155,12 +154,12 @@ class FetchComment {
         fetchComment(retrofit, subredditNamePrefixed, article, comment, locale, isPost, parentDepth,
                 new FetchCommentListener() {
                     @Override
-                    public void onFetchCommentSuccess(List<?> commentsData, String parentId, ArrayList<String> children) {
+                    public void onFetchCommentSuccess(ArrayList<CommentData> commentsData, String parentId, ArrayList<String> children) {
                         if(children.size() != 0) {
                             fetchMoreComment(retrofit, subredditNamePrefixed, parentId, children,
                                     0, locale, new FetchMoreCommentListener() {
                                         @Override
-                                        public void onFetchMoreCommentSuccess(List<?> commentsData,
+                                        public void onFetchMoreCommentSuccess(ArrayList<CommentData> commentsData,
                                                                               int childrenStartingIndex) {
                                             ((ArrayList<CommentData>) commentsData).addAll((ArrayList<CommentData>) commentsData);
                                             fetchAllCommentListener.onFetchAllCommentSuccess(commentsData);
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseComment.java
index 16aaa609..05b9440a 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseComment.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseComment.java
@@ -3,6 +3,8 @@ package ml.docilealligator.infinityforreddit;
 import android.os.AsyncTask;
 import android.util.Log;
 
+import androidx.annotation.Nullable;
+
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
@@ -10,12 +12,11 @@ import org.json.JSONObject;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Calendar;
-import java.util.List;
 import java.util.Locale;
 
 class ParseComment {
     interface ParseCommentListener {
-        void onParseCommentSuccess(List<?> commentData, String parentId, ArrayList<String> children);
+        void onParseCommentSuccess(ArrayList<CommentData> commentData, String parentId, ArrayList<String> moreChildrenIds);
         void onParseCommentFailed();
     }
 
@@ -33,7 +34,8 @@ class ParseComment {
                              boolean isPost, int parentDepth, ParseCommentListener parseCommentListener) {
         try {
             JSONArray childrenArray = new JSONArray(response);
-
+            String parentId = childrenArray.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY)
+                    .getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.NAME_KEY);
             if(isPost) {
                 childrenArray = childrenArray.getJSONObject(1).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY);
             } else {
@@ -41,7 +43,8 @@ class ParseComment {
                         .getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getJSONObject(JSONUtils.REPLIES_KEY)
                         .getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY);
             }
-            new ParseCommentAsyncTask(childrenArray, commentData, locale, parentDepth, parseCommentListener).execute();
+
+            new ParseCommentAsyncTask(childrenArray, commentData, locale, parentId, parentDepth, parseCommentListener).execute();
         } catch (JSONException e) {
             e.printStackTrace();
             if(e.getMessage() != null) {
@@ -59,7 +62,7 @@ class ParseComment {
                                  int parentDepth, ParseCommentListener parseCommentListener) {
         try {
             JSONArray childrenArray = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY);
-            new ParseCommentAsyncTask(childrenArray, commentData, locale, parentDepth, parseCommentListener).execute();
+            new ParseCommentAsyncTask(childrenArray, commentData, locale, null, parentDepth, parseCommentListener).execute();
         } catch (JSONException e) {
             e.printStackTrace();
             if(e.getMessage() != null) {
@@ -78,20 +81,21 @@ class ParseComment {
         private JSONArray comments;
         private ArrayList<CommentData> commentData;
         private ArrayList<CommentData> newcommentData;
-        private ArrayList<String> children;
+        private ArrayList<String> moreChildrenIds;
         private Locale locale;
+        private String parentId;
         private int parentDepth;
         private ParseCommentListener parseCommentListener;
         private boolean parseFailed;
-        private String parentId;
 
         ParseCommentAsyncTask(JSONArray comments, ArrayList<CommentData> commentData, Locale locale,
-                              int parentDepth, ParseCommentListener parseCommentListener){
+                              @Nullable String parentId, int parentDepth, ParseCommentListener parseCommentListener){
             this.comments = comments;
             this.commentData = commentData;
             newcommentData = new ArrayList<>();
-            children = new ArrayList<>();
+            moreChildrenIds = new ArrayList<>();
             this.locale = locale;
+            this.parentId = parentId;
             this.parentDepth = parentDepth;
             parseFailed = false;
             this.parseCommentListener = parseCommentListener;
@@ -100,32 +104,7 @@ class ParseComment {
         @Override
         protected Void doInBackground(Void... voids) {
             try {
-                int actualCommentLength;
-
-                if(comments.length() == 0) {
-                    return null;
-                }
-
-                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)) {
-                    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));
-                    }
-
-                    actualCommentLength = comments.length() - 1;
-                } else {
-                    actualCommentLength = comments.length();
-                }
-
-                for (int i = 0; i < actualCommentLength; i++) {
-                    JSONObject data = comments.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY);
-                    newcommentData.add(parseSingleComment(data, parentDepth, locale));
-                }
+                parseCommentRecursion(comments, newcommentData, moreChildrenIds, parentDepth, locale);
             } catch (JSONException e) {
                 parseFailed = true;
                 if(e.getMessage() != null) {
@@ -139,13 +118,55 @@ class ParseComment {
         protected void onPostExecute(Void aVoid) {
             if(!parseFailed) {
                 commentData.addAll(newcommentData);
-                parseCommentListener.onParseCommentSuccess(commentData, parentId, children);
+                parseCommentListener.onParseCommentSuccess(commentData, parentId, moreChildrenIds);
             } else {
                 parseCommentListener.onParseCommentFailed();
             }
         }
     }
 
+    private static void parseCommentRecursion(JSONArray comments, ArrayList<CommentData> newCommentData,
+                                              ArrayList<String> moreChildrenIds, int parentDepth, Locale locale) throws JSONException {
+        int actualCommentLength;
+
+        if(comments.length() == 0) {
+            return;
+        }
+
+        JSONObject more = comments.getJSONObject(comments.length() - 1).getJSONObject(JSONUtils.DATA_KEY);
+
+        //Maybe moreChildrenIds contain only comments and no more info
+        if(more.has(JSONUtils.COUNT_KEY)) {
+            JSONArray childrenArray = more.getJSONArray(JSONUtils.CHILDREN_KEY);
+
+            for(int i = 0; i < childrenArray.length(); i++) {
+                moreChildrenIds.add(childrenArray.getString(i));
+            }
+
+            actualCommentLength = comments.length() - 1;
+        } else {
+            actualCommentLength = comments.length();
+        }
+
+        for (int i = 0; i < actualCommentLength; i++) {
+            JSONObject data = comments.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY);
+            CommentData singleComment = parseSingleComment(data, parentDepth, locale);
+
+            if(data.get(JSONUtils.REPLIES_KEY) instanceof JSONObject) {
+                JSONArray childrenArray = data.getJSONObject(JSONUtils.REPLIES_KEY)
+                        .getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY);
+                ArrayList<CommentData> children = new ArrayList<>();
+                ArrayList<String> nextMoreChildrenIds = new ArrayList<>();
+                parseCommentRecursion(childrenArray, children, nextMoreChildrenIds, singleComment.getDepth(),
+                        locale);
+                singleComment.addChildren(children);
+                singleComment.setMoreChildrenIds(nextMoreChildrenIds);
+            }
+
+            newCommentData.add(singleComment);
+        }
+    }
+
     private static class ParseMoreCommentBasicInfoAsyncTask extends AsyncTask<Void, Void, Void> {
         private JSONArray children;
         private StringBuilder commaSeparatedChildren;
@@ -229,11 +250,11 @@ class ParseComment {
             }
         }
     }
-
     private static CommentData parseSingleComment(JSONObject singleCommentData, int parentDepth, Locale locale) throws JSONException {
         String id = singleCommentData.getString(JSONUtils.ID_KEY);
         String fullName = singleCommentData.getString(JSONUtils.NAME_KEY);
         String author = singleCommentData.getString(JSONUtils.AUTHOR_KEY);
+        String parentId = singleCommentData.getString(JSONUtils.PARENT_ID_KEY);
         boolean isSubmitter = singleCommentData.getBoolean(JSONUtils.IS_SUBMITTER_KEY);
         String commentContent = "";
         if(!singleCommentData.isNull(JSONUtils.BODY_HTML_KEY)) {
@@ -251,14 +272,14 @@ class ParseComment {
 
         int depth;
         if(singleCommentData.has(JSONUtils.DEPTH_KEY)) {
-            depth = singleCommentData.getInt(JSONUtils.DEPTH_KEY) + parentDepth;
+            depth = singleCommentData.getInt(JSONUtils.DEPTH_KEY);
         } else {
             depth = parentDepth;
         }
         boolean collapsed = singleCommentData.getBoolean(JSONUtils.COLLAPSED_KEY);
         boolean hasReply = !(singleCommentData.get(JSONUtils.REPLIES_KEY) instanceof String);
 
-        return new CommentData(id, fullName, author, formattedSubmitTime, commentContent, score,
+        return new CommentData(id, fullName, author, formattedSubmitTime, commentContent, parentId, score,
                 isSubmitter, permalink, depth, collapsed, hasReply, scoreHidden);
     }
 }
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java
index 741a3a57..3c3db7b5 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java
@@ -28,6 +28,7 @@ import androidx.core.content.ContextCompat;
 import androidx.core.widget.NestedScrollView;
 import androidx.recyclerview.widget.DividerItemDecoration;
 import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
 
 import com.bumptech.glide.Glide;
 import com.bumptech.glide.RequestBuilder;
@@ -41,14 +42,12 @@ import com.google.android.material.card.MaterialCardView;
 import com.google.android.material.chip.Chip;
 import com.google.android.material.snackbar.Snackbar;
 import com.lsjwzh.widget.materialloadingprogressbar.CircleProgressBar;
-import com.multilevelview.MultiLevelRecyclerView;
 import com.santalu.aspectratioimageview.AspectRatioImageView;
 
 import org.greenrobot.eventbus.EventBus;
 import org.greenrobot.eventbus.Subscribe;
 
 import java.util.ArrayList;
-import java.util.List;
 import java.util.Locale;
 
 import javax.inject.Inject;
@@ -90,7 +89,7 @@ public class ViewPostDetailActivity extends AppCompatActivity {
     private ArrayList<String> children;
     private int mChildrenStartingIndex = 0;
 
-    private CommentMultiLevelRecyclerViewAdapter mAdapter;
+    private CommentRecyclerViewAdapter mAdapter;
     private LoadSubredditIconAsyncTask mLoadSubredditIconAsyncTask;
 
     @BindView(R.id.coordinator_layout_view_post_detail) CoordinatorLayout mCoordinatorLayout;
@@ -120,7 +119,7 @@ public class ViewPostDetailActivity extends AppCompatActivity {
     @BindView(R.id.share_button_view_post_detail) ImageView mShareButton;
     @BindView(R.id.comment_progress_bar_view_post_detail) CircleProgressBar mCommentProgressbar;
     @BindView(R.id.comment_card_view_view_post_detail) MaterialCardView 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;
 
@@ -504,23 +503,18 @@ public class ViewPostDetailActivity extends AppCompatActivity {
         FetchComment.fetchComment(mRetrofit, mPost.getSubredditNamePrefixed(), mPost.getId(),
                 null, mLocale, true, 0, new FetchComment.FetchCommentListener() {
                     @Override
-                    public void onFetchCommentSuccess(List<?> commentsData,
+                    public void onFetchCommentSuccess(ArrayList<CommentData> commentsData,
                                                       String parentId, ArrayList<String> children) {
                         ViewPostDetailActivity.this.children = children;
                         mCommentProgressbar.setVisibility(View.GONE);
-                        mCommentsData.addAll((ArrayList<CommentData>) commentsData);
+                        mCommentsData.addAll(commentsData);
 
                         if (mCommentsData.size() > 0) {
                             if(mAdapter == null) {
-                                mAdapter = new CommentMultiLevelRecyclerViewAdapter(
-                                        ViewPostDetailActivity.this, mRetrofit, mOauthRetrofit,
-                                        mSharedPreferences, mCommentsData,
-                                        mRecyclerView, mPost.getSubredditNamePrefixed(),
-                                        mPost.getId(), mLocale);
+                                mAdapter = new CommentRecyclerViewAdapter(ViewPostDetailActivity.this, mRetrofit,
+                                        mOauthRetrofit, mSharedPreferences, commentsData, mRecyclerView,
+                                        mPost.getSubredditNamePrefixed(), mPost.getId(), mLocale);
                                 mRecyclerView.setAdapter(mAdapter);
-                                mRecyclerView.removeItemClickListeners();
-                                mRecyclerView.setToggleItemOnClick(false);
-                                mRecyclerView.setAccordion(false);
 
                                 mNestedScrollView.getViewTreeObserver().addOnScrollChangedListener(() -> {
                                     if(!isLoadingMoreChildren) {
@@ -556,8 +550,8 @@ public class ViewPostDetailActivity extends AppCompatActivity {
         FetchComment.fetchMoreComment(mRetrofit, mPost.getSubredditNamePrefixed(), mPost.getFullName(),
                 children, startingIndex, mLocale, new FetchComment.FetchMoreCommentListener() {
                     @Override
-                    public void onFetchMoreCommentSuccess(List<?> commentsData, int childrenStartingIndex) {
-                        mAdapter.addComments((ArrayList<CommentData>) commentsData);
+                    public void onFetchMoreCommentSuccess(ArrayList<CommentData> commentsData, int childrenStartingIndex) {
+                        mAdapter.addComments(commentsData);
                         mChildrenStartingIndex = childrenStartingIndex;
                         isLoadingMoreChildren = false;
                     }
@@ -678,7 +672,7 @@ public class ViewPostDetailActivity extends AppCompatActivity {
     }
 
     @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
+    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
         switch (item.getItemId()) {
             case R.id.action_refresh_view_post_detail_activity:
                 refresh();
-- 
cgit v1.2.3