1package eu.siacs.conversations.ui;
2
3import android.view.View;
4import android.view.ViewGroup;
5import android.util.TypedValue;
6
7import com.cheogram.android.EmojiSearch;
8
9import com.google.android.material.chip.Chip;
10import com.google.android.material.chip.ChipGroup;
11import com.google.android.material.color.MaterialColors;
12import com.google.android.material.dialog.MaterialAlertDialogBuilder;
13import com.google.common.collect.Collections2;
14import com.google.common.collect.ImmutableSet;
15
16import eu.siacs.conversations.R;
17import eu.siacs.conversations.entities.Conversation;
18import eu.siacs.conversations.entities.Reaction;
19import eu.siacs.conversations.utils.UIHelper;
20
21import java.util.Collection;
22import java.util.List;
23import java.util.Map;
24import java.util.function.Consumer;
25import java.util.stream.Collectors;
26
27public class BindingAdapters {
28
29 public static void setReactionsOnReceived(
30 final ChipGroup chipGroup,
31 final Conversation conversation,
32 final Reaction.Aggregated reactions,
33 final Consumer<Collection<String>> onModifiedReactions,
34 final Consumer<EmojiSearch.CustomEmoji> onCustomReaction,
35 final Runnable addReaction) {
36 setReactions(chipGroup, conversation, reactions, true, onModifiedReactions, onCustomReaction, addReaction);
37 }
38
39 public static void setReactionsOnSent(
40 final ChipGroup chipGroup,
41 final Reaction.Aggregated reactions,
42 final Consumer<Collection<String>> onModifiedReactions) {
43 setReactions(chipGroup, null, reactions, false, onModifiedReactions, null, null);
44 }
45
46 private static void setReactions(
47 final ChipGroup chipGroup,
48 final Conversation conversation,
49 final Reaction.Aggregated aggregated,
50 final boolean onReceived,
51 final Consumer<Collection<String>> onModifiedReactions,
52 final Consumer<EmojiSearch.CustomEmoji> onCustomReaction,
53 final Runnable addReaction) {
54 final var context = chipGroup.getContext();
55 final var size = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 35, context.getResources().getDisplayMetrics());
56 final var corner = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 35, context.getResources().getDisplayMetrics());
57 final var layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, size);
58 final List<Map.Entry<EmojiSearch.Emoji, Collection<Reaction>>> reactions = aggregated.reactions;
59 if (reactions == null || reactions.isEmpty()) {
60 chipGroup.setVisibility(View.GONE);
61 } else {
62 chipGroup.removeAllViews();
63 chipGroup.setVisibility(View.VISIBLE);
64 for (final var reaction : reactions) {
65 final var emoji = reaction.getKey();
66 final var count = reaction.getValue().size();
67 final Chip chip = new Chip(chipGroup.getContext());
68 //chip.setEnsureMinTouchTargetSize(false);
69 chip.setChipMinHeight(size-32.0f);
70 chip.ensureAccessibleTouchTarget(size);
71 chip.setLayoutParams(layoutParams);
72 chip.setChipCornerRadius(corner);
73 emoji.setupChip(chip, count);
74 final boolean oneOfOurs = aggregated.ourReactions.contains(emoji.toString());
75 // received = surface; sent = surface high matches bubbles
76 if (oneOfOurs) {
77 chip.setChipBackgroundColor(
78 MaterialColors.getColorStateListOrNull(
79 context,
80 com.google.android.material.R.attr
81 .colorSurfaceContainerHighest));
82 } else {
83 chip.setChipBackgroundColor(
84 MaterialColors.getColorStateListOrNull(
85 context,
86 com.google.android.material.R.attr.colorSurfaceContainerLow));
87 }
88 chip.setTextEndPadding(0.0f);
89 chip.setTextStartPadding(0.0f);
90 chip.setOnClickListener(
91 v -> {
92 if (oneOfOurs) {
93 onModifiedReactions.accept(
94 ImmutableSet.copyOf(
95 Collections2.filter(
96 aggregated.ourReactions,
97 r -> !r.equals(emoji.toString()))));
98 } else {
99 if (emoji instanceof EmojiSearch.CustomEmoji) {
100 onCustomReaction.accept((EmojiSearch.CustomEmoji) emoji);
101 } else {
102 onModifiedReactions.accept(
103 new ImmutableSet.Builder<String>()
104 .addAll(aggregated.ourReactions)
105 .add(emoji.toString())
106 .build());
107 }
108 }
109 });
110 chip.setOnLongClickListener(v -> {
111 final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context);
112 builder.setTitle(emoji.toString());
113 builder.setMessage(reaction.getValue().stream().map(r -> UIHelper.getDisplayName(conversation, r)).collect(Collectors.joining("\n")));
114 builder.setPositiveButton(context.getResources().getString(R.string.ok), null);
115 builder.create().show();
116 return true;
117 });
118 chipGroup.addView(chip);
119 }
120 if (addReaction != null) {
121 final Chip chip = new Chip(chipGroup.getContext());
122 chip.setChipMinHeight(size-32.0f);
123 chip.ensureAccessibleTouchTarget(size);
124 chip.setLayoutParams(layoutParams);
125 chip.setChipCornerRadius(corner);
126 chip.setChipIconResource(R.drawable.ic_add_reaction_24dp);
127 //chip.setChipStrokeColor(
128 // MaterialColors.getColorStateListOrNull(
129 // chipGroup.getContext(),
130 // com.google.android.material.R.attr.colorTertiary));
131 chip.setChipBackgroundColor(
132 MaterialColors.getColorStateListOrNull(
133 context,
134 com.google.android.material.R.attr.colorSurfaceContainerLow));
135 chip.setChipIconTint(
136 MaterialColors.getColorStateListOrNull(
137 context,
138 com.google.android.material.R.attr.colorOnSurface));
139 //chip.setEnsureMinTouchTargetSize(false);
140 chip.setTextEndPadding(0.0f);
141 chip.setTextStartPadding(0.0f);
142 chip.setOnClickListener(v -> addReaction.run());
143 chipGroup.addView(chip);
144 }
145 }
146 }
147}