Better comment loading and subscription check

Fixes issue #6
Signed-off-by: Balazs Toldi <balazs@toldi.eu>
This commit is contained in:
Balazs Toldi 2023-07-24 12:00:17 +02:00
parent 4d1822aaae
commit e1eadab7ba
No known key found for this signature in database
GPG Key ID: 6C7D440036F99D58
9 changed files with 83 additions and 23 deletions

View File

@ -206,6 +206,7 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
private Call<String> subredditAutocompleteCall; private Call<String> subredditAutocompleteCall;
private String mAccessToken; private String mAccessToken;
private String mAccountName; private String mAccountName;
private String mAccountQualifiedName;
private String subredditName; private String subredditName;
private String description; private String description;
@ -344,6 +345,7 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null);
mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null); mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null);
mAccountQualifiedName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, null);
if (savedInstanceState == null) { if (savedInstanceState == null) {
mMessageFullname = getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME); mMessageFullname = getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME);
@ -1038,7 +1040,7 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
}); });
CheckIsSubscribedToSubreddit.checkIsSubscribedToSubreddit(mExecutor, new Handler(), CheckIsSubscribedToSubreddit.checkIsSubscribedToSubreddit(mExecutor, new Handler(),
mRedditDataRoomDatabase, subredditName, mAccountName, mRedditDataRoomDatabase, qualifiedName, mAccountQualifiedName,
new CheckIsSubscribedToSubreddit.CheckIsSubscribedToSubredditListener() { new CheckIsSubscribedToSubreddit.CheckIsSubscribedToSubredditListener() {
@Override @Override
public void isSubscribed() { public void isSubscribed() {

View File

@ -33,7 +33,10 @@ import com.bumptech.glide.request.RequestOptions;
import com.lsjwzh.widget.materialloadingprogressbar.CircleProgressBar; import com.lsjwzh.widget.materialloadingprogressbar.CircleProgressBar;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Set;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import butterknife.BindView; import butterknife.BindView;
@ -97,6 +100,8 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi
private String mAccountName; private String mAccountName;
private Post mPost; private Post mPost;
private ArrayList<Comment> mVisibleComments; private ArrayList<Comment> mVisibleComments;
private Set<Integer> loadedComments;
private Locale mLocale; private Locale mLocale;
private RequestManager mGlide; private RequestManager mGlide;
private RecyclerView.RecycledViewPool recycledViewPool; private RecyclerView.RecycledViewPool recycledViewPool;
@ -211,6 +216,7 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi
mAccountName = accountName; mAccountName = accountName;
mPost = post; mPost = post;
mVisibleComments = new ArrayList<>(); mVisibleComments = new ArrayList<>();
loadedComments = new HashSet<>();
mLocale = locale; mLocale = locale;
mSingleCommentId = singleCommentId; mSingleCommentId = singleCommentId;
mIsSingleCommentThreadMode = isSingleCommentThreadMode; mIsSingleCommentThreadMode = isSingleCommentThreadMode;
@ -632,12 +638,19 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi
} else { } else {
notifyItemRemoved(placeholderPosition); notifyItemRemoved(placeholderPosition);
} }
List<Comment> trulyNewComments = new ArrayList<>();
mVisibleComments.addAll(placeholderPosition, expandedComments); for (int i = 0; i < expandedComments.size(); i++) {
if (loadedComments.contains(expandedComments.get(i).getId()) || expandedComments.get(i).getDepth() != parentComment.getDepth() + 1) {
continue;
}
trulyNewComments.add(expandedComments.get(i));
loadedComments.add(expandedComments.get(i).getId());
}
mVisibleComments.addAll(placeholderPosition, trulyNewComments);
if (mIsSingleCommentThreadMode) { if (mIsSingleCommentThreadMode) {
notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size()); notifyItemRangeInserted(placeholderPosition + 1, trulyNewComments.size());
} else { } else {
notifyItemRangeInserted(placeholderPosition, expandedComments.size()); notifyItemRangeInserted(placeholderPosition, trulyNewComments.size());
} }
} }
@ -648,8 +661,15 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi
mVisibleComments.get(parentPosition).removeMoreChildrenIds(); mVisibleComments.get(parentPosition).removeMoreChildrenIds();
} }
} }
ArrayList<Comment> trulyNewComments = new ArrayList<>();
mVisibleComments.get(parentPosition).addChildren(expandedComments); for (int i = 0; i < expandedComments.size(); i++) {
if (loadedComments.contains(expandedComments.get(i).getId()) || expandedComments.get(i).getDepth() != parentComment.getDepth() + 1) {
continue;
}
trulyNewComments.add(expandedComments.get(i));
loadedComments.add(expandedComments.get(i).getId());
}
mVisibleComments.get(parentPosition).addChildren(trulyNewComments);
if (mIsSingleCommentThreadMode) { if (mIsSingleCommentThreadMode) {
notifyItemChanged(parentPosition + 1); notifyItemChanged(parentPosition + 1);
} else { } else {
@ -668,6 +688,9 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi
((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments); ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments);
mVisibleComments.addAll(placeholderPosition, expandedComments); mVisibleComments.addAll(placeholderPosition, expandedComments);
for (int j = 0; j < expandedComments.size(); j++) {
loadedComments.add(expandedComments.get(j).getId());
}
if (mIsSingleCommentThreadMode) { if (mIsSingleCommentThreadMode) {
notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size()); notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size());
} else { } else {
@ -835,6 +858,9 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi
int sizeBefore = mVisibleComments.size(); int sizeBefore = mVisibleComments.size();
mVisibleComments.addAll(comments); mVisibleComments.addAll(comments);
for (int i = 0; i < comments.size(); i++) {
loadedComments.add(comments.get(i).getId());
}
if (mIsSingleCommentThreadMode) { if (mIsSingleCommentThreadMode) {
notifyItemRangeInserted(sizeBefore, comments.size() + 1); notifyItemRangeInserted(sizeBefore, comments.size() + 1);
} else { } else {
@ -865,7 +891,7 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi
} }
mVisibleComments.add(0, comment); mVisibleComments.add(0, comment);
loadedComments.add(comment.getId());
if (isInitiallyLoading) { if (isInitiallyLoading) {
notifyItemInserted(1); notifyItemInserted(1);
} else { } else {
@ -890,6 +916,9 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi
expandChildren(mVisibleComments.get(parentPosition).getChildren(), newList); expandChildren(mVisibleComments.get(parentPosition).getChildren(), newList);
mVisibleComments.get(parentPosition).setExpanded(true); mVisibleComments.get(parentPosition).setExpanded(true);
mVisibleComments.addAll(parentPosition + 1, newList); mVisibleComments.addAll(parentPosition + 1, newList);
for (int i = 0; i < newList.size(); i++) {
loadedComments.add(newList.get(i).getId());
}
if (mIsSingleCommentThreadMode) { if (mIsSingleCommentThreadMode) {
notifyItemChanged(parentPosition + 1); notifyItemChanged(parentPosition + 1);
notifyItemRangeInserted(parentPosition + 2, newList.size()); notifyItemRangeInserted(parentPosition + 2, newList.size());
@ -899,6 +928,9 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi
} }
} else { } else {
mVisibleComments.add(parentPosition + 1, comment); mVisibleComments.add(parentPosition + 1, comment);
loadedComments.add(comment.getId());
if (mIsSingleCommentThreadMode) { if (mIsSingleCommentThreadMode) {
notifyItemChanged(parentPosition + 1); notifyItemChanged(parentPosition + 1);
notifyItemInserted(parentPosition + 2); notifyItemInserted(parentPosition + 2);

View File

@ -27,8 +27,6 @@ import java.util.concurrent.Executor;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import eu.toldi.infinityforlemmy.utils.LemmyUtils;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
import eu.toldi.infinityforlemmy.NetworkState; import eu.toldi.infinityforlemmy.NetworkState;
import eu.toldi.infinityforlemmy.R; import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; import eu.toldi.infinityforlemmy.RedditDataRoomDatabase;
@ -37,6 +35,8 @@ import eu.toldi.infinityforlemmy.asynctasks.CheckIsSubscribedToSubreddit;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.subreddit.SubredditData; import eu.toldi.infinityforlemmy.subreddit.SubredditData;
import eu.toldi.infinityforlemmy.subreddit.SubredditSubscription; import eu.toldi.infinityforlemmy.subreddit.SubredditSubscription;
import eu.toldi.infinityforlemmy.utils.LemmyUtils;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
import pl.droidsonroids.gif.GifImageView; import pl.droidsonroids.gif.GifImageView;
import retrofit2.Retrofit; import retrofit2.Retrofit;
@ -146,7 +146,7 @@ public class SubredditListingRecyclerViewAdapter extends PagedListAdapter<Subred
if (!isMultiSelection) { if (!isMultiSelection) {
CheckIsSubscribedToSubreddit.checkIsSubscribedToSubreddit(executor, new Handler(), CheckIsSubscribedToSubreddit.checkIsSubscribedToSubreddit(executor, new Handler(),
redditDataRoomDatabase, subredditData.getName(), accountName, redditDataRoomDatabase, LemmyUtils.actorID2FullName(subredditData.getActorId()), accountName,
new CheckIsSubscribedToSubreddit.CheckIsSubscribedToSubredditListener() { new CheckIsSubscribedToSubreddit.CheckIsSubscribedToSubredditListener() {
@Override @Override
public void isSubscribed() { public void isSubscribed() {

View File

@ -11,7 +11,7 @@ import eu.toldi.infinityforlemmy.subscribedsubreddit.SubscribedSubredditData;
public class CheckIsSubscribedToSubreddit { public class CheckIsSubscribedToSubreddit {
public static void checkIsSubscribedToSubreddit(Executor executor, Handler handler, RedditDataRoomDatabase redditDataRoomDatabase, public static void checkIsSubscribedToSubreddit(Executor executor, Handler handler, RedditDataRoomDatabase redditDataRoomDatabase,
String subredditName, String accountName, String communityQualifiedName, String accountName,
CheckIsSubscribedToSubredditListener checkIsSubscribedToSubredditListener) { CheckIsSubscribedToSubredditListener checkIsSubscribedToSubredditListener) {
executor.execute(() -> { executor.execute(() -> {
if (accountName == null) { if (accountName == null) {
@ -19,7 +19,7 @@ public class CheckIsSubscribedToSubreddit {
redditDataRoomDatabase.accountDao().insert(Account.getAnonymousAccount()); redditDataRoomDatabase.accountDao().insert(Account.getAnonymousAccount());
} }
} }
SubscribedSubredditData subscribedSubredditData = redditDataRoomDatabase.subscribedSubredditDao().getSubscribedSubreddit(subredditName, accountName == null ? "-" : accountName); SubscribedSubredditData subscribedSubredditData = redditDataRoomDatabase.subscribedSubredditDao().getSubscribedSubredditByQualifiedName(communityQualifiedName, accountName == null ? "-" : accountName);
handler.post(() -> { handler.post(() -> {
if (subscribedSubredditData != null) { if (subscribedSubredditData != null) {
checkIsSubscribedToSubredditListener.isSubscribed(); checkIsSubscribedToSubredditListener.isSubscribed();

View File

@ -311,12 +311,35 @@ public class Comment implements Parcelable {
children = moreChildren; children = moreChildren;
} else { } else {
if (children.size() > 1 && children.get(children.size() - 1).placeholderType == PLACEHOLDER_LOAD_MORE_COMMENTS) { if (children.size() > 1 && children.get(children.size() - 1).placeholderType == PLACEHOLDER_LOAD_MORE_COMMENTS) {
children.addAll(children.size() - 2, moreChildren); for (int i = 0; i < moreChildren.size(); i++) {
boolean found = false;
for (int j = 0; j < children.size(); j++) {
if (children.get(j).id == moreChildren.get(i).id) {
found = true;
break;
}
}
if (!found)
children.add(moreChildren.get(i));
}
} else { } else {
children.addAll(moreChildren); // Add only unique children
for (int i = 0; i < moreChildren.size(); i++) {
boolean found = false;
for (int j = 0; j < children.size(); j++) {
if (children.get(j).id == moreChildren.get(i).id) {
found = true;
break;
}
}
if (!found) {
children.add(moreChildren.get(i));
}
}
} }
} }
childCount += moreChildren == null ? 0 : moreChildren.size(); //childCount += moreChildren == null ? 0 : moreChildren.size();
assertChildrenDepth(); assertChildrenDepth();
} }

View File

@ -30,7 +30,7 @@ public class FetchComment {
@Override @Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
if (response.isSuccessful()) { if (response.isSuccessful()) {
ParseComment.parseComments(executor, handler, response.body(), ParseComment.parseComments(executor, handler, response.body(), commentId,
expandChildren, new ParseComment.ParseCommentListener() { expandChildren, new ParseComment.ParseCommentListener() {
@Override @Override
public void onParseCommentSuccess(ArrayList<Comment> topLevelComments, public void onParseCommentSuccess(ArrayList<Comment> topLevelComments,

View File

@ -24,7 +24,7 @@ import eu.toldi.infinityforlemmy.utils.LemmyUtils;
public class ParseComment { public class ParseComment {
public static void parseComments(Executor executor, Handler handler, String response, public static void parseComments(Executor executor, Handler handler, String response, Integer commentId,
boolean expandChildren, boolean expandChildren,
ParseCommentListener parseCommentListener) { ParseCommentListener parseCommentListener) {
executor.execute(() -> { executor.execute(() -> {
@ -48,8 +48,8 @@ public class ParseComment {
topLevelComments.add(singleComment); topLevelComments.add(singleComment);
} }
} }
Comment parentComment = orderedComments.get(0); Comment parentComment = (commentId != null) ? parsedComments.get(commentId) : null;
if (parentComment.getDepth() == 0) if (parentComment != null && parentComment.getDepth() == 0)
parentComment = null; parentComment = null;
for (int i = orderedComments.size() - 1; i >= 0; i--) { for (int i = orderedComments.size() - 1; i >= 0; i--) {
@ -71,9 +71,9 @@ public class ParseComment {
expandChildren(newComments, expandedNewComments, expandChildren); expandChildren(newComments, expandedNewComments, expandChildren);
if (topLevelComments.isEmpty() && !parsedComments.isEmpty() && parentComment != null) { if (topLevelComments.isEmpty() && !parsedComments.isEmpty() && parentComment != null) {
for (int i = orderedComments.size() - 1; i >= 0; i--) { for (int i = 0; i < orderedComments.size(); i++) {
Comment c = orderedComments.get(i); Comment c = orderedComments.get(i);
if (c.getDepth() > parentComment.getDepth()) if (c.getParentId() == parentComment.getId())
expandedNewComments.add(c); expandedNewComments.add(c);
} }
} }

View File

@ -1312,7 +1312,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic
if (mRespectSubredditRecommendedSortType) { if (mRespectSubredditRecommendedSortType) {
fetchCommentsRespectRecommendedSort(false); fetchCommentsRespectRecommendedSort(false);
} else { } else {
ParseComment.parseComments(mExecutor, new Handler(), response.body(), ParseComment.parseComments(mExecutor, new Handler(), response.body(), null,
mExpandChildren, new ParseComment.ParseCommentListener() { mExpandChildren, new ParseComment.ParseCommentListener() {
@Override @Override
public void onParseCommentSuccess(ArrayList<Comment> topLevelComments, ArrayList<Comment> expandedComments, Integer parentId, ArrayList<Integer> moreChildrenIds) { public void onParseCommentSuccess(ArrayList<Comment> topLevelComments, ArrayList<Comment> expandedComments, Integer parentId, ArrayList<Integer> moreChildrenIds) {

View File

@ -28,6 +28,9 @@ public interface SubscribedSubredditDao {
@Query("SELECT * from subscribed_subreddits WHERE name = :subredditName COLLATE NOCASE AND username = :accountName COLLATE NOCASE LIMIT 1") @Query("SELECT * from subscribed_subreddits WHERE name = :subredditName COLLATE NOCASE AND username = :accountName COLLATE NOCASE LIMIT 1")
SubscribedSubredditData getSubscribedSubreddit(String subredditName, String accountName); SubscribedSubredditData getSubscribedSubreddit(String subredditName, String accountName);
@Query("SELECT * from subscribed_subreddits WHERE qualified_name = :qualified_name COLLATE NOCASE AND username = :accountName COLLATE NOCASE LIMIT 1")
SubscribedSubredditData getSubscribedSubredditByQualifiedName(String qualified_name, String accountName);
@Query("DELETE FROM subscribed_subreddits WHERE name = :subredditName COLLATE NOCASE AND username = :accountName COLLATE NOCASE") @Query("DELETE FROM subscribed_subreddits WHERE name = :subredditName COLLATE NOCASE AND username = :accountName COLLATE NOCASE")
void deleteSubscribedSubreddit(String subredditName, String accountName); void deleteSubscribedSubreddit(String subredditName, String accountName);
} }