commit 7b56338e1df5c9bd8057bf13183df3d2579e3b5c from: notfire via: darkwolf date: Sat Jul 11 15:32:51 2026 UTC add support for sending bites commit - a1a12dddfe17f2141ce31b7835a3b2fc5834554f commit + 7b56338e1df5c9bd8057bf13183df3d2579e3b5c blob - f7610292bfdc50ab4b77ca34141eed386b413d33 blob + 4609014b03f68944055cd2f2e89c86cd52bb3a5d --- mastodon/src/main/java/org/joinmastodon/android/api/MastodonAPIRequest.java +++ mastodon/src/main/java/org/joinmastodon/android/api/MastodonAPIRequest.java @@ -139,7 +139,7 @@ public abstract class MastodonAPIRequest extends AP return this; } - protected void setRequestBody(Object body){ + public void setRequestBody(Object body){ requestBody=body; } blob - /dev/null blob + eeed317352506a91c524a1cd83168850f3eb345f (mode 644) --- /dev/null +++ mastodon/src/main/java/org/joinmastodon/android/api/requests/accounts/BiteAccount.java @@ -0,0 +1,14 @@ +package org.joinmastodon.android.api.requests.accounts; + +import com.google.gson.reflect.TypeToken; + +import org.joinmastodon.android.api.MastodonAPIRequest; +import org.joinmastodon.android.model.FollowList; + +import java.util.List; + +public class BiteAccount extends MastodonAPIRequest{ + public BiteAccount(String id){ + super(HttpMethod.POST, "/users/"+id+"/bite", BiteAccount.class); + } +} blob - /dev/null blob + a4722e9557c2dc4066f5e4348d640a84a46c1827 (mode 644) --- /dev/null +++ mastodon/src/main/java/org/joinmastodon/android/api/requests/statuses/BitePost.java @@ -0,0 +1,9 @@ +package org.joinmastodon.android.api.requests.statuses; + +import org.joinmastodon.android.api.MastodonAPIRequest; + +public class BitePost extends MastodonAPIRequest{ + public BitePost(String id){ + super(HttpMethod.POST, "/statuses/"+id+"/bite", BitePost.class); + } +} blob - 6c062a7e0c2c8d0f366bb5aafee4f6a6ef87f1a7 blob + c9a57f35a1561f5fb6abc77efce4bc664ddbe668 --- mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java +++ mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java @@ -60,6 +60,7 @@ import androidx.viewpager2.widget.ViewPager2; import org.joinmastodon.android.GlobalUserPreferences; import org.joinmastodon.android.MastodonApp; import org.joinmastodon.android.R; +import org.joinmastodon.android.api.requests.accounts.BiteAccount; import org.joinmastodon.android.api.requests.accounts.GetAccountByID; import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships; import org.joinmastodon.android.api.requests.accounts.GetAccountStatuses; @@ -816,7 +817,7 @@ public class ProfileFragment extends LoaderFragment im if(isOwnProfile){ UiUtils.enableOptionsMenuIcons(getActivity(), menu, R.id.scheduled, R.id.bookmarks); }else{ - UiUtils.enableOptionsMenuIcons(getActivity(), menu, R.id.edit_note); + UiUtils.enableOptionsMenuIcons(getActivity(), menu, R.id.edit_note, R.id.biteuser_btn); } boolean hasMultipleAccounts = AccountSessionManager.getInstance().getLoggedInAccounts().size() > 1; menu.findItem(R.id.open_with_account).setVisible(hasMultipleAccounts); @@ -933,6 +934,18 @@ public class ProfileFragment extends LoaderFragment im }else if(id==R.id.save){ if(isInEditMode) saveAndExitEditMode(); + }else if(id==R.id.biteuser_btn){ + new BiteAccount(profileAccountID).setCallback(new Callback<>(){ + @Override + public void onSuccess(Object result){ + Toast.makeText(getContext(), "User was bitten", Toast.LENGTH_SHORT).show(); + } + + @Override + public void onError(ErrorResponse error){ + error.showToast(getContext()); + } + }).exec(accountID).setRequestBody(new Object()); }else if(id==R.id.edit_note){ if(noteWrap.getVisibility()==View.GONE){ showPrivateNote(); blob - 3353eea9c54e8a16729354a53df28c5330b0ec89 blob + 06bd136199db77ba10a611898612aedbb0bc08d9 --- mastodon/src/main/java/org/joinmastodon/android/model/Notification.java +++ mastodon/src/main/java/org/joinmastodon/android/model/Notification.java @@ -65,7 +65,9 @@ public class Notification extends BaseModel implements @SerializedName("admin.sign_up") SIGN_UP, @SerializedName("admin.report") - REPORT + REPORT, + @SerializedName("bite") + BITE } @Parcel blob - 16a1ae52e14aed4f12f3801c6625ea63a358d7dd blob + 31a4709c63b3ef5037bd4d4d8452b6265cda5052 --- mastodon/src/main/java/org/joinmastodon/android/ui/CustomEmojiPopupKeyboard.java +++ mastodon/src/main/java/org/joinmastodon/android/ui/CustomEmojiPopupKeyboard.java @@ -111,12 +111,13 @@ public class CustomEmojiPopupKeyboard extends PopupKey list.setPadding(V.dp(16), 0, V.dp(16), 0); imgLoader=new ListImageLoaderWrapper(activity, list, new RecyclerViewDelegate(list), null); - List recentEmoji=new ArrayList<>(lp.recentCustomEmoji); - if(!recentEmoji.isEmpty()) - adapter.addAdapter(new SingleCategoryAdapter(recentEmojiCategory=new EmojiCategory(activity.getString(R.string.mo_emoji_recent), recentEmoji))); - - for(EmojiCategory category:emojis) - adapter.addAdapter(new SingleCategoryAdapter(category)); + if (!forReaction){ + List recentEmoji=new ArrayList<>(lp.recentCustomEmoji); + if(!recentEmoji.isEmpty()) + adapter.addAdapter(new SingleCategoryAdapter(recentEmojiCategory=new EmojiCategory(activity.getString(R.string.mo_emoji_recent), recentEmoji))); + for(EmojiCategory category : emojis) + adapter.addAdapter(new SingleCategoryAdapter(category)); + } list.setAdapter(adapter); list.addItemDecoration(new RecyclerView.ItemDecoration(){ @Override @@ -229,6 +230,15 @@ public class CustomEmojiPopupKeyboard extends PopupKey } } + public void customToggleKeyboardPopup(){ + List recentEmoji=new ArrayList<>(lp.recentCustomEmoji); + if(!recentEmoji.isEmpty()) + adapter.addAdapter(new SingleCategoryAdapter(recentEmojiCategory=new EmojiCategory(activity.getString(R.string.mo_emoji_recent), recentEmoji))); + for(EmojiCategory category : emojis) + adapter.addAdapter(new SingleCategoryAdapter(category)); + super.toggleKeyboardPopup(null); + } + private class SingleCategoryAdapter extends UsableRecyclerView.Adapter implements ImageLoaderRecyclerAdapter, Filterable{ private EmojiCategory category; blob - 0c0c1b99145f2405e985b49d5056debfe87ee733 blob + f3b0a6cf00e14f86059773cbe6105e4d5327074d --- mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/EmojiReactionsStatusDisplayItem.java +++ mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/EmojiReactionsStatusDisplayItem.java @@ -317,7 +317,7 @@ public class EmojiReactionsStatusDisplayItem extends S public void onBackspace() {} private void onReactClick(View v){ - emojiKeyboard.toggleKeyboardPopup(null); + emojiKeyboard.customToggleKeyboardPopup(); v.setSelected(emojiKeyboard.isVisible()); space.setVisibility(emojiKeyboard.isVisible() ? View.VISIBLE : View.GONE); DisplayMetrics displayMetrics = new DisplayMetrics(); blob - 98e4d0e05dcba5062d59bfb950821a8b09f6f818 blob + 0f3bd2935b956619e0f89c9d67d5051e0c417465 --- mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/HeaderStatusDisplayItem.java +++ mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/HeaderStatusDisplayItem.java @@ -22,9 +22,12 @@ import android.widget.TextView; import android.widget.Toast; import org.joinmastodon.android.GlobalUserPreferences; +import org.joinmastodon.android.MastodonApp; import org.joinmastodon.android.R; +import org.joinmastodon.android.api.requests.accounts.BiteAccount; import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships; import org.joinmastodon.android.api.requests.announcements.DismissAnnouncement; +import org.joinmastodon.android.api.requests.statuses.BitePost; import org.joinmastodon.android.api.requests.statuses.CreateStatus; import org.joinmastodon.android.api.requests.statuses.GetStatusSourceText; import org.joinmastodon.android.api.session.AccountSession; @@ -263,6 +266,18 @@ public class HeaderStatusDisplayItem extends StatusDis UiUtils.launchWebBrowser(activity, item.status.url); }else if(id==R.id.copy_link){ UiUtils.copyText(parent, item.status.url); + }else if(id==R.id.bitepost_btn){ + new BitePost(item.status.id).setCallback(new Callback<>(){ + @Override + public void onSuccess(Object result){ + Toast.makeText(MastodonApp.context, "Post was bitten", Toast.LENGTH_SHORT).show(); + } + + @Override + public void onError(ErrorResponse error){ + error.showToast(MastodonApp.context); + } + }).exec(item.parentFragment.getAccountID()).setRequestBody(new Object()); }else if(id==R.id.follow){ if(relationship==null) return true; @@ -513,6 +528,7 @@ public class HeaderStatusDisplayItem extends StatusDis menu.findItem(R.id.unmute_conversation).setVisible(item.status!=null && item.status.muted); menu.findItem(R.id.open_in_browser).setVisible(!isPostScheduled && item.status!=null); menu.findItem(R.id.copy_link).setVisible(!isPostScheduled && item.status!=null); + menu.findItem(R.id.bitepost_btn).setVisible(!isOwnPost && !isPostScheduled && item.status!=null); MenuItem blockDomain=menu.findItem(R.id.block_domain); MenuItem mute=menu.findItem(R.id.mute); MenuItem block=menu.findItem(R.id.block); blob - bb90911fdc1a7521527e96496bb84621c76fbb57 blob + e8ade22a4e6a0e5855ce1b1b49261d41ee49ba77 --- mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/NotificationHeaderStatusDisplayItem.java +++ mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/NotificationHeaderStatusDisplayItem.java @@ -75,6 +75,7 @@ public class NotificationHeaderStatusDisplayItem exten case REPORT -> R.string.sk_reported; case REACTION, PLEROMA_EMOJI_REACTION -> !TextUtils.isEmpty(notification.emoji) ? R.string.sk_reacted_with : R.string.sk_reacted; + case BITE -> R.string.sk_bit_you; default -> throw new IllegalStateException("Unexpected value: "+notification.type); }); @@ -170,6 +171,7 @@ public class NotificationHeaderStatusDisplayItem exten case SIGN_UP -> R.drawable.ic_fluent_person_available_24_filled; case UPDATE -> R.drawable.ic_fluent_edit_24_filled; case REACTION, PLEROMA_EMOJI_REACTION -> R.drawable.ic_fluent_add_24_filled; + case BITE -> R.drawable.ic_fluent_animal_cat_24_regular; default -> throw new IllegalStateException("Unexpected value: "+item.notification.type); }); icon.setImageTintList(ColorStateList.valueOf(UiUtils.getThemeColor(item.parentFragment.getActivity(), switch(item.notification.type){ blob - 724cb34c0da14756b41836b8e0078aa6668985ad blob + 934e57b642018705ac40faf850da36e980b27313 --- mastodon/src/main/java/org/joinmastodon/android/ui/viewholders/AccountViewHolder.java +++ mastodon/src/main/java/org/joinmastodon/android/ui/viewholders/AccountViewHolder.java @@ -25,6 +25,7 @@ import android.widget.TextView; import org.joinmastodon.android.GlobalUserPreferences; import org.joinmastodon.android.R; +import org.joinmastodon.android.api.requests.accounts.BiteAccount; import org.joinmastodon.android.api.requests.accounts.SetAccountFollowed; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.fragments.AddAccountToListsFragment; @@ -66,6 +67,7 @@ public class AccountViewHolder extends BindableViewHol private final View checkbox; private final ProgressBar actionProgress; private final ImageButton menuButton; + private final ImageButton biteUserButton; private final String accountID; private final Fragment fragment; @@ -102,6 +104,7 @@ public class AccountViewHolder extends BindableViewHol checkbox=findViewById(R.id.checkbox); actionProgress=findViewById(R.id.action_progress); menuButton=findViewById(R.id.options_btn); + biteUserButton=findViewById(R.id.biteuser_btn); avatar.setOutlineProvider(OutlineProviders.roundedRect(10)); avatar.setClipToOutline(true); blob - 1beb3d46493af15cc208c794eb9cd32bccab42c4 blob + 9474ff02a1117dc45a4a200d4eefed91fd5d7556 --- mastodon/src/main/res/menu/post.xml +++ mastodon/src/main/res/menu/post.xml @@ -8,6 +8,7 @@ + blob - 043e963123057dfdb149e65e05deb57c2b14c023 blob + 0217336924483512bd76e7ae299dae36f81a64d0 --- mastodon/src/main/res/menu/profile.xml +++ mastodon/src/main/res/menu/profile.xml @@ -2,6 +2,7 @@ + blob - 7a258a06b5be8f19ecfdaee3226c1e3ba1f59611 blob + 3201e3f94b6f841b1b9f708d6ef08087ea644cd3 --- mastodon/src/main/res/values/strings_sk.xml +++ mastodon/src/main/res/values/strings_sk.xml @@ -439,4 +439,7 @@ Multiple choices Show results Hide results + %s bit you + Bite + Bite this post