diff --git a/app/src/main/java/org/thunderdog/challegram/component/emoji/AnimatedEmojiDrawable.java b/app/src/main/java/org/thunderdog/challegram/component/emoji/AnimatedEmojiDrawable.java index 923b7f71c5..629d1cbfbe 100644 --- a/app/src/main/java/org/thunderdog/challegram/component/emoji/AnimatedEmojiDrawable.java +++ b/app/src/main/java/org/thunderdog/challegram/component/emoji/AnimatedEmojiDrawable.java @@ -21,6 +21,7 @@ import android.graphics.drawable.Drawable; import android.view.View; +import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -31,6 +32,7 @@ import org.thunderdog.challegram.loader.ImageReceiver; import org.thunderdog.challegram.loader.gif.GifFile; import org.thunderdog.challegram.loader.gif.GifReceiver; +import org.thunderdog.challegram.theme.PorterDuffColorId; import org.thunderdog.challegram.tool.Drawables; import me.vkryl.core.lambda.Destroyable; @@ -114,6 +116,28 @@ public void setAlpha (int i) { } } + public void setThemedPorterDuffColorId (@PorterDuffColorId int colorId) { + gifReceiver.setThemedPorterDuffColorId(colorId); + imageReceiver.setThemedPorterDuffColorId(colorId); + if (drawable != null) { + drawable.setColorFilter(imageReceiver.getBitmapPaint().getColorFilter()); + } + } + public void setPorterDuffColorFilter (@ColorInt int color) { + gifReceiver.setPorterDuffColorFilter(color); + imageReceiver.setPorterDuffColorFilter(color); + if (drawable != null) { + drawable.setColorFilter(imageReceiver.getBitmapPaint().getColorFilter()); + } + } + public void disablePorterDuffColorFilter () { + gifReceiver.disablePorterDuffColorFilter(); + imageReceiver.disablePorterDuffColorFilter(); + if (drawable != null) { + drawable.setColorFilter(null); + } + } + @Override public void setColorFilter (@Nullable ColorFilter colorFilter) { diff --git a/app/src/main/java/org/thunderdog/challegram/component/emoji/AnimatedEmojiEffect.java b/app/src/main/java/org/thunderdog/challegram/component/emoji/AnimatedEmojiEffect.java index 60e49df8c3..7fac00aae2 100644 --- a/app/src/main/java/org/thunderdog/challegram/component/emoji/AnimatedEmojiEffect.java +++ b/app/src/main/java/org/thunderdog/challegram/component/emoji/AnimatedEmojiEffect.java @@ -18,8 +18,10 @@ import android.graphics.Rect; import android.view.View; +import androidx.annotation.ColorInt; + import org.thunderdog.challegram.charts.CubicBezierInterpolator; -import org.thunderdog.challegram.tool.Paints; +import org.thunderdog.challegram.theme.PorterDuffColorId; import org.thunderdog.challegram.tool.Screen; import org.thunderdog.challegram.tool.Views; @@ -27,8 +29,9 @@ import kotlin.random.Random; import me.vkryl.core.MathUtils; +import me.vkryl.core.lambda.Destroyable; -public class AnimatedEmojiEffect { +public class AnimatedEmojiEffect implements Destroyable { public AnimatedEmojiDrawable animatedEmojiDrawable; Rect bounds = new Rect(); @@ -40,23 +43,23 @@ public class AnimatedEmojiEffect { boolean longAnimation; boolean firsDraw = true; - private AnimatedEmojiEffect(AnimatedEmojiDrawable animatedEmojiDrawable, boolean longAnimation) { + private AnimatedEmojiEffect (AnimatedEmojiDrawable animatedEmojiDrawable, boolean longAnimation) { this.animatedEmojiDrawable = animatedEmojiDrawable; this.longAnimation = longAnimation; startTime = System.currentTimeMillis(); } - public static AnimatedEmojiEffect createFrom(AnimatedEmojiDrawable animatedEmojiDrawable, boolean longAnimation) { + public static AnimatedEmojiEffect createFrom (AnimatedEmojiDrawable animatedEmojiDrawable, boolean longAnimation) { return new AnimatedEmojiEffect(animatedEmojiDrawable, longAnimation); } - public void setBounds(int l, int t, int r, int b) { + public void setBounds (int l, int t, int r, int b) { bounds.set(l, t, r, b); } long lastGenerateTime; - public void draw(Canvas canvas) { + public void draw (Canvas canvas) { if (!longAnimation) { if (firsDraw) { for (int i = 0; i < 7; i++) { @@ -90,19 +93,34 @@ public void draw(Canvas canvas) { firsDraw = false; } - public boolean done() { + public boolean done () { return System.currentTimeMillis() - startTime > 2500; } - public void setView(View view) { + public void setView (View view) { animatedEmojiDrawable.attach(); parentView = view; } - public void removeView() { + public void removeView () { animatedEmojiDrawable.detach(); } + @Override + public void performDestroy () { + animatedEmojiDrawable.performDestroy(); + } + + public void setThemedPorterDuffColorId (@PorterDuffColorId int colorId) { + animatedEmojiDrawable.setThemedPorterDuffColorId(colorId); + } + public void setPorterDuffColorFilter (@ColorInt int color) { + animatedEmojiDrawable.setPorterDuffColorFilter(color); + } + public void disablePorterDuffColorFilter () { + animatedEmojiDrawable.disablePorterDuffColorFilter(); + } + private class Particle { float fromX, fromY; float toX; @@ -116,7 +134,7 @@ private class Particle { boolean mirror; float randomRotation; - public void generate() { + public void generate () { progress = 0; float bestDistance = 0; float bestX = randX(); @@ -155,8 +173,6 @@ public void generate() { fromY = bounds.height() * 0.45f + bounds.height() * 0.1f * (Math.abs(Random.Default.nextInt() % 100) / 100f); - - if (longAnimation) { fromSize = bounds.width() * 0.05f + bounds.width() * 0.1f * (Math.abs(Random.Default.nextInt() % 100) / 100f); toSize = fromSize * (1.5f + 1.5f * (Math.abs(Random.Default.nextInt() % 100) / 100f)); @@ -175,15 +191,15 @@ public void generate() { randomRotation = 20 * ((Random.Default.nextInt() % 100) / 100f); } - private float randY() { + private float randY () { return (bounds.height() * 0.5f * (Math.abs(Random.Default.nextInt() % 100) / 100f)); } - private long randDuration() { + private long randDuration () { return 1000 + Math.abs(Random.Default.nextInt() % 900); } - private float randX() { + private float randX () { if (longAnimation) { return bounds.width() * -0.25f + bounds.width() * 1.5f * (Math.abs(Random.Default.nextInt() % 100) / 100f); } else { @@ -191,7 +207,7 @@ private float randX() { } } - public void draw(Canvas canvas) { + public void draw (Canvas canvas) { progress += (float) Math.min(40, 1000f / Screen.refreshRate()) / duration; progress = MathUtils.clamp(progress); float progressInternal = CubicBezierInterpolator.EASE_OUT.getInterpolation(progress); diff --git a/app/src/main/java/org/thunderdog/challegram/data/EmojiMessageContentType.java b/app/src/main/java/org/thunderdog/challegram/data/EmojiMessageContentType.java new file mode 100644 index 0000000000..978200913f --- /dev/null +++ b/app/src/main/java/org/thunderdog/challegram/data/EmojiMessageContentType.java @@ -0,0 +1,28 @@ +/* + * This file is a part of Telegram X + * Copyright © 2014 (tgx-android@pm.me) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * File created on 24/10/2023 at 02:14 + */ +package org.thunderdog.challegram.data; + +import androidx.annotation.IntDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.SOURCE) +@IntDef({ + EmojiMessageContentType.NOT_EMOJI, EmojiMessageContentType.ANIMATED_EMOJI, EmojiMessageContentType.NON_BUBBLE_EMOJI +}) +public @interface EmojiMessageContentType { + int NOT_EMOJI = 0, ANIMATED_EMOJI = 1, NON_BUBBLE_EMOJI = 2; +} diff --git a/app/src/main/java/org/thunderdog/challegram/data/TD.java b/app/src/main/java/org/thunderdog/challegram/data/TD.java index d88e911698..9ae1896219 100644 --- a/app/src/main/java/org/thunderdog/challegram/data/TD.java +++ b/app/src/main/java/org/thunderdog/challegram/data/TD.java @@ -5442,4 +5442,15 @@ public static boolean hasCustomEmoji (TdApi.FormattedText text) { return false; } + + public static boolean isStickerFromAnimatedEmojiPack (@Nullable TdApi.MessageContent content) { + if (content == null || content.getConstructor() != TdApi.MessageAnimatedEmoji.CONSTRUCTOR) { + return false; + } + return isStickerFromAnimatedEmojiPack(((TdApi.MessageAnimatedEmoji) content).animatedEmoji.sticker); + } + + public static boolean isStickerFromAnimatedEmojiPack (@Nullable TdApi.Sticker sticker) { + return sticker != null && sticker.setId == TdConstants.TELEGRAM_ANIMATED_EMOJI_STICKER_SET_ID; + } } diff --git a/app/src/main/java/org/thunderdog/challegram/data/TGMessage.java b/app/src/main/java/org/thunderdog/challegram/data/TGMessage.java index 3f7c118a55..ccbfe6022f 100644 --- a/app/src/main/java/org/thunderdog/challegram/data/TGMessage.java +++ b/app/src/main/java/org/thunderdog/challegram/data/TGMessage.java @@ -157,6 +157,7 @@ import me.vkryl.td.ChatId; import me.vkryl.td.MessageId; import me.vkryl.td.Td; +import me.vkryl.td.TdConstants; public abstract class TGMessage implements InvalidateContentProvider, TdlibDelegate, FactorAnimator.Target, Comparable, Counter.Callback, TGAvatars.Callback, TranslationsManager.Translatable { private static final int MAXIMUM_CHANNEL_MERGE_TIME_DIFF = 150; @@ -2009,7 +2010,8 @@ public final void draw (MessageView view, Canvas c, @NonNull AvatarReceiver avat hAuthorEmojiStatus.draw(c, left + hAuthorNameT.getWidth() + Screen.dp(3), newTop, 1f, view.getEmojiStatusReceiver()); } if (sender.hasChatMark() && hAuthorChatMark != null) { - int cmLeft = left + hAuthorNameT.getWidth() + Screen.dp(6f); + int cmLeft = left + hAuthorNameT.getWidth() + Screen.dp(3f) + + (hAuthorEmojiStatus != null ? hAuthorEmojiStatus.getWidth(Screen.dp(3)) : 0); RectF rct = Paints.getRectF(); rct.set(cmLeft, newTop, cmLeft + hAuthorChatMark.getWidth() + Screen.dp(8f), newTop + hAuthorNameT.getLineHeight(false)); c.drawRoundRect(rct, Screen.dp(2f), Screen.dp(2f), Paints.getProgressPaint(Theme.getColor(ColorId.textNegative), Screen.dp(1.5f))); @@ -7661,11 +7663,38 @@ public static TGMessage valueOf (MessagesManager context, TdApi.Message msg) { } @Nullable - private static TGMessage checkPendingContent (MessagesManager context, TdApi.Message msg, TdApi.MessageContent oldContent, @Nullable TdApi.MessageContent pendingContent, boolean allowCustomEmoji) { - if (pendingContent == null) { + private static TGMessage checkPendingContent (MessagesManager context, TdApi.Message msg, TdApi.MessageContent oldContent, @Nullable TdApi.MessageContent pendingContent, boolean allowAnimatedEmoji, boolean allowNonBubbleEmoji) { + if (pendingContent == null || oldContent.getConstructor() != TdApi.MessageAnimatedEmoji.CONSTRUCTOR && oldContent.getConstructor() != TdApi.MessageText.CONSTRUCTOR) { return null; } + final @EmojiMessageContentType int emojiPendingContentType = getEmojiMessageContentType(pendingContent, allowAnimatedEmoji, allowNonBubbleEmoji); + if (emojiPendingContentType == EmojiMessageContentType.NOT_EMOJI) { + final TdApi.MessageText oldMessageText; + if (oldContent.getConstructor() == TdApi.MessageAnimatedEmoji.CONSTRUCTOR) { + TdApi.MessageAnimatedEmoji oldEmoji = nonNull((TdApi.MessageAnimatedEmoji) oldContent); + oldMessageText = new TdApi.MessageText(Td.textOrCaption(oldEmoji), null); + } else if (oldContent.getConstructor() == TdApi.MessageText.CONSTRUCTOR) { + oldMessageText = nonNull((TdApi.MessageText) oldContent); + } else { + throw new IllegalArgumentException("Wrong content type"); + } + + final TdApi.MessageText newMessageText; + if (pendingContent.getConstructor() == TdApi.MessageAnimatedEmoji.CONSTRUCTOR) { + TdApi.MessageAnimatedEmoji newEmoji = nonNull((TdApi.MessageAnimatedEmoji) pendingContent); + newMessageText = new TdApi.MessageText(Td.textOrCaption(newEmoji), null); + } else if (pendingContent.getConstructor() == TdApi.MessageText.CONSTRUCTOR) { + newMessageText = (TdApi.MessageText) pendingContent; + } else { + throw new IllegalArgumentException("Wrong content type"); + } + + return new TGMessageText(context, msg, oldMessageText, newMessageText); + } else { + return new TGMessageSticker(context, msg, oldContent, pendingContent); + } + /* final TdApi.MessageText pendingMessageText = pendingContent.getConstructor() == TdApi.MessageText.CONSTRUCTOR ? ((TdApi.MessageText) pendingContent) : null; final TdApi.MessageAnimatedEmoji pendingMessageEmoji = pendingContent.getConstructor() == TdApi.MessageAnimatedEmoji.CONSTRUCTOR ? @@ -7690,6 +7719,7 @@ private static TGMessage checkPendingContent (MessagesManager context, TdApi.Mes } return null; + */ } public static TGMessage valueOf (MessagesManager context, TdApi.Message msg, TdApi.MessageContent content) { @@ -7711,10 +7741,11 @@ public static TGMessage valueOf (MessagesManager context, TdApi.Message msg, TdA int unsupportedStringRes = R.string.UnsupportedMessage; - final boolean allowEmoji = !Settings.instance().getNewSetting(Settings.SETTING_FLAG_NO_ANIMATED_EMOJI); + final boolean allowAnimatedEmoji = !Settings.instance().getNewSetting(Settings.SETTING_FLAG_NO_ANIMATED_EMOJI); + final boolean allowNonBubbleEmoji = Settings.instance().useBigEmoji(); final TdApi.MessageContent pendingContent = tdlib.getPendingMessageText(msg.chatId, msg.id); - TGMessage message = checkPendingContent(context, msg, content, pendingContent, allowEmoji); + TGMessage message = checkPendingContent(context, msg, content, pendingContent, allowAnimatedEmoji, allowNonBubbleEmoji); if (message != null) { return message; } @@ -7722,7 +7753,7 @@ public static TGMessage valueOf (MessagesManager context, TdApi.Message msg, TdA switch (content.getConstructor()) { case TdApi.MessageAnimatedEmoji.CONSTRUCTOR: { TdApi.MessageAnimatedEmoji emoji = nonNull((TdApi.MessageAnimatedEmoji) content); - if (!allowEmoji) { + if (getEmojiMessageContentType(content, allowAnimatedEmoji, allowNonBubbleEmoji) == EmojiMessageContentType.NOT_EMOJI) { return new TGMessageText(context, msg, new TdApi.MessageText(Td.textOrCaption(emoji), null), null); } else { return new TGMessageSticker(context, msg, emoji, null); @@ -7730,7 +7761,7 @@ public static TGMessage valueOf (MessagesManager context, TdApi.Message msg, TdA } case TdApi.MessageText.CONSTRUCTOR: { TdApi.MessageText messageText = nonNull((TdApi.MessageText) content); - if (allowEmoji && NonBubbleEmojiLayout.isValidEmojiText(messageText.text)) { + if (getEmojiMessageContentType(content, allowAnimatedEmoji, allowNonBubbleEmoji) != EmojiMessageContentType.NOT_EMOJI) { return new TGMessageSticker(context, msg, messageText, null); } return new TGMessageText(context, msg, nonNull((TdApi.MessageText) content), null); @@ -8498,6 +8529,7 @@ private void startSetReactionAnimationIfReady () { new ReactionsOverlayView.ReactionInfo(context().reactionsOverlayManager()) .setSticker(nextSetReactionAnimation.reaction.staticCenterAnimationSicker(), false) .setAnimationEndListener(this::onQuickReactionAnimationFinish) + .setRepaintingColorIds(ColorId.text, ColorId.text) .setAnimatedPosition( new Point(startX, startY), new Point(finishX, finishY), @@ -8515,6 +8547,7 @@ private void startSetReactionAnimationIfReady () { new ReactionsOverlayView.ReactionInfo(context().reactionsOverlayManager()) .setSticker(nextSetReactionAnimation.reaction.staticCenterAnimationSicker(), false) .setAnimationEndListener(this::onQuickReactionAnimationFinish) + .setRepaintingColorIds(ColorId.text, ColorId.text) .setAnimatedPosition( new Point(startX, startY), new Point(finishX, finishY), @@ -8636,6 +8669,7 @@ public void startReactionBubbleAnimation (TdApi.ReactionType reactionType) { context().reactionsOverlayManager().addOverlay( new ReactionsOverlayView.ReactionInfo(context().reactionsOverlayManager()) .setSticker(overlaySticker, true) + .setRepaintingColorIds(ColorId.text, ColorId.text) .setUseDefaultSprayAnimation(tgReaction.isCustom()) .setEmojiStatusEffect(tgReaction.isCustom() ? tgReaction.newCenterAnimationSicker() : null) .setPosition(new Point(bubbleX, bubbleY), Screen.dp(90)) @@ -9190,4 +9224,31 @@ public String getSponsoredMessageUrl () { return null; } + + /* * */ + + public static @EmojiMessageContentType int getEmojiMessageContentType (TdApi.MessageContent content) { + final boolean allowAnimatedEmoji = !Settings.instance().getNewSetting(Settings.SETTING_FLAG_NO_ANIMATED_EMOJI); + final boolean allowNonBubbleEmoji = Settings.instance().useBigEmoji(); + return getEmojiMessageContentType(content, allowAnimatedEmoji, allowNonBubbleEmoji); + } + + public static @EmojiMessageContentType int getEmojiMessageContentType (TdApi.MessageContent content, boolean allowAnimatedEmoji, boolean allowNonBubbleEmoji) { + if (content == null) { + return EmojiMessageContentType.NOT_EMOJI; + } + + if (content.getConstructor() == TdApi.MessageAnimatedEmoji.CONSTRUCTOR) { + if (allowAnimatedEmoji && TD.isStickerFromAnimatedEmojiPack(content)) { + return EmojiMessageContentType.ANIMATED_EMOJI; + } else if (allowNonBubbleEmoji) { + return EmojiMessageContentType.NON_BUBBLE_EMOJI; + } + } else if (content.getConstructor() == TdApi.MessageText.CONSTRUCTOR) { + if (allowNonBubbleEmoji && NonBubbleEmojiLayout.isValidEmojiText(((TdApi.MessageText) content).text)) { + return EmojiMessageContentType.NON_BUBBLE_EMOJI; + } + } + return EmojiMessageContentType.NOT_EMOJI; + } } diff --git a/app/src/main/java/org/thunderdog/challegram/data/TGMessageSticker.java b/app/src/main/java/org/thunderdog/challegram/data/TGMessageSticker.java index f57db5a3c7..62f9968f15 100644 --- a/app/src/main/java/org/thunderdog/challegram/data/TGMessageSticker.java +++ b/app/src/main/java/org/thunderdog/challegram/data/TGMessageSticker.java @@ -106,6 +106,9 @@ public void setSticker (@Nullable TdApi.Sticker sticker, int fitzpatrickType, bo } this.sticker = sticker; this.needThemedColorFilter = TD.needThemedColorFilter(sticker); + this.animatedFile = null; + this.staticFile = null; + this.preview = null; if (fitzpatrickType == 0 || !Td.isAnimated(sticker.format)) { this.preview = TD.toImageFile(tdlib, sticker.thumbnail); @@ -170,7 +173,7 @@ public void requestFiles (int key, ComplexReceiver receiver, boolean invalidate) receiver.getPreviewReceiver(key).clear(); return; } - if (!invalidate) { + //if (!invalidate) { DoubleImageReceiver previewReceiver = receiver.getPreviewReceiver(key); if (preview == null || hasAnimationEnded()) { previewReceiver.clear(); @@ -180,12 +183,13 @@ public void requestFiles (int key, ComplexReceiver receiver, boolean invalidate) } else { previewReceiver.requestFile(null, preview); } + //} + GifFile file = receiver.getGifReceiver(key).getCurrentFile(); + if (file != animatedFile) { + receiver.getGifReceiver(key).requestFile(null); // The new file may have the same id as + receiver.getGifReceiver(key).requestFile(animatedFile); // old file, but a different requestedSize } - if (isAnimated()) { - receiver.getGifReceiver(key).requestFile(animatedFile); - } else { - receiver.getImageReceiver(key).requestFile(staticFile); - } + receiver.getImageReceiver(key).requestFile(staticFile); } public void setSize (int width, int height) { @@ -226,8 +230,8 @@ public TGMessageSticker (MessagesManager context, TdApi.Message msg, TdApi.Messa public TGMessageSticker (MessagesManager context, TdApi.Message msg, TdApi.MessageContent content, TdApi.MessageContent pendingContent) { super(context, msg); - this.animatedEmoji = content; - this.pendingEmoji = pendingContent; + this.animatedEmoji = checkContent(content); + this.pendingEmoji = checkContent(pendingContent); this.specialType = SPECIAL_TYPE_ANIMATED_EMOJI; updateAnimatedEmoji(); } @@ -303,7 +307,7 @@ protected int onMessagePendingContentChanged (long chatId, long messageId, int o return MESSAGE_REPLACE_REQUIRED; } } - this.pendingEmoji = content; + this.pendingEmoji = checkContent(content); if (updateAnimatedEmoji()) { rebuildContent(); invalidateContentReceiver(); @@ -407,7 +411,7 @@ protected boolean updateMessageContent (TdApi.Message message, TdApi.MessageCont invalidateContentReceiver(); } } else if (specialType == SPECIAL_TYPE_ANIMATED_EMOJI) { - this.animatedEmoji = newContent; + this.animatedEmoji = checkContent(newContent); if (updateAnimatedEmoji()) { rebuildContent(); invalidateContentReceiver(); @@ -418,9 +422,9 @@ protected boolean updateMessageContent (TdApi.Message message, TdApi.MessageCont } protected boolean isSupportedMessageContent (TdApi.Message message, TdApi.MessageContent messageContent) { - if (messageContent.getConstructor() == TdApi.MessageText.CONSTRUCTOR) { - final boolean allowEmoji = !Settings.instance().getNewSetting(Settings.SETTING_FLAG_NO_ANIMATED_EMOJI); - return allowEmoji && NonBubbleEmojiLayout.isValidEmojiText(((TdApi.MessageText) messageContent).text); + final @EmojiMessageContentType int contentType = getEmojiMessageContentType(messageContent); + if (contentType == EmojiMessageContentType.NOT_EMOJI) { + return false; } return super.isSupportedMessageContent(message, messageContent); } @@ -632,41 +636,41 @@ protected void drawContent (MessageView view, Canvas c, int startX, int startY, for (Representation representation : representation) { int left = (int) (leftDefault + stickerWidth * (representation.xIndex)); int top = topDefault + stickerHeight * (representation.yIndex); - if (representation.outline != null) { - DoubleImageReceiver preview = receiver.getPreviewReceiver(index); - Receiver target = representation.isAnimated() ? receiver.getGifReceiver(index) : receiver.getImageReceiver(index); - if (target.needPlaceholder() && preview.needPlaceholder()) { - final int saveCount = Views.save(c); - c.translate(left, top); - c.drawPath(representation.outline, Paints.getPlaceholderPaint()); - Views.restore(c, saveCount); - } - index++; - } + } boolean needScale = representation.size() > 1 && specialType == SPECIAL_TYPE_ANIMATED_EMOJI; - for (int a = 0; a < 2; a++) { + for (int a = 0; a < 3; a++) { index = 0; for (Representation representation : representation) { final boolean isTgsSticker = representation.sticker != null && representation.sticker.format.getConstructor() == TdApi.StickerFormatTgs.CONSTRUCTOR; - if (isTgsSticker && a == 1 || !isTgsSticker && a == 0) { - final float scale = needScale && representation.sticker != null ? TextMedia.getScale(representation.sticker, stickerWidth) : 1f; - - int left = (int) (leftDefault + stickerWidth * (representation.xIndex)); - int top = topDefault + stickerHeight * (representation.yIndex); - int right = left + stickerWidth; - int bottom = top + stickerHeight; - - final int saveScaleToCount; - boolean needRestore = scale != 1f; - if (needRestore) { - saveScaleToCount = Views.save(c); - c.scale(scale, scale, left + stickerWidth / 2f, top + stickerHeight / 2f); - } else { - saveScaleToCount = -1; + final float scale = needScale && representation.sticker != null ? TextMedia.getScale(representation.sticker, stickerWidth) : 1f; + int left = (int) (leftDefault + stickerWidth * (representation.xIndex)); + int top = topDefault + stickerHeight * (representation.yIndex); + int right = left + stickerWidth; + int bottom = top + stickerHeight; + + final int saveScaleToCount; + boolean needRestore = scale != 1f; + if (needRestore) { + saveScaleToCount = Views.save(c); + c.scale(scale, scale, left + stickerWidth / 2f, top + stickerHeight / 2f); + } else { + saveScaleToCount = -1; + } + + if (a == 0 && representation.outline != null) { + DoubleImageReceiver preview = receiver.getPreviewReceiver(index); + Receiver target = representation.isAnimated() ? receiver.getGifReceiver(index) : receiver.getImageReceiver(index); + if (target.needPlaceholder() && preview.needPlaceholder()) { + final int saveCount = Views.save(c); + c.translate(left, top); + c.drawPath(representation.outline, Paints.getPlaceholderPaint()); + Views.restore(c, saveCount); } + } + if (isTgsSticker && a == 2 || !isTgsSticker && a == 1) { if (representation.sticker == null && representation.emojiInfo != null) { tmpRect.set(left + Screen.dp(2), top + Screen.dp(2), right - Screen.dp(2), bottom - Screen.dp(2)); Emoji.instance().draw(c, representation.emojiInfo, tmpRect); @@ -693,25 +697,21 @@ protected void drawContent (MessageView view, Canvas c, int startX, int startY, } DrawAlgorithms.drawReceiver(c, preview, target, !representation.isAnimated(), false, left, top, right, bottom); } - if (needRestore) { - Views.restore(c, saveScaleToCount); + } + if (a == 2) { + if (Config.DEBUG_STICKER_OUTLINES) { + if (representation.outline != null) { + final int saveCount = Views.save(c); + c.translate(left, top); + c.drawPath(representation.outline, Paints.fillingPaint(0x99ff0000)); + Views.restore(c, saveCount); + } } } - index++; - } - } - - if (Config.DEBUG_STICKER_OUTLINES) { - for (Representation representation : representation) { - if (representation.outline == null) { - continue; + if (needRestore) { + Views.restore(c, saveScaleToCount); } - int left = (int) (leftDefault + stickerWidth * (representation.xIndex)); - int top = topDefault + stickerHeight * (representation.yIndex); - final int saveCount = Views.save(c); - c.translate(left, top); - c.drawPath(representation.outline, Paints.fillingPaint(0x99ff0000)); - Views.restore(c, saveCount); + index++; } } } @@ -940,4 +940,10 @@ public void onCustomEmojiLoaded (TdlibEmojiManager context, TdlibEmojiManager.En } }); } + + private static TdApi.MessageContent checkContent (TdApi.MessageContent content) { + final boolean allowAnimatedEmoji = !Settings.instance().getNewSetting(Settings.SETTING_FLAG_NO_ANIMATED_EMOJI); + return !allowAnimatedEmoji && TD.isStickerFromAnimatedEmojiPack(content) ? + new TdApi.MessageText(Td.textOrCaption(content), null): content; + } } diff --git a/app/src/main/java/org/thunderdog/challegram/data/TGMessageText.java b/app/src/main/java/org/thunderdog/challegram/data/TGMessageText.java index 7b1c4ad888..d2e0f2d3d3 100644 --- a/app/src/main/java/org/thunderdog/challegram/data/TGMessageText.java +++ b/app/src/main/java/org/thunderdog/challegram/data/TGMessageText.java @@ -37,7 +37,6 @@ import org.thunderdog.challegram.tool.Screen; import org.thunderdog.challegram.tool.Strings; import org.thunderdog.challegram.unsorted.Settings; -import org.thunderdog.challegram.util.NonBubbleEmojiLayout; import org.thunderdog.challegram.util.text.Highlight; import org.thunderdog.challegram.util.text.Text; import org.thunderdog.challegram.util.text.TextColorSet; @@ -133,11 +132,10 @@ public String findUriFragment (TdApi.WebPage webPage) { protected int onMessagePendingContentChanged (long chatId, long messageId, int oldHeight) { if (currentMessageText != null) { TdApi.MessageContent messageContent = tdlib.getPendingMessageText(chatId, messageId); + final @EmojiMessageContentType int contentType = getEmojiMessageContentType(messageContent); boolean allowEmoji = !Settings.instance().getNewSetting(Settings.SETTING_FLAG_NO_ANIMATED_EMOJI); - if (messageContent != null && messageContent.getConstructor() == TdApi.MessageText.CONSTRUCTOR && allowEmoji) { - if (NonBubbleEmojiLayout.isValidEmojiText(((TdApi.MessageText) messageContent).text)) { - return MESSAGE_REPLACE_REQUIRED; - } + if (contentType != EmojiMessageContentType.NOT_EMOJI) { + return MESSAGE_REPLACE_REQUIRED; } if (messageContent != null && Td.isAnimatedEmoji(messageContent) && !allowEmoji) { messageContent = new TdApi.MessageText(Td.textOrCaption(messageContent), null); @@ -332,12 +330,10 @@ private int getWebY () { @Override protected boolean isSupportedMessageContent (TdApi.Message message, TdApi.MessageContent messageContent) { - final boolean allowEmoji = !Settings.instance().getNewSetting(Settings.SETTING_FLAG_NO_ANIMATED_EMOJI); - if (messageContent.getConstructor() == TdApi.MessageText.CONSTRUCTOR) { - return !(NonBubbleEmojiLayout.isValidEmojiText(((TdApi.MessageText) messageContent).text) && allowEmoji); + final @EmojiMessageContentType int contentType = getEmojiMessageContentType(messageContent); + if (messageContent.getConstructor() == TdApi.MessageText.CONSTRUCTOR || messageContent.getConstructor() == TdApi.MessageAnimatedEmoji.CONSTRUCTOR) { + return contentType == EmojiMessageContentType.NOT_EMOJI; } - if (messageContent.getConstructor() == TdApi.MessageAnimatedEmoji.CONSTRUCTOR) - return !allowEmoji; return super.isSupportedMessageContent(message, messageContent); } diff --git a/app/src/main/java/org/thunderdog/challegram/loader/ImageReceiver.java b/app/src/main/java/org/thunderdog/challegram/loader/ImageReceiver.java index 098870709e..f684a5cfca 100644 --- a/app/src/main/java/org/thunderdog/challegram/loader/ImageReceiver.java +++ b/app/src/main/java/org/thunderdog/challegram/loader/ImageReceiver.java @@ -1136,7 +1136,16 @@ public boolean isInsideContent (float x, float y, int emptyWidth, int emptyHeigh return false; } - + public Paint getBitmapPaint () { + float alpha = (float) metadataPaint.getAlpha() / 255f; + if (porterDuffColorIsId && porterDuffColor == ColorId.NONE) { + return Paints.bitmapPaint(alpha); + } else if (porterDuffColorIsId) { + return PorterDuffPaint.get(porterDuffColor, porterDuffAlpha * alpha); + } else { + return Paints.getPorterDuffPaint(ColorUtils.alphaColor(porterDuffAlpha * alpha, porterDuffColor)); + } + } @Override public void draw (Canvas c) { @@ -1144,15 +1153,7 @@ public void draw (Canvas c) { return; } - float alpha = (float) metadataPaint.getAlpha() / 255f; - Paint paint; - if (porterDuffColorIsId && porterDuffColor == ColorId.NONE) { - paint = Paints.bitmapPaint(alpha); - } else if (porterDuffColorIsId) { - paint = PorterDuffPaint.get(porterDuffColor, porterDuffAlpha * alpha); - } else { - paint = Paints.getPorterDuffPaint(ColorUtils.alphaColor(porterDuffAlpha * alpha, porterDuffColor)); - } + Paint paint = getBitmapPaint(); if (roundPaint != null) { roundPaint.setColorFilter(paint.getColorFilter()); } diff --git a/app/src/main/java/org/thunderdog/challegram/loader/gif/GifReceiver.java b/app/src/main/java/org/thunderdog/challegram/loader/gif/GifReceiver.java index 322dee07eb..b57fd9a83c 100644 --- a/app/src/main/java/org/thunderdog/challegram/loader/gif/GifReceiver.java +++ b/app/src/main/java/org/thunderdog/challegram/loader/gif/GifReceiver.java @@ -838,6 +838,9 @@ public void draw (Canvas c) { c.drawBitmap(frame.bitmap, rect, drawRegion, paint); } isFirstFrame = frame.no == 0; + if (Config.DEBUG_GIF_OPTIMIZATION_MODE) { + c.drawText("" + file.getRequestedSize(), (int) drawRegion.left, (int) drawRegion.top + Screen.dp(16), Paints.robotoStyleProvider(12f).getFakeBoldPaint()); + } } } if (isFirstFrame) { diff --git a/app/src/main/java/org/thunderdog/challegram/mediaview/MediaViewController.java b/app/src/main/java/org/thunderdog/challegram/mediaview/MediaViewController.java index a9f69b26ca..f62eb77eaa 100644 --- a/app/src/main/java/org/thunderdog/challegram/mediaview/MediaViewController.java +++ b/app/src/main/java/org/thunderdog/challegram/mediaview/MediaViewController.java @@ -8527,7 +8527,7 @@ private void setTextFormattingLayoutVisible (boolean visible) { textFormattingVisible = visible; if (emojiLayout != null && textFormattingLayout != null) { textFormattingLayout.setVisibility(visible ? View.VISIBLE : View.GONE); - emojiLayout.optimizeForDisplayTextFormattingLayout(!visible); + emojiLayout.optimizeForDisplayTextFormattingLayout(visible); if (visible) { textFormattingLayout.checkButtonsActive(false); } diff --git a/app/src/main/java/org/thunderdog/challegram/navigation/ReactionsOverlayView.java b/app/src/main/java/org/thunderdog/challegram/navigation/ReactionsOverlayView.java index 677440dc75..b645454fa7 100644 --- a/app/src/main/java/org/thunderdog/challegram/navigation/ReactionsOverlayView.java +++ b/app/src/main/java/org/thunderdog/challegram/navigation/ReactionsOverlayView.java @@ -314,14 +314,23 @@ public void draw (Canvas canvas) { @PorterDuffColorId int colorId = factor == 0f ? repaintingColorIdStart : repaintingColorIdEnd; imageReceiver.setThemedPorterDuffColorId(colorId); gifReceiver.setThemedPorterDuffColorId(colorId); + if (animatedEmojiEffect != null) { + animatedEmojiEffect.setThemedPorterDuffColorId(colorId); + } } else { int color = ColorUtils.fromToArgb(Theme.getColor(repaintingColorIdStart), Theme.getColor(repaintingColorIdEnd), factor); imageReceiver.setPorterDuffColorFilter(color); gifReceiver.setPorterDuffColorFilter(color); + if (animatedEmojiEffect != null) { + animatedEmojiEffect.setThemedPorterDuffColorId(color); + } } } else { imageReceiver.disablePorterDuffColorFilter(); gifReceiver.disablePorterDuffColorFilter(); + if (animatedEmojiEffect != null) { + animatedEmojiEffect.disablePorterDuffColorFilter(); + } } if (gifReceiver.needPlaceholder() || Config.DEBUG_REACTIONS_ANIMATIONS) { @@ -403,7 +412,7 @@ public void performDestroy () { imageReceiver.destroy(); gifReceiver.destroy(); if (animatedEmojiEffect != null) { - + animatedEmojiEffect.performDestroy(); } } } diff --git a/app/src/main/java/org/thunderdog/challegram/navigation/ViewPagerTopView.java b/app/src/main/java/org/thunderdog/challegram/navigation/ViewPagerTopView.java index ca2f0eeb9c..cb3ac65ec9 100644 --- a/app/src/main/java/org/thunderdog/challegram/navigation/ViewPagerTopView.java +++ b/app/src/main/java/org/thunderdog/challegram/navigation/ViewPagerTopView.java @@ -733,7 +733,9 @@ public void draw (Canvas c) { item.imageReceiver.drawScaled(c, item.imageReceiverScale); item.counter.draw(c, cx + size, viewHeight / 2f, Gravity.LEFT, counterAlpha, item.provider, 0); } else { - item.counter.draw(c, cx + itemWidth / 2f, viewHeight / 2f, Gravity.CENTER, counterAlpha, imageAlpha, item.provider, 0); + float counterWidth = item.counter.getWidth(); + float addX = -Math.min((itemWidth - counterWidth) / 2f + item.translationX, 0); + item.counter.draw(c, cx + itemWidth / 2f + addX, viewHeight / 2f, Gravity.CENTER, counterAlpha, imageAlpha, item.provider, 0); } } else if (item.ellipsizedString != null) { c.drawText(item.ellipsizedString, cx + itemWidth / 2 - item.actualWidth / 2, viewHeight / 2 + Screen.dp(6f), Paints.getViewPagerTextPaint(color, item.needFakeBold)); diff --git a/app/src/main/java/org/thunderdog/challegram/ui/BottomSheetViewController.java b/app/src/main/java/org/thunderdog/challegram/ui/BottomSheetViewController.java index d2a95ed023..3af2d93235 100644 --- a/app/src/main/java/org/thunderdog/challegram/ui/BottomSheetViewController.java +++ b/app/src/main/java/org/thunderdog/challegram/ui/BottomSheetViewController.java @@ -4,6 +4,7 @@ import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; +import android.os.Build; import android.util.Log; import android.view.MotionEvent; import android.view.View; @@ -244,10 +245,14 @@ protected void checkHeaderPosition (RecyclerView recyclerView) { } protected int getTargetHeight () { - return Screen.currentHeight() - + (context.isKeyboardVisible() ? Keyboard.getSize() : 0) - - (Screen.needsKeyboardPadding(context) ? Screen.getNavigationBarFrameDifference() : 0) - + (context.isKeyboardVisible() && Device.NEED_ADD_KEYBOARD_SIZE ? Screen.getNavigationBarHeight() : 0); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + return Screen.currentHeight() + + (context.isKeyboardVisible() ? Keyboard.getSize() : 0) + - (Screen.needsKeyboardPadding(context) ? Screen.getNavigationBarFrameDifference() : 0) + + (context.isKeyboardVisible() && Device.NEED_ADD_KEYBOARD_SIZE ? Screen.getNavigationBarHeight() : 0); + } else { + return Screen.currentHeight(); + } } protected void invalidateAllItemDecorations () { diff --git a/app/src/main/java/org/thunderdog/challegram/ui/MessageOptionsPagerController.java b/app/src/main/java/org/thunderdog/challegram/ui/MessageOptionsPagerController.java index c5627e7eb8..01c5ad3aef 100644 --- a/app/src/main/java/org/thunderdog/challegram/ui/MessageOptionsPagerController.java +++ b/app/src/main/java/org/thunderdog/challegram/ui/MessageOptionsPagerController.java @@ -408,7 +408,7 @@ private void getMessageOptions () { private int cachedHintHeight, cachedHintAvailWidth; private int getOptionItemsHeight () { - int optionItemsHeight = Screen.dp(54) * state.options.items.length; + int optionItemsHeight = state.options.items != null ? Screen.dp(54) * state.options.items.length : 0; int hintHeight; if (!StringUtils.isEmpty(state.options.info)) { int availWidth = Screen.currentWidth() - Screen.dp(16f) * 2; // FIXME: rely on parent view width @@ -850,9 +850,8 @@ public boolean onBackgroundTouchDown (PopupLayout popupLayout, MotionEvent e) { @Override public void onFactorChanged (int id, float factor, float fraction, FactorAnimator callee) { - float pickerOffset = Math.min(getOptionItemsHeight(), getTargetHeight()); - if (id == REACTIONS_PICKER_VISIBILITY_ANIMATOR_ID) { + float pickerOffset = Math.min(getOptionItemsHeight(), getTargetHeight()); invalidatePickerWrapper(); contentView.setTranslationY(pickerOffset * factor); if (headerView != null) { @@ -865,6 +864,7 @@ public void onFactorChanged (int id, float factor, float fraction, FactorAnimato } if (reactionsPickerBottomHeaderView != null) { + float pickerOffset = Math.min(getOptionItemsHeight(), getTargetHeight()); reactionsPickerBottomHeaderView.setTranslationY(-pickerOffset * (1f - reactionsPickerVisibility.getFloatValue()) - keyboardHeight.getFactor()); } } diff --git a/app/src/main/java/org/thunderdog/challegram/ui/MessagesController.java b/app/src/main/java/org/thunderdog/challegram/ui/MessagesController.java index 142c35c394..689e866d46 100644 --- a/app/src/main/java/org/thunderdog/challegram/ui/MessagesController.java +++ b/app/src/main/java/org/thunderdog/challegram/ui/MessagesController.java @@ -228,6 +228,7 @@ import org.thunderdog.challegram.util.SenderPickerDelegate; import org.thunderdog.challegram.util.StringList; import org.thunderdog.challegram.util.Unlockable; +import org.thunderdog.challegram.util.text.TextColorSets; import org.thunderdog.challegram.v.HeaderEditText; import org.thunderdog.challegram.v.MessagesLayoutManager; import org.thunderdog.challegram.v.MessagesRecyclerView; @@ -4402,11 +4403,33 @@ public void showMessageAddedReactions (TGMessage message, TdApi.ReactionType rea showMessageOptions(null, message, reactionType, newMessageOptionDelegate(message, null, null)); } + private boolean isMessageOptionsVisible; + private void showMessageOptions (Options options, TGMessage message, @Nullable TdApi.ReactionType reactionType, OptionDelegate optionsDelegate) { - MessageOptionsPagerController r = new MessageOptionsPagerController(context, tdlib, options, message, reactionType, optionsDelegate); + if (isMessageOptionsVisible) { + return; + } + isMessageOptionsVisible = true; + + MessageOptionsPagerController r = new MessageOptionsPagerController(context, tdlib, options, message, reactionType, optionsDelegate) { + @Override + protected void onCustomShowComplete () { + super.onCustomShowComplete(); + optimizeEmojiLayoutForOptionsWindow(true); + } + }; r.show(); - r.setDismissListener(p -> { - onHideMessageOptions(); + r.setDismissListener(new PopupLayout.DismissListener() { + @Override + public void onPopupDismiss (PopupLayout popup) { + optimizeEmojiLayoutForOptionsWindow(false); + isMessageOptionsVisible = false; + } + + @Override + public void onPopupDismissPrepare (PopupLayout popup) { + onHideMessageOptions(); + } }); prepareToShowMessageOptions(); hideCursorsForInputView(); @@ -4420,19 +4443,20 @@ private void prepareToShowMessageOptions () { needShowEmojiKeyboardAfterHideMessageOptions = emojiShown; if (needShowKeyboardAfterHideMessageOptions) { // показываем emoji-клавиатуру, чтобы скрыть системную openEmojiKeyboard(); // делаем emojiLayout невидимым для оптимизации + emojiLayout.optimizeForDisplayMessageOptionsWindow(true); } // todo: если меню сообщения ниже EmojiLayout, то не скрывать? + } + + private void optimizeEmojiLayoutForOptionsWindow (boolean needOptimize) { if (needShowKeyboardAfterHideMessageOptions || needShowEmojiKeyboardAfterHideMessageOptions) { - emojiLayout.setVisibility(View.INVISIBLE); + emojiLayout.optimizeForDisplayMessageOptionsWindow(needOptimize); } } private void onHideMessageOptions () { if (needShowEmojiKeyboardAfterHideMessageOptions) { - if (emojiShown) { - emojiLayout.setVisibility(View.VISIBLE); - } else { - openEmojiKeyboard(); - } + openEmojiKeyboard(); + emojiLayout.optimizeForDisplayMessageOptionsWindow(false); } else if (needShowKeyboardAfterHideMessageOptions) { showKeyboard(); } @@ -11341,7 +11365,7 @@ public void startTranslateMessages (TGMessage message, boolean forcePopup) { translationPopup = new TranslationControllerV2.Wrapper(context, tdlib, this); translationPopup.setArguments(new TranslationControllerV2.Args(message)); translationPopup.setClickCallback(message.clickCallback()); - translationPopup.setTextColorSet(message.getTextColorSet()); + translationPopup.setTextColorSet(TextColorSets.Regular.NORMAL); translationPopup.show(); translationPopup.setDismissListener(popup -> translationPopup = null); hideCursorsForInputView(); @@ -11382,7 +11406,7 @@ private void setTextFormattingLayoutVisible (boolean visible) { textFormattingVisible = visible; if (emojiLayout != null && textFormattingLayout != null) { textFormattingLayout.setVisibility(visible ? View.VISIBLE : View.GONE); - emojiLayout.optimizeForDisplayTextFormattingLayout(!visible); + emojiLayout.optimizeForDisplayTextFormattingLayout(visible); if (visible) { textFormattingLayout.checkButtonsActive(false); } diff --git a/app/src/main/java/org/thunderdog/challegram/ui/ShareController.java b/app/src/main/java/org/thunderdog/challegram/ui/ShareController.java index 81f224b6e6..95dcef43dd 100644 --- a/app/src/main/java/org/thunderdog/challegram/ui/ShareController.java +++ b/app/src/main/java/org/thunderdog/challegram/ui/ShareController.java @@ -3311,7 +3311,7 @@ private void setTextFormattingLayoutVisible (boolean visible) { textFormattingVisible = visible; if (emojiLayout != null && textFormattingLayout != null) { textFormattingLayout.setVisibility(visible ? View.VISIBLE : View.GONE); - emojiLayout.optimizeForDisplayTextFormattingLayout(!visible); + emojiLayout.optimizeForDisplayTextFormattingLayout(visible); if (visible) { textFormattingLayout.checkButtonsActive(false); } diff --git a/app/src/main/java/org/thunderdog/challegram/widget/EmojiLayout.java b/app/src/main/java/org/thunderdog/challegram/widget/EmojiLayout.java index d1b0fda95c..15ec39696a 100644 --- a/app/src/main/java/org/thunderdog/challegram/widget/EmojiLayout.java +++ b/app/src/main/java/org/thunderdog/challegram/widget/EmojiLayout.java @@ -422,14 +422,18 @@ public boolean onTouchEvent (MotionEvent event) { addView(shadowView); addView(circleButton); + checkBackground(); + // NewEmoji.instance().loadAllEmoji(); + + setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + } + + private void checkBackground () { if (useDarkMode) { setBackgroundColor(Theme.getColor(ColorId.chatKeyboard, ThemeId.NIGHT_BLACK)); } else { - ViewSupport.setThemedBackground(this, ColorId.chatKeyboard, themeProvider); + ViewSupport.setThemedBackground(this, isOptimizedForDisplayMessageOptionsWindow ? ColorId.filling : ColorId.chatKeyboard, themeProvider); } - // NewEmoji.instance().loadAllEmoji(); - - setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); } public void setAllowPremiumFeatures (boolean allowPremiumFeatures) { @@ -473,9 +477,17 @@ public void setCircleVisible (boolean isVisible, boolean isSearch) { } } + private boolean isOptimizedForDisplayMessageOptionsWindow; + + public void optimizeForDisplayMessageOptionsWindow (boolean needOptimize) { + isOptimizedForDisplayMessageOptionsWindow = needOptimize; + optimizeForDisplayTextFormattingLayout(needOptimize); + checkBackground(); + } + public void optimizeForDisplayTextFormattingLayout (boolean needOptimize) { - int visibility = needOptimize ? VISIBLE : GONE; - // if (headerView != null) headerView.setVisibility(visibility); + int visibility = needOptimize ? GONE : VISIBLE; + if (headerView != null) headerView.setVisibility(needOptimize ? INVISIBLE : VISIBLE); if (shadowView != null) shadowView.setVisibility(visibility); if (pager != null) pager.setVisibility(visibility); if (circleButton != null) circleButton.setVisibility(visibility); diff --git a/app/src/main/java/org/thunderdog/challegram/widget/StickersSuggestionsLayout.java b/app/src/main/java/org/thunderdog/challegram/widget/StickersSuggestionsLayout.java index f8d15575e7..4917ab69e7 100644 --- a/app/src/main/java/org/thunderdog/challegram/widget/StickersSuggestionsLayout.java +++ b/app/src/main/java/org/thunderdog/challegram/widget/StickersSuggestionsLayout.java @@ -76,6 +76,19 @@ public StickersSuggestionsLayout (Context context) { stickerSuggestionsView = new RecyclerView(context) { @Override public boolean onTouchEvent (MotionEvent e) { + if (e.getAction() == MotionEvent.ACTION_DOWN) { + View v = manager.findViewByPosition(0); + if (v != null && v.getLeft() > e.getX()) { + return false; + } + int i = manager.findLastVisibleItemPosition(); + if (i != -1) { + v = manager.findViewByPosition(i); + if (v != null && v.getRight() < e.getX()) { + return false; + } + } + } return areStickersVisible && getAlpha() == 1f && super.onTouchEvent(e); } };