From 4c95404fe176c8a02402d5a4fb94530979c2ba4f Mon Sep 17 00:00:00 2001 From: Balazs Toldi Date: Tue, 1 Aug 2023 15:24:44 +0200 Subject: [PATCH] Basic InboxActivity This commits adds basic functionality for the Inbox Activity. It can now show you replies and mentions. --- .../activities/InboxActivity.java | 44 +++--- .../ViewPrivateMessagesActivity.java | 4 +- .../adapters/MessageRecyclerViewAdapter.java | 105 +++++++-------- .../toldi/infinityforlemmy/apis/LemmyAPI.java | 9 ++ .../events/PassPrivateMessageEvent.java | 6 +- .../fragments/InboxFragment.java | 20 +-- .../message/CommentInteraction.java | 36 +++++ .../message/FetchCommentInteractions.java | 100 ++++++++++++++ .../message/FetchMessage.java | 5 + .../message/MessageDataSource.java | 126 ++++++++++++------ .../message/MessageViewModel.java | 4 +- app/src/main/res/values/strings.xml | 2 + 12 files changed, 323 insertions(+), 138 deletions(-) create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/message/CommentInteraction.java create mode 100644 app/src/main/java/eu/toldi/infinityforlemmy/message/FetchCommentInteractions.java diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/activities/InboxActivity.java b/app/src/main/java/eu/toldi/infinityforlemmy/activities/InboxActivity.java index 91c7dc66..122cff54 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/activities/InboxActivity.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/activities/InboxActivity.java @@ -56,8 +56,8 @@ import eu.toldi.infinityforlemmy.events.PassPrivateMessageEvent; import eu.toldi.infinityforlemmy.events.PassPrivateMessageIndexEvent; import eu.toldi.infinityforlemmy.events.SwitchAccountEvent; import eu.toldi.infinityforlemmy.fragments.InboxFragment; +import eu.toldi.infinityforlemmy.message.CommentInteraction; import eu.toldi.infinityforlemmy.message.FetchMessage; -import eu.toldi.infinityforlemmy.message.Message; import eu.toldi.infinityforlemmy.utils.APIUtils; import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; import eu.toldi.infinityforlemmy.utils.Utils; @@ -268,13 +268,16 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf } }); viewPager2.setAdapter(sectionsPagerAdapter); - viewPager2.setOffscreenPageLimit(2); + viewPager2.setOffscreenPageLimit(3); new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { switch (position) { case 0: - Utils.setTitleWithCustomFontToTab(typeface, tab, getString(R.string.notifications)); + Utils.setTitleWithCustomFontToTab(typeface, tab, getString(R.string.replies)); break; case 1: + Utils.setTitleWithCustomFontToTab(typeface, tab, getString(R.string.mentions)); + break; + case 2: Utils.setTitleWithCustomFontToTab(typeface, tab, getString(R.string.messages)); break; } @@ -438,7 +441,7 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf } } - Message getPrivateMessage(int index) { + CommentInteraction getPrivateMessage(int index) { if (viewPager2 == null || fragmentManager == null) { return null; } @@ -452,26 +455,29 @@ public class InboxActivity extends BaseActivity implements ActivityToolbarInterf @NonNull @Override public Fragment createFragment(int position) { - if (position == 0) { - InboxFragment fragment = new InboxFragment(); - Bundle bundle = new Bundle(); - bundle.putString(InboxFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(InboxFragment.EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_INBOX); - fragment.setArguments(bundle); - return fragment; - } else { - InboxFragment fragment = new InboxFragment(); - Bundle bundle = new Bundle(); - bundle.putString(InboxFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(InboxFragment.EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_MESSAGES); - fragment.setArguments(bundle); - return fragment; + InboxFragment fragment = new InboxFragment(); + Bundle bundle = new Bundle(); + bundle.putString(InboxFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + switch (position) { + case 0: + bundle.putString(InboxFragment.EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_REPLIES); + break; + case 1: + bundle.putString(InboxFragment.EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_MENTIONS); + fragment.setArguments(bundle); + break; + case 2: + bundle.putString(InboxFragment.EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_MESSAGES); + fragment.setArguments(bundle); + break; } + fragment.setArguments(bundle); + return fragment; } @Override public int getItemCount() { - return 2; + return 3; } } } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewPrivateMessagesActivity.java b/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewPrivateMessagesActivity.java index 036a8973..1598346e 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewPrivateMessagesActivity.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/activities/ViewPrivateMessagesActivity.java @@ -332,7 +332,7 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit @Subscribe public void onPassPrivateMessageEvent(PassPrivateMessageEvent passPrivateMessageEvent) { - privateMessage = passPrivateMessageEvent.message; + /* privateMessage = passPrivateMessageEvent.message; if (privateMessage != null) { if (privateMessage.getAuthor().equals(mAccountName)) { if (privateMessage.getReplies() != null) { @@ -351,7 +351,7 @@ public class ViewPrivateMessagesActivity extends BaseActivity implements Activit } bindView(); - } + }*/ } public interface ProvideUserAvatarCallback { diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/adapters/MessageRecyclerViewAdapter.java b/app/src/main/java/eu/toldi/infinityforlemmy/adapters/MessageRecyclerViewAdapter.java index c56ac067..6fd6885e 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/adapters/MessageRecyclerViewAdapter.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/adapters/MessageRecyclerViewAdapter.java @@ -17,12 +17,22 @@ import androidx.paging.PagedListAdapter; import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.RecyclerView; -import org.greenrobot.eventbus.EventBus; - -import java.util.ArrayList; - import butterknife.BindView; import butterknife.ButterKnife; +import eu.toldi.infinityforlemmy.NetworkState; +import eu.toldi.infinityforlemmy.R; +import eu.toldi.infinityforlemmy.activities.BaseActivity; +import eu.toldi.infinityforlemmy.activities.LinkResolverActivity; +import eu.toldi.infinityforlemmy.activities.ViewPostDetailActivity; +import eu.toldi.infinityforlemmy.activities.ViewPrivateMessagesActivity; +import eu.toldi.infinityforlemmy.activities.ViewUserDetailActivity; +import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; +import eu.toldi.infinityforlemmy.markdown.RedditHeadingPlugin; +import eu.toldi.infinityforlemmy.markdown.SpoilerAwareMovementMethod; +import eu.toldi.infinityforlemmy.markdown.SpoilerParserPlugin; +import eu.toldi.infinityforlemmy.markdown.SuperscriptPlugin; +import eu.toldi.infinityforlemmy.message.CommentInteraction; +import eu.toldi.infinityforlemmy.message.FetchMessage; import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon; import io.noties.markwon.MarkwonConfiguration; @@ -33,36 +43,21 @@ import io.noties.markwon.inlineparser.HtmlInlineProcessor; import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; import io.noties.markwon.linkify.LinkifyPlugin; import io.noties.markwon.movement.MovementMethodPlugin; -import eu.toldi.infinityforlemmy.NetworkState; -import eu.toldi.infinityforlemmy.R; -import eu.toldi.infinityforlemmy.activities.BaseActivity; -import eu.toldi.infinityforlemmy.activities.LinkResolverActivity; -import eu.toldi.infinityforlemmy.activities.ViewPrivateMessagesActivity; -import eu.toldi.infinityforlemmy.activities.ViewUserDetailActivity; -import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; -import eu.toldi.infinityforlemmy.events.ChangeInboxCountEvent; -import eu.toldi.infinityforlemmy.markdown.RedditHeadingPlugin; -import eu.toldi.infinityforlemmy.markdown.SpoilerAwareMovementMethod; -import eu.toldi.infinityforlemmy.markdown.SpoilerParserPlugin; -import eu.toldi.infinityforlemmy.markdown.SuperscriptPlugin; -import eu.toldi.infinityforlemmy.message.FetchMessage; -import eu.toldi.infinityforlemmy.message.Message; -import eu.toldi.infinityforlemmy.message.ReadMessage; import retrofit2.Retrofit; -public class MessageRecyclerViewAdapter extends PagedListAdapter { +public class MessageRecyclerViewAdapter extends PagedListAdapter { private static final int VIEW_TYPE_DATA = 0; private static final int VIEW_TYPE_ERROR = 1; private static final int VIEW_TYPE_LOADING = 2; - private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback<>() { + private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback<>() { @Override - public boolean areItemsTheSame(@NonNull Message message, @NonNull Message t1) { - return message.getId().equals(t1.getId()); + public boolean areItemsTheSame(@NonNull CommentInteraction message, @NonNull CommentInteraction t1) { + return message.getComment().getId() == t1.getComment().getId(); } @Override - public boolean areContentsTheSame(@NonNull Message message, @NonNull Message t1) { - return message.getBody().equals(t1.getBody()); + public boolean areContentsTheSame(@NonNull CommentInteraction message, @NonNull CommentInteraction t1) { + return message.getComment().getCommentMarkdown().equals(t1.getComment().getCommentMarkdown()); } }; private BaseActivity mActivity; @@ -154,41 +149,35 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter replies = message.getReplies(); - Message displayedMessage; - if (replies != null && !replies.isEmpty() && replies.get(replies.size() - 1) != null) { - displayedMessage = replies.get(replies.size() - 1); - } else { - displayedMessage = message; - } - if (message.isNew()) { + + if (message.isRead()) { if (markAllMessagesAsRead) { - message.setNew(false); + message.markAsRead(); } else { holder.itemView.setBackgroundColor( mUnreadMessageBackgroundColor); } } - if (message.wasComment()) { - ((DataViewHolder) holder).titleTextView.setText(message.getTitle()); - } else { - ((DataViewHolder) holder).titleTextView.setVisibility(View.GONE); - } - ((DataViewHolder) holder).authorTextView.setText(displayedMessage.getAuthor()); - String subject = displayedMessage.getSubject().substring(0, 1).toUpperCase() + displayedMessage.getSubject().substring(1); + ((DataViewHolder) holder).titleTextView.setVisibility(View.GONE); + + + ((DataViewHolder) holder).authorTextView.setText(message.getComment().getAuthorQualifiedName()); + String subject = message.getComment().getCommunityQualifiedName(); ((DataViewHolder) holder).subjectTextView.setText(subject); - mMarkwon.setMarkdown(((DataViewHolder) holder).contentCustomMarkwonView, displayedMessage.getBody()); + mMarkwon.setMarkdown(((DataViewHolder) holder).contentCustomMarkwonView, message.getComment().getCommentMarkdown()); holder.itemView.setOnClickListener(view -> { if (mMessageType == FetchMessage.MESSAGE_TYPE_INBOX - && message.getContext() != null && !message.getContext().equals("")) { - Uri uri = Uri.parse(message.getContext()); - Intent intent = new Intent(mActivity, LinkResolverActivity.class); - intent.setData(uri); + && message.getComment() != null) { + + Intent intent = new Intent(mActivity, ViewPostDetailActivity.class); + + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, message.getComment().getPostId()); + intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, message.getComment().getId()); mActivity.startActivity(intent); } else if (mMessageType == FetchMessage.MESSAGE_TYPE_PRIVATE_MESSAGE) { Intent intent = new Intent(mActivity, ViewPrivateMessagesActivity.class); @@ -197,32 +186,32 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter { - if (message.isAuthorDeleted()) { - return; - } + Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, message.getAuthor()); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, message.getComment().getAuthor()); + intent.putExtra(ViewUserDetailActivity.EXTRA_QUALIFIED_USER_NAME_KEY, message.getComment().getCommunityQualifiedName()); mActivity.startActivity(intent); }); } @@ -280,9 +269,9 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter= 0 && position < super.getItemCount()) { - Message message = getItem(position); + CommentInteraction message = getItem(position); if (message != null) { notifyItemChanged(position); } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/apis/LemmyAPI.java b/app/src/main/java/eu/toldi/infinityforlemmy/apis/LemmyAPI.java index a5a164f7..8994ba3f 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/apis/LemmyAPI.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/apis/LemmyAPI.java @@ -36,6 +36,15 @@ public interface LemmyAPI { @GET("api/v3/user") Call userInfo(@Query("username") String username, @Query("auth") String access_token); + @GET("api/v3/user/mention") + Call userMentions(@Query("sort") String sort, @Query("page") Integer page, @Query("limit") Integer limit, @Query("unread_only") boolean unread_only, @Query("auth") String access_token); + + @GET("api/v3/user/replies") + Call userReplies(@Query("sort") String sort, @Query("page") Integer page, @Query("limit") Integer limit, @Query("unread_only") boolean unread_only, @Query("auth") String access_token); + + @GET("api/v3/private_message/list") + Call privateMessageList(@Query("page") Integer page, @Query("limit") Integer limit, @Query("unread_only") boolean unread_only, @Query("auth") String access_token); + @GET("api/v3/community") Call communityInfo(@Query("name") String name, @Query("auth") String access_token); diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/events/PassPrivateMessageEvent.java b/app/src/main/java/eu/toldi/infinityforlemmy/events/PassPrivateMessageEvent.java index 51730d72..d2e8fd3d 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/events/PassPrivateMessageEvent.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/events/PassPrivateMessageEvent.java @@ -1,11 +1,11 @@ package eu.toldi.infinityforlemmy.events; -import eu.toldi.infinityforlemmy.message.Message; +import eu.toldi.infinityforlemmy.message.CommentInteraction; public class PassPrivateMessageEvent { - public Message message; + public CommentInteraction message; - public PassPrivateMessageEvent(Message message) { + public PassPrivateMessageEvent(CommentInteraction message) { this.message = message; } } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/InboxFragment.java b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/InboxFragment.java index 39c6f9b6..df74a34c 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/fragments/InboxFragment.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/fragments/InboxFragment.java @@ -35,15 +35,15 @@ import eu.toldi.infinityforlemmy.NetworkState; import eu.toldi.infinityforlemmy.R; import eu.toldi.infinityforlemmy.RecyclerViewContentScrollingInterface; import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; +import eu.toldi.infinityforlemmy.RetrofitHolder; import eu.toldi.infinityforlemmy.activities.BaseActivity; import eu.toldi.infinityforlemmy.adapters.MessageRecyclerViewAdapter; import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; import eu.toldi.infinityforlemmy.customviews.LinearLayoutManagerBugFixed; import eu.toldi.infinityforlemmy.events.RepliedToPrivateMessageEvent; +import eu.toldi.infinityforlemmy.message.CommentInteraction; import eu.toldi.infinityforlemmy.message.FetchMessage; -import eu.toldi.infinityforlemmy.message.Message; import eu.toldi.infinityforlemmy.message.MessageViewModel; -import retrofit2.Retrofit; public class InboxFragment extends Fragment implements FragmentCommunicator { @@ -61,8 +61,8 @@ public class InboxFragment extends Fragment implements FragmentCommunicator { TextView mFetchMessageInfoTextView; MessageViewModel mMessageViewModel; @Inject - @Named("oauth") - Retrofit mOauthRetrofit; + @Named("no_oauth") + RetrofitHolder mRetrofit; @Inject RedditDataRoomDatabase mRedditDataRoomDatabase; @Inject @@ -106,7 +106,7 @@ public class InboxFragment extends Fragment implements FragmentCommunicator { } mWhere = arguments.getString(EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_INBOX); - mAdapter = new MessageRecyclerViewAdapter(mActivity, mOauthRetrofit, mCustomThemeWrapper, + mAdapter = new MessageRecyclerViewAdapter(mActivity, mRetrofit.getRetrofit(), mCustomThemeWrapper, mAccessToken, mWhere, () -> mMessageViewModel.retryLoadingMore()); mLinearLayoutManager = new LinearLayoutManagerBugFixed(mActivity); mRecyclerView.setLayoutManager(mLinearLayoutManager); @@ -127,7 +127,7 @@ public class InboxFragment extends Fragment implements FragmentCommunicator { }); } - MessageViewModel.Factory factory = new MessageViewModel.Factory(mOauthRetrofit, + MessageViewModel.Factory factory = new MessageViewModel.Factory(mRetrofit.getRetrofit(), getResources().getConfiguration().locale, mAccessToken, mWhere); mMessageViewModel = new ViewModelProvider(this, factory).get(MessageViewModel.class); mMessageViewModel.getMessages().observe(getViewLifecycleOwner(), messages -> mAdapter.submitList(messages)); @@ -216,11 +216,11 @@ public class InboxFragment extends Fragment implements FragmentCommunicator { mAdapter.setNetworkState(null); } - public Message getMessageByIndex(int index) { + public CommentInteraction getMessageByIndex(int index) { if (mMessageViewModel == null || index < 0) { return null; } - PagedList messages = mMessageViewModel.getMessages().getValue(); + PagedList messages = mMessageViewModel.getMessages().getValue(); if (messages == null) { return null; } @@ -245,8 +245,8 @@ public class InboxFragment extends Fragment implements FragmentCommunicator { @Subscribe public void onRepliedToPrivateMessageEvent(RepliedToPrivateMessageEvent repliedToPrivateMessageEvent) { - if (mAdapter != null && mWhere.equals(FetchMessage.WHERE_MESSAGES)) { + /* if (mAdapter != null && mWhere.equals(FetchMessage.WHERE_MESSAGES)) { mAdapter.updateMessageReply(repliedToPrivateMessageEvent.newReply, repliedToPrivateMessageEvent.messagePosition); - } + }*/ } } \ No newline at end of file diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/message/CommentInteraction.java b/app/src/main/java/eu/toldi/infinityforlemmy/message/CommentInteraction.java new file mode 100644 index 00000000..fd6a6511 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/message/CommentInteraction.java @@ -0,0 +1,36 @@ +package eu.toldi.infinityforlemmy.message; + +import eu.toldi.infinityforlemmy.comment.Comment; + +public class CommentInteraction { + int id; + private Comment comment; + private boolean isRead; + + public CommentInteraction(int id, Comment comment, boolean isRead) { + this.id = id; + this.comment = comment; + this.isRead = isRead; + } + + public Comment getComment() { + return this.comment; + } + + public boolean isRead() { + return this.isRead; + } + + public void markAsUnRead() { + this.isRead = false; + } + + + public void markAsRead() { + this.isRead = true; + } + + public int getId() { + return id; + } +} diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/message/FetchCommentInteractions.java b/app/src/main/java/eu/toldi/infinityforlemmy/message/FetchCommentInteractions.java new file mode 100644 index 00000000..29f2c918 --- /dev/null +++ b/app/src/main/java/eu/toldi/infinityforlemmy/message/FetchCommentInteractions.java @@ -0,0 +1,100 @@ +package eu.toldi.infinityforlemmy.message; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +import eu.toldi.infinityforlemmy.apis.LemmyAPI; +import eu.toldi.infinityforlemmy.comment.Comment; +import eu.toldi.infinityforlemmy.comment.ParseComment; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class FetchCommentInteractions { + static void fetchReplies(Retrofit retrofit, Integer page, boolean unreadOnly, String auth, FetchCommentInteractionsListener fetchMessagesListener) { + LemmyAPI api = retrofit.create(LemmyAPI.class); + + api.userReplies("New", page, 25, unreadOnly, auth).enqueue( + new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()) { + try { + JSONObject jsonObject = new JSONObject(response.body()); + JSONArray jsonArray = jsonObject.getJSONArray("replies"); + List commentInteractions = new ArrayList<>(); + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject commentInteractionObject = jsonArray.getJSONObject(i); + Comment comment = ParseComment.parseSingleComment(commentInteractionObject); + boolean isRead = !commentInteractionObject.getJSONObject("comment_reply").getBoolean("read"); + int id = commentInteractionObject.getJSONObject("comment_reply").getInt("id"); + commentInteractions.add(new CommentInteraction(id, comment, isRead)); + } + fetchMessagesListener.fetchSuccess(commentInteractions); + + } catch (JSONException e) { + e.printStackTrace(); + fetchMessagesListener.fetchFailed(); + } + } else { + fetchMessagesListener.fetchFailed(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + fetchMessagesListener.fetchFailed(); + } + } + ); + } + + static void fetchMentions(Retrofit retrofit, Integer page, boolean unreadOnly, String auth, FetchCommentInteractionsListener fetchMessagesListener) { + LemmyAPI api = retrofit.create(LemmyAPI.class); + + api.userMentions("New", page, 25, unreadOnly, auth).enqueue( + new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()) { + try { + JSONObject jsonObject = new JSONObject(response.body()); + JSONArray jsonArray = jsonObject.getJSONArray("mentions"); + List commentInteractions = new ArrayList<>(); + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject commentInteractionObject = jsonArray.getJSONObject(i); + Comment comment = ParseComment.parseSingleComment(commentInteractionObject); + boolean isRead = commentInteractionObject.getJSONObject("person_mention").getBoolean("read"); + int id = commentInteractionObject.getJSONObject("person_mention").getInt("id"); + commentInteractions.add(new CommentInteraction(id, comment, isRead)); + } + fetchMessagesListener.fetchSuccess(commentInteractions); + + } catch (JSONException e) { + e.printStackTrace(); + fetchMessagesListener.fetchFailed(); + } + } else { + fetchMessagesListener.fetchFailed(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + fetchMessagesListener.fetchFailed(); + } + } + ); + } + + public interface FetchCommentInteractionsListener { + void fetchSuccess(List commentInteractions); + + void fetchFailed(); + } +} diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/message/FetchMessage.java b/app/src/main/java/eu/toldi/infinityforlemmy/message/FetchMessage.java index 21547bf9..bdeaef36 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/message/FetchMessage.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/message/FetchMessage.java @@ -15,6 +15,8 @@ import retrofit2.Retrofit; public class FetchMessage { + public static final String WHERE_REPLIES = "replies"; + public static final String WHERE_MENTIONS = "mentions"; public static final String WHERE_INBOX = "inbox"; public static final String WHERE_UNREAD = "unread"; public static final String WHERE_SENT = "sent"; @@ -24,6 +26,9 @@ public class FetchMessage { public static final int MESSAGE_TYPE_INBOX = 0; public static final int MESSAGE_TYPE_PRIVATE_MESSAGE = 1; public static final int MESSAGE_TYPE_NOTIFICATION = 2; + public static final int MESSAGE_TYPE_REPLIES = 3; + public static final int MESSAGE_TYPE_MENTIONS = 4; + static void fetchInbox(Retrofit oauthRetrofit, Locale locale, String accessToken, String where, String after, int messageType, FetchMessagesListener fetchMessagesListener) { diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/message/MessageDataSource.java b/app/src/main/java/eu/toldi/infinityforlemmy/message/MessageDataSource.java index 2e783745..6745e35a 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/message/MessageDataSource.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/message/MessageDataSource.java @@ -1,18 +1,18 @@ package eu.toldi.infinityforlemmy.message; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.lifecycle.MutableLiveData; import androidx.paging.PageKeyedDataSource; import java.util.ArrayList; +import java.util.List; import java.util.Locale; import eu.toldi.infinityforlemmy.NetworkState; import retrofit2.Retrofit; -class MessageDataSource extends PageKeyedDataSource { - private Retrofit oauthRetrofit; +class MessageDataSource extends PageKeyedDataSource { + private Retrofit retrofit; private Locale locale; private String accessToken; private String where; @@ -22,18 +22,22 @@ class MessageDataSource extends PageKeyedDataSource { private MutableLiveData initialLoadStateLiveData; private MutableLiveData hasPostLiveData; - private LoadParams params; - private LoadCallback callback; + private LoadParams params; + private LoadCallback callback; + + private int page = 0; MessageDataSource(Retrofit oauthRetrofit, Locale locale, String accessToken, String where) { - this.oauthRetrofit = oauthRetrofit; + this.retrofit = oauthRetrofit; this.locale = locale; this.accessToken = accessToken; this.where = where; if (where.equals(FetchMessage.WHERE_MESSAGES)) { messageType = FetchMessage.MESSAGE_TYPE_PRIVATE_MESSAGE; + } else if (where.equals(FetchMessage.WHERE_REPLIES)) { + messageType = FetchMessage.MESSAGE_TYPE_REPLIES; } else { - messageType = FetchMessage.MESSAGE_TYPE_INBOX; + messageType = FetchMessage.MESSAGE_TYPE_MENTIONS; } paginationNetworkStateLiveData = new MutableLiveData<>(); initialLoadStateLiveData = new MutableLiveData<>(); @@ -57,63 +61,97 @@ class MessageDataSource extends PageKeyedDataSource { } @Override - public void loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback callback) { + public void loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback callback) { initialLoadStateLiveData.postValue(NetworkState.LOADING); - - FetchMessage.fetchInbox(oauthRetrofit, locale, accessToken, where, null, messageType, - new FetchMessage.FetchMessagesListener() { - @Override - public void fetchSuccess(ArrayList messages, @Nullable String after) { - if (messages.size() == 0) { - hasPostLiveData.postValue(false); - } else { + if (messageType == FetchMessage.MESSAGE_TYPE_REPLIES) { + FetchCommentInteractions.fetchReplies(retrofit, 1, false, accessToken, new FetchCommentInteractions.FetchCommentInteractionsListener() { + @Override + public void fetchSuccess(List commentInteractions) { hasPostLiveData.postValue(true); + if (commentInteractions.size() == 0) { + callback.onResult(commentInteractions, null, null); + } else { + callback.onResult(commentInteractions, null, 2); + } + + initialLoadStateLiveData.postValue(NetworkState.LOADED); } - if (after == null || after.equals("") || after.equals("null")) { - callback.onResult(messages, null, null); - } else { - callback.onResult(messages, null, after); + @Override + public void fetchFailed() { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetch messages")); } - initialLoadStateLiveData.postValue(NetworkState.LOADED); - } + }); + } else if (messageType == FetchMessage.MESSAGE_TYPE_MENTIONS) { + FetchCommentInteractions.fetchMentions(retrofit, 1, false, accessToken, new FetchCommentInteractions.FetchCommentInteractionsListener() { + @Override + public void fetchSuccess(List commentInteractions) { + hasPostLiveData.postValue(true); + if (commentInteractions.size() == 0) { + callback.onResult(commentInteractions, null, null); + } else { + callback.onResult(commentInteractions, null, 2); + } - @Override - public void fetchFailed() { - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetch messages")); - } - }); + initialLoadStateLiveData.postValue(NetworkState.LOADED); + } + + @Override + public void fetchFailed() { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetch messages")); + } + }); + } } @Override - public void loadBefore(@NonNull LoadParams params, @NonNull LoadCallback callback) { + public void loadBefore(@NonNull LoadParams params, @NonNull LoadCallback callback) { } @Override - public void loadAfter(@NonNull LoadParams params, @NonNull LoadCallback callback) { + public void loadAfter(@NonNull LoadParams params, @NonNull LoadCallback callback) { this.params = params; this.callback = callback; paginationNetworkStateLiveData.postValue(NetworkState.LOADING); + if (messageType == FetchMessage.MESSAGE_TYPE_REPLIES) { + FetchCommentInteractions.fetchReplies(retrofit, params.key, false, accessToken, new FetchCommentInteractions.FetchCommentInteractionsListener() { + @Override + public void fetchSuccess(List commentInteractions) { + hasPostLiveData.postValue(true); + if (commentInteractions.size() == 0) { + callback.onResult(new ArrayList<>(), null); + } else { + callback.onResult(commentInteractions, params.key + 1); + } - FetchMessage.fetchInbox(oauthRetrofit, locale, accessToken, where, params.key, messageType, - new FetchMessage.FetchMessagesListener() { - @Override - public void fetchSuccess(ArrayList messages, @Nullable String after) { - if (after == null || after.equals("") || after.equals("null")) { - callback.onResult(messages, null); - } else { - callback.onResult(messages, after); + paginationNetworkStateLiveData.postValue(NetworkState.LOADED); } - paginationNetworkStateLiveData.postValue(NetworkState.LOADED); - } + @Override + public void fetchFailed() { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetch messages")); + } + }); + } else if (messageType == FetchMessage.MESSAGE_TYPE_MENTIONS) { + FetchCommentInteractions.fetchMentions(retrofit, params.key, false, accessToken, new FetchCommentInteractions.FetchCommentInteractionsListener() { + @Override + public void fetchSuccess(List commentInteractions) { + hasPostLiveData.postValue(true); + if (commentInteractions.size() == 0) { + callback.onResult(new ArrayList<>(), null); + } else { + callback.onResult(commentInteractions, params.key + 1); + } + paginationNetworkStateLiveData.postValue(NetworkState.LOADED); + } - @Override - public void fetchFailed() { - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetching data")); - } - }); + @Override + public void fetchFailed() { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetch messages")); + } + }); + } } } diff --git a/app/src/main/java/eu/toldi/infinityforlemmy/message/MessageViewModel.java b/app/src/main/java/eu/toldi/infinityforlemmy/message/MessageViewModel.java index 42bbd563..9f010ccd 100644 --- a/app/src/main/java/eu/toldi/infinityforlemmy/message/MessageViewModel.java +++ b/app/src/main/java/eu/toldi/infinityforlemmy/message/MessageViewModel.java @@ -19,7 +19,7 @@ public class MessageViewModel extends ViewModel { private LiveData paginationNetworkState; private LiveData initialLoadingState; private LiveData hasMessageLiveData; - private LiveData> messages; + private LiveData> messages; private MutableLiveData whereLiveData; public MessageViewModel(Retrofit retrofit, Locale locale, String accessToken, String where) { @@ -47,7 +47,7 @@ public class MessageViewModel extends ViewModel { }); } - public LiveData> getMessages() { + public LiveData> getMessages() { return messages; } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8329cce8..ea060afd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1344,4 +1344,6 @@ Could not resolve URL :( Failed to mark post as read Upload an image + Mentions + Replies