Added ability to read comments on claims (#920)
* Added ability to read comments on claims * Added simple handling for pagination in CommentListTask
This commit is contained in:
parent
a40c160ac6
commit
dcc91f75cc
9 changed files with 364 additions and 12 deletions
|
@ -0,0 +1,52 @@
|
|||
package io.lbry.browser.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import io.lbry.browser.R;
|
||||
import io.lbry.browser.model.Comment;
|
||||
|
||||
public class CommentListAdapter extends RecyclerView.Adapter<CommentListAdapter.ViewHolder> {
|
||||
private List<Comment> items;
|
||||
private Context context;
|
||||
|
||||
public CommentListAdapter(List<Comment> items, Context context) {
|
||||
this.items = items;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return items != null ? items.size() : 0;
|
||||
}
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
protected TextView channelName;
|
||||
protected TextView commentText;
|
||||
|
||||
public ViewHolder (View v) {
|
||||
super(v);
|
||||
channelName = v.findViewById(R.id.comment_channel_name);
|
||||
commentText = v.findViewById(R.id.comment_text);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(context).inflate(R.layout.list_item_comment, parent, false);
|
||||
return new CommentListAdapter.ViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
Comment comment = items.get(position);
|
||||
holder.channelName.setText(comment.getChannelName());
|
||||
holder.commentText.setText(comment.getText());
|
||||
}
|
||||
}
|
40
app/src/main/java/io/lbry/browser/model/Comment.java
Normal file
40
app/src/main/java/io/lbry/browser/model/Comment.java
Normal file
|
@ -0,0 +1,40 @@
|
|||
package io.lbry.browser.model;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class Comment {
|
||||
private final String channelName, text, id, parentId;
|
||||
|
||||
public Comment(String channelName, String text, String id, String parentId) {
|
||||
this.channelName = channelName;
|
||||
this.text = text;
|
||||
this.id = id;
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
public static Comment fromJSONObject(JSONObject jsonObject) {
|
||||
try {
|
||||
String parentId = null;
|
||||
if (jsonObject.has("parent_id")) {
|
||||
parentId = jsonObject.getString("parent_id");
|
||||
}
|
||||
|
||||
return new Comment(
|
||||
jsonObject.getString("channel_name"),
|
||||
jsonObject.getString("comment"),
|
||||
jsonObject.getString("comment_id"),
|
||||
parentId
|
||||
);
|
||||
} catch (JSONException ex) {
|
||||
// TODO: Throw exception
|
||||
Log.e("Comments", ex.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package io.lbry.browser.tasks;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.lbry.browser.model.Comment;
|
||||
|
||||
public interface CommentListHandler {
|
||||
void onSuccess(List<Comment> comments);
|
||||
void onError(Exception error);
|
||||
}
|
77
app/src/main/java/io/lbry/browser/tasks/CommentListTask.java
Normal file
77
app/src/main/java/io/lbry/browser/tasks/CommentListTask.java
Normal file
|
@ -0,0 +1,77 @@
|
|||
package io.lbry.browser.tasks;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.lbry.browser.model.Comment;
|
||||
import io.lbry.browser.utils.Helper;
|
||||
import io.lbry.browser.utils.Lbry;
|
||||
|
||||
public class CommentListTask extends AsyncTask<Void, Void, List<Comment>> {
|
||||
private final int page;
|
||||
private final int pageSize;
|
||||
private final String claim;
|
||||
private ProgressBar progressBar;
|
||||
private CommentListHandler handler;
|
||||
private Exception error;
|
||||
|
||||
public CommentListTask(int page, int pageSize, String claim, ProgressBar progressBar, CommentListHandler handler) {
|
||||
this.page = page;
|
||||
this.pageSize = pageSize;
|
||||
this.claim = claim;
|
||||
this.progressBar = progressBar;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
protected void onPreExecute() {
|
||||
Helper.setViewVisibility(progressBar, View.VISIBLE);
|
||||
}
|
||||
|
||||
protected List<Comment> doInBackground(Void... voids) {
|
||||
List<Comment> comments = null;
|
||||
|
||||
try {
|
||||
Map<String, Object> options = new HashMap<>();
|
||||
|
||||
options.put("claim_id", claim);
|
||||
options.put("page", page);
|
||||
options.put("page_size", pageSize);
|
||||
options.put("include_replies", false);
|
||||
options.put("is_channel_signature_valid", true);
|
||||
options.put("visible", true);
|
||||
options.put("hidden", false);
|
||||
|
||||
JSONObject result = (JSONObject) Lbry.genericApiCall(Lbry.METHOD_COMMENT_LIST, options);
|
||||
JSONArray items = result.getJSONArray("items");
|
||||
comments = new ArrayList<>();
|
||||
for (int i = 0; i < items.length(); i++) {
|
||||
comments.add(Comment.fromJSONObject(items.getJSONObject(i)));
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
error = ex;
|
||||
}
|
||||
return comments;
|
||||
}
|
||||
|
||||
protected void onPostExecute(List<Comment> comments) {
|
||||
Helper.setViewVisibility(progressBar, View.GONE);
|
||||
if (handler != null) {
|
||||
if (comments != null && error == null) {
|
||||
handler.onSuccess(comments);
|
||||
} else {
|
||||
handler.onError(error);
|
||||
if (error != null) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -89,6 +89,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import io.lbry.browser.MainActivity;
|
||||
import io.lbry.browser.R;
|
||||
import io.lbry.browser.adapter.ClaimListAdapter;
|
||||
import io.lbry.browser.adapter.CommentListAdapter;
|
||||
import io.lbry.browser.adapter.TagListAdapter;
|
||||
import io.lbry.browser.dialog.RepostClaimDialogFragment;
|
||||
import io.lbry.browser.dialog.SendTipDialogFragment;
|
||||
|
@ -102,6 +103,7 @@ import io.lbry.browser.listener.StoragePermissionListener;
|
|||
import io.lbry.browser.listener.WalletBalanceListener;
|
||||
import io.lbry.browser.model.Claim;
|
||||
import io.lbry.browser.model.ClaimCacheKey;
|
||||
import io.lbry.browser.model.Comment;
|
||||
import io.lbry.browser.model.Fee;
|
||||
import io.lbry.browser.model.LbryFile;
|
||||
import io.lbry.browser.model.NavMenuItem;
|
||||
|
@ -110,6 +112,8 @@ import io.lbry.browser.model.UrlSuggestion;
|
|||
import io.lbry.browser.model.WalletBalance;
|
||||
import io.lbry.browser.model.lbryinc.Reward;
|
||||
import io.lbry.browser.model.lbryinc.Subscription;
|
||||
import io.lbry.browser.tasks.CommentListHandler;
|
||||
import io.lbry.browser.tasks.CommentListTask;
|
||||
import io.lbry.browser.tasks.GenericTaskHandler;
|
||||
import io.lbry.browser.tasks.LighthouseSearchTask;
|
||||
import io.lbry.browser.tasks.ReadTextFileTask;
|
||||
|
@ -164,6 +168,7 @@ public class FileViewFragment extends BaseFragment implements
|
|||
private Claim claim;
|
||||
private String currentUrl;
|
||||
private ClaimListAdapter relatedContentAdapter;
|
||||
private CommentListAdapter commentListAdapter;
|
||||
private BroadcastReceiver sdkReceiver;
|
||||
private Player.EventListener fileViewPlayerListener;
|
||||
|
||||
|
@ -317,6 +322,7 @@ public class FileViewFragment extends BaseFragment implements
|
|||
if (claim != null) {
|
||||
Helper.saveViewHistory(currentUrl, claim);
|
||||
checkAndLoadRelatedContent();
|
||||
checkAndLoadComments();
|
||||
renderClaim();
|
||||
if (claim.getFile() == null) {
|
||||
loadFile();
|
||||
|
@ -451,6 +457,7 @@ public class FileViewFragment extends BaseFragment implements
|
|||
loadFile();
|
||||
}
|
||||
checkOwnClaim();
|
||||
checkAndLoadComments();
|
||||
}
|
||||
|
||||
private String getStreamingUrl() {
|
||||
|
@ -532,6 +539,7 @@ public class FileViewFragment extends BaseFragment implements
|
|||
if (claim != null) {
|
||||
Helper.saveViewHistory(url, claim);
|
||||
checkAndLoadRelatedContent();
|
||||
checkAndLoadComments();
|
||||
renderClaim();
|
||||
}
|
||||
}
|
||||
|
@ -571,7 +579,7 @@ public class FileViewFragment extends BaseFragment implements
|
|||
loadAndScheduleDurations();
|
||||
}
|
||||
|
||||
if (Lbry.SDK_READY) {
|
||||
if (!Lbry.SDK_READY) {
|
||||
if (context instanceof MainActivity) {
|
||||
((MainActivity) context).addSdkStatusListener(this);
|
||||
}
|
||||
|
@ -652,6 +660,7 @@ public class FileViewFragment extends BaseFragment implements
|
|||
loadFile();
|
||||
|
||||
checkAndLoadRelatedContent();
|
||||
checkAndLoadComments();
|
||||
renderClaim();
|
||||
} else {
|
||||
// render nothing at location
|
||||
|
@ -989,9 +998,13 @@ public class FileViewFragment extends BaseFragment implements
|
|||
});
|
||||
|
||||
RecyclerView relatedContentList = root.findViewById(R.id.file_view_related_content_list);
|
||||
RecyclerView commentsList = root.findViewById(R.id.file_view_comments_list);
|
||||
relatedContentList.setNestedScrollingEnabled(false);
|
||||
LinearLayoutManager llm = new LinearLayoutManager(getContext());
|
||||
relatedContentList.setLayoutManager(llm);
|
||||
commentsList.setNestedScrollingEnabled(false);
|
||||
LinearLayoutManager relatedContentListLLM = new LinearLayoutManager(getContext());
|
||||
LinearLayoutManager commentsListLLM = new LinearLayoutManager(getContext());
|
||||
relatedContentList.setLayoutManager(relatedContentListLLM);
|
||||
commentsList.setLayoutManager(commentsListLLM);
|
||||
}
|
||||
|
||||
private void deleteCurrentClaim() {
|
||||
|
@ -1317,6 +1330,22 @@ public class FileViewFragment extends BaseFragment implements
|
|||
}
|
||||
}
|
||||
|
||||
private void checkAndLoadComments() {
|
||||
View root = getView();
|
||||
if (root != null) {
|
||||
RecyclerView commentsList = root.findViewById(R.id.file_view_comments_list);
|
||||
if (commentsList == null || commentsList.getAdapter() == null || commentsList.getAdapter().getItemCount() == 0) {
|
||||
TextView commentsSDKInitializing = root.findViewById(R.id.file_view_comments_sdk_initializing);
|
||||
if (Lbry.SDK_READY) {
|
||||
Helper.setViewVisibility(commentsSDKInitializing, View.GONE);
|
||||
loadComments();
|
||||
} else {
|
||||
Helper.setViewVisibility(commentsSDKInitializing, View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showUnsupportedView() {
|
||||
View root = getView();
|
||||
if (root != null) {
|
||||
|
@ -1856,6 +1885,39 @@ public class FileViewFragment extends BaseFragment implements
|
|||
}
|
||||
}
|
||||
|
||||
private void loadComments() {
|
||||
View root = getView();
|
||||
ProgressBar relatedLoading = root.findViewById(R.id.file_view_comments_progress);
|
||||
if (claim != null && root != null) {
|
||||
CommentListTask relatedTask = new CommentListTask(1, 999, claim.getClaimId(), relatedLoading, new CommentListHandler() {
|
||||
@Override
|
||||
public void onSuccess(List<Comment> comments) {
|
||||
Context ctx = getContext();
|
||||
if (ctx != null) {
|
||||
commentListAdapter = new CommentListAdapter(comments, ctx);
|
||||
|
||||
View v = getView();
|
||||
if (v != null) {
|
||||
RecyclerView relatedContentList = root.findViewById(R.id.file_view_comments_list);
|
||||
relatedContentList.setAdapter(commentListAdapter);
|
||||
commentListAdapter.notifyDataSetChanged();
|
||||
|
||||
Helper.setViewVisibility(
|
||||
v.findViewById(R.id.file_view_no_comments),
|
||||
commentListAdapter == null || commentListAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception error) {
|
||||
|
||||
}
|
||||
});
|
||||
relatedTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean onBackPressed() {
|
||||
if (isInFullscreenMode()) {
|
||||
disableFullScreenMode();
|
||||
|
|
|
@ -102,6 +102,8 @@ public final class Lbry {
|
|||
public static final String METHOD_STREAM_ABANDON = "stream_abandon";
|
||||
public static final String METHOD_STREAM_REPOST = "stream_repost";
|
||||
|
||||
public static final String METHOD_COMMENT_LIST = "comment_list";
|
||||
|
||||
public static KeyStore KEYSTORE;
|
||||
public static boolean SDK_READY = false;
|
||||
|
||||
|
|
|
@ -480,23 +480,24 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/file_view_publisher_name_area"
|
||||
android:clickable="true"
|
||||
android:orientation="vertical"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/file_view_publisher_name"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/lbryGreen"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textFontWeight="600" />
|
||||
android:textColor="@color/lbryGreen"
|
||||
android:textFontWeight="600"
|
||||
android:textSize="14sp" />
|
||||
</LinearLayout>
|
||||
<io.lbry.browser.ui.controls.SolidIconView
|
||||
android:id="@+id/file_view_icon_follow_unfollow"
|
||||
|
@ -611,6 +612,75 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0.5dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:background="@color/divider" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/file_view_comments_area"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/file_view_comments_progress"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/inter"
|
||||
android:text="@string/comments"
|
||||
android:textSize="16sp" />
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/file_view_no_comments"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:fontFamily="@font/inter"
|
||||
android:text="@string/no_comments"
|
||||
android:textFontWeight="300"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/file_view_comments_sdk_initializing"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:fontFamily="@font/inter"
|
||||
android:text="@string/sdk_initializing_comments"
|
||||
android:textFontWeight="300"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/file_view_comments_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:overScrollMode="never" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</LinearLayout>
|
||||
|
|
36
app/src/main/res/layout/list_item_comment.xml
Normal file
36
app/src/main/res/layout/list_item_comment.xml
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingTop="8dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/comment_channel_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter"
|
||||
android:text="channel_name"
|
||||
android:textColor="@color/lbryGreen"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/comment_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter"
|
||||
android:text="comment_text" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -59,6 +59,9 @@
|
|||
<string name="report">Report</string>
|
||||
<string name="loading_decentralized_data">Loading decentralized data...</string>
|
||||
<string name="related_content">Related Content</string>
|
||||
<string name="comments">Comments</string>
|
||||
<string name="no_comments">No comments to display.</string>
|
||||
<string name="sdk_initializing_comments">Comments will display once the background service is done initializing.</string>
|
||||
<string name="share_lbry_content">Share LBRY content</string>
|
||||
<string name="view">View</string>
|
||||
<string name="play">Play</string>
|
||||
|
|
Loading…
Reference in a new issue