1package eu.siacs.conversations.ui;
2
3import android.view.View;
4
5import com.google.android.material.chip.Chip;
6import com.google.android.material.chip.ChipGroup;
7import com.google.android.material.color.MaterialColors;
8import com.google.common.collect.Collections2;
9import com.google.common.collect.ImmutableSet;
10
11import eu.siacs.conversations.R;
12import eu.siacs.conversations.entities.Reaction;
13
14import java.util.Collection;
15import java.util.List;
16import java.util.Locale;
17import java.util.Map;
18import java.util.function.Consumer;
19import java.util.function.Function;
20
21public class BindingAdapters {
22
23 public static void setReactionsOnReceived(
24 final ChipGroup chipGroup,
25 final Reaction.Aggregated reactions,
26 final Consumer<Collection<String>> onModifiedReactions,
27 final Function<String, Boolean> onDetailsClicked,
28 final Runnable addReaction) {
29 setReactions(
30 chipGroup, reactions, true, onModifiedReactions, onDetailsClicked, addReaction);
31 }
32
33 public static void setReactionsOnSent(
34 final ChipGroup chipGroup,
35 final Reaction.Aggregated reactions,
36 final Consumer<Collection<String>> onModifiedReactions,
37 final Function<String, Boolean> onDetailsClicked) {
38 setReactions(chipGroup, reactions, false, onModifiedReactions, onDetailsClicked, null);
39 }
40
41 private static void setReactions(
42 final ChipGroup chipGroup,
43 final Reaction.Aggregated aggregated,
44 final boolean onReceived,
45 final Consumer<Collection<String>> onModifiedReactions,
46 final Function<String, Boolean> onDetailsClicked,
47 final Runnable addReaction) {
48 final var context = chipGroup.getContext();
49 final List<Map.Entry<String, Integer>> reactions = aggregated.reactions;
50 if (reactions == null || reactions.isEmpty()) {
51 chipGroup.setVisibility(View.GONE);
52 } else {
53 chipGroup.removeAllViews();
54 chipGroup.setVisibility(View.VISIBLE);
55 for (final Map.Entry<String, Integer> reaction : reactions) {
56 final var emoji = reaction.getKey();
57 final var count = reaction.getValue();
58 final Chip chip = new Chip(chipGroup.getContext());
59 chip.setEnsureMinTouchTargetSize(false);
60 chip.setChipStartPadding(0.0f);
61 chip.setChipEndPadding(0.0f);
62 if (count == 1) {
63 chip.setText(emoji);
64 } else {
65 chip.setText(String.format(Locale.ENGLISH, "%s %d", emoji, count));
66 }
67 final boolean oneOfOurs = aggregated.ourReactions.contains(emoji);
68 // received = surface; sent = surface high matches bubbles
69 if (oneOfOurs) {
70 chip.setChipBackgroundColor(
71 MaterialColors.getColorStateListOrNull(
72 context,
73 com.google.android.material.R.attr
74 .colorSurfaceContainerHighest));
75 } else {
76 chip.setChipBackgroundColor(
77 MaterialColors.getColorStateListOrNull(
78 context,
79 com.google.android.material.R.attr.colorSurfaceContainerLow));
80 }
81 chip.setOnClickListener(
82 v -> {
83 if (oneOfOurs) {
84 onModifiedReactions.accept(
85 ImmutableSet.copyOf(
86 Collections2.filter(
87 aggregated.ourReactions,
88 r -> !r.equals(emoji))));
89 } else {
90 onModifiedReactions.accept(
91 new ImmutableSet.Builder<String>()
92 .addAll(aggregated.ourReactions)
93 .add(emoji)
94 .build());
95 }
96 });
97 chip.setOnLongClickListener(v -> onDetailsClicked.apply(emoji));
98 chipGroup.addView(chip);
99 }
100 if (onReceived) {
101 final Chip chip = new Chip(chipGroup.getContext());
102 chip.setChipIconResource(R.drawable.ic_add_reaction_24dp);
103 chip.setChipStrokeColor(
104 MaterialColors.getColorStateListOrNull(
105 chipGroup.getContext(),
106 com.google.android.material.R.attr.colorTertiary));
107 chip.setChipBackgroundColor(
108 MaterialColors.getColorStateListOrNull(
109 chipGroup.getContext(),
110 com.google.android.material.R.attr.colorTertiaryContainer));
111 chip.setChipIconTint(
112 MaterialColors.getColorStateListOrNull(
113 chipGroup.getContext(),
114 com.google.android.material.R.attr.colorOnTertiaryContainer));
115 chip.setEnsureMinTouchTargetSize(false);
116 chip.setTextEndPadding(0.0f);
117 chip.setTextStartPadding(0.0f);
118 chip.setOnClickListener(v -> addReaction.run());
119 chipGroup.addView(chip);
120 }
121 }
122 }
123}