diff --git a/mastodon/src/main/java/org/joinmastodon/android/api/requests/announcements/AddAnnouncementReaction.java b/mastodon/src/main/java/org/joinmastodon/android/api/requests/announcements/AddAnnouncementReaction.java new file mode 100644 index 000000000..f92167cd2 --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/api/requests/announcements/AddAnnouncementReaction.java @@ -0,0 +1,11 @@ +package org.joinmastodon.android.api.requests.announcements; + +import org.joinmastodon.android.api.MastodonAPIRequest; +import org.joinmastodon.android.model.Status; + +public class AddAnnouncementReaction extends MastodonAPIRequest { + public AddAnnouncementReaction(String id, String emoji) { + super(HttpMethod.PUT, "/announcements/" + id + "/reactions/" + emoji, Object.class); + setRequestBody(new Object()); + } +} diff --git a/mastodon/src/main/java/org/joinmastodon/android/api/requests/announcements/DeleteAnnouncementReaction.java b/mastodon/src/main/java/org/joinmastodon/android/api/requests/announcements/DeleteAnnouncementReaction.java new file mode 100644 index 000000000..e1a667f36 --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/api/requests/announcements/DeleteAnnouncementReaction.java @@ -0,0 +1,9 @@ +package org.joinmastodon.android.api.requests.announcements; + +import org.joinmastodon.android.api.MastodonAPIRequest; + +public class DeleteAnnouncementReaction extends MastodonAPIRequest { + public DeleteAnnouncementReaction(String id, String emoji) { + super(HttpMethod.DELETE, "/announcements/" + id + "/reactions/" + emoji, Object.class); + } +} diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/AnnouncementsFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/AnnouncementsFragment.java index a304c766f..30e2e4b07 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/AnnouncementsFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/AnnouncementsFragment.java @@ -26,6 +26,8 @@ import org.joinmastodon.android.model.HeaderPaginationList; import org.joinmastodon.android.model.Instance; import org.joinmastodon.android.model.ScheduledStatus; import org.joinmastodon.android.model.Status; +import org.joinmastodon.android.ui.displayitems.DummyStatusDisplayItem; +import org.joinmastodon.android.ui.displayitems.EmojiReactionsStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.HeaderStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.StatusDisplayItem; import org.joinmastodon.android.ui.displayitems.TextStatusDisplayItem; @@ -68,11 +70,12 @@ public class AnnouncementsFragment extends BaseStatusListFragment instanceUser.emojis = List.of(); Status fakeStatus = a.toStatus(); TextStatusDisplayItem textItem = new TextStatusDisplayItem(a.id, HtmlParser.parse(a.content, a.emojis, a.mentions, a.tags, accountID), this, fakeStatus, true); - // TODO: emoji reactions! textItem.textSelectable = true; return List.of( HeaderStatusDisplayItem.fromAnnouncement(a, fakeStatus, instanceUser, this, accountID, this::onMarkAsRead), - textItem + textItem, + new EmojiReactionsStatusDisplayItem(a.id, this, fakeStatus, accountID, false, true) +// new DummyStatusDisplayItem(a.id, this) ); } diff --git a/mastodon/src/main/java/org/joinmastodon/android/model/Announcement.java b/mastodon/src/main/java/org/joinmastodon/android/model/Announcement.java index 1d54b5215..76d37fe49 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/model/Announcement.java +++ b/mastodon/src/main/java/org/joinmastodon/android/model/Announcement.java @@ -1,9 +1,11 @@ package org.joinmastodon.android.model; +import org.joinmastodon.android.api.ObjectValidationException; import org.joinmastodon.android.api.RequiredField; import org.parceler.Parcel; import java.time.Instant; +import java.util.ArrayList; import java.util.List; @Parcel @@ -20,6 +22,7 @@ public class Announcement extends BaseModel implements DisplayItemsParent { public Instant updatedAt; public boolean read; public List emojis; + public List reactions; public List mentions; public List tags; @@ -41,10 +44,17 @@ public class Announcement extends BaseModel implements DisplayItemsParent { '}'; } - public Status toStatus() { - Status s = Status.ofFake(id, content, publishedAt); - s.createdAt = startsAt != null ? startsAt : publishedAt; - if (updatedAt != null) s.editedAt = updatedAt; + @Override + public void postprocess() throws ObjectValidationException{ + super.postprocess(); + if(reactions==null) reactions=new ArrayList<>(); + } + + public Status toStatus() { + Status s=Status.ofFake(id, content, publishedAt); + s.createdAt=startsAt != null ? startsAt : publishedAt; + s.reactions=reactions; + if(updatedAt != null) s.editedAt=updatedAt; return s; } diff --git a/mastodon/src/main/java/org/joinmastodon/android/model/Status.java b/mastodon/src/main/java/org/joinmastodon/android/model/Status.java index 363b43f55..35ec59419 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/model/Status.java +++ b/mastodon/src/main/java/org/joinmastodon/android/model/Status.java @@ -100,7 +100,7 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{ t.postprocess(); for(Emoji e:emojis) e.postprocess(); - if (mediaAttachments == null) mediaAttachments = List.of(); + if (mediaAttachments == null) mediaAttachments=List.of(); for(Attachment a:mediaAttachments) a.postprocess(); account.postprocess(); @@ -201,17 +201,18 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{ } public static Status ofFake(String id, String text, Instant createdAt) { - Status s = new Status(); - s.id = id; - s.mediaAttachments = List.of(); - s.createdAt = createdAt; - s.content = s.text = text; - s.spoilerText = ""; - s.visibility = StatusPrivacy.PUBLIC; - s.mentions = List.of(); - s.tags = List.of(); - s.emojis = List.of(); - s.filtered = List.of(); + Status s=new Status(); + s.id=id; + s.mediaAttachments=List.of(); + s.createdAt=createdAt; + s.content=s.text=text; + s.spoilerText=""; + s.visibility=StatusPrivacy.PUBLIC; + s.reactions=List.of(); + s.mentions=List.of(); + s.tags =List.of(); + s.emojis=List.of(); + s.filtered=List.of(); return s; } @@ -223,21 +224,21 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{ public static class StatusDeserializer implements JsonDeserializer { @Override public Status deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - JsonObject obj = json.getAsJsonObject(); + JsonObject obj=json.getAsJsonObject(); - Status quote = null; + Status quote=null; if (obj.has("quote") && obj.get("quote").isJsonObject()) - quote = gson.fromJson(obj.get("quote"), Status.class); + quote=gson.fromJson(obj.get("quote"), Status.class); obj.remove("quote"); - Status reblog = null; + Status reblog=null; if (obj.has("reblog")) - reblog = gson.fromJson(obj.get("reblog"), Status.class); + reblog=gson.fromJson(obj.get("reblog"), Status.class); obj.remove("reblog"); - Status status = gsonWithoutDeserializer.fromJson(json, Status.class); - status.quote = quote; - status.reblog = reblog; + Status status=gsonWithoutDeserializer.fromJson(json, Status.class); + status.quote=quote; + status.reblog=reblog; return status; } diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/DummyStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/DummyStatusDisplayItem.java index 04d05eaf8..6d9ea36b6 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/DummyStatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/DummyStatusDisplayItem.java @@ -7,7 +7,6 @@ import android.widget.Space; import androidx.recyclerview.widget.RecyclerView; import org.joinmastodon.android.fragments.BaseStatusListFragment; -import org.joinmastodon.android.model.Status; import me.grishka.appkit.utils.V; diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/EmojiReactionsStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/EmojiReactionsStatusDisplayItem.java index 6b2c203b1..2cc7f1f19 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/EmojiReactionsStatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/EmojiReactionsStatusDisplayItem.java @@ -21,6 +21,8 @@ import androidx.recyclerview.widget.LinearLayoutManager; import org.joinmastodon.android.E; import org.joinmastodon.android.R; import org.joinmastodon.android.api.MastodonAPIRequest; +import org.joinmastodon.android.api.requests.announcements.AddAnnouncementReaction; +import org.joinmastodon.android.api.requests.announcements.DeleteAnnouncementReaction; import org.joinmastodon.android.api.requests.statuses.AddStatusReaction; import org.joinmastodon.android.api.requests.statuses.DeleteStatusReaction; import org.joinmastodon.android.api.requests.statuses.PleromaAddStatusReaction; @@ -31,6 +33,7 @@ import org.joinmastodon.android.events.StatusCountersUpdatedEvent; import org.joinmastodon.android.fragments.BaseStatusListFragment; import org.joinmastodon.android.fragments.account_list.StatusEmojiReactionsListFragment; import org.joinmastodon.android.model.Account; +import org.joinmastodon.android.model.Announcement; import org.joinmastodon.android.model.Emoji; import org.joinmastodon.android.model.EmojiReaction; import org.joinmastodon.android.model.Status; @@ -54,14 +57,15 @@ import me.grishka.appkit.views.UsableRecyclerView; public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem { public final Status status; private final Drawable placeholder; - private final boolean hideAdd; + private final boolean hideAdd, forAnnouncement; private final String accountID; private boolean hidden; - public EmojiReactionsStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, Status status, String accountID, boolean hideAdd) { + public EmojiReactionsStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, Status status, String accountID, boolean hideAdd, boolean forAnnouncement) { super(parentID, parentFragment); this.status=status; this.hideAdd=hideAdd; + this.forAnnouncement=forAnnouncement; this.accountID=accountID; placeholder=parentFragment.getContext().getDrawable(R.drawable.image_placeholder).mutate(); placeholder.setBounds(0, 0, V.sp(24), V.sp(24)); @@ -91,6 +95,31 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem { hidden=status.reactions.isEmpty() && hideAdd; } + private MastodonAPIRequest createRequest(String name, boolean delete, Runnable cb){ + boolean ak=parentFragment.isInstanceAkkoma(); + if(forAnnouncement){ + MastodonAPIRequest req=delete + ? new DeleteAnnouncementReaction(status.id, name) + : new AddAnnouncementReaction(status.id, name); + return req.setCallback(new Callback<>(){ + @Override + public void onSuccess(Object result){ cb.run(); } + @Override + public void onError(ErrorResponse error){ error.showToast(parentFragment.getContext()); } + }); + }else{ + MastodonAPIRequest req=delete + ? (ak ? new PleromaDeleteStatusReaction(status.id, name) : new DeleteStatusReaction(status.id, name)) + : (ak ? new PleromaAddStatusReaction(status.id, name) : new AddStatusReaction(status.id, name)); + return req.setCallback(new Callback<>(){ + @Override + public void onSuccess(Status result){ cb.run(); } + @Override + public void onError(ErrorResponse error){ error.showToast(parentFragment.getContext()); } + }); + } + } + public static class Holder extends StatusDisplayItem.Holder implements ImageLoaderViewHolder, CustomEmojiPopupKeyboard.Listener { private final UsableRecyclerView list; private final LinearLayout root, line; @@ -129,7 +158,12 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem { item.updateHidden(); root.setVisibility(item.hidden ? View.GONE : View.VISIBLE); line.setVisibility(item.hidden ? View.GONE : View.VISIBLE); - line.setPadding(list.getPaddingLeft(), item.hidden ? 0 : V.dp(8), list.getPaddingRight(), 0); + line.setPadding( + list.getPaddingLeft(), + item.hidden ? 0 : V.dp(8), + list.getPaddingRight(), + item.forAnnouncement ? V.dp(8) : 0 + ); imgLoader.updateImages(); adapter.notifyDataSetChanged(); } @@ -154,37 +188,25 @@ public class EmojiReactionsStatusDisplayItem extends StatusDisplayItem { private void addEmojiReaction(String emoji, Emoji info) { if(item.status.reactions.stream().filter(r->r.name.equals(emoji) && r.me).findAny().isPresent()) return; - - MastodonAPIRequest req = item.parentFragment.isInstanceAkkoma() - ? new PleromaAddStatusReaction(item.status.id, emoji) - : new AddStatusReaction(item.status.id, emoji); - req.setCallback(new Callback<>() { - @Override - public void onSuccess(Status result) { - Account me=AccountSessionManager.get(item.accountID).self; - boolean found=false; - for(int i=0; i{ + Account me=AccountSessionManager.get(item.accountID).self; + boolean found=false; + for(int i=0; i { + btn.setOnClickListener(e->{ boolean deleting=reaction.me; - boolean ak=parent.parentFragment.isInstanceAkkoma(); - MastodonAPIRequest req = deleting - ? (ak ? new PleromaDeleteStatusReaction(parent.status.id, reaction.name) : new DeleteStatusReaction(parent.status.id, reaction.name)) - : (ak ? new PleromaAddStatusReaction(parent.status.id, reaction.name) : new AddStatusReaction(parent.status.id, reaction.name)); - req.setCallback(new Callback<>() { - @Override - public void onSuccess(Status result) { - EmojiReactionsAdapter adapter = (EmojiReactionsAdapter) getBindingAdapter(); + parent.createRequest(reaction.name, deleting, ()->{ + EmojiReactionsAdapter adapter = (EmojiReactionsAdapter) getBindingAdapter(); - for(int i=0; i