Skip to content

Commit

Permalink
Added "Tap to remove" emoji in ReactionsBottomSheet
Browse files Browse the repository at this point in the history
  • Loading branch information
Sagar0-0 committed Jan 13, 2025
1 parent f6a1aca commit fa22aa6
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@

final class ReactionRecipientsAdapter extends RecyclerView.Adapter<ReactionRecipientsAdapter.ViewHolder> {

private List<ReactionDetails> data = Collections.emptyList();
private ReactionViewPagerAdapter.EventListener listener = null;
private List<ReactionDetails> data = Collections.emptyList();

void addListener(ReactionViewPagerAdapter.EventListener listener) {
this.listener = listener;
}

public void updateData(List<ReactionDetails> newData) {
data = newData;
Expand All @@ -37,7 +42,7 @@ public void updateData(List<ReactionDetails> newData) {

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.bind(data.get(position));
holder.bind(data.get(position), listener);
}

@Override
Expand All @@ -51,28 +56,34 @@ static final class ViewHolder extends RecyclerView.ViewHolder {
private final BadgeImageView badge;
private final TextView recipient;
private final TextView emoji;
private final TextView tapToRemoveText;

public ViewHolder(@NonNull View itemView) {
super(itemView);

avatar = itemView.findViewById(R.id.reactions_bottom_view_recipient_avatar);
badge = itemView.findViewById(R.id.reactions_bottom_view_recipient_badge);
recipient = itemView.findViewById(R.id.reactions_bottom_view_recipient_name);
emoji = itemView.findViewById(R.id.reactions_bottom_view_recipient_emoji);
avatar = itemView.findViewById(R.id.reactions_bottom_view_recipient_avatar);
badge = itemView.findViewById(R.id.reactions_bottom_view_recipient_badge);
recipient = itemView.findViewById(R.id.reactions_bottom_view_recipient_name);
emoji = itemView.findViewById(R.id.reactions_bottom_view_recipient_emoji);
tapToRemoveText = itemView.findViewById(R.id.reactions_bottom_view_recipient_tap_to_remove_action_text);
}

void bind(@NonNull ReactionDetails reaction) {
void bind(@NonNull ReactionDetails reaction, ReactionViewPagerAdapter.EventListener listener) {
this.emoji.setText(reaction.getDisplayEmoji());

if (reaction.getSender().isSelf()) {
this.recipient.setText(R.string.ReactionsRecipientAdapter_you);
this.avatar.setAvatar(Glide.with(avatar), null, false);
this.badge.setBadge(null);
AvatarUtil.loadIconIntoImageView(reaction.getSender(), avatar);
itemView.setOnClickListener((view) -> listener.onClick());
tapToRemoveText.setVisibility(View.VISIBLE);
} else {
this.recipient.setText(reaction.getSender().getDisplayName(itemView.getContext()));
this.avatar.setAvatar(Glide.with(avatar), reaction.getSender(), false);
this.badge.setBadgeFromRecipient(reaction.getSender());
itemView.setOnClickListener(null);
tapToRemoveText.setVisibility(View.GONE);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@
*/
class ReactionViewPagerAdapter extends ListAdapter<EmojiCount, ReactionViewPagerAdapter.ViewHolder> {

private int selectedPosition = 0;
private int selectedPosition = 0;
private EventListener listener = null;

protected ReactionViewPagerAdapter() {
super(new AlwaysChangedDiffUtil<>());
}

void addListener(EventListener listener) {
this.listener = listener;
}

@NonNull EmojiCount getEmojiCount(int position) {
return getItem(position);
}
Expand All @@ -50,7 +55,7 @@ public void onBindViewHolder(@NonNull ViewHolder holder, int position, @NonNull

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.onBind(getItem(position));
holder.onBind(getItem(position),listener);
holder.setSelected(selectedPosition);
}

Expand Down Expand Up @@ -80,12 +85,17 @@ public ViewHolder(@NonNull View itemView) {
recycler.setAdapter(adapter);
}

public void onBind(@NonNull EmojiCount emojiCount) {
public void onBind(@NonNull EmojiCount emojiCount, EventListener listener) {
adapter.updateData(emojiCount.getReactions());
adapter.addListener(listener);
}

public void setSelected(int position) {
recycler.setNestedScrollingEnabled(getAdapterPosition() == position);
}
}

interface EventListener {
void onClick();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,17 @@

import java.util.Objects;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;

public final class ReactionsBottomSheetDialogFragment extends BottomSheetDialogFragment {

private static final String ARGS_MESSAGE_ID = "reactions.args.message.id";
private static final String ARGS_IS_MMS = "reactions.args.is.mms";

private ViewPager2 recipientPagerView;
private ReactionViewPagerAdapter recipientsAdapter;
private ReactionsViewModel viewModel;
private Callback callback;
private ViewPager2 recipientPagerView;
private ReactionViewPagerAdapter recipientsAdapter;
private ReactionsViewModel viewModel;
private Callback callback;

private final LifecycleDisposable disposables = new LifecycleDisposable();

Expand Down Expand Up @@ -173,6 +175,16 @@ private void setUpViewModel(@NonNull MessageId messageId) {

recipientsAdapter.submitList(emojiCounts);
}));

recipientsAdapter.addListener(
() -> disposables.add(
viewModel.removeReactionEmoji(getContext())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
it -> recipientsAdapter.notifyItemRemoved(0)
)
)
);
}

public interface Callback {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.thoughtcrime.securesms.reactions

import android.content.Context
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.ObservableEmitter
import io.reactivex.rxjava3.schedulers.Schedulers
Expand All @@ -10,6 +12,8 @@ import org.thoughtcrime.securesms.database.model.MessageId
import org.thoughtcrime.securesms.database.model.ReactionRecord
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.sms.MessageSender
import java.util.NoSuchElementException

class ReactionsRepository {

Expand Down Expand Up @@ -45,4 +49,19 @@ class ReactionsRepository {
)
}
}

fun sendReactionRemoval(context: Context, messageId: MessageId): Completable {
val oldReactionRecord = oldReactionRecord(messageId) ?: return Completable.error(NoSuchElementException("Removing invalid emoji!"))
return Completable.fromAction {
MessageSender.sendReactionRemoval(
context.applicationContext,
MessageId(messageId.id),
oldReactionRecord
)
}.subscribeOn(Schedulers.io())
}

private fun oldReactionRecord(messageId: MessageId): ReactionRecord? {
return SignalDatabase.reactions.getReactions(messageId).firstOrNull { it.author == Recipient.self().id }
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.thoughtcrime.securesms.reactions;

import android.content.Context;

import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
Expand All @@ -13,6 +15,7 @@
import java.util.Map;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Maybe;
import io.reactivex.rxjava3.core.Observable;

public class ReactionsViewModel extends ViewModel {
Expand Down Expand Up @@ -70,6 +73,10 @@ private long getLatestTimestamp(List<ReactionDetails> reactions) {
return reactions.get(reactions.size() - 1).getDisplayEmoji();
}

Maybe<Void> removeReactionEmoji(Context context) {
return repository.sendReactionRemoval(context, messageId).toMaybe();
}

static final class Factory implements ViewModelProvider.Factory {

private final MessageId messageId;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:viewBindingIgnore="true"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="52dp">
android:layout_height="52dp"
tools:viewBindingIgnore="true">

<org.thoughtcrime.securesms.components.AvatarImageView
android:id="@+id/reactions_bottom_view_recipient_avatar"
Expand All @@ -25,23 +25,44 @@
app:layout_constraintStart_toStartOf="@id/reactions_bottom_view_recipient_avatar"
app:layout_constraintTop_toTopOf="@id/reactions_bottom_view_recipient_avatar" />

<org.thoughtcrime.securesms.components.FromTextView
android:id="@+id/reactions_bottom_view_recipient_name"
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="2"
android:textAppearance="@style/TextAppearance.Signal.Body1.Bold"
android:textColor="@color/signal_text_primary"
android:orientation="vertical"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/reactions_bottom_view_recipient_emoji"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@id/reactions_bottom_view_recipient_avatar"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/full_names" />
app:layout_constraintTop_toTopOf="parent">

<org.thoughtcrime.securesms.components.FromTextView
android:id="@+id/reactions_bottom_view_recipient_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="2"
android:textAppearance="@style/TextAppearance.Signal.Body1.Bold"
android:textColor="@color/signal_text_primary"
tools:text="@tools:sample/full_names" />

<org.thoughtcrime.securesms.components.FromTextView
android:id="@+id/reactions_bottom_view_recipient_tap_to_remove_action_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:ellipsize="end"
android:maxLines="1"
android:text="@string/ReactionsBottomSheetDialogFragment_tap_to_remove"
android:textAppearance="@style/TextAppearance.Signal.Caption"
android:textColor="@color/signal_text_secondary"
android:visibility="gone"
tools:text="Tap to remove"
tools:visibility="visible" />
</LinearLayout>


<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/reactions_bottom_view_recipient_emoji"
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2133,6 +2133,7 @@

<!-- ReactionsBottomSheetDialogFragment -->
<string name="ReactionsBottomSheetDialogFragment_all">All &#183; %1$d</string>
<string name="ReactionsBottomSheetDialogFragment_tap_to_remove">Tap to remove</string>

<!-- ReactionsConversationView -->
<string name="ReactionsConversationView_plus">+%1$d</string>
Expand Down

0 comments on commit fa22aa6

Please sign in to comment.