2021-05-02 11:16:25 +02:00
|
|
|
package awais.instagrabber.viewmodels;
|
|
|
|
|
|
|
|
import android.util.Log;
|
|
|
|
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import androidx.annotation.Nullable;
|
|
|
|
import androidx.lifecycle.LiveData;
|
|
|
|
import androidx.lifecycle.MutableLiveData;
|
|
|
|
import androidx.lifecycle.ViewModel;
|
|
|
|
|
|
|
|
import com.google.common.collect.ImmutableList;
|
|
|
|
|
|
|
|
import org.json.JSONArray;
|
|
|
|
import org.json.JSONException;
|
|
|
|
import org.json.JSONObject;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Objects;
|
|
|
|
import java.util.OptionalInt;
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
import java.util.stream.IntStream;
|
|
|
|
|
|
|
|
import awais.instagrabber.R;
|
|
|
|
import awais.instagrabber.models.Comment;
|
|
|
|
import awais.instagrabber.models.Resource;
|
2021-05-29 16:46:23 +02:00
|
|
|
import awais.instagrabber.repositories.responses.ChildCommentsFetchResponse;
|
|
|
|
import awais.instagrabber.repositories.responses.CommentsFetchResponse;
|
2021-05-02 11:16:25 +02:00
|
|
|
import awais.instagrabber.repositories.responses.User;
|
|
|
|
import awais.instagrabber.utils.Constants;
|
|
|
|
import awais.instagrabber.utils.CookieUtils;
|
2021-06-06 06:14:29 +02:00
|
|
|
import awais.instagrabber.utils.CoroutineUtilsKt;
|
2021-05-02 11:16:25 +02:00
|
|
|
import awais.instagrabber.utils.Utils;
|
2021-07-22 20:29:24 +02:00
|
|
|
import awais.instagrabber.utils.TextUtils;
|
2021-05-29 16:46:23 +02:00
|
|
|
import awais.instagrabber.webservices.CommentService;
|
2021-06-12 05:34:50 +02:00
|
|
|
import awais.instagrabber.webservices.GraphQLRepository;
|
2021-05-02 11:16:25 +02:00
|
|
|
import awais.instagrabber.webservices.ServiceCallback;
|
2021-06-06 06:14:29 +02:00
|
|
|
import kotlin.coroutines.Continuation;
|
|
|
|
import kotlinx.coroutines.Dispatchers;
|
2021-05-02 11:16:25 +02:00
|
|
|
|
|
|
|
import static awais.instagrabber.utils.Utils.settingsHelper;
|
|
|
|
|
|
|
|
public class CommentsViewerViewModel extends ViewModel {
|
|
|
|
private static final String TAG = CommentsViewerViewModel.class.getSimpleName();
|
|
|
|
|
|
|
|
private final MutableLiveData<Long> currentUserId = new MutableLiveData<>(0L);
|
|
|
|
private final MutableLiveData<Resource<List<Comment>>> rootList = new MutableLiveData<>();
|
|
|
|
private final MutableLiveData<Integer> rootCount = new MutableLiveData<>(0);
|
|
|
|
private final MutableLiveData<Resource<List<Comment>>> replyList = new MutableLiveData<>();
|
2021-06-12 05:34:50 +02:00
|
|
|
private final GraphQLRepository graphQLRepository;
|
2021-05-02 11:16:25 +02:00
|
|
|
|
|
|
|
private String shortCode;
|
|
|
|
private String postId;
|
|
|
|
private String rootCursor;
|
|
|
|
private boolean rootHasNext = true;
|
2021-06-28 18:02:34 +02:00
|
|
|
private Comment repliesParent, replyTo;
|
2021-05-02 11:16:25 +02:00
|
|
|
private String repliesCursor;
|
|
|
|
private boolean repliesHasNext = true;
|
2021-05-29 16:46:23 +02:00
|
|
|
private final CommentService commentService;
|
2021-05-02 11:16:25 +02:00
|
|
|
private List<Comment> prevReplies;
|
|
|
|
private String prevRepliesCursor;
|
|
|
|
private boolean prevRepliesHasNext = true;
|
|
|
|
|
2021-05-29 16:46:23 +02:00
|
|
|
private final ServiceCallback<CommentsFetchResponse> ccb = new ServiceCallback<CommentsFetchResponse>() {
|
|
|
|
@Override
|
|
|
|
public void onSuccess(final CommentsFetchResponse result) {
|
|
|
|
// Log.d(TAG, "onSuccess: " + result);
|
2021-06-11 18:24:25 +02:00
|
|
|
if (result == null) {
|
2021-06-12 01:42:12 +02:00
|
|
|
rootList.postValue(Resource.error(R.string.generic_null_response, getPrevList(rootList)));
|
2021-06-11 18:24:25 +02:00
|
|
|
return;
|
|
|
|
}
|
2021-05-29 16:46:23 +02:00
|
|
|
List<Comment> comments = result.getComments();
|
|
|
|
if (rootCursor == null) {
|
|
|
|
rootCount.postValue(result.getCommentCount());
|
|
|
|
}
|
|
|
|
if (rootCursor != null) {
|
|
|
|
comments = mergeList(rootList, comments);
|
|
|
|
}
|
|
|
|
rootCursor = result.getNextMinId();
|
2021-07-22 20:29:24 +02:00
|
|
|
rootHasNext = !TextUtils.isEmpty(rootCursor);
|
2021-05-29 16:46:23 +02:00
|
|
|
rootList.postValue(Resource.success(comments));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onFailure(final Throwable t) {
|
|
|
|
Log.e(TAG, "onFailure: ", t);
|
|
|
|
rootList.postValue(Resource.error(t.getMessage(), getPrevList(rootList)));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
private final ServiceCallback<ChildCommentsFetchResponse> rcb = new ServiceCallback<ChildCommentsFetchResponse>() {
|
|
|
|
@Override
|
|
|
|
public void onSuccess(final ChildCommentsFetchResponse result) {
|
|
|
|
// Log.d(TAG, "onSuccess: " + result);
|
2021-06-11 18:24:25 +02:00
|
|
|
if (result == null) {
|
2021-06-12 01:42:12 +02:00
|
|
|
rootList.postValue(Resource.error(R.string.generic_null_response, getPrevList(replyList)));
|
2021-06-11 18:24:25 +02:00
|
|
|
return;
|
|
|
|
}
|
2021-05-29 16:46:23 +02:00
|
|
|
List<Comment> comments = result.getChildComments();
|
|
|
|
// Replies
|
|
|
|
if (repliesCursor == null) {
|
|
|
|
// add parent to top of replies
|
|
|
|
comments = ImmutableList.<Comment>builder()
|
|
|
|
.add(repliesParent)
|
|
|
|
.addAll(comments)
|
|
|
|
.build();
|
|
|
|
}
|
|
|
|
if (repliesCursor != null) {
|
|
|
|
comments = mergeList(replyList, comments);
|
|
|
|
}
|
2021-06-08 00:10:48 +02:00
|
|
|
repliesCursor = result.getNextMaxChildCursor();
|
|
|
|
repliesHasNext = result.getHasMoreTailChildComments();
|
2021-05-29 16:46:23 +02:00
|
|
|
replyList.postValue(Resource.success(comments));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onFailure(final Throwable t) {
|
|
|
|
Log.e(TAG, "onFailure: ", t);
|
|
|
|
replyList.postValue(Resource.error(t.getMessage(), getPrevList(replyList)));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-05-02 11:16:25 +02:00
|
|
|
public CommentsViewerViewModel() {
|
2021-06-12 05:39:55 +02:00
|
|
|
graphQLRepository = GraphQLRepository.Companion.getInstance();
|
2021-05-02 11:16:25 +02:00
|
|
|
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
|
|
|
final String deviceUuid = Utils.settingsHelper.getString(Constants.DEVICE_UUID);
|
|
|
|
final String csrfToken = CookieUtils.getCsrfTokenFromCookie(cookie);
|
|
|
|
final long userIdFromCookie = CookieUtils.getUserIdFromCookie(cookie);
|
2021-05-29 16:46:23 +02:00
|
|
|
commentService = CommentService.getInstance(deviceUuid, csrfToken, userIdFromCookie);
|
2021-05-02 11:16:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setCurrentUser(final User currentUser) {
|
|
|
|
currentUserId.postValue(currentUser == null ? 0 : currentUser.getPk());
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setPostDetails(final String shortCode, final String postId, final long postUserId) {
|
|
|
|
this.shortCode = shortCode;
|
|
|
|
this.postId = postId;
|
|
|
|
}
|
|
|
|
|
|
|
|
public LiveData<Long> getCurrentUserId() {
|
|
|
|
return currentUserId;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
public Comment getRepliesParent() {
|
|
|
|
return repliesParent;
|
|
|
|
}
|
|
|
|
|
2021-06-28 18:02:34 +02:00
|
|
|
@Nullable
|
|
|
|
public void setReplyTo(final Comment replyTo) {
|
|
|
|
this.replyTo = replyTo;
|
|
|
|
}
|
|
|
|
|
2021-05-02 11:16:25 +02:00
|
|
|
public LiveData<Resource<List<Comment>>> getRootList() {
|
|
|
|
return rootList;
|
|
|
|
}
|
|
|
|
|
|
|
|
public LiveData<Resource<List<Comment>>> getReplyList() {
|
|
|
|
return replyList;
|
|
|
|
}
|
|
|
|
|
|
|
|
public LiveData<Integer> getRootCommentsCount() {
|
|
|
|
return rootCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void fetchComments() {
|
2021-05-29 16:46:23 +02:00
|
|
|
if (shortCode == null || postId == null) return;
|
|
|
|
if (!rootHasNext) return;
|
|
|
|
rootList.postValue(Resource.loading(getPrevList(rootList)));
|
2021-07-22 20:08:39 +02:00
|
|
|
if (currentUserId.getValue() != 0L) {
|
2021-05-29 16:46:23 +02:00
|
|
|
commentService.fetchComments(postId, rootCursor, ccb);
|
|
|
|
return;
|
|
|
|
}
|
2021-06-12 05:34:50 +02:00
|
|
|
graphQLRepository.fetchComments(
|
2021-06-06 06:14:29 +02:00
|
|
|
shortCode,
|
|
|
|
true,
|
|
|
|
rootCursor,
|
|
|
|
enqueueRequest(true, shortCode, ccb)
|
|
|
|
);
|
2021-05-02 11:16:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void fetchReplies() {
|
|
|
|
if (repliesParent == null) return;
|
2021-05-29 16:46:23 +02:00
|
|
|
fetchReplies(repliesParent.getPk());
|
2021-05-02 11:16:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void fetchReplies(@NonNull final String commentId) {
|
2021-05-29 16:46:23 +02:00
|
|
|
if (!repliesHasNext) return;
|
|
|
|
final List<Comment> list;
|
|
|
|
if (repliesParent != null && !Objects.equals(repliesParent.getPk(), commentId)) {
|
|
|
|
repliesCursor = null;
|
|
|
|
repliesHasNext = false;
|
|
|
|
list = Collections.emptyList();
|
2021-05-02 11:16:25 +02:00
|
|
|
} else {
|
2021-05-29 16:46:23 +02:00
|
|
|
list = getPrevList(replyList);
|
2021-05-02 11:16:25 +02:00
|
|
|
}
|
2021-05-29 16:46:23 +02:00
|
|
|
replyList.postValue(Resource.loading(list));
|
2021-07-22 20:08:39 +02:00
|
|
|
if (currentUserId.getValue() != 0L) {
|
2021-06-01 11:16:54 +02:00
|
|
|
commentService.fetchChildComments(postId, commentId, repliesCursor, rcb);
|
2021-05-29 16:46:23 +02:00
|
|
|
return;
|
|
|
|
}
|
2021-06-12 05:34:50 +02:00
|
|
|
graphQLRepository.fetchComments(commentId, false, repliesCursor, enqueueRequest(false, commentId, rcb));
|
2021-05-02 11:16:25 +02:00
|
|
|
}
|
|
|
|
|
2021-06-06 06:14:29 +02:00
|
|
|
private Continuation<String> enqueueRequest(final boolean root,
|
|
|
|
final String shortCodeOrCommentId,
|
|
|
|
@SuppressWarnings("rawtypes") final ServiceCallback callback) {
|
|
|
|
return CoroutineUtilsKt.getContinuation((response, throwable) -> {
|
|
|
|
if (throwable != null) {
|
|
|
|
callback.onFailure(throwable);
|
|
|
|
return;
|
2021-05-02 11:16:25 +02:00
|
|
|
}
|
2021-06-06 06:14:29 +02:00
|
|
|
if (response == null) {
|
|
|
|
Log.e(TAG, "Error occurred while fetching gql comments of " + shortCodeOrCommentId);
|
|
|
|
//noinspection unchecked
|
|
|
|
callback.onSuccess(null);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
final JSONObject body = root ? new JSONObject(response).getJSONObject("data")
|
|
|
|
.getJSONObject("shortcode_media")
|
|
|
|
.getJSONObject("edge_media_to_parent_comment")
|
|
|
|
: new JSONObject(response).getJSONObject("data")
|
|
|
|
.getJSONObject("comment")
|
|
|
|
.getJSONObject("edge_threaded_comments");
|
|
|
|
final int count = body.optInt("count");
|
|
|
|
final JSONObject pageInfo = body.getJSONObject("page_info");
|
|
|
|
final boolean hasNextPage = pageInfo.getBoolean("has_next_page");
|
|
|
|
final String endCursor = pageInfo.isNull("end_cursor") || !hasNextPage ? null : pageInfo.optString("end_cursor");
|
|
|
|
final JSONArray commentsJsonArray = body.getJSONArray("edges");
|
|
|
|
final ImmutableList.Builder<Comment> builder = ImmutableList.builder();
|
|
|
|
for (int i = 0; i < commentsJsonArray.length(); i++) {
|
|
|
|
final Comment commentModel = getComment(commentsJsonArray.getJSONObject(i).getJSONObject("node"), root);
|
|
|
|
builder.add(commentModel);
|
|
|
|
}
|
2021-07-22 20:29:24 +02:00
|
|
|
final Object result = root ? new CommentsFetchResponse(count, endCursor, builder.build())
|
2021-06-08 00:10:48 +02:00
|
|
|
: new ChildCommentsFetchResponse(count, endCursor, builder.build(), hasNextPage);
|
2021-06-06 06:14:29 +02:00
|
|
|
//noinspection unchecked
|
|
|
|
callback.onSuccess(result);
|
|
|
|
} catch (Exception e) {
|
|
|
|
Log.e(TAG, "onResponse", e);
|
|
|
|
callback.onFailure(e);
|
2021-05-02 11:16:25 +02:00
|
|
|
}
|
2021-06-06 06:14:29 +02:00
|
|
|
}, Dispatchers.getIO());
|
2021-05-02 11:16:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@NonNull
|
|
|
|
private Comment getComment(@NonNull final JSONObject commentJsonObject, final boolean root) throws JSONException {
|
|
|
|
final JSONObject owner = commentJsonObject.getJSONObject("owner");
|
|
|
|
final User user = new User(
|
|
|
|
owner.optLong(Constants.EXTRAS_ID, 0),
|
|
|
|
owner.getString(Constants.EXTRAS_USERNAME),
|
|
|
|
null,
|
|
|
|
false,
|
|
|
|
owner.getString("profile_pic_url"),
|
2021-05-15 18:52:31 +02:00
|
|
|
owner.optBoolean("is_verified"));
|
2021-05-02 11:16:25 +02:00
|
|
|
final JSONObject likedBy = commentJsonObject.optJSONObject("edge_liked_by");
|
|
|
|
final String commentId = commentJsonObject.getString("id");
|
|
|
|
final JSONObject childCommentsJsonObject = commentJsonObject.optJSONObject("edge_threaded_comments");
|
|
|
|
int replyCount = 0;
|
|
|
|
if (childCommentsJsonObject != null) {
|
|
|
|
replyCount = childCommentsJsonObject.optInt("count");
|
|
|
|
}
|
|
|
|
return new Comment(commentId,
|
|
|
|
commentJsonObject.getString("text"),
|
|
|
|
commentJsonObject.getLong("created_at"),
|
|
|
|
likedBy != null ? likedBy.optLong("count", 0) : 0,
|
|
|
|
commentJsonObject.getBoolean("viewer_has_liked"),
|
|
|
|
user,
|
2021-05-29 16:46:23 +02:00
|
|
|
replyCount);
|
2021-05-02 11:16:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@NonNull
|
|
|
|
private List<Comment> getPrevList(@NonNull final LiveData<Resource<List<Comment>>> list) {
|
|
|
|
if (list.getValue() == null) return Collections.emptyList();
|
|
|
|
final Resource<List<Comment>> listResource = list.getValue();
|
|
|
|
if (listResource.data == null) return Collections.emptyList();
|
|
|
|
return listResource.data;
|
|
|
|
}
|
|
|
|
|
|
|
|
private List<Comment> mergeList(@NonNull final LiveData<Resource<List<Comment>>> list,
|
|
|
|
final List<Comment> comments) {
|
|
|
|
final List<Comment> prevList = getPrevList(list);
|
|
|
|
if (comments == null) {
|
|
|
|
return prevList;
|
|
|
|
}
|
|
|
|
return ImmutableList.<Comment>builder()
|
|
|
|
.addAll(prevList)
|
|
|
|
.addAll(comments)
|
|
|
|
.build();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void showReplies(final Comment comment) {
|
|
|
|
if (comment == null) return;
|
2021-05-29 16:46:23 +02:00
|
|
|
if (repliesParent == null || !Objects.equals(repliesParent.getPk(), comment.getPk())) {
|
2021-05-02 11:16:25 +02:00
|
|
|
repliesParent = comment;
|
2021-06-28 18:02:34 +02:00
|
|
|
replyTo = comment;
|
2021-05-02 11:16:25 +02:00
|
|
|
prevReplies = null;
|
|
|
|
prevRepliesCursor = null;
|
|
|
|
prevRepliesHasNext = true;
|
2021-05-29 16:46:23 +02:00
|
|
|
fetchReplies(comment.getPk());
|
2021-05-02 11:16:25 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (prevReplies != null && !prevReplies.isEmpty()) {
|
|
|
|
// user clicked same comment, show prev loaded replies
|
|
|
|
repliesCursor = prevRepliesCursor;
|
|
|
|
repliesHasNext = prevRepliesHasNext;
|
|
|
|
replyList.postValue(Resource.success(prevReplies));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// prev list was null or empty, fetch
|
|
|
|
prevRepliesCursor = null;
|
|
|
|
prevRepliesHasNext = true;
|
2021-05-29 16:46:23 +02:00
|
|
|
fetchReplies(comment.getPk());
|
2021-05-02 11:16:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public LiveData<Resource<Object>> likeComment(@NonNull final Comment comment, final boolean liked, final boolean isReply) {
|
|
|
|
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>(Resource.loading(null));
|
|
|
|
final ServiceCallback<Boolean> callback = new ServiceCallback<Boolean>() {
|
|
|
|
@Override
|
|
|
|
public void onSuccess(final Boolean result) {
|
|
|
|
if (result == null || !result) {
|
|
|
|
data.postValue(Resource.error(R.string.downloader_unknown_error, null));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
data.postValue(Resource.success(new Object()));
|
|
|
|
setLiked(isReply, comment, liked);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onFailure(final Throwable t) {
|
|
|
|
Log.e(TAG, "Error liking comment", t);
|
|
|
|
data.postValue(Resource.error(t.getMessage(), null));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
if (liked) {
|
2021-05-29 16:46:23 +02:00
|
|
|
commentService.commentLike(comment.getPk(), callback);
|
2021-05-02 11:16:25 +02:00
|
|
|
} else {
|
2021-05-29 16:46:23 +02:00
|
|
|
commentService.commentUnlike(comment.getPk(), callback);
|
2021-05-02 11:16:25 +02:00
|
|
|
}
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void setLiked(final boolean isReply,
|
|
|
|
@NonNull final Comment comment,
|
|
|
|
final boolean liked) {
|
|
|
|
final List<Comment> list = getPrevList(isReply ? replyList : rootList);
|
|
|
|
if (list == null) return;
|
|
|
|
final List<Comment> copy = new ArrayList<>(list);
|
|
|
|
OptionalInt indexOpt = IntStream.range(0, copy.size())
|
2021-05-29 16:46:23 +02:00
|
|
|
.filter(i -> copy.get(i) != null && Objects.equals(copy.get(i).getPk(), comment.getPk()))
|
2021-05-02 11:16:25 +02:00
|
|
|
.findFirst();
|
|
|
|
if (!indexOpt.isPresent()) return;
|
|
|
|
try {
|
|
|
|
final Comment clone = (Comment) comment.clone();
|
|
|
|
clone.setLiked(liked);
|
|
|
|
copy.set(indexOpt.getAsInt(), clone);
|
|
|
|
final MutableLiveData<Resource<List<Comment>>> liveData = isReply ? replyList : rootList;
|
|
|
|
liveData.postValue(Resource.success(copy));
|
|
|
|
} catch (Exception e) {
|
|
|
|
Log.e(TAG, "setLiked: ", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public LiveData<Resource<Object>> comment(@NonNull final String text,
|
|
|
|
final boolean isReply) {
|
|
|
|
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>(Resource.loading(null));
|
|
|
|
String replyToId = null;
|
2021-06-28 18:02:34 +02:00
|
|
|
if (isReply && replyTo != null) {
|
|
|
|
replyToId = replyTo.getPk();
|
2021-05-02 11:16:25 +02:00
|
|
|
}
|
|
|
|
if (isReply && replyToId == null) {
|
|
|
|
data.postValue(Resource.error(null, null));
|
|
|
|
return data;
|
|
|
|
}
|
2021-05-29 16:46:23 +02:00
|
|
|
commentService.comment(postId, text, replyToId, new ServiceCallback<Comment>() {
|
2021-05-02 11:16:25 +02:00
|
|
|
@Override
|
|
|
|
public void onSuccess(final Comment result) {
|
|
|
|
if (result == null) {
|
|
|
|
data.postValue(Resource.error(R.string.downloader_unknown_error, null));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
addComment(result, isReply);
|
|
|
|
data.postValue(Resource.success(new Object()));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onFailure(final Throwable t) {
|
|
|
|
Log.e(TAG, "Error during comment", t);
|
|
|
|
data.postValue(Resource.error(t.getMessage(), null));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void addComment(@NonNull final Comment comment, final boolean isReply) {
|
|
|
|
final List<Comment> list = getPrevList(isReply ? replyList : rootList);
|
|
|
|
final ImmutableList.Builder<Comment> builder = ImmutableList.builder();
|
|
|
|
if (isReply) {
|
2021-06-28 18:02:34 +02:00
|
|
|
// replies are added to the bottom of the list to preserve chronological order
|
|
|
|
builder.addAll(list)
|
|
|
|
.add(comment);
|
2021-05-02 11:16:25 +02:00
|
|
|
} else {
|
|
|
|
builder.add(comment)
|
|
|
|
.addAll(list);
|
|
|
|
}
|
|
|
|
final MutableLiveData<Resource<List<Comment>>> liveData = isReply ? replyList : rootList;
|
|
|
|
liveData.postValue(Resource.success(builder.build()));
|
|
|
|
}
|
|
|
|
|
|
|
|
public void translate(@NonNull final Comment comment,
|
|
|
|
@NonNull final ServiceCallback<String> callback) {
|
2021-05-29 16:46:23 +02:00
|
|
|
commentService.translate(comment.getPk(), callback);
|
2021-05-02 11:16:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public LiveData<Resource<Object>> deleteComment(@NonNull final Comment comment, final boolean isReply) {
|
|
|
|
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>(Resource.loading(null));
|
2021-05-29 16:46:23 +02:00
|
|
|
commentService.deleteComment(postId, comment.getPk(), new ServiceCallback<Boolean>() {
|
2021-05-02 11:16:25 +02:00
|
|
|
@Override
|
|
|
|
public void onSuccess(final Boolean result) {
|
|
|
|
if (result == null || !result) {
|
|
|
|
data.postValue(Resource.error(R.string.downloader_unknown_error, null));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
removeComment(comment, isReply);
|
|
|
|
data.postValue(Resource.success(new Object()));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onFailure(final Throwable t) {
|
|
|
|
Log.e(TAG, "Error deleting comment", t);
|
|
|
|
data.postValue(Resource.error(t.getMessage(), null));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void removeComment(@NonNull final Comment comment, final boolean isReply) {
|
|
|
|
final List<Comment> list = getPrevList(isReply ? replyList : rootList);
|
|
|
|
final List<Comment> updated = list.stream()
|
|
|
|
.filter(Objects::nonNull)
|
2021-05-29 16:46:23 +02:00
|
|
|
.filter(c -> !Objects.equals(c.getPk(), comment.getPk()))
|
2021-05-02 11:16:25 +02:00
|
|
|
.collect(Collectors.toList());
|
|
|
|
final MutableLiveData<Resource<List<Comment>>> liveData = isReply ? replyList : rootList;
|
|
|
|
liveData.postValue(Resource.success(updated));
|
|
|
|
}
|
|
|
|
|
|
|
|
public void clearReplies() {
|
|
|
|
prevRepliesCursor = repliesCursor;
|
|
|
|
prevRepliesHasNext = repliesHasNext;
|
|
|
|
repliesCursor = null;
|
|
|
|
repliesHasNext = true;
|
|
|
|
// cache prev reply list to save time and data if user clicks same comment again
|
|
|
|
prevReplies = getPrevList(replyList);
|
|
|
|
replyList.postValue(Resource.success(Collections.emptyList()));
|
|
|
|
}
|
|
|
|
}
|