emoji_reactions: general refactoring, implement emoji_reactions_by
This commit is contained in:
parent
0257cd3b07
commit
97ffa14268
@ -37,7 +37,8 @@ class AccountListActivity : BaseActivity(), HasAndroidInjector {
|
||||
MUTES,
|
||||
FOLLOW_REQUESTS,
|
||||
REBLOGGED,
|
||||
FAVOURITED
|
||||
FAVOURITED,
|
||||
REACTED
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@ -46,6 +47,7 @@ class AccountListActivity : BaseActivity(), HasAndroidInjector {
|
||||
|
||||
val type = intent.getSerializableExtra(EXTRA_TYPE) as Type
|
||||
val id: String? = intent.getStringExtra(EXTRA_ID)
|
||||
val emoji: String? = intent.getStringExtra(EXTRA_EMOJI)
|
||||
|
||||
setSupportActionBar(toolbar)
|
||||
supportActionBar?.apply {
|
||||
@ -57,6 +59,7 @@ class AccountListActivity : BaseActivity(), HasAndroidInjector {
|
||||
Type.FOLLOWS -> setTitle(R.string.title_follows)
|
||||
Type.REBLOGGED -> setTitle(R.string.title_reblogged_by)
|
||||
Type.FAVOURITED -> setTitle(R.string.title_favourited_by)
|
||||
Type.REACTED -> setTitle(R.string.title_emoji_reacted_by)
|
||||
}
|
||||
setDisplayHomeAsUpEnabled(true)
|
||||
setDisplayShowHomeEnabled(true)
|
||||
@ -64,7 +67,7 @@ class AccountListActivity : BaseActivity(), HasAndroidInjector {
|
||||
|
||||
supportFragmentManager
|
||||
.beginTransaction()
|
||||
.replace(R.id.fragment_container, AccountListFragment.newInstance(type, id))
|
||||
.replace(R.id.fragment_container, AccountListFragment.newInstance(type, id, emoji))
|
||||
.commit()
|
||||
}
|
||||
|
||||
@ -83,13 +86,20 @@ class AccountListActivity : BaseActivity(), HasAndroidInjector {
|
||||
companion object {
|
||||
private const val EXTRA_TYPE = "type"
|
||||
private const val EXTRA_ID = "id"
|
||||
private const val EXTRA_EMOJI = "emoji"
|
||||
|
||||
@JvmStatic
|
||||
fun newIntent(context: Context, type: Type, id: String? = null): Intent {
|
||||
fun newIntent(context: Context, type: Type, id: String?, emoji: String?): Intent {
|
||||
return Intent(context, AccountListActivity::class.java).apply {
|
||||
putExtra(EXTRA_TYPE, type)
|
||||
putExtra(EXTRA_ID, id)
|
||||
putExtra(EXTRA_EMOJI, emoji)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun newIntent(context: Context, type: Type, id: String? = null): Intent {
|
||||
return newIntent(context, type, id, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,39 @@
|
||||
package com.keylesspalace.tusky.adapter;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.emoji.widget.EmojiAppCompatButton;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.google.android.flexbox.FlexboxLayoutManager;
|
||||
|
||||
import com.keylesspalace.tusky.R;
|
||||
import com.keylesspalace.tusky.entity.Status;
|
||||
import com.keylesspalace.tusky.entity.EmojiReaction;
|
||||
import com.keylesspalace.tusky.interfaces.StatusActionListener;
|
||||
import com.keylesspalace.tusky.util.CardViewMode;
|
||||
import com.keylesspalace.tusky.util.LinkHelper;
|
||||
import com.keylesspalace.tusky.util.StatusDisplayOptions;
|
||||
import com.keylesspalace.tusky.viewdata.StatusViewData;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.util.List;
|
||||
import java.util.Date;
|
||||
|
||||
public class EmojiReactionViewHolder extends RecyclerView.ViewHolder {
|
||||
public EmojiAppCompatButton emojiReaction;
|
||||
EmojiReactionViewHolder(View view) {
|
||||
super(view);
|
||||
emojiReaction = view.findViewById(R.id.status_emoji_reaction);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,70 @@
|
||||
package com.keylesspalace.tusky.adapter;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.emoji.widget.EmojiAppCompatButton;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.keylesspalace.tusky.R;
|
||||
import com.keylesspalace.tusky.entity.Status;
|
||||
import com.keylesspalace.tusky.entity.EmojiReaction;
|
||||
import com.keylesspalace.tusky.interfaces.StatusActionListener;
|
||||
import com.keylesspalace.tusky.util.CardViewMode;
|
||||
import com.keylesspalace.tusky.util.LinkHelper;
|
||||
import com.keylesspalace.tusky.util.StatusDisplayOptions;
|
||||
import com.keylesspalace.tusky.viewdata.StatusViewData;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.util.List;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
public class EmojiReactionsAdapter extends RecyclerView.Adapter<EmojiReactionViewHolder> {
|
||||
private final List<EmojiReaction> reactions;
|
||||
private final StatusActionListener listener;
|
||||
private final String statusId;
|
||||
|
||||
EmojiReactionsAdapter(final List<EmojiReaction> reactions, final StatusActionListener listener, final String statusId) {
|
||||
this.reactions = reactions;
|
||||
this.listener = listener;
|
||||
this.statusId = statusId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmojiReactionViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_emoji_reaction, parent, false);
|
||||
return new EmojiReactionViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(EmojiReactionViewHolder holder, int position) {
|
||||
EmojiReaction reaction = reactions.get(position);
|
||||
String str = reaction.getName() + " " + reaction.getCount();
|
||||
|
||||
// no custom emoji yet!
|
||||
holder.emojiReaction.setText(str);
|
||||
holder.emojiReaction.setActivated(reaction.getMe());
|
||||
holder.emojiReaction.setOnClickListener(v -> {
|
||||
listener.onEmojiReactMenu(v, reaction, statusId, position);
|
||||
});
|
||||
}
|
||||
|
||||
// total number of rows
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return reactions.size();
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
|
||||
import com.bumptech.glide.load.resource.bitmap.GranularRoundedCorners;
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.flexbox.FlexboxLayoutManager;
|
||||
import com.keylesspalace.tusky.R;
|
||||
import com.keylesspalace.tusky.entity.Attachment;
|
||||
import com.keylesspalace.tusky.entity.Attachment.Focus;
|
||||
@ -35,6 +36,7 @@ import com.keylesspalace.tusky.entity.Attachment.MetaData;
|
||||
import com.keylesspalace.tusky.entity.Card;
|
||||
import com.keylesspalace.tusky.entity.Emoji;
|
||||
import com.keylesspalace.tusky.entity.Status;
|
||||
import com.keylesspalace.tusky.entity.EmojiReaction;
|
||||
import com.keylesspalace.tusky.interfaces.StatusActionListener;
|
||||
import com.keylesspalace.tusky.util.CardViewMode;
|
||||
import com.keylesspalace.tusky.util.CustomEmojiHelper;
|
||||
@ -112,6 +114,8 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
|
||||
private int avatarRadius24dp;
|
||||
|
||||
private final Drawable mediaPreviewUnloaded;
|
||||
|
||||
private RecyclerView emojiReactionsView;
|
||||
|
||||
protected StatusBaseViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
@ -125,7 +129,8 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
|
||||
favouriteButton = itemView.findViewById(R.id.status_favourite);
|
||||
bookmarkButton = itemView.findViewById(R.id.status_bookmark);
|
||||
moreButton = itemView.findViewById(R.id.status_more);
|
||||
|
||||
emojiReactionsView = itemView.findViewById(R.id.status_emoji_reactions);
|
||||
|
||||
float INCREASE_HORIZONTAL_HIT_AREA = 20.0f;
|
||||
|
||||
ViewExtensionsKt.increaseHitArea(replyButton, 0.0f, INCREASE_HORIZONTAL_HIT_AREA);
|
||||
@ -700,6 +705,15 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
private void setEmojiReactions(@Nullable List<EmojiReaction> reactions, final StatusActionListener listener, final String statusId) {
|
||||
if(emojiReactionsView != null && reactions != null && reactions.size() > 0) {
|
||||
emojiReactionsView.setVisibility(View.VISIBLE);
|
||||
FlexboxLayoutManager lm = new FlexboxLayoutManager(emojiReactionsView.getContext());
|
||||
emojiReactionsView.setLayoutManager(lm);
|
||||
emojiReactionsView.setAdapter(new EmojiReactionsAdapter(reactions, listener, statusId));
|
||||
}
|
||||
}
|
||||
|
||||
public void setupWithStatus(StatusViewData.Concrete status, final StatusActionListener listener,
|
||||
StatusDisplayOptions statusDisplayOptions) {
|
||||
@ -752,6 +766,8 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
|
||||
setSpoilerAndContent(status.isExpanded(), status.getContent(), status.getSpoilerText(), status.getMentions(), status.getStatusEmojis(), status.getPoll(), statusDisplayOptions, listener);
|
||||
|
||||
setDescriptionForStatus(status, statusDisplayOptions);
|
||||
|
||||
setEmojiReactions(status.getEmojiReactions(), listener, status.getId());
|
||||
|
||||
// Workaround for RecyclerView 1.0.0 / androidx.core 1.0.0
|
||||
// RecyclerView tries to set AccessibilityDelegateCompat to null
|
||||
|
@ -33,14 +33,12 @@ class StatusDetailedViewHolder extends StatusBaseViewHolder {
|
||||
private TextView reblogs;
|
||||
private TextView favourites;
|
||||
private View infoDivider;
|
||||
private RecyclerView emojiReactionsView;
|
||||
|
||||
StatusDetailedViewHolder(View view) {
|
||||
super(view);
|
||||
reblogs = view.findViewById(R.id.status_reblogs);
|
||||
favourites = view.findViewById(R.id.status_favourites);
|
||||
infoDivider = view.findViewById(R.id.status_info_divider);
|
||||
emojiReactionsView = view.findViewById(R.id.status_emoji_reactions);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -108,60 +106,6 @@ class StatusDetailedViewHolder extends StatusBaseViewHolder {
|
||||
}
|
||||
}
|
||||
|
||||
private class EmojiReactionViewHolder extends RecyclerView.ViewHolder {
|
||||
public EmojiAppCompatButton emojiReaction;
|
||||
EmojiReactionViewHolder(View view) {
|
||||
super(view);
|
||||
emojiReaction = view.findViewById(R.id.status_emoji_reaction);
|
||||
}
|
||||
}
|
||||
|
||||
private class EmojiReactionsAdapter extends RecyclerView.Adapter<EmojiReactionViewHolder> {
|
||||
private List<EmojiReaction> reactions;
|
||||
|
||||
EmojiReactionsAdapter(List<EmojiReaction> reactions) {
|
||||
this.reactions = reactions;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmojiReactionViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_emoji_reaction, parent, false);
|
||||
return new EmojiReactionViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(EmojiReactionViewHolder holder, int position) {
|
||||
EmojiReaction reaction = reactions.get(position);
|
||||
String str = reaction.getName() + " " + reaction.getCount();
|
||||
|
||||
// no custom emoji yet!
|
||||
holder.emojiReaction.setText(str);
|
||||
holder.emojiReaction.setActivated(reaction.getMe());
|
||||
holder.emojiReaction.setOnClickListener(v -> {});
|
||||
}
|
||||
|
||||
// total number of rows
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return reactions.size();
|
||||
}
|
||||
}
|
||||
|
||||
private void setEmojiReactions(@Nullable List<EmojiReaction> reactions) {
|
||||
if(reactions != null) {
|
||||
emojiReactionsView.setVisibility(View.VISIBLE);
|
||||
FlexboxLayoutManager lm = new FlexboxLayoutManager(emojiReactionsView.getContext());
|
||||
// lm.setFlexDirection(FlexDirection.COLUMN);
|
||||
// StaggeredGridLayoutManager.HORIZONTAL);
|
||||
// lm.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);
|
||||
emojiReactionsView.setLayoutManager(lm);
|
||||
emojiReactionsView.setAdapter(new EmojiReactionsAdapter(reactions));
|
||||
//emojiReactionsView.setLayoutManager StaggeredGridLayoutManager
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupWithStatus(final StatusViewData.Concrete status,
|
||||
final StatusActionListener listener,
|
||||
@ -173,7 +117,6 @@ class StatusDetailedViewHolder extends StatusBaseViewHolder {
|
||||
setReblogAndFavCount(status.getReblogsCount(), status.getFavouritesCount(), listener);
|
||||
|
||||
setApplication(status.getApplication());
|
||||
setEmojiReactions(status.getEmojiReactions());
|
||||
View.OnLongClickListener longClickListener = view -> {
|
||||
TextView textView = (TextView) view;
|
||||
ClipboardManager clipboard = (ClipboardManager) view.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
|
@ -31,8 +31,7 @@ import com.keylesspalace.tusky.BaseActivity
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.adapter.*
|
||||
import com.keylesspalace.tusky.di.Injectable
|
||||
import com.keylesspalace.tusky.entity.Account
|
||||
import com.keylesspalace.tusky.entity.Relationship
|
||||
import com.keylesspalace.tusky.entity.*
|
||||
import com.keylesspalace.tusky.interfaces.AccountActionListener
|
||||
import com.keylesspalace.tusky.network.MastodonApi
|
||||
import com.keylesspalace.tusky.util.HttpHeaderLink
|
||||
@ -58,6 +57,7 @@ class AccountListFragment : BaseFragment(), AccountActionListener, Injectable {
|
||||
|
||||
private lateinit var type: Type
|
||||
private var id: String? = null
|
||||
private var emojiReaction: String? = null
|
||||
|
||||
private lateinit var scrollListener: EndlessOnScrollListener
|
||||
private lateinit var adapter: AccountAdapter
|
||||
@ -68,6 +68,7 @@ class AccountListFragment : BaseFragment(), AccountActionListener, Injectable {
|
||||
super.onCreate(savedInstanceState)
|
||||
type = arguments?.getSerializable(ARG_TYPE) as Type
|
||||
id = arguments?.getString(ARG_ID)
|
||||
emojiReaction = arguments?.getString(ARG_EMOJI)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
@ -273,11 +274,22 @@ class AccountListFragment : BaseFragment(), AccountActionListener, Injectable {
|
||||
val statusId = requireId(type, id)
|
||||
api.statusFavouritedBy(statusId, fromId)
|
||||
}
|
||||
Type.REACTED -> {
|
||||
// HACKHACK: make compiler happy
|
||||
val statusId = requireId(type, id)
|
||||
api.statusFavouritedBy(statusId, fromId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun requireId(type: Type, id: String?): String {
|
||||
return requireNotNull(id) { "id must not be null for type "+type.name }
|
||||
|
||||
private fun requireId(type: Type, id: String?, name: String = "id"): String {
|
||||
return requireNotNull(id) { name+" must not be null for type "+type.name }
|
||||
}
|
||||
|
||||
private fun getEmojiReactionFetchCall(): Single<Response<List<EmojiReaction>>> {
|
||||
val statusId = requireId(type, id)
|
||||
val emoji = requireId(type, emojiReaction, "emoji")
|
||||
return api.statusReactedBy(statusId, emoji)
|
||||
}
|
||||
|
||||
private fun fetchAccounts(fromId: String? = null) {
|
||||
@ -289,8 +301,25 @@ class AccountListFragment : BaseFragment(), AccountActionListener, Injectable {
|
||||
if (fromId != null) {
|
||||
recyclerView.post { adapter.setBottomLoading(true) }
|
||||
}
|
||||
|
||||
if(type == Type.REACTED) {
|
||||
getEmojiReactionFetchCall()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.autoDispose(from(this, Lifecycle.Event.ON_DESTROY))
|
||||
.subscribe({ response ->
|
||||
val emojiReaction = response.body()
|
||||
|
||||
getFetchCallByListType(fromId)
|
||||
if (response.isSuccessful && emojiReaction != null && emojiReaction.size > 0 && emojiReaction.get(0).accounts != null) {
|
||||
val linkHeader = response.headers()["Link"]
|
||||
onFetchAccountsSuccess(emojiReaction.get(0).accounts!!, linkHeader)
|
||||
} else {
|
||||
onFetchAccountsFailure(Exception(response.message()))
|
||||
}
|
||||
}, {throwable ->
|
||||
onFetchAccountsFailure(throwable)
|
||||
})
|
||||
} else {
|
||||
getFetchCallByListType(fromId)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.autoDispose(from(this, Lifecycle.Event.ON_DESTROY))
|
||||
.subscribe({ response ->
|
||||
@ -305,7 +334,7 @@ class AccountListFragment : BaseFragment(), AccountActionListener, Injectable {
|
||||
}, {throwable ->
|
||||
onFetchAccountsFailure(throwable)
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun onFetchAccountsSuccess(accounts: List<Account>, linkHeader: String?) {
|
||||
@ -361,12 +390,14 @@ class AccountListFragment : BaseFragment(), AccountActionListener, Injectable {
|
||||
private const val TAG = "AccountList" // logging tag
|
||||
private const val ARG_TYPE = "type"
|
||||
private const val ARG_ID = "id"
|
||||
private const val ARG_EMOJI = "emoji"
|
||||
|
||||
fun newInstance(type: Type, id: String? = null): AccountListFragment {
|
||||
fun newInstance(type: Type, id: String? = null, emoji: String? = null): AccountListFragment {
|
||||
return AccountListFragment().apply {
|
||||
arguments = Bundle(2).apply {
|
||||
arguments = Bundle(3).apply {
|
||||
putSerializable(ARG_TYPE, type)
|
||||
putString(ARG_ID, id)
|
||||
putString(ARG_EMOJI, emoji)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ import androidx.lifecycle.Lifecycle;
|
||||
import com.keylesspalace.tusky.BaseActivity;
|
||||
import com.keylesspalace.tusky.BottomSheetActivity;
|
||||
import com.keylesspalace.tusky.MainActivity;
|
||||
import com.keylesspalace.tusky.AccountListActivity;
|
||||
import com.keylesspalace.tusky.R;
|
||||
import com.keylesspalace.tusky.PostLookupFallbackBehavior;
|
||||
import com.keylesspalace.tusky.ViewMediaActivity;
|
||||
@ -57,6 +58,7 @@ import com.keylesspalace.tusky.entity.Attachment;
|
||||
import com.keylesspalace.tusky.entity.Filter;
|
||||
import com.keylesspalace.tusky.entity.PollOption;
|
||||
import com.keylesspalace.tusky.entity.Status;
|
||||
import com.keylesspalace.tusky.entity.EmojiReaction;
|
||||
import com.keylesspalace.tusky.network.MastodonApi;
|
||||
import com.keylesspalace.tusky.network.TimelineCases;
|
||||
import com.keylesspalace.tusky.viewdata.AttachmentViewData;
|
||||
@ -172,6 +174,33 @@ public abstract class SFragment extends BaseFragment implements Injectable {
|
||||
Intent intent = ComposeActivity.startIntent(getContext(), composeOptions);
|
||||
getActivity().startActivity(intent);
|
||||
}
|
||||
|
||||
protected void emojiReactMenu(@NonNull final String statusId, @NonNull final EmojiReaction reaction, View view, final int position) {
|
||||
PopupMenu popup = new PopupMenu(getContext(), view);
|
||||
|
||||
popup.inflate(R.menu.emoji_reaction_more);
|
||||
Menu menu = popup.getMenu();
|
||||
menu.findItem(R.id.emoji_react).setVisible(!reaction.getMe());
|
||||
menu.findItem(R.id.emoji_unreact).setVisible(reaction.getMe());
|
||||
|
||||
popup.setOnMenuItemClickListener(item -> {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.emoji_react:
|
||||
// TODO
|
||||
return true;
|
||||
case R.id.emoji_unreact:
|
||||
// TODO
|
||||
return true;
|
||||
case R.id.emoji_reacted_by:
|
||||
Intent intent = AccountListActivity.newIntent(getContext(), AccountListActivity.Type.REACTED, statusId, reaction.getName());
|
||||
((BaseActivity) getActivity()).startActivityWithSlideInAnimation(intent);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
popup.show();
|
||||
}
|
||||
|
||||
protected void more(@NonNull final Status status, View view, final int position) {
|
||||
final String id = status.getActionableId();
|
||||
|
@ -52,10 +52,7 @@ import com.keylesspalace.tusky.appstore.ReblogEvent;
|
||||
import com.keylesspalace.tusky.appstore.StatusComposedEvent;
|
||||
import com.keylesspalace.tusky.appstore.StatusDeletedEvent;
|
||||
import com.keylesspalace.tusky.di.Injectable;
|
||||
import com.keylesspalace.tusky.entity.Filter;
|
||||
import com.keylesspalace.tusky.entity.Poll;
|
||||
import com.keylesspalace.tusky.entity.Status;
|
||||
import com.keylesspalace.tusky.entity.StatusContext;
|
||||
import com.keylesspalace.tusky.entity.*;
|
||||
import com.keylesspalace.tusky.interfaces.StatusActionListener;
|
||||
import com.keylesspalace.tusky.network.MastodonApi;
|
||||
import com.keylesspalace.tusky.util.CardViewMode;
|
||||
@ -747,4 +744,9 @@ public final class ViewThreadFragment extends SFragment implements
|
||||
protected void refreshAfterApplyingFilters() {
|
||||
onRefresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEmojiReactMenu(@NonNull View view, final EmojiReaction emoji, final String statusId, final int position) {
|
||||
super.emojiReactMenu(statusId, emoji, view, position);
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package com.keylesspalace.tusky.interfaces;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.List;
|
||||
import com.keylesspalace.tusky.entity.EmojiReaction;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@ -64,6 +65,7 @@ public interface StatusActionListener extends LinkListener {
|
||||
void onVoteInPoll(int position, @NonNull List<Integer> choices);
|
||||
|
||||
default void onMute(int position, boolean isMuted) {}
|
||||
default void onEmojiReact(final boolean react, final String emoji, final int position) {};
|
||||
// default void onEmojiReact(final boolean react, final String emoji, final int position) {};
|
||||
default void onEmojiReactMenu(@NonNull View view, final EmojiReaction emoji, final String statusId, final int position) {};
|
||||
|
||||
}
|
||||
|
@ -588,19 +588,20 @@ interface MastodonApi {
|
||||
fun getNodeinfo(@Url url: String) : Single<NodeInfo>
|
||||
|
||||
@PUT("api/v1/pleroma/statuses/{id}/reactions/{emoji}")
|
||||
fun reactWithEmoji(
|
||||
@Path("id") statusId: String,
|
||||
@Path("emoji") emoji: String
|
||||
): Single<Status>
|
||||
|
||||
@DELETE("api/v1/pleroma/statuses/{id}/reactions/{emoji}")
|
||||
fun unreactWithEmoji(
|
||||
@Path("id") statusId: String,
|
||||
@Path("emoji") emoji: String
|
||||
): Single<Status>
|
||||
|
||||
@GET("api/v1/pleroma/statuses/{id}/reactions")
|
||||
fun statusReactedBy(
|
||||
@Path("id") statusId: String
|
||||
): Single<List<EmojiReaction>>
|
||||
fun reactWithEmoji(
|
||||
@Path("id") statusId: String,
|
||||
@Path("emoji") emoji: String
|
||||
): Single<Status>
|
||||
|
||||
@DELETE("api/v1/pleroma/statuses/{id}/reactions/{emoji}")
|
||||
fun unreactWithEmoji(
|
||||
@Path("id") statusId: String,
|
||||
@Path("emoji") emoji: String
|
||||
): Single<Status>
|
||||
|
||||
@GET("api/v1/pleroma/statuses/{id}/reactions/{emoji}")
|
||||
fun statusReactedBy(
|
||||
@Path("id") statusId: String,
|
||||
@Path("emoji") emoji: String
|
||||
): Single<Response<List<EmojiReaction>>>
|
||||
}
|
||||
|
13
app/src/main/res/menu/emoji_reaction_more.xml
Normal file
13
app/src/main/res/menu/emoji_reaction_more.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/emoji_react"
|
||||
android:title="@string/action_emoji_react" />
|
||||
<item
|
||||
android:id="@+id/emoji_unreact"
|
||||
android:title="@string/action_emoji_unreact" />
|
||||
<item
|
||||
android:id="@+id/emoji_reacted_by"
|
||||
android:title="@string/action_emoji_reacted_by" />
|
||||
</menu>
|
||||
|
@ -2,8 +2,13 @@
|
||||
|
||||
<string name="action_reply_to">Reply to</string>
|
||||
<string name="action_markdown">Markdown</string>
|
||||
<string name="action_mute_conversation">Mute conversation</string>
|
||||
<string name="action_unmute_conversation">Unmute conversation</string>
|
||||
<string name="action_mute_conversation">Mute conversation</string>
|
||||
<string name="action_unmute_conversation">Unmute conversation</string>
|
||||
<string name="action_emoji_react">Add reaction</string>
|
||||
<string name="action_emoji_unreact">Remove reaction</string>
|
||||
<string name="action_emoji_reacted_by">Who reacted</string>
|
||||
|
||||
<string name="title_emoji_reacted_by">Emoji reacted by</string>
|
||||
|
||||
<string name="hint_appname">Application name</string>
|
||||
<string name="hint_website">Application website</string>
|
||||
@ -13,7 +18,7 @@
|
||||
|
||||
<string name="error_media_upload_size">File size exceeds instance limits</string>
|
||||
|
||||
<string name="notification_emoji_format">%s reacted to your post with %s</string>
|
||||
<string name="notification_emoji_format">%s reacted with %s to your post</string>
|
||||
<string name="notification_emoji_name">Emoji Reactions</string>
|
||||
<string name="notification_emoji_description">Notifications about new emoji reactions</string>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user