Merge pull request #980 from lbryio/channel-comment-hash

properly handle channel comment notifications
This commit is contained in:
Akinwale Ariwodola 2020-08-20 16:26:08 +01:00 committed by GitHub
commit 47cbc3624c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 74 additions and 22 deletions

View file

@ -18,6 +18,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.AppCompatSpinner; import androidx.appcompat.widget.AppCompatSpinner;
import androidx.core.widget.NestedScrollView;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -64,6 +65,8 @@ public class ChannelCommentsFragment extends Fragment implements SdkStatusListen
@Setter @Setter
private Claim claim; private Claim claim;
@Setter
private String commentHash;
private CommentListAdapter commentListAdapter; private CommentListAdapter commentListAdapter;
private Comment replyToComment; private Comment replyToComment;
@ -156,7 +159,8 @@ public class ChannelCommentsFragment extends Fragment implements SdkStatusListen
if (context instanceof MainActivity) { if (context instanceof MainActivity) {
((MainActivity) context).addWalletBalanceListener(this); ((MainActivity) context).addWalletBalanceListener(this);
} }
checkCommentSdkInitializing();
checkAndLoadComments();
} }
public void onStop() { public void onStop() {
@ -180,13 +184,11 @@ public class ChannelCommentsFragment extends Fragment implements SdkStatusListen
@Override @Override
public void onSdkReady() { public void onSdkReady() {
fetchChannels(); fetchChannels();
checkAndLoadComments();
} }
private void checkAndLoadComments() { private void checkAndLoadComments() {
View root = getView(); View root = getView();
if (root != null) { if (root != null) {
checkCommentSdkInitializing();
RecyclerView commentsList = root.findViewById(R.id.channel_comments_list); RecyclerView commentsList = root.findViewById(R.id.channel_comments_list);
if (commentsList == null || commentsList.getAdapter() == null || commentsList.getAdapter().getItemCount() == 0) { if (commentsList == null || commentsList.getAdapter() == null || commentsList.getAdapter().getItemCount() == 0) {
loadComments(); loadComments();
@ -198,7 +200,7 @@ public class ChannelCommentsFragment extends Fragment implements SdkStatusListen
View root = getView(); View root = getView();
ProgressBar relatedLoading = root.findViewById(R.id.channel_comments_progress); ProgressBar relatedLoading = root.findViewById(R.id.channel_comments_progress);
if (claim != null && root != null) { 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 @Override
public void onSuccess(List<Comment> comments, boolean hasReachedEnd) { public void onSuccess(List<Comment> comments, boolean hasReachedEnd) {
Context ctx = getContext(); Context ctx = getContext();
@ -228,6 +230,7 @@ public class ChannelCommentsFragment extends Fragment implements SdkStatusListen
checkNoComments(); checkNoComments();
resolveCommentPosters(); 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() { private void resolveCommentPosters() {
if (commentListAdapter != null) { if (commentListAdapter != null) {
List<String> urlsToResolve = new ArrayList<>(commentListAdapter.getClaimUrlsToResolve()); List<String> urlsToResolve = new ArrayList<>(commentListAdapter.getClaimUrlsToResolve());

View file

@ -6,6 +6,7 @@ import android.content.Intent;
import android.graphics.Color; import android.graphics.Color;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -14,7 +15,6 @@ import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter; import androidx.viewpager2.adapter.FragmentStateAdapter;
@ -62,7 +62,7 @@ import lombok.SneakyThrows;
public class ChannelFragment extends BaseFragment implements FetchChannelsListener { public class ChannelFragment extends BaseFragment implements FetchChannelsListener {
private Claim claim; private Claim claim;
private boolean subscribing; private boolean subscribing;
private String url; private String currentUrl;
private View layoutResolving; private View layoutResolving;
private View layoutDisplayArea; private View layoutDisplayArea;
@ -86,6 +86,9 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen
private View layoutNothingAtLocation; private View layoutNothingAtLocation;
private View layoutLoadingState; private View layoutLoadingState;
// if this is set, scroll to the specific comment on load
private String commentHash;
public View onCreateView(@NonNull LayoutInflater inflater, public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) { ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_channel, container, false); View root = inflater.inflate(R.layout.fragment_channel, container, false);
@ -321,7 +324,7 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen
private void checkParams() { private void checkParams() {
boolean updateRequired = false; boolean updateRequired = false;
Map<String, Object> params = getParams(); Map<String, Object> params = getParams();
String newUrl = null;
if (params != null) { if (params != null) {
if (params.containsKey("claim")) { if (params.containsKey("claim")) {
Claim claim = (Claim) params.get("claim"); Claim claim = (Claim) params.get("claim");
@ -331,21 +334,39 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen
} }
} }
if (params.containsKey("url")) { if (params.containsKey("url")) {
String newUrl = params.get("url").toString(); LbryUri newLbryUri = LbryUri.tryParse(params.get("url").toString());
if (claim == null || !newUrl.equalsIgnoreCase(url)) { 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.claim = null;
this.url = newUrl; this.currentUrl = newUrl;
updateRequired = true; updateRequired = true;
} }
} }
} }
}
if (updateRequired) { if (updateRequired) {
resetSubCount(); resetSubCount();
if (!Helper.isNullOrEmpty(url)) { if (!Helper.isNullOrEmpty(currentUrl)) {
// check if the claim is already cached // check if the claim is already cached
ClaimCacheKey key = new ClaimCacheKey(); ClaimCacheKey key = new ClaimCacheKey();
key.setUrl(url); key.setUrl(currentUrl);
if (Lbry.claimCache.containsKey(key)) { if (Lbry.claimCache.containsKey(key)) {
claim = Lbry.claimCache.get(key); claim = Lbry.claimCache.get(key);
} else { } else {
@ -357,8 +378,8 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen
} }
} }
if (!Helper.isNullOrEmpty(url)) { if (!Helper.isNullOrEmpty(currentUrl)) {
Helper.saveUrlHistory(url, claim != null ? claim.getTitle() : null, UrlSuggestion.TYPE_CHANNEL); Helper.saveUrlHistory(currentUrl, claim != null ? claim.getTitle() : null, UrlSuggestion.TYPE_CHANNEL);
} }
if (claim != null) { if (claim != null) {
@ -369,13 +390,13 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen
private void resolveUrl() { private void resolveUrl() {
Helper.setViewVisibility(layoutDisplayArea, View.INVISIBLE); Helper.setViewVisibility(layoutDisplayArea, View.INVISIBLE);
Helper.setViewVisibility(layoutLoadingState, View.VISIBLE); 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 @Override
public void onSuccess(List<Claim> claims) { public void onSuccess(List<Claim> claims) {
if (claims.size() > 0 && !Helper.isNullOrEmpty(claims.get(0).getClaimId())) { if (claims.size() > 0 && !Helper.isNullOrEmpty(claims.get(0).getClaimId())) {
claim = claims.get(0); claim = claims.get(0);
if (!Helper.isNullOrEmpty(url)) { if (!Helper.isNullOrEmpty(currentUrl)) {
Helper.saveUrlHistory(url, claim.getTitle(), UrlSuggestion.TYPE_CHANNEL); Helper.saveUrlHistory(currentUrl, claim.getTitle(), UrlSuggestion.TYPE_CHANNEL);
} }
renderClaim(); renderClaim();
@ -441,7 +462,16 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen
try { try {
if (tabPager.getAdapter() == null && context instanceof MainActivity) { 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() { new TabLayoutMediator(tabLayout, tabPager, new TabLayoutMediator.TabConfigurationStrategy() {
@Override @Override
@ -491,9 +521,11 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen
private static class ChannelPagerAdapter extends FragmentStateAdapter { private static class ChannelPagerAdapter extends FragmentStateAdapter {
private Claim channelClaim; private Claim channelClaim;
public ChannelPagerAdapter(Claim channelClaim, FragmentActivity activity) { private String commentHash;
public ChannelPagerAdapter(Claim channelClaim, String commentHash, FragmentActivity activity) {
super(activity); super(activity);
this.channelClaim = channelClaim; this.channelClaim = channelClaim;
this.commentHash = commentHash;
} }
@SneakyThrows @SneakyThrows
@ -526,6 +558,9 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen
if (channelClaim != null) { if (channelClaim != null) {
commentsFragment.setClaim(channelClaim); commentsFragment.setClaim(channelClaim);
} }
if (!Helper.isNullOrEmpty(commentHash)) {
commentsFragment.setCommentHash(commentHash);
}
return commentsFragment; return commentsFragment;
} }

View file

@ -2218,7 +2218,7 @@ public class FileViewFragment extends BaseFragment implements
if (root != null && !Helper.isNullOrEmpty(commentHash) && commentListAdapter != null && commentListAdapter.getItemCount() > 0) { if (root != null && !Helper.isNullOrEmpty(commentHash) && commentListAdapter != null && commentListAdapter.getItemCount() > 0) {
RecyclerView commentList = root.findViewById(R.id.file_view_comments_list); RecyclerView commentList = root.findViewById(R.id.file_view_comments_list);
int position = commentListAdapter.getPositionForComment(commentHash); int position = commentListAdapter.getPositionForComment(commentHash);
if (position > -1) { if (position > -1 && commentList.getLayoutManager() != null) {
NestedScrollView scrollView = root.findViewById(R.id.file_view_scroll_view); NestedScrollView scrollView = root.findViewById(R.id.file_view_scroll_view);
scrollView.requestChildFocus(commentList, commentList); scrollView.requestChildFocus(commentList, commentList);
commentList.getLayoutManager().scrollToPosition(position); commentList.getLayoutManager().scrollToPosition(position);