emoji_reactions: implement adding and removing on existing reactions(LOW PERFORMANCE)
This commit is contained in:
parent
6a4215363e
commit
c2ded20df8
@ -57,7 +57,7 @@ public class EmojiReactionsAdapter extends RecyclerView.Adapter<EmojiReactionVie
|
||||
holder.emojiReaction.setText(str);
|
||||
holder.emojiReaction.setActivated(reaction.getMe());
|
||||
holder.emojiReaction.setOnClickListener(v -> {
|
||||
listener.onEmojiReactMenu(v, reaction, statusId, position);
|
||||
listener.onEmojiReactMenu(v, reaction, statusId);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ data class FavoriteEvent(val statusId: String, val favourite: Boolean) : Dispatc
|
||||
data class ReblogEvent(val statusId: String, val reblog: Boolean) : Dispatchable
|
||||
data class BookmarkEvent(val statusId: String, val bookmark: Boolean) : Dispatchable
|
||||
data class MuteStatusEvent(val statusId: String, val mute: Boolean) : Dispatchable
|
||||
data class EmojiReactEvent(val statusId: String, val reacted: Boolean, val emoji: String) : Dispatchable
|
||||
data class EmojiReactEvent(val newStatus: Status) : Dispatchable
|
||||
data class UnfollowEvent(val accountId: String) : Dispatchable
|
||||
data class BlockEvent(val accountId: String) : Dispatchable
|
||||
data class MuteEvent(val accountId: String) : Dispatchable
|
||||
|
@ -145,8 +145,8 @@ data class Status(
|
||||
|
||||
fun getEmojiReactions(): List<EmojiReaction>? {
|
||||
return pleroma?.emojiReactions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun getEditableText(): String {
|
||||
val builder = SpannableStringBuilder(content)
|
||||
for (span in content.getSpans(0, content.length, URLSpan::class.java)) {
|
||||
|
@ -62,6 +62,7 @@ import com.keylesspalace.tusky.entity.EmojiReaction;
|
||||
import com.keylesspalace.tusky.network.MastodonApi;
|
||||
import com.keylesspalace.tusky.network.TimelineCases;
|
||||
import com.keylesspalace.tusky.viewdata.AttachmentViewData;
|
||||
import com.keylesspalace.tusky.interfaces.StatusActionListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
@ -175,7 +176,7 @@ public abstract class SFragment extends BaseFragment implements Injectable {
|
||||
getActivity().startActivity(intent);
|
||||
}
|
||||
|
||||
protected void emojiReactMenu(@NonNull final String statusId, @NonNull final EmojiReaction reaction, View view, final int position) {
|
||||
protected void emojiReactMenu(@NonNull final String statusId, @NonNull final EmojiReaction reaction, View view, final StatusActionListener listener) {
|
||||
PopupMenu popup = new PopupMenu(getContext(), view);
|
||||
|
||||
popup.inflate(R.menu.emoji_reaction_more);
|
||||
@ -186,10 +187,10 @@ public abstract class SFragment extends BaseFragment implements Injectable {
|
||||
popup.setOnMenuItemClickListener(item -> {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.emoji_react:
|
||||
// TODO
|
||||
listener.onEmojiReact(true, reaction.getName(), statusId);
|
||||
return true;
|
||||
case R.id.emoji_unreact:
|
||||
// TODO
|
||||
listener.onEmojiReact(false, reaction.getName(), statusId);
|
||||
return true;
|
||||
case R.id.emoji_reacted_by:
|
||||
Intent intent = AccountListActivity.newIntent(getContext(), AccountListActivity.Type.REACTED, statusId, reaction.getName());
|
||||
|
@ -531,6 +531,8 @@ public class TimelineFragment extends SFragment implements
|
||||
handleStatusComposeEvent(status);
|
||||
} else if (event instanceof PreferenceChangedEvent) {
|
||||
onPreferenceChanged(((PreferenceChangedEvent) event).getPreferenceKey());
|
||||
} else if (event instanceof EmojiReactEvent) {
|
||||
handleEmojiReactEvent((EmojiReactEvent)event);
|
||||
}
|
||||
});
|
||||
eventRegistered = true;
|
||||
@ -1497,9 +1499,47 @@ public class TimelineFragment extends SFragment implements
|
||||
isNeedRefresh = true;
|
||||
}
|
||||
|
||||
private void setEmojiReactionForStatus(int position, Status newStatus) {
|
||||
StatusViewData newViewData = ViewDataUtils.statusToViewData(newStatus, false, false);
|
||||
statuses.setPairedItem(position, newViewData);
|
||||
updateAdapter();
|
||||
}
|
||||
|
||||
private void setEmojiReactForStatus(int position, Status status, Status newStatus) {
|
||||
Pair<StatusViewData.Concrete, Integer> actual =
|
||||
findStatusAndPosition(position, status);
|
||||
if (actual == null) return;
|
||||
|
||||
setEmojiReactionForStatus(actual.second, newStatus);
|
||||
}
|
||||
|
||||
public void handleEmojiReactEvent(EmojiReactEvent event) {
|
||||
int pos = findStatusOrReblogPositionById(event.getNewStatus().getActionableId());
|
||||
if (pos < 0) return;
|
||||
Status status = statuses.get(pos).asRight();
|
||||
setEmojiReactForStatus(pos, status, event.getNewStatus());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEmojiReactMenu(@NonNull View view, final EmojiReaction emoji, final String statusId, final int position) {
|
||||
super.emojiReactMenu(statusId, emoji, view, position);
|
||||
public void onEmojiReact(final boolean react, final String emoji, final String statusId) {
|
||||
int position = findStatusOrReblogPositionById(statusId);
|
||||
if (position < 0) return;
|
||||
|
||||
timelineCases.react(emoji, statusId, react)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.as(autoDisposable(from(this)))
|
||||
.subscribe(
|
||||
(newStatus) -> setEmojiReactionForStatus(position, newStatus),
|
||||
(t) -> Log.d(TAG,
|
||||
"Failed to react with " + emoji + " on status: " + statusId, t)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onEmojiReactMenu(@NonNull View view, final EmojiReaction emoji, final String statusId) {
|
||||
super.emojiReactMenu(statusId, emoji, view, this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -44,13 +44,7 @@ import com.keylesspalace.tusky.BuildConfig;
|
||||
import com.keylesspalace.tusky.R;
|
||||
import com.keylesspalace.tusky.ViewThreadActivity;
|
||||
import com.keylesspalace.tusky.adapter.ThreadAdapter;
|
||||
import com.keylesspalace.tusky.appstore.BlockEvent;
|
||||
import com.keylesspalace.tusky.appstore.BookmarkEvent;
|
||||
import com.keylesspalace.tusky.appstore.EventHub;
|
||||
import com.keylesspalace.tusky.appstore.FavoriteEvent;
|
||||
import com.keylesspalace.tusky.appstore.ReblogEvent;
|
||||
import com.keylesspalace.tusky.appstore.StatusComposedEvent;
|
||||
import com.keylesspalace.tusky.appstore.StatusDeletedEvent;
|
||||
import com.keylesspalace.tusky.appstore.*;
|
||||
import com.keylesspalace.tusky.di.Injectable;
|
||||
import com.keylesspalace.tusky.entity.*;
|
||||
import com.keylesspalace.tusky.interfaces.StatusActionListener;
|
||||
@ -196,6 +190,8 @@ public final class ViewThreadFragment extends SFragment implements
|
||||
handleStatusComposedEvent((StatusComposedEvent) event);
|
||||
} else if (event instanceof StatusDeletedEvent) {
|
||||
handleStatusDeletedEvent((StatusDeletedEvent) event);
|
||||
} else if (event instanceof EmojiReactEvent) {
|
||||
handleEmojiReactEvent((EmojiReactEvent)event);
|
||||
}
|
||||
});
|
||||
|
||||
@ -745,8 +741,40 @@ public final class ViewThreadFragment extends SFragment implements
|
||||
onRefresh();
|
||||
}
|
||||
|
||||
private void setEmojiReactionForStatus(int position, Status status) {
|
||||
StatusViewData.Concrete newViewData = ViewDataUtils.statusToViewData(status, false, false);
|
||||
|
||||
statuses.setPairedItem(position, newViewData);
|
||||
adapter.setItem(position, newViewData, true);
|
||||
}
|
||||
|
||||
public void handleEmojiReactEvent(EmojiReactEvent event) {
|
||||
Pair<Integer, Status> posAndStatus = findStatusAndPos(event.getNewStatus().getActionableId());
|
||||
if (posAndStatus == null) return;
|
||||
setEmojiReactionForStatus(posAndStatus.first, event.getNewStatus());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEmojiReactMenu(@NonNull View view, final EmojiReaction emoji, final String statusId, final int position) {
|
||||
super.emojiReactMenu(statusId, emoji, view, position);
|
||||
public void onEmojiReact(final boolean react, final String emoji, final String statusId) {
|
||||
Pair<Integer, Status> statusAndPos = findStatusAndPos(statusId);
|
||||
|
||||
if(statusAndPos == null)
|
||||
return;
|
||||
int position = statusAndPos.first;
|
||||
|
||||
timelineCases.react(emoji, statusId, react)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.as(autoDisposable(from(this)))
|
||||
.subscribe(
|
||||
(newStatus) -> setEmojiReactionForStatus(position, newStatus),
|
||||
(t) -> Log.d(TAG,
|
||||
"Failed to react with " + emoji + " on status: " + statusId, t)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEmojiReactMenu(@NonNull View view, final EmojiReaction emoji, final String statusId) {
|
||||
super.emojiReactMenu(statusId, emoji, view, this);
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +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 onEmojiReactMenu(@NonNull View view, final EmojiReaction emoji, final String statusId, final int position) {};
|
||||
default void onEmojiReact(final boolean react, final String emoji, final String statusId) {};
|
||||
default void onEmojiReactMenu(@NonNull View view, final EmojiReaction emoji, final String statusId) {};
|
||||
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ interface TimelineCases {
|
||||
fun delete(id: String): Single<DeletedStatus>
|
||||
fun pin(status: Status, pin: Boolean)
|
||||
fun voteInPoll(status: Status, choices: List<Int>): Single<Poll>
|
||||
|
||||
fun react(emoji: String, id: String, react: Boolean) : Single<Status>
|
||||
}
|
||||
|
||||
class TimelineCasesImpl(
|
||||
@ -157,4 +157,14 @@ class TimelineCasesImpl(
|
||||
}
|
||||
}
|
||||
|
||||
override fun react(emoji: String, id: String, react: Boolean): Single<Status> {
|
||||
val call = if (react) {
|
||||
mastodonApi.reactWithEmoji(id, emoji)
|
||||
} else {
|
||||
mastodonApi.unreactWithEmoji(id, emoji)
|
||||
}
|
||||
return call.doAfterSuccess { status ->
|
||||
eventHub.dispatch(EmojiReactEvent(status))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user