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