From 1f9a0886a011fcc9fb7b0a3aea7daa72196b7a23 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Thu, 20 Aug 2020 16:20:46 +0100 Subject: [PATCH] properly handle channel comment notifications --- .../ui/channel/ChannelCommentsFragment.java | 25 +++++-- .../browser/ui/channel/ChannelFragment.java | 69 ++++++++++++++----- .../ui/findcontent/FileViewFragment.java | 2 +- 3 files changed, 74 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/io/lbry/browser/ui/channel/ChannelCommentsFragment.java b/app/src/main/java/io/lbry/browser/ui/channel/ChannelCommentsFragment.java index ec2a006a..3189cc5e 100644 --- a/app/src/main/java/io/lbry/browser/ui/channel/ChannelCommentsFragment.java +++ b/app/src/main/java/io/lbry/browser/ui/channel/ChannelCommentsFragment.java @@ -18,6 +18,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.AppCompatSpinner; +import androidx.core.widget.NestedScrollView; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -64,6 +65,8 @@ public class ChannelCommentsFragment extends Fragment implements SdkStatusListen @Setter private Claim claim; + @Setter + private String commentHash; private CommentListAdapter commentListAdapter; private Comment replyToComment; @@ -156,7 +159,8 @@ public class ChannelCommentsFragment extends Fragment implements SdkStatusListen if (context instanceof MainActivity) { ((MainActivity) context).addWalletBalanceListener(this); } - checkCommentSdkInitializing(); + + checkAndLoadComments(); } public void onStop() { @@ -180,13 +184,11 @@ public class ChannelCommentsFragment extends Fragment implements SdkStatusListen @Override public void onSdkReady() { fetchChannels(); - checkAndLoadComments(); } private void checkAndLoadComments() { View root = getView(); if (root != null) { - checkCommentSdkInitializing(); RecyclerView commentsList = root.findViewById(R.id.channel_comments_list); if (commentsList == null || commentsList.getAdapter() == null || commentsList.getAdapter().getItemCount() == 0) { loadComments(); @@ -198,7 +200,7 @@ public class ChannelCommentsFragment extends Fragment implements SdkStatusListen View root = getView(); ProgressBar relatedLoading = root.findViewById(R.id.channel_comments_progress); if (claim != null && root != null) { - CommentListTask task = new CommentListTask(1, 500, claim.getClaimId(), relatedLoading, new CommentListHandler() { + CommentListTask task = new CommentListTask(1, 200, claim.getClaimId(), relatedLoading, new CommentListHandler() { @Override public void onSuccess(List comments, boolean hasReachedEnd) { Context ctx = getContext(); @@ -228,6 +230,7 @@ public class ChannelCommentsFragment extends Fragment implements SdkStatusListen checkNoComments(); resolveCommentPosters(); + scrollToCommentHash(); } } @@ -240,6 +243,20 @@ public class ChannelCommentsFragment extends Fragment implements SdkStatusListen } } + private void scrollToCommentHash() { + View root = getView(); + // check for the position of commentHash if set + if (root != null && !Helper.isNullOrEmpty(commentHash) && commentListAdapter != null && commentListAdapter.getItemCount() > 0) { + RecyclerView commentList = root.findViewById(R.id.channel_comments_list); + int position = commentListAdapter.getPositionForComment(commentHash); + if (position > -1 && commentList.getLayoutManager() != null) { + NestedScrollView scrollView = root.findViewById(R.id.channel_comments_area); + scrollView.requestChildFocus(commentList, commentList); + commentList.getLayoutManager().scrollToPosition(position); + } + } + } + private void resolveCommentPosters() { if (commentListAdapter != null) { List urlsToResolve = new ArrayList<>(commentListAdapter.getClaimUrlsToResolve()); diff --git a/app/src/main/java/io/lbry/browser/ui/channel/ChannelFragment.java b/app/src/main/java/io/lbry/browser/ui/channel/ChannelFragment.java index 0f325bc8..9149e0c4 100644 --- a/app/src/main/java/io/lbry/browser/ui/channel/ChannelFragment.java +++ b/app/src/main/java/io/lbry/browser/ui/channel/ChannelFragment.java @@ -6,6 +6,7 @@ import android.content.Intent; import android.graphics.Color; import android.os.AsyncTask; import android.os.Bundle; +import android.os.Handler; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -14,7 +15,6 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; -import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.viewpager2.adapter.FragmentStateAdapter; @@ -62,7 +62,7 @@ import lombok.SneakyThrows; public class ChannelFragment extends BaseFragment implements FetchChannelsListener { private Claim claim; private boolean subscribing; - private String url; + private String currentUrl; private View layoutResolving; private View layoutDisplayArea; @@ -86,6 +86,9 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen private View layoutNothingAtLocation; private View layoutLoadingState; + // if this is set, scroll to the specific comment on load + private String commentHash; + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_channel, container, false); @@ -321,7 +324,7 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen private void checkParams() { boolean updateRequired = false; Map params = getParams(); - + String newUrl = null; if (params != null) { if (params.containsKey("claim")) { Claim claim = (Claim) params.get("claim"); @@ -331,21 +334,39 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen } } if (params.containsKey("url")) { - String newUrl = params.get("url").toString(); - if (claim == null || !newUrl.equalsIgnoreCase(url)) { - this.claim = null; - this.url = newUrl; - updateRequired = true; + LbryUri newLbryUri = LbryUri.tryParse(params.get("url").toString()); + if (newLbryUri != null) { + newUrl = newLbryUri.toString(); + String qs = newLbryUri.getQueryString(); + if (!Helper.isNullOrEmpty(qs)) { + String[] qsPairs = qs.split("&"); + for (String pair : qsPairs) { + String[] parts = pair.split("="); + if (parts.length < 2) { + continue; + } + if ("comment_hash".equalsIgnoreCase(parts[0])) { + commentHash = parts[1]; + break; + } + } + } + + if (claim == null || !newUrl.equalsIgnoreCase(currentUrl)) { + this.claim = null; + this.currentUrl = newUrl; + updateRequired = true; + } } } } if (updateRequired) { resetSubCount(); - if (!Helper.isNullOrEmpty(url)) { + if (!Helper.isNullOrEmpty(currentUrl)) { // check if the claim is already cached ClaimCacheKey key = new ClaimCacheKey(); - key.setUrl(url); + key.setUrl(currentUrl); if (Lbry.claimCache.containsKey(key)) { claim = Lbry.claimCache.get(key); } else { @@ -357,8 +378,8 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen } } - if (!Helper.isNullOrEmpty(url)) { - Helper.saveUrlHistory(url, claim != null ? claim.getTitle() : null, UrlSuggestion.TYPE_CHANNEL); + if (!Helper.isNullOrEmpty(currentUrl)) { + Helper.saveUrlHistory(currentUrl, claim != null ? claim.getTitle() : null, UrlSuggestion.TYPE_CHANNEL); } if (claim != null) { @@ -369,13 +390,13 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen private void resolveUrl() { Helper.setViewVisibility(layoutDisplayArea, View.INVISIBLE); Helper.setViewVisibility(layoutLoadingState, View.VISIBLE); - ResolveTask task = new ResolveTask(url, Lbry.LBRY_TV_CONNECTION_STRING, layoutResolving, new ClaimListResultHandler() { + ResolveTask task = new ResolveTask(currentUrl, Lbry.LBRY_TV_CONNECTION_STRING, layoutResolving, new ClaimListResultHandler() { @Override public void onSuccess(List claims) { if (claims.size() > 0 && !Helper.isNullOrEmpty(claims.get(0).getClaimId())) { claim = claims.get(0); - if (!Helper.isNullOrEmpty(url)) { - Helper.saveUrlHistory(url, claim.getTitle(), UrlSuggestion.TYPE_CHANNEL); + if (!Helper.isNullOrEmpty(currentUrl)) { + Helper.saveUrlHistory(currentUrl, claim.getTitle(), UrlSuggestion.TYPE_CHANNEL); } renderClaim(); @@ -441,7 +462,16 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen try { if (tabPager.getAdapter() == null && context instanceof MainActivity) { - tabPager.setAdapter(new ChannelPagerAdapter(claim, (MainActivity) context)); + tabPager.setAdapter(new ChannelPagerAdapter(claim, commentHash, (MainActivity) context)); + if (!Helper.isNullOrEmpty(commentHash)) { + // set the Comments tab active if a comment hash is set + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + tabPager.setCurrentItem(2); + } + }, 500); + } } new TabLayoutMediator(tabLayout, tabPager, new TabLayoutMediator.TabConfigurationStrategy() { @Override @@ -491,9 +521,11 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen private static class ChannelPagerAdapter extends FragmentStateAdapter { private Claim channelClaim; - public ChannelPagerAdapter(Claim channelClaim, FragmentActivity activity) { + private String commentHash; + public ChannelPagerAdapter(Claim channelClaim, String commentHash, FragmentActivity activity) { super(activity); this.channelClaim = channelClaim; + this.commentHash = commentHash; } @SneakyThrows @@ -526,6 +558,9 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen if (channelClaim != null) { commentsFragment.setClaim(channelClaim); } + if (!Helper.isNullOrEmpty(commentHash)) { + commentsFragment.setCommentHash(commentHash); + } return commentsFragment; } diff --git a/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java b/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java index 6a34eca8..30e41d01 100644 --- a/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java +++ b/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java @@ -2218,7 +2218,7 @@ public class FileViewFragment extends BaseFragment implements if (root != null && !Helper.isNullOrEmpty(commentHash) && commentListAdapter != null && commentListAdapter.getItemCount() > 0) { RecyclerView commentList = root.findViewById(R.id.file_view_comments_list); int position = commentListAdapter.getPositionForComment(commentHash); - if (position > -1) { + if (position > -1 && commentList.getLayoutManager() != null) { NestedScrollView scrollView = root.findViewById(R.id.file_view_scroll_view); scrollView.requestChildFocus(commentList, commentList); commentList.getLayoutManager().scrollToPosition(position);