From 4b2c94ab5268bb1ff0c6227edd1a8c06437459e7 Mon Sep 17 00:00:00 2001 From: Grishka Date: Sun, 27 Nov 2022 12:43:07 +0300 Subject: [PATCH] Implement bookmarks and add favorites list Closes #22, at last --- .../api/StatusInteractionController.java | 32 ++++++++++++++++ .../statuses/GetBookmarkedStatuses.java | 16 ++++++++ .../statuses/GetFavoritedStatuses.java | 16 ++++++++ .../statuses/SetStatusBookmarked.java | 11 ++++++ .../events/StatusCountersUpdatedEvent.java | 3 +- .../BookmarkedStatusListFragment.java | 37 +++++++++++++++++++ .../FavoritedStatusListFragment.java | 37 +++++++++++++++++++ .../android/fragments/ProfileFragment.java | 18 +++++---- .../joinmastodon/android/model/Status.java | 1 + .../displayitems/HeaderStatusDisplayItem.java | 9 +++++ .../ic_fluent_bookmark_24_regular.xml | 3 ++ mastodon/src/main/res/menu/post.xml | 1 + mastodon/src/main/res/menu/profile_own.xml | 6 +++ mastodon/src/main/res/values/strings.xml | 4 ++ 14 files changed, 186 insertions(+), 8 deletions(-) create mode 100644 mastodon/src/main/java/org/joinmastodon/android/api/requests/statuses/GetBookmarkedStatuses.java create mode 100644 mastodon/src/main/java/org/joinmastodon/android/api/requests/statuses/GetFavoritedStatuses.java create mode 100644 mastodon/src/main/java/org/joinmastodon/android/api/requests/statuses/SetStatusBookmarked.java create mode 100644 mastodon/src/main/java/org/joinmastodon/android/fragments/BookmarkedStatusListFragment.java create mode 100644 mastodon/src/main/java/org/joinmastodon/android/fragments/FavoritedStatusListFragment.java create mode 100644 mastodon/src/main/res/drawable/ic_fluent_bookmark_24_regular.xml create mode 100644 mastodon/src/main/res/menu/profile_own.xml diff --git a/mastodon/src/main/java/org/joinmastodon/android/api/StatusInteractionController.java b/mastodon/src/main/java/org/joinmastodon/android/api/StatusInteractionController.java index a2a72e90..4d260489 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/api/StatusInteractionController.java +++ b/mastodon/src/main/java/org/joinmastodon/android/api/StatusInteractionController.java @@ -4,6 +4,7 @@ import android.os.Looper; import org.joinmastodon.android.E; import org.joinmastodon.android.MastodonApp; +import org.joinmastodon.android.api.requests.statuses.SetStatusBookmarked; import org.joinmastodon.android.api.requests.statuses.SetStatusFavorited; import org.joinmastodon.android.api.requests.statuses.SetStatusReblogged; import org.joinmastodon.android.events.StatusCountersUpdatedEvent; @@ -18,6 +19,7 @@ public class StatusInteractionController{ private final String accountID; private final HashMap runningFavoriteRequests=new HashMap<>(); private final HashMap runningReblogRequests=new HashMap<>(); + private final HashMap runningBookmarkRequests=new HashMap<>(); public StatusInteractionController(String accountID){ this.accountID=accountID; @@ -98,4 +100,34 @@ public class StatusInteractionController{ status.reblogsCount--; E.post(new StatusCountersUpdatedEvent(status)); } + + public void setBookmarked(Status status, boolean bookmarked){ + if(!Looper.getMainLooper().isCurrentThread()) + throw new IllegalStateException("Can only be called from main thread"); + + SetStatusBookmarked current=runningBookmarkRequests.remove(status.id); + if(current!=null){ + current.cancel(); + } + SetStatusBookmarked req=(SetStatusBookmarked) new SetStatusBookmarked(status.id, bookmarked) + .setCallback(new Callback<>(){ + @Override + public void onSuccess(Status result){ + runningBookmarkRequests.remove(status.id); + E.post(new StatusCountersUpdatedEvent(result)); + } + + @Override + public void onError(ErrorResponse error){ + runningBookmarkRequests.remove(status.id); + error.showToast(MastodonApp.context); + status.bookmarked=!bookmarked; + E.post(new StatusCountersUpdatedEvent(status)); + } + }) + .exec(accountID); + runningBookmarkRequests.put(status.id, req); + status.bookmarked=bookmarked; + E.post(new StatusCountersUpdatedEvent(status)); + } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/api/requests/statuses/GetBookmarkedStatuses.java b/mastodon/src/main/java/org/joinmastodon/android/api/requests/statuses/GetBookmarkedStatuses.java new file mode 100644 index 00000000..b8e81c26 --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/api/requests/statuses/GetBookmarkedStatuses.java @@ -0,0 +1,16 @@ +package org.joinmastodon.android.api.requests.statuses; + +import com.google.gson.reflect.TypeToken; + +import org.joinmastodon.android.api.requests.HeaderPaginationRequest; +import org.joinmastodon.android.model.Status; + +public class GetBookmarkedStatuses extends HeaderPaginationRequest{ + public GetBookmarkedStatuses(String maxID, int limit){ + super(HttpMethod.GET, "/bookmarks", new TypeToken<>(){}); + if(maxID!=null) + addQueryParameter("max_id", maxID); + if(limit>0) + addQueryParameter("limit", limit+""); + } +} diff --git a/mastodon/src/main/java/org/joinmastodon/android/api/requests/statuses/GetFavoritedStatuses.java b/mastodon/src/main/java/org/joinmastodon/android/api/requests/statuses/GetFavoritedStatuses.java new file mode 100644 index 00000000..7627d006 --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/api/requests/statuses/GetFavoritedStatuses.java @@ -0,0 +1,16 @@ +package org.joinmastodon.android.api.requests.statuses; + +import com.google.gson.reflect.TypeToken; + +import org.joinmastodon.android.api.requests.HeaderPaginationRequest; +import org.joinmastodon.android.model.Status; + +public class GetFavoritedStatuses extends HeaderPaginationRequest{ + public GetFavoritedStatuses(String maxID, int limit){ + super(HttpMethod.GET, "/favourites", new TypeToken<>(){}); + if(maxID!=null) + addQueryParameter("max_id", maxID); + if(limit>0) + addQueryParameter("limit", limit+""); + } +} diff --git a/mastodon/src/main/java/org/joinmastodon/android/api/requests/statuses/SetStatusBookmarked.java b/mastodon/src/main/java/org/joinmastodon/android/api/requests/statuses/SetStatusBookmarked.java new file mode 100644 index 00000000..3b010e24 --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/api/requests/statuses/SetStatusBookmarked.java @@ -0,0 +1,11 @@ +package org.joinmastodon.android.api.requests.statuses; + +import org.joinmastodon.android.api.MastodonAPIRequest; +import org.joinmastodon.android.model.Status; + +public class SetStatusBookmarked extends MastodonAPIRequest{ + public SetStatusBookmarked(String id, boolean bookmarked){ + super(HttpMethod.POST, "/statuses/"+id+"/"+(bookmarked ? "bookmark" : "unbookmark"), Status.class); + setRequestBody(new Object()); + } +} diff --git a/mastodon/src/main/java/org/joinmastodon/android/events/StatusCountersUpdatedEvent.java b/mastodon/src/main/java/org/joinmastodon/android/events/StatusCountersUpdatedEvent.java index 926f0bf6..c4f15282 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/events/StatusCountersUpdatedEvent.java +++ b/mastodon/src/main/java/org/joinmastodon/android/events/StatusCountersUpdatedEvent.java @@ -5,7 +5,7 @@ import org.joinmastodon.android.model.Status; public class StatusCountersUpdatedEvent{ public String id; public long favorites, reblogs, replies; - public boolean favorited, reblogged; + public boolean favorited, reblogged, bookmarked; public StatusCountersUpdatedEvent(Status s){ id=s.id; @@ -14,5 +14,6 @@ public class StatusCountersUpdatedEvent{ replies=s.repliesCount; favorited=s.favourited; reblogged=s.reblogged; + bookmarked=s.bookmarked; } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/BookmarkedStatusListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/BookmarkedStatusListFragment.java new file mode 100644 index 00000000..501ff127 --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/BookmarkedStatusListFragment.java @@ -0,0 +1,37 @@ +package org.joinmastodon.android.fragments; + +import android.app.Activity; + +import org.joinmastodon.android.R; +import org.joinmastodon.android.api.requests.statuses.GetBookmarkedStatuses; +import org.joinmastodon.android.model.HeaderPaginationList; +import org.joinmastodon.android.model.Status; + +import me.grishka.appkit.api.SimpleCallback; + +public class BookmarkedStatusListFragment extends StatusListFragment{ + private String nextMaxID; + + @Override + public void onAttach(Activity activity){ + super.onAttach(activity); + setTitle(R.string.bookmarks); + loadData(); + } + + @Override + protected void doLoadData(int offset, int count){ + currentRequest=new GetBookmarkedStatuses(offset==0 ? null : nextMaxID, count) + .setCallback(new SimpleCallback<>(this){ + @Override + public void onSuccess(HeaderPaginationList result){ + if(result.nextPageUri!=null) + nextMaxID=result.nextPageUri.getQueryParameter("max_id"); + else + nextMaxID=null; + onDataLoaded(result, nextMaxID!=null); + } + }) + .exec(accountID); + } +} diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/FavoritedStatusListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/FavoritedStatusListFragment.java new file mode 100644 index 00000000..f0779e71 --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/FavoritedStatusListFragment.java @@ -0,0 +1,37 @@ +package org.joinmastodon.android.fragments; + +import android.app.Activity; + +import org.joinmastodon.android.R; +import org.joinmastodon.android.api.requests.statuses.GetFavoritedStatuses; +import org.joinmastodon.android.model.HeaderPaginationList; +import org.joinmastodon.android.model.Status; + +import me.grishka.appkit.api.SimpleCallback; + +public class FavoritedStatusListFragment extends StatusListFragment{ + private String nextMaxID; + + @Override + public void onAttach(Activity activity){ + super.onAttach(activity); + setTitle(R.string.your_favorites); + loadData(); + } + + @Override + protected void doLoadData(int offset, int count){ + currentRequest=new GetFavoritedStatuses(offset==0 ? null : nextMaxID, count) + .setCallback(new SimpleCallback<>(this){ + @Override + public void onSuccess(HeaderPaginationList result){ + if(result.nextPageUri!=null) + nextMaxID=result.nextPageUri.getQueryParameter("max_id"); + else + nextMaxID=null; + onDataLoaded(result, nextMaxID!=null); + } + }) + .exec(accountID); + } +} diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java index 5450a284..53ee3d29 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java @@ -534,15 +534,11 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList } if(relationship==null && !isOwnProfile) return; - inflater.inflate(R.menu.profile, menu); + inflater.inflate(isOwnProfile ? R.menu.profile_own : R.menu.profile, menu); menu.findItem(R.id.share).setTitle(getString(R.string.share_user, account.getDisplayUsername())); - if(isOwnProfile){ - for(int i=0;i{}); + }else if(id==R.id.bookmark){ + AccountSessionManager.getInstance().getAccount(item.accountID).getStatusInteractionController().setBookmarked(item.status, !item.status.bookmarked); } return true; }); @@ -290,6 +292,13 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{ MenuItem block=menu.findItem(R.id.block); MenuItem report=menu.findItem(R.id.report); MenuItem follow=menu.findItem(R.id.follow); + MenuItem bookmark=menu.findItem(R.id.bookmark); + if(item.status!=null){ + bookmark.setVisible(true); + bookmark.setTitle(item.status.bookmarked ? R.string.remove_bookmark : R.string.add_bookmark); + }else{ + bookmark.setVisible(false); + } if(isOwnPost){ mute.setVisible(false); block.setVisible(false); diff --git a/mastodon/src/main/res/drawable/ic_fluent_bookmark_24_regular.xml b/mastodon/src/main/res/drawable/ic_fluent_bookmark_24_regular.xml new file mode 100644 index 00000000..62930463 --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_fluent_bookmark_24_regular.xml @@ -0,0 +1,3 @@ + + + diff --git a/mastodon/src/main/res/menu/post.xml b/mastodon/src/main/res/menu/post.xml index ca14e2b7..30a412ac 100644 --- a/mastodon/src/main/res/menu/post.xml +++ b/mastodon/src/main/res/menu/post.xml @@ -7,5 +7,6 @@ + \ No newline at end of file diff --git a/mastodon/src/main/res/menu/profile_own.xml b/mastodon/src/main/res/menu/profile_own.xml new file mode 100644 index 00000000..c8895bb8 --- /dev/null +++ b/mastodon/src/main/res/menu/profile_own.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/mastodon/src/main/res/values/strings.xml b/mastodon/src/main/res/values/strings.xml index ecaacaab..1e0f4051 100644 --- a/mastodon/src/main/res/values/strings.xml +++ b/mastodon/src/main/res/values/strings.xml @@ -390,4 +390,8 @@ This list is empty This server does not accept new registrations. Copied to clipboard + Bookmark + Remove bookmark + Bookmarks + Your Favorites \ No newline at end of file