From f0f858ad3fa89ed18cce9570ea319099127316a4 Mon Sep 17 00:00:00 2001 From: xaxtix Date: Tue, 18 Jan 2022 23:51:58 +0300 Subject: [PATCH] Update to 8.4.4 --- TMessagesProj/build.gradle | 4 +- .../widget/ChatListItemAnimator.java | 2 +- .../telegram/messenger/AndroidUtilities.java | 3 +- .../org/telegram/messenger/BuildVars.java | 6 +- .../org/telegram/messenger/ImageLoader.java | 6 +- .../messenger/MediaDataController.java | 10 +- .../messenger/MessagesController.java | 6 + .../org/telegram/messenger/SharedConfig.java | 27 +- .../main/java/org/telegram/tgnet/TLRPC.java | 97 +++++- .../org/telegram/ui/ActionBar/ActionBar.java | 23 ++ .../java/org/telegram/ui/ActionBar/Theme.java | 7 +- .../telegram/ui/Cells/ChatMessageCell.java | 62 ++-- .../ui/Cells/ThemePreviewMessagesCell.java | 2 +- .../java/org/telegram/ui/ChatActivity.java | 172 ++++++++--- .../org/telegram/ui/Components/Bulletin.java | 31 +- .../ui/Components/BulletinFactory.java | 4 + .../ui/Components/ChatActivityEnterView.java | 29 +- .../ChatAttachAlertPhotoLayout.java | 50 ++-- .../ui/Components/ChatBlurredFrameLayout.java | 73 +++++ .../ui/Components/FragmentContextView.java | 12 +- .../ui/Components/ReactionTabHolderView.java | 12 +- .../Reactions/ReactionsEffectOverlay.java | 246 +++++++++++---- .../Reactions/ReactionsLayoutInBubble.java | 69 ++++- .../Components/ReactionsContainerLayout.java | 263 ++++++++++++---- .../Components/SizeNotifierFrameLayout.java | 281 +++++++++++++++++- .../ui/Components/TranslateAlert.java | 42 +++ .../org/telegram/ui/Components/UndoView.java | 4 + .../java/org/telegram/ui/PhotoViewer.java | 11 +- .../java/org/telegram/ui/ProfileActivity.java | 6 +- .../java/org/telegram/ui/VoIPFragment.java | 2 +- TMessagesProj/src/main/res/values/strings.xml | 1 - 31 files changed, 1304 insertions(+), 259 deletions(-) create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/ChatBlurredFrameLayout.java diff --git a/TMessagesProj/build.gradle b/TMessagesProj/build.gradle index bc7ba0287..ee5221d22 100644 --- a/TMessagesProj/build.gradle +++ b/TMessagesProj/build.gradle @@ -300,7 +300,7 @@ android { } } - defaultConfig.versionCode = 2531 + defaultConfig.versionCode = 2538 applicationVariants.all { variant -> variant.outputs.all { output -> @@ -319,7 +319,7 @@ android { defaultConfig { minSdkVersion 16 targetSdkVersion 30 - versionName "8.4.3" + versionName "8.4.4" vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi'] diff --git a/TMessagesProj/src/main/java/androidx/recyclerview/widget/ChatListItemAnimator.java b/TMessagesProj/src/main/java/androidx/recyclerview/widget/ChatListItemAnimator.java index b5e44f1c4..3e63e716a 100644 --- a/TMessagesProj/src/main/java/androidx/recyclerview/widget/ChatListItemAnimator.java +++ b/TMessagesProj/src/main/java/androidx/recyclerview/widget/ChatListItemAnimator.java @@ -102,7 +102,7 @@ public class ChatListItemAnimator extends DefaultItemAnimator { ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1f); valueAnimator.addUpdateListener(animation -> { if (activity != null) { - activity.onListItemAniamtorTick(); + activity.onListItemAnimatorTick(); } else { recyclerListView.invalidate(); } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java b/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java index 217bac40e..7b7273606 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java @@ -39,7 +39,6 @@ import android.graphics.Typeface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; -import android.media.MediaScannerConnection; import android.net.Uri; import android.os.Build; import android.os.Environment; @@ -96,7 +95,6 @@ import androidx.recyclerview.widget.RecyclerView; import androidx.viewpager.widget.ViewPager; import com.android.internal.telephony.ITelephony; -import com.google.android.exoplayer2.util.Log; import com.google.android.gms.auth.api.phone.SmsRetriever; import com.google.android.gms.auth.api.phone.SmsRetrieverClient; import com.google.android.gms.tasks.Task; @@ -190,6 +188,7 @@ public class AndroidUtilities { private static RectF bitmapRect; public static final RectF rectTmp = new RectF(); + public static final Rect rectTmp2 = new Rect(); public static Pattern WEB_URL = null; public static Pattern BAD_CHARS_PATTERN = null; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java index 6f2d8c755..c78ceb20d 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java @@ -20,11 +20,11 @@ public class BuildVars { public static boolean USE_CLOUD_STRINGS = true; public static boolean CHECK_UPDATES = true; public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29; - public static int BUILD_VERSION = 2531; - public static String BUILD_VERSION_STRING = "8.4.3"; + public static int BUILD_VERSION = 2538; + public static String BUILD_VERSION_STRING = "8.4.4"; public static int APP_ID = 4; public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103"; - + public static String SMS_HASH = isStandaloneApp() ? "w0lkcmTZkKh" : (DEBUG_VERSION ? "O2P2z+/jBpJ" : "oLeq9AcOZkT"); public static String PLAYSTORE_APP_URL = "https://play.google.com/store/apps/details?id=org.telegram.messenger"; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ImageLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/ImageLoader.java index 74e6c6cbd..1252bee9a 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ImageLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ImageLoader.java @@ -517,7 +517,7 @@ public class ImageLoader { fileOutputStream = new RandomAccessFile(cacheImage.tempFilePath, "rws"); } } catch (Throwable e) { - boolean sentLogs = true; + boolean sentLogs = true; if (e instanceof SocketTimeoutException) { if (ApplicationLoader.isNetworkOnline()) { canRetry = false; @@ -534,6 +534,8 @@ public class ImageLoader { } else if (e instanceof FileNotFoundException) { canRetry = false; sentLogs = false; + } else if (e instanceof InterruptedException) { + sentLogs = false; } FileLog.e(e, sentLogs); } @@ -909,7 +911,7 @@ public class ImageLoader { compressed = true; } } catch (Exception e) { - FileLog.e(e); + FileLog.e(e, false); } finally { if (randomAccessFile != null) { try { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java b/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java index 87f0c4d03..e43a141bd 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java @@ -309,7 +309,7 @@ public class MediaDataController extends BaseController { date = c.intValue(2); } } catch (Exception e) { - FileLog.e(e); + FileLog.e(e, false); } finally { if (c != null) { c.dispose(); @@ -360,6 +360,14 @@ public class MediaDataController extends BaseController { imageReceiver.setImage(ImageLocation.getForDocument(reaction.appear_animation), "60_60_nolimit", null, null, 0, 1); ImageLoader.getInstance().loadImageForImageReceiver(imageReceiver); + imageReceiver = new ImageReceiver(); + imageReceiver.setImage(ImageLocation.getForDocument(reaction.around_animation), null, null, null, 0, 1); + ImageLoader.getInstance().loadImageForImageReceiver(imageReceiver); + + imageReceiver = new ImageReceiver(); + imageReceiver.setImage(ImageLocation.getForDocument(reaction.center_icon), null, null, null, 0, 1); + ImageLoader.getInstance().loadImageForImageReceiver(imageReceiver); + imageReceiver = new ImageReceiver(); imageReceiver.setImage(ImageLocation.getForDocument(reaction.static_icon), null, null, null, 0, 1); ImageLoader.getInstance().loadImageForImageReceiver(imageReceiver); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java index a3a6dfe31..8926ff35f 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java @@ -14899,6 +14899,12 @@ public class MessagesController extends BaseController implements NotificationCe processUpdates((TLRPC.Updates) response, false); TLRPC.ChatFull full = getChatFull(chatId); if (full != null) { + if (full instanceof TLRPC.TL_chatFull) { + full.flags |= 262144; + } + if (full instanceof TLRPC.TL_channelFull) { + full.flags |= 1073741824; + } full.available_reactions = new ArrayList<>(reactions); getMessagesStorage().updateChatInfo(full, false); } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java b/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java index 230297c39..eedb53b6f 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java @@ -77,7 +77,6 @@ public class SharedConfig { public static boolean searchMessagesAsListUsed; public static boolean stickersReorderingHintUsed; public static boolean disableVoiceAudioEffects; - public static boolean drawSnowInChat; private static int lastLocalId = -210000; public static String storageCacheDir; @@ -107,6 +106,7 @@ public class SharedConfig { public static boolean saveStreamMedia = true; public static boolean smoothKeyboard = true; public static boolean pauseMusicOnRecord = true; + public static boolean chatBlur = false; public static boolean noiseSupression; public static boolean noStatusBar; public static boolean sortContactsByName; @@ -349,6 +349,7 @@ public class SharedConfig { saveStreamMedia = preferences.getBoolean("saveStreamMedia", true); smoothKeyboard = preferences.getBoolean("smoothKeyboard2", true); pauseMusicOnRecord = preferences.getBoolean("pauseMusicOnRecord", false); + chatBlur = preferences.getBoolean("chatBlur", false); streamAllVideo = preferences.getBoolean("streamAllVideo", BuildVars.DEBUG_VERSION); streamMkv = preferences.getBoolean("streamMkv", false); suggestStickers = preferences.getInt("suggestStickers", 0); @@ -381,7 +382,6 @@ public class SharedConfig { mediaColumnsCount = preferences.getInt("mediaColumnsCount", 3); fastScrollHintCount = preferences.getInt("fastScrollHintCount", 3); dontAskManageStorage = preferences.getBoolean("dontAskManageStorage", false); - drawSnowInChat = preferences.getBoolean("drawSnowInChat", BuildVars.DEBUG_VERSION); preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); showNotificationsForAllAccounts = preferences.getBoolean("AllAccounts", true); @@ -715,14 +715,6 @@ public class SharedConfig { editor.commit(); } - public static void toggleDrawSnowInChat() { - drawSnowInChat = !drawSnowInChat; - SharedPreferences preferences = MessagesController.getGlobalMainSettings(); - SharedPreferences.Editor editor = preferences.edit(); - editor.putBoolean("drawSnowInChat", drawSnowInChat); - editor.commit(); - } - public static void toggleNoiseSupression() { noiseSupression = !noiseSupression; SharedPreferences preferences = MessagesController.getGlobalMainSettings(); @@ -941,6 +933,14 @@ public class SharedConfig { editor.commit(); } + public static void toggleDebugChatBlur() { + chatBlur = !chatBlur; + SharedPreferences preferences = MessagesController.getGlobalMainSettings(); + SharedPreferences.Editor editor = preferences.edit(); + editor.putBoolean("chatBlur", chatBlur); + editor.commit(); + } + public static void toggleInappCamera() { inappCamera = !inappCamera; SharedPreferences preferences = MessagesController.getGlobalMainSettings(); @@ -1194,4 +1194,11 @@ public class SharedConfig { dontAskManageStorage = b; ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).edit().putBoolean("dontAskManageStorage", dontAskManageStorage).apply(); } + + public static boolean canBlurChat() { + return BuildVars.DEBUG_VERSION && getDevicePerformanceClass() == PERFORMANCE_CLASS_HIGH; + } + public static boolean chatBlurEnabled() { + return canBlurChat() && chatBlur; + } } diff --git a/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java b/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java index 459459798..71fb91ef6 100644 --- a/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java +++ b/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java @@ -64,7 +64,7 @@ public class TLRPC { public static final int MESSAGE_FLAG_HAS_BOT_ID = 0x00000800; public static final int MESSAGE_FLAG_EDITED = 0x00008000; - public static final int LAYER = 136; + public static final int LAYER = 137; public static class TL_stats_megagroupStats extends TLObject { public static int constructor = 0xef7ff916; @@ -36623,7 +36623,7 @@ public class TLRPC { } public static class TL_availableReaction extends TLObject { - public static int constructor = 0x21d7c4b; + public static int constructor = 0xc077ec01; public int flags; public boolean inactive; @@ -36634,6 +36634,8 @@ public class TLRPC { public Document select_animation; public Document activate_animation; public Document effect_animation; + public Document around_animation; + public Document center_icon; public int positionInList; //custom public static TL_availableReaction TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) { @@ -36659,6 +36661,12 @@ public class TLRPC { select_animation = Document.TLdeserialize(stream, stream.readInt32(exception), exception); activate_animation = Document.TLdeserialize(stream, stream.readInt32(exception), exception); effect_animation = Document.TLdeserialize(stream, stream.readInt32(exception), exception); + if ((flags & 2) != 0) { + around_animation = Document.TLdeserialize(stream, stream.readInt32(exception), exception); + } + if ((flags & 2) != 0) { + center_icon = Document.TLdeserialize(stream, stream.readInt32(exception), exception); + } } public void serializeToStream(AbstractSerializedData stream) { @@ -36672,6 +36680,12 @@ public class TLRPC { select_animation.serializeToStream(stream); activate_animation.serializeToStream(stream); effect_animation.serializeToStream(stream); + if ((flags & 2) != 0) { + around_animation.serializeToStream(stream); + } + if ((flags & 2) != 0) { + center_icon.serializeToStream(stream); + } } } @@ -39861,6 +39875,52 @@ public class TLRPC { } } + public static abstract class messages_TranslatedText extends TLObject { + + public static messages_TranslatedText TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) { + messages_TranslatedText result = null; + switch (constructor) { + case 0x67ca4737: + result = new TL_messages_translateNoResult(); + break; + case 0xa214f7d0: + result = new TL_messages_translateResultText(); + break; + } + if (result == null && exception) { + throw new RuntimeException(String.format("can't parse magic %x in messages_TranslatedText", constructor)); + } + if (result != null) { + result.readParams(stream, exception); + } + return result; + } + } + + public static class TL_messages_translateNoResult extends messages_TranslatedText { + public static int constructor = 0x67ca4737; + + + public void serializeToStream(AbstractSerializedData stream) { + stream.writeInt32(constructor); + } + } + + public static class TL_messages_translateResultText extends messages_TranslatedText { + public static int constructor = 0xa214f7d0; + + public String text; + + public void readParams(AbstractSerializedData stream, boolean exception) { + text = stream.readString(exception); + } + + public void serializeToStream(AbstractSerializedData stream) { + stream.writeInt32(constructor); + stream.writeString(text); + } + } + public static abstract class MessagesFilter extends TLObject { public int flags; public boolean missed; @@ -49479,6 +49539,39 @@ public class TLRPC { } } + public static class TL_messages_translateText extends TLObject { + public static int constructor = 0x24ce6dee; + + public int flags; + public InputPeer peer; + public int msg_id; + public String text; + public String from_lang; + public String to_lang; + + public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) { + return messages_TranslatedText.TLdeserialize(stream, constructor, exception); + } + + public void serializeToStream(AbstractSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(flags); + if ((flags & 1) != 0) { + peer.serializeToStream(stream); + } + if ((flags & 1) != 0) { + stream.writeInt32(msg_id); + } + if ((flags & 2) != 0) { + stream.writeString(text); + } + if ((flags & 4) != 0) { + stream.writeString(from_lang); + } + stream.writeString(to_lang); + } + } + public static class TL_messages_getMessagesReactions extends TLObject { public static int constructor = 0x8bba90e6; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBar.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBar.java index 838a6a18f..23979951e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBar.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBar.java @@ -47,6 +47,7 @@ import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.EllipsizeSpanAnimator; import org.telegram.ui.Components.FireworksEffect; import org.telegram.ui.Components.LayoutHelper; +import org.telegram.ui.Components.SizeNotifierFrameLayout; import org.telegram.ui.Components.SnowflakesEffect; import java.util.ArrayList; @@ -1516,4 +1517,26 @@ public class ActionBar extends FrameLayout { } return color != null ? color : Theme.getColor(key); } + + SizeNotifierFrameLayout contentView; + boolean blurredBackground; + + public void setDrawBlurBackground(SizeNotifierFrameLayout contentView) { + blurredBackground = true; + this.contentView = contentView; + contentView.blurBehindViews.add(this); + setBackground(null); + } + + Paint blurScrimPaint = new Paint(); + Rect rectTmp = new Rect(); + @Override + protected void dispatchDraw(Canvas canvas) { + if (blurredBackground) { + rectTmp.set(0, 0, getMeasuredWidth(), getMeasuredHeight()); + blurScrimPaint.setColor(actionBarColor); + contentView.drawBlur(canvas, 0, rectTmp, blurScrimPaint, true); + } + super.dispatchDraw(canvas); + } } \ No newline at end of file diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java index 958e2084f..43fe8aec4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java @@ -65,8 +65,6 @@ import androidx.annotation.Nullable; import androidx.annotation.UiThread; import androidx.core.graphics.ColorUtils; -import com.google.android.exoplayer2.util.Log; - import org.json.JSONArray; import org.json.JSONObject; import org.telegram.messenger.AndroidUtilities; @@ -3454,6 +3452,7 @@ public class Theme { public static final String key_chat_inTextSelectionHighlight = "chat_inTextSelectionHighlight"; public static final String key_chat_recordedVoiceHighlight = "key_chat_recordedVoiceHighlight"; public static final String key_chat_TextSelectionCursor = "chat_TextSelectionCursor"; + public static final String key_chat_BlurAlpha = "chat_BlurAlpha"; public static final String key_voipgroup_listSelector = "voipgroup_listSelector"; public static final String key_voipgroup_inviteMembersBackground = "voipgroup_inviteMembersBackground"; @@ -4446,6 +4445,7 @@ public class Theme { defaultColors.put(key_chat_outTextSelectionHighlight, 0x2E3F9923); defaultColors.put(key_chat_inTextSelectionHighlight, 0x5062A9E3); defaultColors.put(key_chat_TextSelectionCursor, 0xFF419FE8); + defaultColors.put(key_chat_BlurAlpha, 0xAF000000); defaultColors.put(key_statisticChartSignature, 0x7f252529); defaultColors.put(key_statisticChartSignatureAlpha, 0x7f252529); @@ -7683,7 +7683,8 @@ public class Theme { if (gradientRotation == null) { gradientRotation = 45; } - final int[] gradientColors = {backColor, gradientToColor2}; + int gradientToColorInt = gradientToColor2 == null ? 0 : gradientToColor2; + final int[] gradientColors = {backColor, gradientToColorInt}; wallpaperDrawable = BackgroundGradientDrawable.createDitheredGradientBitmapDrawable(gradientRotation, gradientColors, bitmap.getWidth(), bitmap.getHeight() - 120); quality = 90; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java index 516523100..a928d1c49 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java @@ -64,6 +64,7 @@ import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeProvider; import android.view.animation.Interpolator; +import android.widget.TextView; import android.widget.Toast; import androidx.core.graphics.ColorUtils; @@ -375,6 +376,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate default boolean isLandscape() { return false; } + + default void invalidateBlur() { } } private final static int DOCUMENT_ATTACH_TYPE_NONE = 0; @@ -421,7 +424,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate public boolean pinnedTop; public boolean pinnedBottom; private boolean drawPinnedTop; - private boolean drawPinnedBottom; + public boolean drawPinnedBottom; private MessageObject.GroupedMessages currentMessagesGroup; private MessageObject.GroupedMessagePosition currentPosition; private boolean groupPhotoInvisible; @@ -946,6 +949,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate private Stack captionSpoilersPool = new Stack<>(); private AtomicReference captionPatchedSpoilersLayout = new AtomicReference<>(); private Path sPath = new Path(); + public boolean isBlurred; public ChatMessageCell(Context context) { this(context, false, null); @@ -3918,10 +3922,6 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate backgroundWidth = reactionsLayoutInBubble.width; } - if ((hasLinkPreview || hasInvoicePreview) && !drawInstantView) { - reactionsLayoutInBubble.totalHeight += AndroidUtilities.dp(6); - reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(3); - } totalHeight += reactionsLayoutInBubble.totalHeight; } } @@ -4868,7 +4868,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate if (!reactionsLayoutInBubble.isSmall) { reactionsLayoutInBubble.measure(maxWidth - AndroidUtilities.dp(24)); if (!reactionsLayoutInBubble.isEmpty) { - reactionsLayoutInBubble.totalHeight = reactionsLayoutInBubble.height + AndroidUtilities.dp(12); + reactionsLayoutInBubble.totalHeight = reactionsLayoutInBubble.height; + if (TextUtils.isEmpty(messageObject.caption)) { + reactionsLayoutInBubble.totalHeight += AndroidUtilities.dp(12); + } else { + reactionsLayoutInBubble.totalHeight += AndroidUtilities.dp(8); + } measureTime(messageObject); if (reactionsLayoutInBubble.width > backgroundWidth) { backgroundWidth = reactionsLayoutInBubble.width; @@ -5309,10 +5314,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate int lineCount = infoLayout.getLineCount(); measureTime(messageObject); int timeLeft = backgroundWidth - AndroidUtilities.dp(40 + 18 + 56 + 8) - infoWidth; - if (timeLeft < timeWidth && (reactionsLayoutInBubble.isSmall || reactionsLayoutInBubble.isEmpty)) { - photoHeight += AndroidUtilities.dp(12); - } else if (lineCount == 1) { - photoHeight += AndroidUtilities.dp(4); + if (reactionsLayoutInBubble.isSmall || reactionsLayoutInBubble.isEmpty) { + if (timeLeft < timeWidth) { + photoHeight += AndroidUtilities.dp(12); + } else if (lineCount == 1) { + photoHeight += AndroidUtilities.dp(4); + } } } } @@ -5320,8 +5327,16 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate if (captionLayout != null && currentPosition != null && currentMessagesGroup != null && currentMessagesGroup.isDocuments) { reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(10); } + if (!drawPhotoImage && !TextUtils.isEmpty(messageObject.caption) && docTitleLayout != null && docTitleLayout.getLineCount() > 1) { + reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(10); + } reactionsLayoutInBubble.totalHeight = reactionsLayoutInBubble.height + AndroidUtilities.dp(8); measureTime(messageObject); + + if (drawPhotoImage && captionLayout == null) { + reactionsLayoutInBubble.totalHeight += AndroidUtilities.dp(8); + } + int timeLeft = backgroundWidth - reactionsLayoutInBubble.lastLineX - AndroidUtilities.dp(24); if (timeLeft < timeWidth) { @@ -5747,7 +5762,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate } if (messageObject.type == MessageObject.TYPE_ROUND_VIDEO) { - availableTimeWidth = (int) (AndroidUtilities.roundMessageSize - Math.ceil(Theme.chat_audioTimePaint.measureText("00:00")) + AndroidUtilities.dp(40)); + availableTimeWidth = (int) (AndroidUtilities.roundMessageSize - Math.ceil(Theme.chat_audioTimePaint.measureText("00:00")) - AndroidUtilities.dp(46)); } measureTime(messageObject); int timeWidthTotal = timeWidth + AndroidUtilities.dp((SharedConfig.bubbleRadius >= 10 ? 22 : 18) + (messageObject.isOutOwner() ? 20 : 0)); @@ -5949,7 +5964,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate } if (!reactionsLayoutInBubble.isSmall) { boolean useBackgroundWidth = backgroundWidth - AndroidUtilities.dp(24) > widthForCaption; - int maxWidth = Math.max(backgroundWidth - AndroidUtilities.dp(24), widthForCaption); + int maxWidth = Math.max(backgroundWidth - AndroidUtilities.dp(36), widthForCaption); reactionsLayoutInBubble.measure(maxWidth); if (!reactionsLayoutInBubble.isEmpty) { if (shouldDrawTimeOnMedia()) { @@ -6253,7 +6268,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate captionWidth = width; captionHeight = captionLayout.getHeight(); totalHeight += captionHeight + AndroidUtilities.dp(9); - if (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0) { + if ((reactionsLayoutInBubble.isEmpty || reactionsLayoutInBubble.isSmall) && (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0)) { int timeWidthTotal = timeWidth + (messageObject.isOutOwner() ? AndroidUtilities.dp(20) : 0) + getExtraTimeX(); float lastLineWidth = captionLayout.getLineWidth(captionLayout.getLineCount() - 1) + captionLayout.getLineLeft(captionLayout.getLineCount() - 1); if (width - AndroidUtilities.dp(8) - lastLineWidth < timeWidthTotal) { @@ -6790,6 +6805,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate parent.invalidate(); } } + if (isBlurred && delegate != null) { + delegate.invalidateBlur(); + } } @Override @@ -8428,7 +8446,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate if (hasNewLineForTime) { reactionsLayoutInBubble.y -= AndroidUtilities.dp(16); } - if (captionLayout != null) { + if (captionLayout != null && ((currentMessageObject.type != 2 && !(currentMessageObject.type == 9 && drawPhotoImage)) || (currentPosition != null && currentMessagesGroup != null))) { reactionsLayoutInBubble.y -= AndroidUtilities.dp(14); } if (!botButtons.isEmpty() && currentMessageObject.type == 9) { @@ -10052,11 +10070,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate } else { edited = false; hasReplies = currentMessagesGroup.messages.get(0).hasReplies(); - for (int a = 0, size = currentMessagesGroup.messages.size(); a < size; a++) { - MessageObject object = currentMessagesGroup.messages.get(a); - if ((object.messageOwner.flags & TLRPC.MESSAGE_FLAG_EDITED) != 0 || object.isEditing()) { - edited = true; - break; + if (!currentMessagesGroup.messages.get(0).messageOwner.edit_hide) { + for (int a = 0, size = currentMessagesGroup.messages.size(); a < size; a++) { + MessageObject object = currentMessagesGroup.messages.get(a); + if ((object.messageOwner.flags & TLRPC.MESSAGE_FLAG_EDITED) != 0 || object.isEditing()) { + edited = true; + break; + } } } } @@ -11418,6 +11438,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate sideStartY -= getTranslationY(); } } + if (!reactionsLayoutInBubble.isSmall && reactionsLayoutInBubble.drawServiceShaderBackground) { + sideStartY -= reactionsLayoutInBubble.getCurrentTotalHeight(transitionParams.animateChangeProgress); + } if (!currentMessageObject.isOutOwner() && isRoundVideo && isAvatarVisible) { float offsetSize = (AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize) * 0.7f; float offsetX = isPlayingRound ? offsetSize : 0; @@ -14673,7 +14696,6 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate } accessibilityText = sb; } - info.setText(accessibilityText); info.setEnabled(true); if (Build.VERSION.SDK_INT >= 19) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ThemePreviewMessagesCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ThemePreviewMessagesCell.java index e3af3caf2..3922ac69f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ThemePreviewMessagesCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ThemePreviewMessagesCell.java @@ -177,7 +177,7 @@ public class ThemePreviewMessagesCell extends LinearLayout { requestLayout(); ReactionsEffectOverlay.removeCurrent(false); if (added) { - ReactionsEffectOverlay.show(fragment, null, cells[1], e.getX(), e.getY(), MediaDataController.getInstance(currentAccount).getDoubleTapReaction(), currentAccount); + ReactionsEffectOverlay.show(fragment, null, cells[1], e.getX(), e.getY(), MediaDataController.getInstance(currentAccount).getDoubleTapReaction(), currentAccount, ReactionsEffectOverlay.LONG_ANIMATION); ReactionsEffectOverlay.startAnimation(); } getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index 370d966cd..edc555997 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -61,7 +61,6 @@ import android.text.TextUtils; import android.text.style.CharacterStyle; import android.text.style.ForegroundColorSpan; import android.text.style.URLSpan; -import android.util.Log; import android.util.Property; import android.util.SparseArray; import android.util.SparseIntArray; @@ -188,6 +187,7 @@ import org.telegram.ui.Components.ChatAttachAlert; import org.telegram.ui.Components.ChatAttachAlertDocumentLayout; import org.telegram.ui.Components.ChatAvatarContainer; import org.telegram.ui.Components.ChatBigEmptyView; +import org.telegram.ui.Components.ChatBlurredFrameLayout; import org.telegram.ui.Components.ChatGreetingsView; import org.telegram.ui.Components.ChatScrimPopupContainerLayout; import org.telegram.ui.Components.ChatThemeBottomSheet; @@ -239,6 +239,7 @@ import org.telegram.ui.Components.SizeNotifierFrameLayout; import org.telegram.ui.Components.StickersAlert; import org.telegram.ui.Components.TextSelectionHint; import org.telegram.ui.Components.TextStyleSpan; +import org.telegram.ui.Components.ThemeEditorView; import org.telegram.ui.Components.TranslateAlert; import org.telegram.ui.Components.TrendingStickersAlert; import org.telegram.ui.Components.TypefaceSpan; @@ -312,7 +313,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private ImageView bottomOverlayImage; private RadialProgressView bottomOverlayProgress; private AnimatorSet bottomOverlayAnimation; - private FrameLayout bottomOverlayChat; + private ChatBlurredFrameLayout bottomOverlayChat; private FrameLayout bottomMessagesActionContainer; private TextView forwardButton; private TextView replyButton; @@ -353,7 +354,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private ExtendedGridLayoutManager mentionGridLayoutManager; private AnimatorSet mentionListAnimation; private ChatAttachAlert chatAttachAlert; - private FrameLayout topChatPanelView; + private ChatBlurredFrameLayout topChatPanelView; private AnimatorSet reportSpamViewAnimator; private TextView addToContactsButton; private boolean addToContactsButtonArchive; @@ -382,7 +383,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private HintView forwardHintView; private ChecksHintView checksHintView; private View emojiButtonRed; - private FrameLayout pinnedMessageView; + private ChatBlurredFrameLayout pinnedMessageView; private BluredView blurredView; private PinnedLineView pinnedLineView; private boolean setPinnedTextTranslationX; @@ -665,7 +666,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private boolean scrollToVideo; private Path aspectPath; private Paint aspectPaint; - private Runnable destroyTextureViewRunnable = this::destroyTextureView; + private Runnable destroyTextureViewRunnable = () -> { + destroyTextureView(); + }; private Paint scrimPaint; private View scrimView; @@ -860,6 +863,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private PinchToZoomHelper pinchToZoomHelper; private EmojiAnimationsOverlay emojiAnimationsOverlay; public float drawingChatLisViewYoffset; + private boolean drawListBackgroundBlur; + private boolean drawListBackgroundBlurTop; + private int blurredViewTopOffset; + private int blurredViewBottomOffset; public void deleteHistory(int dateSelectedStart, int dateSelectedEnd, boolean forAll) { chatAdapter.frozenMessages.clear(); @@ -1404,10 +1411,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } } - if (!available) { + if (!available || !(view instanceof ChatMessageCell)) { return false; } - return (view instanceof ChatMessageCell) && ((ChatMessageCell)view).getMessageObject().type != 16 && !actionBar.isActionModeShowed() && !isSecretChat() && !isInScheduleMode(); + ChatMessageCell cell = (ChatMessageCell) view; + return !cell.getMessageObject().isSending() && !cell.getMessageObject().isEditing() && cell.getMessageObject().type != 16 && !actionBar.isActionModeShowed() && !isSecretChat() && !isInScheduleMode(); } @Override @@ -1434,7 +1442,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (!available) { return; } - selectReaction(primaryMessage, null, x, y, reaction, true); + selectReaction(primaryMessage, null, x, y, reaction, true, false); } }; @@ -2792,6 +2800,27 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not Paint backgroundPaint; int backgroundColor; + @Override + protected void drawList(Canvas blurCanvas, boolean top) { + blurCanvas.save(); + blurCanvas.translate(chatListView.getX(), chatListView.getY()); + drawListBackgroundBlurTop = top; + drawListBackgroundBlur = true; + chatListView.draw(blurCanvas); + drawListBackgroundBlur = false; + blurCanvas.restore(); + } + + @Override + protected int getScrollOffset() { + return chatListView.computeVerticalScrollOffset(); + } + + @Override + protected float getBottomOffset() { + return chatListView.getBottom(); + } + AdjustPanLayoutHelper adjustPanLayoutHelper = new AdjustPanLayoutHelper(this) { @Override @@ -3054,7 +3083,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not float canvasOffsetX = chatListView.getLeft() + cell.getLeft(); float canvasOffsetY = chatListView.getY() + cell.getY(); float alpha = cell.shouldDrawAlphaLayer() ? cell.getAlpha() : 1f; - canvas.clipRect(chatListView.getLeft(), listTop, chatListView.getRight(), chatListView.getY() + chatListView.getMeasuredHeight()); + canvas.clipRect(chatListView.getLeft(), listTop, chatListView.getRight(), chatListView.getY() + chatListView.getMeasuredHeight() - blurredViewBottomOffset); canvas.translate(canvasOffsetX, canvasOffsetY); cell.setInvalidatesParent(true); if (type == 0) { @@ -3168,7 +3197,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not t = chatListViewPaddingTop - chatListViewPaddingVisibleOffset - AndroidUtilities.dp(20); } - if (b > chatListView.getMeasuredHeight() + AndroidUtilities.dp(20)) { + if (b > chatListView.getMeasuredHeight() + AndroidUtilities.dp(20)) { b = chatListView.getMeasuredHeight() + AndroidUtilities.dp(20); } @@ -3183,7 +3212,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } canvas.save(); - canvas.clipRect(0, listTop, getMeasuredWidth(), chatListView.getY() + chatListView.getHeight()); + canvas.clipRect(0, listTop, getMeasuredWidth(), chatListView.getY() + chatListView.getMeasuredHeight() - blurredViewBottomOffset); canvas.translate(0, chatListView.getY()); scrimGroup.transitionParams.cell.drawBackground(canvas, (int) l, (int) t, (int) r, (int) b, scrimGroup.transitionParams.pinnedTop, scrimGroup.transitionParams.pinnedBotton, selected, contentView.getKeyboardHeight()); canvas.restore(); @@ -3197,7 +3226,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not float viewClipLeft = chatListView.getLeft(); float viewClipTop = listTop; float viewClipRight = chatListView.getRight(); - float viewClipBottom = chatListView.getY() + chatListView.getMeasuredHeight(); + float viewClipBottom = chatListView.getY() + chatListView.getMeasuredHeight() - blurredViewBottomOffset; if (cell == null || !cell.getTransitionParams().animateBackgroundBoundsInner) { viewClipLeft = Math.max(viewClipLeft, chatListView.getLeft() + child.getX()); @@ -3335,8 +3364,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = allHeight = MeasureSpec.getSize(heightMeasureSpec); - long time = System.currentTimeMillis(); - if (lastWidth != widthSize) { globalIgnoreLayout = true; lastWidth = widthMeasureSpec; @@ -3439,7 +3466,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not chatActivityEnterView.runEmojiPanelAnimation(); } - int childCount = getChildCount(); measureChildWithMargins(chatActivityEnterView, widthMeasureSpec, 0, heightMeasureSpec, 0); @@ -3452,6 +3478,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not listViewTopHeight = AndroidUtilities.dp(49); } + blurredViewTopOffset = 0; + blurredViewBottomOffset = 0; + if (SharedConfig.chatBlurEnabled()) { + blurredViewTopOffset = actionBarHeight; + blurredViewBottomOffset = AndroidUtilities.dp(203); + } for (int i = 0; i < childCount; i++) { View child = getChildAt(i); @@ -3468,7 +3500,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not child.measure(contentWidthSpec, contentHeightSpec); } else if (child == chatListView) { int contentWidthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY); - int h = heightSize - listViewTopHeight - (inPreviewMode && Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0); + int h = heightSize - listViewTopHeight - (inPreviewMode && Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0) + blurredViewTopOffset + blurredViewBottomOffset; if (keyboardSize > AndroidUtilities.dp(20) && getLayoutParams().height < 0) { h += keyboardSize; } @@ -3553,7 +3585,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } else if (child == textSelectionHelper.getOverlayView(context)) { int contentWidthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY); - int h = heightSize; + int h = heightSize + blurredViewTopOffset; if (keyboardSize > AndroidUtilities.dp(20) && getLayoutParams().height < 0) { h += keyboardSize; textSelectionHelper.setKeyboardSize(keyboardSize); @@ -3693,6 +3725,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } else if (child == gifHintTextView || child == voiceHintTextView || child == mediaBanTooltip) { childTop -= inputFieldHeight; } else if (child == chatListView || child == floatingDateView || child == infoTopView) { + childTop -= blurredViewTopOffset; if (!inPreviewMode) { childTop -= (inputFieldHeight - AndroidUtilities.dp(51)); } @@ -3722,6 +3755,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (keyboardSize > AndroidUtilities.dp(20) && getLayoutParams().height < 0) { childTop -= keyboardSize; } + childTop -= blurredViewTopOffset; } else if (chatActivityEnterView != null && child == chatActivityEnterView.botCommandsMenuContainer) { childTop -= inputFieldHeight; } else if (child == forwardingPreviewView) { @@ -3778,6 +3812,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not }; contentView = (SizeNotifierFrameLayout) fragmentView; + contentView.needBlur = true; if (inBubbleMode) { contentView.setOccupyStatusBar(false); } @@ -4288,7 +4323,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (pullingDownAnimateProgress != 0) { transitionOffset = (chatListView.getMeasuredHeight() - pullingDownOffset) * pullingDownAnimateProgress; } - c.translate(0, getMeasuredHeight() - transitionOffset); + c.translate(0, getMeasuredHeight() - blurredViewBottomOffset - transitionOffset); if (pullingDownDrawable == null) { pullingDownDrawable = new ChatPullingDownDrawable(currentAccount, fragmentView, dialog_id, dialogFolderId, dialogFilterId, themeDelegate); pullingDownDrawable.onAttach(); @@ -4574,12 +4609,21 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not public boolean drawChild(Canvas canvas, View child, long drawingTime) { int clipLeft = 0; int clipBottom = 0; - boolean skipDraw = child == scrimView; + boolean skipDraw = !drawListBackgroundBlur && child == scrimView; ChatMessageCell cell; float cilpTop = chatListViewPaddingTop - chatListViewPaddingVisibleOffset - AndroidUtilities.dp(4); - if (child.getY() > getMeasuredHeight() || child.getY() + child.getMeasuredHeight() < cilpTop) { - skipDraw = true; + if (drawListBackgroundBlur) { + if (drawListBackgroundBlurTop && child.getY() > cilpTop + AndroidUtilities.dp(40)) { + skipDraw = true; + } + if (!drawListBackgroundBlurTop && child.getY() + child.getMeasuredHeight() < AndroidUtilities.dp(203)) { + skipDraw = true; + } + } else { + if (child.getY() > getMeasuredHeight() || child.getY() + child.getMeasuredHeight() < cilpTop) { + skipDraw = true; + } } MessageObject.GroupedMessages group = null; @@ -5065,6 +5109,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } return super.createAccessibilityNodeInfo(); } + + @Override + public void invalidate() { + super.invalidate(); + contentView.invalidateBlur(); + } }; if (currentEncryptedChat != null && Build.VERSION.SDK_INT >= 19) { chatListView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS); @@ -5621,7 +5671,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } if (currentEncryptedChat == null) { - pinnedMessageView = new FrameLayout(context) { + pinnedMessageView = new ChatBlurredFrameLayout(context, ChatActivity.this) { float lastY; float startY; @@ -5691,6 +5741,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not pinnedMessageEnterOffset = -AndroidUtilities.dp(50); pinnedMessageView.setVisibility(View.GONE); pinnedMessageView.setBackgroundResource(R.drawable.blockpanel); + pinnedMessageView.backgroundColor = getThemedColor(Theme.key_chat_topPanelBackground); + pinnedMessageView.backgroundPaddingBottom = AndroidUtilities.dp(2); pinnedMessageView.getBackground().mutate().setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_chat_topPanelBackground), PorterDuff.Mode.MULTIPLY)); contentView.addView(pinnedMessageView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 50, Gravity.TOP | Gravity.LEFT)); pinnedMessageView.setOnClickListener(v -> { @@ -5851,7 +5903,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not }); } - topChatPanelView = new FrameLayout(context) { + topChatPanelView = new ChatBlurredFrameLayout(context, this) { private boolean ignoreLayout; @@ -5897,6 +5949,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not super.requestLayout(); } }; + topChatPanelView.backgroundColor = getThemedColor(Theme.key_chat_topPanelBackground); + topChatPanelView.backgroundPaddingBottom = AndroidUtilities.dp(2); topChatPanelView.setTag(1); topChatPanelViewOffset = -AndroidUtilities.dp(50); invalidateChatListViewTopPadding(); @@ -6799,6 +6853,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not undoView.showWithAction(0, Math.abs(value - 1.0f) > 0.001f ? UndoView.ACTION_PLAYBACK_SPEED_ENABLED : UndoView.ACTION_PLAYBACK_SPEED_DISABLED, value, null, null); } } + + }; contentView.addView(fragmentLocationContextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 38, Gravity.TOP | Gravity.LEFT, 0, -36, 0, 0)); contentView.addView(fragmentContextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 38, Gravity.TOP | Gravity.LEFT, 0, -36, 0, 0)); @@ -7796,7 +7852,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not bottomOverlayText.setTextColor(getThemedColor(Theme.key_chat_secretChatStatusText)); bottomOverlay.addView(bottomOverlayText, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER, 14, 0, 14, 0)); - bottomOverlayChat = new FrameLayout(context) { + bottomOverlayChat = new ChatBlurredFrameLayout(context, this) { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int allWidth = MeasureSpec.getSize(widthMeasureSpec); @@ -7810,9 +7866,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not int bottom = Theme.chat_composeShadowDrawable.getIntrinsicHeight(); Theme.chat_composeShadowDrawable.setBounds(0, 0, getMeasuredWidth(), bottom); Theme.chat_composeShadowDrawable.draw(canvas); - canvas.drawRect(0, bottom, getMeasuredWidth(), getMeasuredHeight(), getThemedPaint(Theme.key_paint_chatComposeBackground)); + if (SharedConfig.chatBlurEnabled()) { + AndroidUtilities.rectTmp2.set(0, bottom, getMeasuredWidth(), getMeasuredHeight()); + contentView.drawBlur(canvas, getY(), AndroidUtilities.rectTmp2, getThemedPaint(Theme.key_paint_chatComposeBackground), false); + } else { + canvas.drawRect(0, bottom, getMeasuredWidth(), getMeasuredHeight(), getThemedPaint(Theme.key_paint_chatComposeBackground)); + } } }; + bottomOverlayChat.isTopView = false; + bottomOverlayChat.drawBlur = false; bottomOverlayChat.setWillNotDraw(false); bottomOverlayChat.setPadding(0, AndroidUtilities.dp(1.5f), 0, 0); bottomOverlayChat.setVisibility(View.INVISIBLE); @@ -8166,6 +8229,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not topBottom[0] = chatListView.getTop() + chatListViewPaddingTop - AndroidUtilities.dp(4); }); emojiAnimationsOverlay = new EmojiAnimationsOverlay(ChatActivity.this, contentView, chatListView, currentAccount, dialog_id, threadMessageId); + actionBar.setDrawBlurBackground(contentView); return fragmentView; } @@ -8731,6 +8795,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not float oldPadding = chatListViewPaddingTop; chatListViewPaddingTopOnlyTopViews = topPanelViewH + pinnedViewH; chatListViewPaddingTop = AndroidUtilities.dp(4) + contentPaddingTop + topPanelViewH + pinnedViewH + pendingViewH; + chatListViewPaddingTop += blurredViewTopOffset; chatListViewPaddingVisibleOffset = 0; chatListViewPaddingTop += contentPanTranslation + bottomPanelTranslationY; @@ -8781,7 +8846,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } - chatListView.setPadding(0, p, 0, AndroidUtilities.dp(3)); + chatListView.setPadding(0, p, 0, AndroidUtilities.dp(3) + blurredViewBottomOffset); if (firstVisPos != RecyclerView.NO_POSITION && scrollToMessageObject != null) { chatAdapter.updateRowsSafe(); @@ -11569,6 +11634,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } int top = (int) view.getY(); int bottom = top + view.getMeasuredHeight(); + ChatMessageCell messageCell = null; + if (view instanceof ChatMessageCell) { + messageCell = (ChatMessageCell) view; + } + if (messageCell != null) { + messageCell.isBlurred = view.getY() < clipTop || view.getY() + view.getMeasuredHeight() > AndroidUtilities.dp(203); + } + if (bottom <= clipTop - chatListViewPaddingVisibleOffset || top > chatListView.getMeasuredHeight()) { continue; } @@ -11583,8 +11656,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not keyboardOffset = chatActivityEnterView.getEmojiPadding(); } - if (view instanceof ChatMessageCell) { - ChatMessageCell messageCell = (ChatMessageCell) view; + if (messageCell != null) { messageObject = messageCell.getMessageObject(); if (messageObject.getDialogId() == dialog_id && messageObject.getId() > maxVisibleId) { maxVisibleId = messageObject.getId(); @@ -20974,6 +21046,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not TranslateAlert.OnLinkPress onLinkPress = (link) -> { didPressMessageUrl(link, false, selectedObject, v instanceof ChatMessageCell ? (ChatMessageCell) v : null); }; + TLRPC.InputPeer inputPeer = getMessagesController().getInputPeer(dialog_id); + int messageId = selectedObject.messageOwner.id; if (LanguageDetector.hasSupport()) { final String[] fromLang = { null }; cell.setVisibility(View.GONE); @@ -20993,7 +21067,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } }, (Exception e) -> { - Log.e("mlkit", "failed to detect language in message"); + FileLog.e("mlkit: failed to detect language in message"); e.printStackTrace(); waitForLangDetection.set(false); if (onLangDetectionDone.get() != null) { @@ -21006,7 +21080,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (selectedObject == null || i >= options.size() || getParentActivity() == null) { return; } - TranslateAlert.showAlert(getParentActivity(), this, fromLang[0], toLang, finalMessageText, currentChat != null && currentChat.noforwards, onLinkPress); + TranslateAlert.showAlert(getParentActivity(), this, currentAccount, inputPeer, messageId, fromLang[0], toLang, finalMessageText, currentChat != null && currentChat.noforwards, onLinkPress); scrimView = null; scrimViewReaction = null; contentView.invalidate(); @@ -21026,7 +21100,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (selectedObject == null || i >= options.size() || getParentActivity() == null) { return; } - TranslateAlert.showAlert(getParentActivity(), this, "und", toLang, finalMessageText, currentChat != null && currentChat.noforwards, onLinkPress); + TranslateAlert.showAlert(getParentActivity(), this, currentAccount, inputPeer, messageId, "und", toLang, finalMessageText, currentChat != null && currentChat.noforwards, onLinkPress); scrimView = null; scrimViewReaction = null; contentView.invalidate(); @@ -21087,13 +21161,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not int sPad = 24; reactionsLayout.setPadding(AndroidUtilities.dp(4) + (LocaleController.isRTL ? 0 : sPad), AndroidUtilities.dp(4), AndroidUtilities.dp(4) + (LocaleController.isRTL ? sPad : 0), AndroidUtilities.dp(pad)); - reactionsLayout.setDelegate((rView, reaction) -> { - selectReaction(primaryMessage, reactionsLayout, 0, 0, reaction, false); + reactionsLayout.setDelegate((rView, reaction, longress) -> { + selectReaction(primaryMessage, reactionsLayout, 0, 0, reaction, false, longress); }); - LinearLayout.LayoutParams params = LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 52 + pad, Gravity.RIGHT, 0, 0, 0, -20); + LinearLayout.LayoutParams params = LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 52 + pad, Gravity.RIGHT, 0, 50, 0, -20); scrimPopupContainerLayout.addView(reactionsLayout, params); scrimPopupContainerLayout.reactionsLayout = reactionsLayout; + scrimPopupContainerLayout.setClipChildren(false); reactionsLayout.setMessage(message, chatInfo); reactionsLayout.setTransitionProgress(0); @@ -21333,12 +21408,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } Runnable updateReactionRunnable; - private void selectReaction(MessageObject primaryMessage, ReactionsContainerLayout reactionsLayout, float x, float y, TLRPC.TL_availableReaction reaction, boolean fromDoubleTap) { + private void selectReaction(MessageObject primaryMessage, ReactionsContainerLayout reactionsLayout, float x, float y, TLRPC.TL_availableReaction reaction, boolean fromDoubleTap, boolean bigEmoji) { ReactionsEffectOverlay.removeCurrent(false); boolean added = primaryMessage.selectReaction(reaction.reaction, fromDoubleTap); int messageIdForCell = primaryMessage.getId(); if (groupedMessagesMap.get(primaryMessage.getGroupId()) != null) { - MessageObject messageObject = groupedMessagesMap.get(primaryMessage.getGroupId()).findMessageWithFlags(MessageObject.POSITION_FLAG_BOTTOM | MessageObject.POSITION_FLAG_LEFT); + int flags = primaryMessage.shouldDrawReactionsInLayout() ? MessageObject.POSITION_FLAG_BOTTOM | MessageObject.POSITION_FLAG_LEFT : MessageObject.POSITION_FLAG_BOTTOM | MessageObject.POSITION_FLAG_RIGHT; + MessageObject messageObject = groupedMessagesMap.get(primaryMessage.getGroupId()).findMessageWithFlags(flags); if (messageObject != null) { messageIdForCell = messageObject.getId(); } @@ -21348,7 +21424,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (added && !fromDoubleTap) { ChatMessageCell cell = findMessageCell(finalMessageIdForCell); - ReactionsEffectOverlay.show(ChatActivity.this, reactionsLayout, cell, x, y, reaction.reaction, currentAccount); + ReactionsEffectOverlay.show(ChatActivity.this, reactionsLayout, cell, x, y, reaction.reaction, currentAccount, reactionsLayout != null ? (bigEmoji ? ReactionsEffectOverlay.LONG_ANIMATION : ReactionsEffectOverlay.ONLY_MOVE_ANIMATION) : ReactionsEffectOverlay.SHORT_ANIMATION); } getSendMessagesHelper().sendReaction(primaryMessage, added ? reaction.reaction : null, ChatActivity.this, updateReactionRunnable = new Runnable() { @Override @@ -21360,7 +21436,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not AndroidUtilities.runOnUIThread(() -> { ChatMessageCell cell = findMessageCell(finalMessageIdForCell); if (added) { - ReactionsEffectOverlay.show(ChatActivity.this, reactionsLayout, cell, x, y, reaction.reaction, currentAccount); + ReactionsEffectOverlay.show(ChatActivity.this, reactionsLayout, cell, x, y, reaction.reaction, currentAccount, ReactionsEffectOverlay.SHORT_ANIMATION); ReactionsEffectOverlay.startAnimation(); } }, 50); @@ -21383,8 +21459,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not updateReactionRunnable.run(); } AndroidUtilities.runOnUIThread(updateReactionRunnable, 50); - - } @SuppressLint("NotifyDataSetChanged") @@ -22363,7 +22437,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not updateVisibleRows(); } - public void onListItemAniamtorTick() { + public void onListItemAnimatorTick() { invalidateMessagesVisiblePart(); if (scrimView != null) { fragmentView.invalidate(); @@ -24106,7 +24180,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } } else { - selectReaction(cell.getPrimaryMessageObject(), null, 0, 0, getMediaDataController().getReactionsMap().get(reaction.reaction), false); + selectReaction(cell.getPrimaryMessageObject(), null, 0, 0, getMediaDataController().getReactionsMap().get(reaction.reaction), false, false); } } @@ -24445,6 +24519,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not public boolean isLandscape() { return contentView.getMeasuredWidth() > contentView.getMeasuredHeight(); } + + @Override + public void invalidateBlur() { + contentView.invalidateBlur(); + } }); if (currentEncryptedChat == null) { chatMessageCell.setAllowAssistant(true); @@ -25551,6 +25630,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (avatarContainer != null) { avatarContainer.updateColors(); } + if (pinnedMessageView != null) { + pinnedMessageView.backgroundColor = getThemedColor(Theme.key_chat_topPanelBackground); + } + if (topChatPanelView != null) { + topChatPanelView.backgroundColor = getThemedColor(Theme.key_chat_topPanelBackground); + } }; ArrayList themeDescriptions = new ArrayList<>(); @@ -26126,6 +26211,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not themeDescriptions.add(new ThemeDescription(null, 0, null, null, null, null, Theme.key_chat_outReactionButtonText)); themeDescriptions.add(new ThemeDescription(null, 0, null, null, null, null, Theme.key_chat_inReactionButtonTextSelected)); themeDescriptions.add(new ThemeDescription(null, 0, null, null, null, null, Theme.key_chat_inReactionButtonTextSelected)); + themeDescriptions.add(new ThemeDescription(null, 0, null, null, null, selectedBackgroundDelegate, Theme.key_chat_BlurAlpha)); if (chatActivityEnterView != null) { themeDescriptions.add(new ThemeDescription(chatActivityEnterView.botCommandsMenuContainer.listView, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{BotCommandsMenuView.BotCommandView.class}, new String[]{"description"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText)); @@ -26362,7 +26448,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not setupChatTheme(chatTheme, false, true); } } - if (!setup) { + if (!setup && ThemeEditorView.getInstance() == null) { Theme.refreshThemeColors(true, true); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Bulletin.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Bulletin.java index 4c9111eb7..d6e5ae053 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Bulletin.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Bulletin.java @@ -1,5 +1,7 @@ package org.telegram.ui.Components; +import static java.lang.annotation.RetentionPolicy.SOURCE; + import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; @@ -51,9 +53,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import static java.lang.annotation.RetentionPolicy.SOURCE; - -public final class Bulletin { +public class Bulletin { public static final int DURATION_SHORT = 1500; public static final int DURATION_LONG = 2750; @@ -117,6 +117,12 @@ public final class Bulletin { private Delegate currentDelegate; private Layout.Transition layoutTransition; + private Bulletin() { + layout = null; + parentLayout = null; + containerLayout = null; + } + private Bulletin(@NonNull FrameLayout containerLayout, @NonNull Layout layout, int duration) { this.layout = layout; this.parentLayout = new ParentLayout(layout) { @@ -214,7 +220,7 @@ public final class Bulletin { } private void setCanHide(boolean canHide) { - if (this.canHide != canHide) { + if (this.canHide != canHide && layout != null) { this.canHide = canHide; if (canHide) { layout.postDelayed(hideRunnable, duration); @@ -225,7 +231,7 @@ public final class Bulletin { } private void ensureLayoutTransitionCreated() { - if (layoutTransition == null) { + if (layout != null && layoutTransition == null) { layoutTransition = layout.createTransition(); } } @@ -239,6 +245,9 @@ public final class Bulletin { } public void hide(boolean animated, long duration) { + if (layout == null) { + return; + } if (showing) { showing = false; @@ -1216,4 +1225,16 @@ public final class Bulletin { } } //endregion + + public static class EmptyBulletin extends Bulletin { + + public EmptyBulletin() { + super(); + } + + @Override + public Bulletin show() { + return this; + } + } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/BulletinFactory.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/BulletinFactory.java index 3acef80f0..95f0c733c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/BulletinFactory.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/BulletinFactory.java @@ -1,6 +1,7 @@ package org.telegram.ui.Components; import android.content.Context; +import android.os.Build; import android.widget.FrameLayout; import androidx.annotation.CheckResult; @@ -196,6 +197,9 @@ public final class BulletinFactory { @CheckResult public Bulletin createCopyLinkBulletin(boolean isPrivate, Theme.ResourcesProvider resourcesProvider) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + return new Bulletin.EmptyBulletin(); + } if (isPrivate) { final Bulletin.TwoLineLottieLayout layout = new Bulletin.TwoLineLottieLayout(getContext(), resourcesProvider); layout.setAnimation(R.raw.voip_invite, 36, 36, "Wibe", "Circle"); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java index feb17b1df..6fe3161fb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java @@ -147,7 +147,7 @@ import java.util.List; import java.util.Locale; import java.util.concurrent.atomic.AtomicReference; -public class ChatActivityEnterView extends FrameLayout implements NotificationCenter.NotificationCenterDelegate, SizeNotifierFrameLayout.SizeNotifierFrameLayoutDelegate, StickersAlert.StickersAlertDelegate { +public class ChatActivityEnterView extends ChatBlurredFrameLayout implements NotificationCenter.NotificationCenterDelegate, SizeNotifierFrameLayout.SizeNotifierFrameLayoutDelegate, StickersAlert.StickersAlertDelegate { public interface ChatActivityEnterViewDelegate { void onMessageSend(CharSequence message, boolean notify, int scheduleDate); @@ -1680,8 +1680,10 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe @SuppressLint("ClickableViewAccessibility") public ChatActivityEnterView(Activity context, SizeNotifierFrameLayout parent, ChatActivity fragment, final boolean isChat, Theme.ResourcesProvider resourcesProvider) { - super(context); + super(context, fragment); this.resourcesProvider = resourcesProvider; + this.backgroundColor = getThemedColor(Theme.key_chat_messagePanelBackground); + this.drawBlur = false; smoothKeyboard = isChat && SharedConfig.smoothKeyboard && !AndroidUtilities.isInMultiwindow && (fragment == null || !fragment.isInBubbleMode()); dotPaint = new Paint(Paint.ANTI_ALIAS_FLAG); @@ -2988,7 +2990,13 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe senderSelectView.setVisibility(GONE); frameLayout.addView(senderSelectView, LayoutHelper.createFrame(32, 32, Gravity.BOTTOM | Gravity.LEFT, 10, 8, 10, 8)); - recordedAudioPanel = new FrameLayout(context); + recordedAudioPanel = new FrameLayout(context) { + @Override + public void setVisibility(int visibility) { + super.setVisibility(visibility); + updateSendAsButton(); + } + }; recordedAudioPanel.setVisibility(audioToSend == null ? GONE : VISIBLE); recordedAudioPanel.setFocusable(true); recordedAudioPanel.setFocusableInTouchMode(true); @@ -3648,7 +3656,12 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe Theme.chat_composeShadowDrawable.setBounds(0, top, getMeasuredWidth(), bottom); Theme.chat_composeShadowDrawable.draw(canvas); backgroundPaint.setColor(getThemedColor(Theme.key_chat_messagePanelBackground)); - canvas.drawRect(0, bottom, getWidth(), getHeight(), backgroundPaint); + if (SharedConfig.chatBlurEnabled() && chatActivity != null) { + AndroidUtilities.rectTmp2.set(0, bottom, getWidth(), getHeight()); + chatActivity.contentView.drawBlur(canvas, getY(), AndroidUtilities.rectTmp2, backgroundPaint, false); + } else { + canvas.drawRect(0, bottom, getWidth(), getHeight(), backgroundPaint); + } } @Override @@ -4670,7 +4683,6 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe recordPannelAnimation.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - recordedAudioPanel.setVisibility(GONE); recordedAudioSeekBar.setAlpha(1f); recordedAudioSeekBar.setTranslationX(0); recordedAudioPlayButton.setAlpha(1f); @@ -4684,6 +4696,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe messageEditText.setAlpha(1f); messageEditText.setTranslationX(0); messageEditText.requestFocus(); + recordedAudioPanel.setVisibility(GONE); } }); @@ -6826,7 +6839,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe } public void updateSendAsButton() { - if (parentFragment == null) { + if (parentFragment == null || delegate == null) { return; } TLRPC.ChatFull full = parentFragment.getMessagesController().getChatFull(-dialog_id); @@ -6844,7 +6857,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe } } boolean wasVisible = senderSelectView.getVisibility() == View.VISIBLE; - boolean isVisible = delegate.getSendAsPeers() != null && defPeer != null && delegate.getSendAsPeers().peers.size() > 1 && !isEditingMessage() && !isRecordingAudioVideo(); + boolean isVisible = delegate.getSendAsPeers() != null && defPeer != null && delegate.getSendAsPeers().peers.size() > 1 && !isEditingMessage() && !isRecordingAudioVideo() && recordedAudioPanel.getVisibility() != View.VISIBLE; int pad = AndroidUtilities.dp(2); MarginLayoutParams params = (MarginLayoutParams) senderSelectView.getLayoutParams(); float sA = isVisible ? 0 : 1; @@ -6861,6 +6874,8 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe if (parentFragment.getOtherSameChatsDiff() == 0 && parentFragment.fragmentOpened) { ValueAnimator anim = ValueAnimator.ofFloat(0, 1).setDuration(150); + senderSelectView.setTranslationX(sX); + messageEditText.setTranslationX(senderSelectView.getTranslationX()); anim.addUpdateListener(animation -> { float val = (float) animation.getAnimatedValue(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlertPhotoLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlertPhotoLayout.java index 5ba076f5e..9a938af13 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlertPhotoLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlertPhotoLayout.java @@ -49,6 +49,14 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.Keep; +import androidx.core.graphics.ColorUtils; +import androidx.exifinterface.media.ExifInterface; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.LinearSmoothScroller; +import androidx.recyclerview.widget.RecyclerView; + import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.BuildVars; @@ -86,14 +94,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import androidx.annotation.Keep; -import androidx.core.graphics.ColorUtils; -import androidx.exifinterface.media.ExifInterface; -import androidx.recyclerview.widget.GridLayoutManager; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.LinearSmoothScroller; -import androidx.recyclerview.widget.RecyclerView; - public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayout implements NotificationCenter.NotificationCenterDelegate { private RecyclerListView cameraPhotoRecyclerView; @@ -362,6 +362,11 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou } } + @Override + public void onApplyCaption(CharSequence caption) { + parentAlert.commentTextView.setText(caption); + } + @Override public boolean cancelButtonPressed() { return false; @@ -2510,16 +2515,25 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou @Override void applyCaption(CharSequence text) { - int imageId = (Integer) selectedPhotosOrder.get(0); - Object entry = selectedPhotos.get(imageId); - if (entry instanceof MediaController.PhotoEntry) { - MediaController.PhotoEntry photoEntry = (MediaController.PhotoEntry) entry; - photoEntry.caption = text; - photoEntry.entities = MediaDataController.getInstance(UserConfig.selectedAccount).getEntities(new CharSequence[] {text}, false); - } else if (entry instanceof MediaController.SearchImage) { - MediaController.SearchImage searchImage = (MediaController.SearchImage) entry; - searchImage.caption = text; - searchImage.entities = MediaDataController.getInstance(UserConfig.selectedAccount).getEntities(new CharSequence[] {text}, false); + for (int a = 0; a < selectedPhotosOrder.size(); a++) { + Object o = selectedPhotos.get(selectedPhotosOrder.get(a)); + if (o instanceof MediaController.PhotoEntry) { + MediaController.PhotoEntry photoEntry1 = (MediaController.PhotoEntry) o; + if (a == 0) { + photoEntry1.caption = text; + photoEntry1.entities = MediaDataController.getInstance(UserConfig.selectedAccount).getEntities(new CharSequence[] {text}, false); + } else { + photoEntry1.caption = null; + } + } else if (o instanceof MediaController.SearchImage) { + MediaController.SearchImage photoEntry1 = (MediaController.SearchImage) o; + if (a == 0) { + photoEntry1.caption = text; + photoEntry1.entities = MediaDataController.getInstance(UserConfig.selectedAccount).getEntities(new CharSequence[] {text}, false); + } else { + photoEntry1.caption = null; + } + } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatBlurredFrameLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatBlurredFrameLayout.java new file mode 100644 index 000000000..ebeb9da2f --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatBlurredFrameLayout.java @@ -0,0 +1,73 @@ +package org.telegram.ui.Components; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.view.View; +import android.widget.FrameLayout; + +import androidx.annotation.NonNull; + +import org.telegram.messenger.AndroidUtilities; +import org.telegram.messenger.SharedConfig; +import org.telegram.ui.ChatActivity; + +public class ChatBlurredFrameLayout extends FrameLayout { + + ChatActivity chatActivity; + Paint backgroundPaint; + public int backgroundColor; + public int backgroundPaddingBottom; + public int backgroundPaddingTop; + public boolean isTopView = true; + public boolean drawBlur = true; + + public ChatBlurredFrameLayout(@NonNull Context context, ChatActivity chatActivity) { + super(context); + this.chatActivity = chatActivity; + } + + @Override + protected void dispatchDraw(Canvas canvas) { + if (SharedConfig.chatBlurEnabled() && chatActivity != null && drawBlur) { + if (backgroundPaint == null) { + backgroundPaint = new Paint(); + } + backgroundPaint.setColor(backgroundColor); + AndroidUtilities.rectTmp2.set(0, backgroundPaddingTop, getMeasuredWidth(), getMeasuredHeight() - backgroundPaddingBottom); + float y = 0; + View view = this; + while (view != chatActivity.contentView) { + y += view.getY(); + view = (View) view.getParent(); + } + chatActivity.contentView.drawBlur(canvas, y, AndroidUtilities.rectTmp2, backgroundPaint, isTopView); + } + super.dispatchDraw(canvas); + } + + @Override + public void setBackgroundColor(int color) { + if (SharedConfig.chatBlurEnabled() && chatActivity != null) { + backgroundColor = color; + } else { + super.setBackgroundColor(color); + } + } + + @Override + protected void onAttachedToWindow() { + if (SharedConfig.chatBlurEnabled() && chatActivity != null) { + chatActivity.contentView.blurBehindViews.add(this); + } + super.onAttachedToWindow(); + } + + @Override + protected void onDetachedFromWindow() { + if (SharedConfig.chatBlurEnabled() && chatActivity != null) { + chatActivity.contentView.blurBehindViews.remove(this); + } + super.onDetachedFromWindow(); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/FragmentContextView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/FragmentContextView.java index c3647b51c..3173e4a31 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/FragmentContextView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/FragmentContextView.java @@ -27,9 +27,6 @@ import android.graphics.Shader; import android.graphics.Typeface; import android.os.Build; import android.os.Bundle; - -import androidx.annotation.Keep; - import android.os.SystemClock; import android.text.Layout; import android.text.SpannableStringBuilder; @@ -49,6 +46,8 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.Keep; + import org.telegram.messenger.AccountInstance; import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.ChatObject; @@ -89,6 +88,7 @@ public class FragmentContextView extends FrameLayout implements NotificationCent private AudioPlayerAlert.ClippingTextViewSwitcher subtitleTextView; private AnimatorSet animatorSet; private BaseFragment fragment; + private ChatActivity chatActivity; private View applyingView; private FrameLayout frameLayout; private View shadow; @@ -215,6 +215,9 @@ public class FragmentContextView extends FrameLayout implements NotificationCent this.resourcesProvider = resourcesProvider; fragment = parentFragment; + if (fragment instanceof ChatActivity) { + chatActivity = (ChatActivity) fragment; + } applyingView = paddingView; visible = true; isLocation = location; @@ -223,7 +226,8 @@ public class FragmentContextView extends FrameLayout implements NotificationCent } setTag(1); - frameLayout = new FrameLayout(context) { + frameLayout = new ChatBlurredFrameLayout(context, chatActivity) { + @Override public void invalidate() { super.invalidate(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ReactionTabHolderView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ReactionTabHolderView.java index 81f5de33c..7e94ed393 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ReactionTabHolderView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ReactionTabHolderView.java @@ -39,17 +39,15 @@ public class ReactionTabHolderView extends FrameLayout { private BackupImageView reactView; private ImageView iconView; private TextView counterView; - + View overlaySelectorView; private float outlineProgress; Drawable drawable; public ReactionTabHolderView(@NonNull Context context) { super(context); - View overlaySelectorView = new View(context); - overlaySelectorView.setBackground(Theme.createSimpleSelectorRoundRectDrawable((int) radius, Color.TRANSPARENT, Theme.getColor(Theme.key_chat_inReactionButtonTextSelected))); + overlaySelectorView = new View(context); addView(overlaySelectorView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); - iconView = new ImageView(context); drawable = ContextCompat.getDrawable(context, R.drawable.msg_reactions_filled).mutate(); iconView.setImageDrawable(drawable); @@ -82,6 +80,12 @@ public class ReactionTabHolderView extends FrameLayout { bgPaint.setColor(ColorUtils.blendARGB(backgroundColor, backgroundSelectedColor, outlineProgress)); counterView.setTextColor(textFinalColor); drawable.setColorFilter(new PorterDuffColorFilter(textFinalColor, PorterDuff.Mode.MULTIPLY)); + + if (outlineProgress == 1f) { + overlaySelectorView.setBackground(Theme.createSimpleSelectorRoundRectDrawable((int) radius, Color.TRANSPARENT, ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_chat_inReactionButtonTextSelected), (int) (0.3f * 255)))); + } else if (outlineProgress == 0) { + overlaySelectorView.setBackground(Theme.createSimpleSelectorRoundRectDrawable((int) radius, Color.TRANSPARENT, ColorUtils.setAlphaComponent(backgroundSelectedColor, (int) (0.3f * 255)))); + } invalidate(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Reactions/ReactionsEffectOverlay.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Reactions/ReactionsEffectOverlay.java index f456d1c96..211621fd6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Reactions/ReactionsEffectOverlay.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Reactions/ReactionsEffectOverlay.java @@ -1,8 +1,10 @@ package org.telegram.ui.Components.Reactions; +import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.PixelFormat; +import android.view.HapticFeedbackConstants; import android.view.View; import android.view.WindowManager; import android.widget.FrameLayout; @@ -21,19 +23,28 @@ import org.telegram.ui.Components.ReactionsContainerLayout; public class ReactionsEffectOverlay { + public final static int LONG_ANIMATION = 0; + public final static int SHORT_ANIMATION = 1; + public final static int ONLY_MOVE_ANIMATION = 2; + + private final int animationType; + @SuppressLint("StaticFieldLeak") public static ReactionsEffectOverlay currentOverlay; + public static ReactionsEffectOverlay currentShortOverlay; private final AnimationView effectImageView; private final AnimationView emojiImageView; private final AnimationView emojiStaticImageView; private final FrameLayout container; + private final BaseFragment fragment; + private final int currentAccount; boolean animateIn; float animateInProgress; float animateOutProgress; FrameLayout windowView; BackupImageView backupImageView; - private static int unicPrefix; + private static int uniqPrefix; int[] loc = new int[2]; private WindowManager windowManager; @@ -47,12 +58,17 @@ public class ReactionsEffectOverlay { private boolean started; private ReactionsContainerLayout.ReactionHolderView holderView = null; private boolean wasScrolled; + private ChatMessageCell cell; + private boolean finished; - - private ReactionsEffectOverlay(Context context, BaseFragment fragment, ReactionsContainerLayout reactionsLayout, ChatMessageCell cell, float x, float y, String reaction, int currentAccount) { + private ReactionsEffectOverlay(Context context, BaseFragment fragment, ReactionsContainerLayout reactionsLayout, ChatMessageCell cell, float x, float y, String reaction, int currentAccount, int animationType) { + this.fragment = fragment; this.messageId = cell.getMessageObject().getId(); this.groupId = cell.getMessageObject().getGroupId(); this.reaction = reaction; + this.animationType = animationType; + this.currentAccount = currentAccount; + this.cell = cell; ReactionsLayoutInBubble.ReactionButton reactionButton = cell.getReactionButton(reaction); float fromX, fromY, fromHeight, fromWidth; ChatActivity chatActivity = (fragment instanceof ChatActivity) ? (ChatActivity) fragment : null; @@ -66,10 +82,10 @@ public class ReactionsEffectOverlay { } boolean fromHolder = holderView != null || (x != 0 && y != 0); if (holderView != null) { - reactionsLayout.getLocationOnScreen(loc); - fromX = loc[0] + holderView.getX() + holderView.backupImageView.getX() + AndroidUtilities.dp(16); - fromY = loc[1] + holderView.getY() + holderView.backupImageView.getY() + AndroidUtilities.dp(16); - fromHeight = holderView.backupImageView.getWidth(); + holderView.getLocationOnScreen(loc); + fromX = loc[0] + holderView.backupImageView.getX(); + fromY = loc[1] + holderView.backupImageView.getY(); + fromHeight = holderView.backupImageView.getWidth() * holderView.getScaleX(); } else if (reactionButton != null) { cell.getLocationInWindow(loc); fromX = loc[0] + cell.reactionsLayoutInBubble.x + reactionButton.x + reactionButton.imageReceiver.getImageX(); @@ -84,7 +100,14 @@ public class ReactionsEffectOverlay { fromWidth = 0; } - int size = Math.round(Math.min(AndroidUtilities.dp(350), Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y)) * 0.8f); + int size; + if (animationType == ONLY_MOVE_ANIMATION) { + size = AndroidUtilities.dp(34); + } else if (animationType == SHORT_ANIMATION) { + size = AndroidUtilities.dp(80); + } else { + size = Math.round(Math.min(AndroidUtilities.dp(350), Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y)) * 0.8f); + } int sizeForFilter = (int) (2f * size / AndroidUtilities.density); int emojiSize = size >> 1; int emojiSizeForFilter = sizeForFilter >> 1; @@ -125,6 +148,7 @@ public class ReactionsEffectOverlay { } else { if (holderView != null) { holderView.backupImageView.setAlpha(0); + holderView.pressedBackupImageView.setAlpha(0); } } ChatMessageCell drawingCell; @@ -133,7 +157,13 @@ public class ReactionsEffectOverlay { } else { drawingCell = cell; } - float toX, toY; + float toX, toY, toH; + + if (cell.getMessageObject().shouldDrawReactionsInLayout()) { + toH = AndroidUtilities.dp(20); + } else { + toH = AndroidUtilities.dp(14); + } if (drawingCell != null) { cell.getLocationInWindow(loc); @@ -147,31 +177,40 @@ public class ReactionsEffectOverlay { if (chatActivity != null) { toY += chatActivity.drawingChatLisViewYoffset; } - + if (drawingCell.drawPinnedBottom && !drawingCell.shouldDrawTimeOnMedia()) { + toY += AndroidUtilities.dp(2); + } lastDrawnToX = toX; lastDrawnToY = toY; } else { toX = lastDrawnToX; toY = lastDrawnToY; } - float previewX = toX - emojiSize / 2f; - float previewY = toY - emojiSize / 2f; + if (fragment.getParentActivity() != null && fragment.getFragmentView().getParent() != null && fragment.getFragmentView().getVisibility() == View.VISIBLE && fragment.getFragmentView() != null) { fragment.getFragmentView().getLocationOnScreen(loc); setAlpha(((View) fragment.getFragmentView().getParent()).getAlpha()); } else { return; } - if (previewX < loc[0]) { - previewX = loc[0]; - } - if (previewX + emojiSize > loc[0] + getMeasuredWidth()) { - previewX = loc[0] + getMeasuredWidth() - emojiSize; + float previewX = toX - (emojiSize - toH) / 2f; + float previewY = toY - (emojiSize - toH) / 2f; + + if (animationType != SHORT_ANIMATION) { + if (previewX < loc[0]) { + previewX = loc[0]; + } + if (previewX + emojiSize > loc[0] + getMeasuredWidth()) { + previewX = loc[0] + getMeasuredWidth() - emojiSize; + } } float animateInProgressX, animateInProgressY; float animateOutProgress = CubicBezierInterpolator.DEFAULT.getInterpolation(ReactionsEffectOverlay.this.animateOutProgress); - if (fromHolder) { + if (animationType == ONLY_MOVE_ANIMATION) { + animateInProgressX = CubicBezierInterpolator.EASE_OUT_QUINT.getInterpolation(animateOutProgress); + animateInProgressY = CubicBezierInterpolator.DEFAULT.getInterpolation(animateOutProgress); + } else if (fromHolder) { animateInProgressX = CubicBezierInterpolator.EASE_OUT_QUINT.getInterpolation(animateInProgress); animateInProgressY = CubicBezierInterpolator.DEFAULT.getInterpolation(animateInProgress); } else { @@ -180,31 +219,41 @@ public class ReactionsEffectOverlay { float scale = animateInProgressX + (1f - animateInProgressX) * fromScale; - float toScale; - if (cell.getMessageObject().shouldDrawReactionsInLayout()) { - toScale = AndroidUtilities.dp(20) / (float) emojiSize; + float toScale = toH / (float) emojiSize; + + float x; + float y; + if (animationType == SHORT_ANIMATION) { + x = previewX; + y = previewY; + scale = 1f; } else { - toScale = AndroidUtilities.dp(14) / (float) emojiSize; + x = fromX * (1f - animateInProgressX) + previewX * animateInProgressX; + y = fromY * (1f - animateInProgressY) + previewY * animateInProgressY; } - float x = fromX * (1f - animateInProgressX) + previewX * animateInProgressX; - float y = fromY * (1f - animateInProgressY) + previewY * animateInProgressY; - effectImageView.setTranslationX(x); effectImageView.setTranslationY(y); effectImageView.setAlpha((1f - animateOutProgress)); effectImageView.setScaleX(scale); effectImageView.setScaleY(scale); - if (animateOutProgress != 0) { - scale = scale * (1f - animateOutProgress) + toScale * animateOutProgress; - x = x * (1f - animateOutProgress) + toX * animateOutProgress; - y = y * (1f - animateOutProgress) + toY * animateOutProgress; + if (animationType == ONLY_MOVE_ANIMATION) { + scale = fromScale * (1f - animateInProgressX) + toScale * animateInProgressX; + x = fromX * (1f - animateInProgressX) + toX * animateInProgressX; + y = fromY * (1f - animateInProgressY) + toY * animateInProgressY; + } else { + if (animateOutProgress != 0) { + scale = scale * (1f - animateOutProgress) + toScale * animateOutProgress; + x = x * (1f - animateOutProgress) + toX * animateOutProgress; + y = y * (1f - animateOutProgress) + toY * animateOutProgress; + } } - - emojiStaticImageView.setAlpha(animateOutProgress > 0.7f ? (animateOutProgress - 0.7f) / 0.3f : 0); + if (animationType != SHORT_ANIMATION) { + emojiStaticImageView.setAlpha(animateOutProgress > 0.7f ? (animateOutProgress - 0.7f) / 0.3f : 0); + } //emojiImageView.setAlpha(animateOutProgress < 0.5f ? 1f - (animateOutProgress / 0.5f) : 0f); container.setTranslationX(x); container.setTranslationY(y); @@ -214,7 +263,7 @@ public class ReactionsEffectOverlay { super.dispatchDraw(canvas); - if (emojiImageView.wasPlaying && animateInProgress != 1f) { + if ((animationType == SHORT_ANIMATION || emojiImageView.wasPlaying) && animateInProgress != 1f) { if (fromHolder) { animateInProgress += 16f / 350f; } else { @@ -225,12 +274,28 @@ public class ReactionsEffectOverlay { } } - if (wasScrolled || (emojiImageView.wasPlaying && emojiImageView.getImageReceiver().getLottieAnimation() != null && !emojiImageView.getImageReceiver().getLottieAnimation().isRunning())) { + if (animationType == ONLY_MOVE_ANIMATION || (wasScrolled && animationType == LONG_ANIMATION) || (animationType != SHORT_ANIMATION && emojiImageView.wasPlaying && emojiImageView.getImageReceiver().getLottieAnimation() != null && !emojiImageView.getImageReceiver().getLottieAnimation().isRunning()) || + (animationType == SHORT_ANIMATION && effectImageView.wasPlaying && effectImageView.getImageReceiver().getLottieAnimation() != null && !effectImageView.getImageReceiver().getLottieAnimation().isRunning())) { if (ReactionsEffectOverlay.this.animateOutProgress != 1f) { - ReactionsEffectOverlay.this.animateOutProgress += 16f / 220f; - if (ReactionsEffectOverlay.this.animateOutProgress > 1f) { + if (animationType == SHORT_ANIMATION) { ReactionsEffectOverlay.this.animateOutProgress = 1f; - currentOverlay = null; + } else { + float duration = animationType == ONLY_MOVE_ANIMATION ? 350f : 220f; + ReactionsEffectOverlay.this.animateOutProgress += 16f / duration; + } + if (ReactionsEffectOverlay.this.animateOutProgress > 0.7f && !finished) { + startShortAnimation(); + } + if (ReactionsEffectOverlay.this.animateOutProgress >= 1f) { + if (animationType == LONG_ANIMATION || animationType == ONLY_MOVE_ANIMATION) { + cell.reactionsLayoutInBubble.animateReaction(reaction); + } + ReactionsEffectOverlay.this.animateOutProgress = 1f; + if (animationType == SHORT_ANIMATION) { + currentShortOverlay = null; + } else { + currentOverlay = null; + } cell.invalidate(); if (cell.getCurrentMessagesGroup() != null && cell.getParent() != null) { ((View) cell.getParent()).invalidate(); @@ -254,41 +319,59 @@ public class ReactionsEffectOverlay { emojiStaticImageView = new AnimationView(context); TLRPC.TL_availableReaction availableReaction = MediaDataController.getInstance(currentAccount).getReactionsMap().get(reaction); if (availableReaction != null) { - TLRPC.Document document = availableReaction.effect_animation; - effectImageView.getImageReceiver().setUniqKeyPrefix((unicPrefix++) + "_" + cell.getMessageObject().getId() + "_"); - effectImageView.setImage(ImageLocation.getForDocument(document), sizeForFilter + "_" + sizeForFilter + "_pcache", null, null, 0, null); + if (animationType != ONLY_MOVE_ANIMATION) { + TLRPC.Document document = animationType == SHORT_ANIMATION ? availableReaction.around_animation : availableReaction.effect_animation; + effectImageView.getImageReceiver().setUniqKeyPrefix((uniqPrefix++) + "_" + cell.getMessageObject().getId() + "_"); + effectImageView.setImage(ImageLocation.getForDocument(document), sizeForFilter + "_" + sizeForFilter + "_pcache", null, null, 0, null); - effectImageView.getImageReceiver().setAutoRepeat(0); - effectImageView.getImageReceiver().setAllowStartAnimation(false); + effectImageView.getImageReceiver().setAutoRepeat(0); + effectImageView.getImageReceiver().setAllowStartAnimation(false); - if (effectImageView.getImageReceiver().getLottieAnimation() != null) { - effectImageView.getImageReceiver().getLottieAnimation().setCurrentFrame(0, false); - effectImageView.getImageReceiver().getLottieAnimation().start(); + if (effectImageView.getImageReceiver().getLottieAnimation() != null) { + effectImageView.getImageReceiver().getLottieAnimation().setCurrentFrame(0, false); + effectImageView.getImageReceiver().getLottieAnimation().start(); + } } - document = availableReaction.activate_animation; - emojiImageView.getImageReceiver().setUniqKeyPrefix((unicPrefix++) + "_" + cell.getMessageObject().getId() + "_"); - emojiImageView.setImage(ImageLocation.getForDocument(document), emojiSizeForFilter + "_" + emojiSizeForFilter, null, null, 0, null); + if (animationType == ONLY_MOVE_ANIMATION) { + TLRPC.Document document = availableReaction.appear_animation; + emojiImageView.getImageReceiver().setUniqKeyPrefix((uniqPrefix++) + "_" + cell.getMessageObject().getId() + "_"); + emojiImageView.setImage(ImageLocation.getForDocument(document), emojiSizeForFilter + "_" + emojiSizeForFilter, null, null, 0, null); + } else if (animationType == LONG_ANIMATION) { + TLRPC.Document document = availableReaction.activate_animation; + emojiImageView.getImageReceiver().setUniqKeyPrefix((uniqPrefix++) + "_" + cell.getMessageObject().getId() + "_"); + emojiImageView.setImage(ImageLocation.getForDocument(document), emojiSizeForFilter + "_" + emojiSizeForFilter, null, null, 0, null); + } emojiImageView.getImageReceiver().setAutoRepeat(0); emojiImageView.getImageReceiver().setAllowStartAnimation(false); if (emojiImageView.getImageReceiver().getLottieAnimation() != null) { - emojiImageView.getImageReceiver().getLottieAnimation().setCurrentFrame(0, false); - emojiImageView.getImageReceiver().getLottieAnimation().start(); + if (animationType == ONLY_MOVE_ANIMATION) { + emojiImageView.getImageReceiver().getLottieAnimation().setCurrentFrame(emojiImageView.getImageReceiver().getLottieAnimation().getFramesCount() - 1, false); + } else { + emojiImageView.getImageReceiver().getLottieAnimation().setCurrentFrame(0, false); + emojiImageView.getImageReceiver().getLottieAnimation().start(); + } } int topOffset = (size - emojiSize) >> 1; - int leftOffset = size - emojiSize; + int leftOffset; + if (animationType == SHORT_ANIMATION) { + leftOffset = topOffset; + } else { + leftOffset = size - emojiSize; + } container.addView(emojiImageView); emojiImageView.getLayoutParams().width = emojiSize; emojiImageView.getLayoutParams().height = emojiSize; ((FrameLayout.LayoutParams) emojiImageView.getLayoutParams()).topMargin = topOffset; ((FrameLayout.LayoutParams) emojiImageView.getLayoutParams()).leftMargin = leftOffset; - emojiStaticImageView.getImageReceiver().setImage(ImageLocation.getForDocument(availableReaction.static_icon), "40_40", null, "webp", availableReaction, 1); - + if (animationType != SHORT_ANIMATION) { + emojiStaticImageView.getImageReceiver().setImage(ImageLocation.getForDocument(availableReaction.static_icon), "40_40", null, "webp", availableReaction, 1); + } container.addView(emojiStaticImageView); emojiStaticImageView.getLayoutParams().width = emojiSize; emojiStaticImageView.getLayoutParams().height = emojiSize; @@ -311,12 +394,14 @@ public class ReactionsEffectOverlay { ((FrameLayout.LayoutParams) effectImageView.getLayoutParams()).topMargin = -topOffset; ((FrameLayout.LayoutParams) effectImageView.getLayoutParams()).leftMargin = -leftOffset; + // if (!SHORT_ANIMATION) { container.setPivotX(leftOffset); container.setPivotY(topOffset); + //} } } - public static void show(BaseFragment baseFragment, ReactionsContainerLayout reactionsLayout, ChatMessageCell cell, float x, float y, String reaction, int currentAccount) { + public static void show(BaseFragment baseFragment, ReactionsContainerLayout reactionsLayout, ChatMessageCell cell, float x, float y, String reaction, int currentAccount, int animationType) { if (cell == null) { return; } @@ -324,8 +409,16 @@ public class ReactionsEffectOverlay { if (!animationEnabled) { return; } - ReactionsEffectOverlay reactionsEffectOverlay = new ReactionsEffectOverlay(baseFragment.getParentActivity(), baseFragment, reactionsLayout, cell, x, y, reaction, currentAccount); - currentOverlay = reactionsEffectOverlay; + if (animationType == ONLY_MOVE_ANIMATION || animationType == LONG_ANIMATION) { + show(baseFragment, null, cell, 0, 0, reaction, currentAccount, SHORT_ANIMATION); + } + + ReactionsEffectOverlay reactionsEffectOverlay = new ReactionsEffectOverlay(baseFragment.getParentActivity(), baseFragment, reactionsLayout, cell, x, y, reaction, currentAccount, animationType); + if (animationType == SHORT_ANIMATION) { + currentShortOverlay = reactionsEffectOverlay; + } else { + currentOverlay = reactionsEffectOverlay; + } WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); lp.width = lp.height = WindowManager.LayoutParams.MATCH_PARENT; @@ -339,31 +432,50 @@ public class ReactionsEffectOverlay { if (cell.getCurrentMessagesGroup() != null && cell.getParent() != null) { ((View) cell.getParent()).invalidate(); } + } public static void startAnimation() { if (currentOverlay != null) { currentOverlay.started = true; + } else { + startShortAnimation(); + if (currentShortOverlay != null) { + currentShortOverlay.cell.reactionsLayoutInBubble.animateReaction(currentShortOverlay.reaction); + } + } + } + + public static void startShortAnimation() { + if (currentShortOverlay != null && !currentShortOverlay.started) { + currentShortOverlay.started = true; + if (currentShortOverlay.animationType == SHORT_ANIMATION) { + currentShortOverlay.cell.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP); + } } } public static void removeCurrent(boolean instant) { - if (currentOverlay != null) { - if (instant) { - try { - currentOverlay.windowManager.removeView(currentOverlay.windowView); - } catch (Exception e) { + for (int i = 0; i < 2; i++) { + ReactionsEffectOverlay overlay = i == 0 ? currentOverlay : currentShortOverlay; + if (overlay != null) { + if (instant) { + try { + overlay.windowManager.removeView(overlay.windowView); + } catch (Exception e) { + } + } else { + overlay.dismissed = true; } - } else { - currentOverlay.dismissed = true; } } + currentShortOverlay = null; currentOverlay = null; } public static boolean isPlaying(int messageId, long groupId, String reaction) { - if (currentOverlay != null) { + if (currentOverlay != null && (currentOverlay.animationType == ONLY_MOVE_ANIMATION || currentOverlay.animationType == LONG_ANIMATION)) { return ((currentOverlay.groupId != 0 && groupId == currentOverlay.groupId) || messageId == currentOverlay.messageId) && currentOverlay.reaction.equals(reaction); } return false; @@ -384,8 +496,12 @@ public class ReactionsEffectOverlay { wasPlaying = true; } if (!wasPlaying && getImageReceiver().getLottieAnimation() != null && !getImageReceiver().getLottieAnimation().isRunning()) { - getImageReceiver().getLottieAnimation().setCurrentFrame(0, false); - getImageReceiver().getLottieAnimation().start(); + if (animationType == ONLY_MOVE_ANIMATION) { + getImageReceiver().getLottieAnimation().setCurrentFrame(getImageReceiver().getLottieAnimation().getFramesCount() - 1, false); + } else { + getImageReceiver().getLottieAnimation().setCurrentFrame(0, false); + getImageReceiver().getLottieAnimation().start(); + } } super.onDraw(canvas); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Reactions/ReactionsLayoutInBubble.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Reactions/ReactionsLayoutInBubble.java index 39ac444c4..06bb0f057 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Reactions/ReactionsLayoutInBubble.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Reactions/ReactionsLayoutInBubble.java @@ -51,6 +51,7 @@ public class ReactionsLayoutInBubble { private boolean wasDrawn; private boolean animateMove; private boolean animateWidth; + private boolean animateHeight; public int positionOffsetY; int currentAccount; public int height; @@ -72,8 +73,12 @@ public class ReactionsLayoutInBubble { int availableWidth; private int lastDrawnWidth; boolean attached; + private static int animationUniq; private final static ButtonsComparator comparator = new ButtonsComparator(); + HashMap animatedReactions = new HashMap<>(); + private int lastDrawTotalHeight; + private int animateFromTotalHeight; public ReactionsLayoutInBubble(ChatMessageCell parentView) { this.parentView = parentView; @@ -151,6 +156,7 @@ public class ReactionsLayoutInBubble { height = 0; width = 0; positionOffsetY = 0; + totalHeight = 0; if (isEmpty) { return; } @@ -192,7 +198,6 @@ public class ReactionsLayoutInBubble { lastLineX = currentX; width = maxWidth; height = currentY + (reactionButtons.size() == 0 ? 0 : AndroidUtilities.dp(26)); - drawServiceShaderBackground = false; } @@ -255,6 +260,7 @@ public class ReactionsLayoutInBubble { lastDrawnX = x; lastDrawnY = y; lastDrawnWidth = width; + lastDrawTotalHeight = totalHeight; } public boolean animateChange() { @@ -325,6 +331,12 @@ public class ReactionsLayoutInBubble { changed = true; } + if (lastDrawTotalHeight != totalHeight) { + animateHeight = true; + animateFromTotalHeight = lastDrawTotalHeight; + changed = true; + } + return changed; } @@ -335,6 +347,7 @@ public class ReactionsLayoutInBubble { outButtons.clear(); animateMove = false; animateWidth = false; + animateHeight = false; for (int i = 0; i < reactionButtons.size(); i++) { reactionButtons.get(i).animationType = 0; } @@ -507,7 +520,28 @@ public class ReactionsLayoutInBubble { private void drawImage(Canvas canvas) { if (drawImage && ((realCount > 1 || !ReactionsEffectOverlay.isPlaying(messageObject.getId(), messageObject.getGroupId(), reaction)) || !isSelected)) { - imageReceiver.draw(canvas); + ImageReceiver imageReceiver2 = animatedReactions.get(reaction); + boolean drawStaticImage = true; + if (imageReceiver2 != null) { + imageReceiver2.setAlpha(imageReceiver.getAlpha()); + imageReceiver2.setImageCoords(imageReceiver.getImageX() - imageReceiver.getImageWidth() / 2, imageReceiver.getImageY() - imageReceiver.getImageWidth() / 2, imageReceiver.getImageWidth() * 2, imageReceiver.getImageHeight() * 2); + imageReceiver2.draw(canvas); + if (imageReceiver2.getLottieAnimation() != null && imageReceiver2.getLottieAnimation().hasBitmap()) { + drawStaticImage = false; + } + if (imageReceiver2.getLottieAnimation() != null && !imageReceiver2.getLottieAnimation().isRunning()) { + float alpha = imageReceiver2.getAlpha() - 16f / 200; + if (alpha < 0) { + imageReceiver2.onDetachedFromWindow(); + animatedReactions.remove(reaction); + } else { + imageReceiver2.setAlpha(alpha); + } + } + } + if (drawStaticImage) { + imageReceiver.draw(canvas); + } lastImageDrawn = true; } else { imageReceiver.setAlpha(0); @@ -633,6 +667,13 @@ public class ReactionsLayoutInBubble { return width; } + public float getCurrentTotalHeight(float transitionProgress) { + if (animateHeight) { + return animateFromTotalHeight * (1f - transitionProgress) + totalHeight * transitionProgress; + } + return totalHeight; + } + private static class ButtonsComparator implements Comparator { int currentAccount; @@ -661,5 +702,29 @@ public class ReactionsLayoutInBubble { for (int i = 0; i < reactionButtons.size(); i++) { reactionButtons.get(i).detach(); } + if (!animatedReactions.isEmpty()) { + for (ImageReceiver imageReceiver : animatedReactions.values()) { + imageReceiver.onDetachedFromWindow(); + } + } + animatedReactions.clear(); } + + public void animateReaction(String reaction) { + if (animatedReactions.get(reaction) == null) { + ImageReceiver imageReceiver = new ImageReceiver(); + imageReceiver.setParentView(parentView); + imageReceiver.setUniqKeyPrefix(Integer.toString(animationUniq++)); + if (reaction != null) { + TLRPC.TL_availableReaction r = MediaDataController.getInstance(currentAccount).getReactionsMap().get(reaction); + if (r != null) { + imageReceiver.setImage(ImageLocation.getForDocument(r.center_icon), "40_40_nolimit", null, "tgs", r, 1); + } + } + imageReceiver.setAutoRepeat(0); + imageReceiver.onAttachedToWindow(); + animatedReactions.put(reaction, imageReceiver); + } + } + } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ReactionsContainerLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ReactionsContainerLayout.java index a6b642b4f..53955406a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ReactionsContainerLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ReactionsContainerLayout.java @@ -15,12 +15,14 @@ import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.Rect; import android.graphics.RectF; -import android.graphics.Region; import android.graphics.Shader; import android.graphics.drawable.Drawable; import android.util.Property; import android.view.Gravity; +import android.view.HapticFeedbackConstants; +import android.view.MotionEvent; import android.view.View; +import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.animation.OvershootInterpolator; import android.widget.FrameLayout; @@ -55,7 +57,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio public final static Property TRANSITION_PROGRESS_VALUE = new Property(Float.class, "transitionProgress") { @Override public Float get(ReactionsContainerLayout reactionsContainerLayout) { - return reactionsContainerLayout.transitionProgress ; + return reactionsContainerLayout.transitionProgress; } @Override @@ -86,6 +88,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio private MessageObject messageObject; private int currentAccount; private long waitingLoadingChatId; + ValueAnimator cancelPressedAnimation; private List reactionsList = Collections.emptyList(); @@ -102,6 +105,13 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio private List triggeredReactions = new ArrayList<>(); Theme.ResourcesProvider resourcesProvider; + private String pressedReaction; + private int pressedReactionPosition; + private float pressedProgress; + private float cancelPressedProgress; + private float pressedViewScale; + private float otherViewsScale; + private boolean clicked; public ReactionsContainerLayout(@NonNull Context context, int currentAccount, Theme.ResourcesProvider resourcesProvider) { super(context); @@ -114,7 +124,15 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio shadowPad.left = shadowPad.top = shadowPad.right = shadowPad.bottom = AndroidUtilities.dp(7); shadow.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_chat_messagePanelShadow), PorterDuff.Mode.MULTIPLY)); - recyclerListView = new RecyclerListView(context); + recyclerListView = new RecyclerListView(context) { + @Override + public boolean drawChild(Canvas canvas, View child, long drawingTime) { + if (pressedReaction != null && ((ReactionHolderView) child).currentReaction.equals(pressedReaction)) { + return true; + } + return super.drawChild(canvas, child, drawingTime); + } + }; linearLayoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false); recyclerListView.addItemDecoration(new RecyclerView.ItemDecoration() { @Override @@ -155,11 +173,6 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio return reactionsList.size(); } }); - recyclerListView.setOnItemClickListener((view, position) -> { - ReactionHolderView h = (ReactionHolderView) view; - if (delegate != null) - delegate.onReactionClicked(h, h.currentReaction); - }); recyclerListView.addOnScrollListener(new LeftRightShadowsListener()); recyclerListView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override @@ -177,8 +190,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio int dX1 = ch1X - rX; float s1 = SIDE_SCALE + (1f - Math.min(1, -Math.min(dX1, 0f) / ch1.getWidth())) * sideDiff; if (Float.isNaN(s1)) s1 = 1f; - ch1.setScaleX(s1); - ch1.setScaleY(s1); + ((ReactionHolderView) ch1).sideScale = s1; View ch2 = recyclerView.getChildAt(recyclerView.getChildCount() - 1); ch2.getLocationInWindow(location); @@ -187,14 +199,11 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio int dX2 = rX + recyclerView.getWidth() - (ch2X + ch2.getWidth()); float s2 = SIDE_SCALE + (1f - Math.min(1, -Math.min(dX2, 0f) / ch2.getWidth())) * sideDiff; if (Float.isNaN(s2)) s2 = 1f; - ch2.setScaleX(s2); - ch2.setScaleY(s2); + ((ReactionHolderView) ch2).sideScale = s2; } for (int i = 1; i < recyclerListView.getChildCount() - 1; i++) { View ch = recyclerListView.getChildAt(i); - float sc = 1f; - ch.setScaleX(sc); - ch.setScaleY(sc); + ((ReactionHolderView) ch).sideScale = 1f; } invalidate(); } @@ -238,46 +247,24 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio lastVisibleViewsTmp.clear(); lastVisibleViewsTmp.addAll(lastVisibleViews); lastVisibleViews.clear(); - if (transitionProgress != 0) { - int delay = 0; - for (int i = 0; i < recyclerListView.getChildCount(); i++) { - ReactionHolderView view = (ReactionHolderView) recyclerListView.getChildAt(i); - if (view.backupImageView.getImageReceiver().getLottieAnimation() == null) { - continue; - } - if (view.getX() + view.getMeasuredWidth() / 2f > 0 && view.getX() + view.getMeasuredWidth() / 2f < recyclerListView.getWidth()) { - if (!lastVisibleViewsTmp.contains(view)) { - view.play(delay); - delay += 30; - } - lastVisibleViews.add(view); - } else if (!view.isEnter) { - view.resetAnimation(); + + if (pressedReaction != null) { + if (pressedProgress != 1f) { + pressedProgress += 16f / 2000f; + if (pressedProgress >= 1f) { + pressedProgress = 1f; } + invalidate(); } } float cPr = (Math.max(CLIP_PROGRESS, Math.min(transitionProgress, 1f)) - CLIP_PROGRESS) / (1f - CLIP_PROGRESS); float br = bigCircleRadius * cPr, sr = smallCircleRadius * cPr; - float cx = LocaleController.isRTL ? bigCircleOffset : getWidth() - bigCircleOffset, cy = getHeight() - getPaddingBottom(); - int sPad = AndroidUtilities.dp(3); - shadow.setBounds((int) (cx - br - sPad * cPr), (int) (cy - br - sPad * cPr), (int) (cx + br + sPad * cPr), (int) (cy + br + sPad * cPr)); - shadow.draw(canvas); - canvas.drawCircle(cx, cy, br, bgPaint); - - cx = LocaleController.isRTL ? bigCircleOffset - bigCircleRadius : getWidth() - bigCircleOffset + bigCircleRadius; - cy = getHeight() - smallCircleRadius - sPad; - sPad = -AndroidUtilities.dp(1); - shadow.setBounds((int) (cx - br - sPad * cPr), (int) (cy - br - sPad * cPr), (int) (cx + br + sPad * cPr), (int) (cy + br + sPad * cPr)); - shadow.draw(canvas); - canvas.drawCircle(cx, cy, sr, bgPaint); + pressedViewScale = 1 + 2 * pressedProgress; + otherViewsScale = 1 - 0.15f * pressedProgress; int s = canvas.save(); - mPath.rewind(); - mPath.addCircle(LocaleController.isRTL ? bigCircleOffset : getWidth() - bigCircleOffset, getHeight() - getPaddingBottom(), br, Path.Direction.CW); - canvas.clipPath(mPath, Region.Op.DIFFERENCE); - float pivotX = LocaleController.isRTL ? getWidth() * 0.125f : getWidth() * 0.875f; if (transitionProgress <= SCALE_PROGRESS) { @@ -291,7 +278,8 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio } else { lt = (1f - Math.max(CLIP_PROGRESS, transitionProgress)); } - rect.set(getPaddingLeft() + (getWidth() - getPaddingRight()) * lt, getPaddingTop(), (getWidth() - getPaddingRight()) * rt, getHeight() - getPaddingBottom()); + rect.set(getPaddingLeft() + (getWidth() - getPaddingRight()) * lt, getPaddingTop() + recyclerListView.getMeasuredHeight() * (1f - otherViewsScale), (getWidth() - getPaddingRight()) * rt, getHeight() - getPaddingBottom()); + radius = rect.height() / 2f; shadow.setBounds((int) (getPaddingLeft() + (getWidth() - getPaddingRight() + shadowPad.right) * lt - shadowPad.left), getPaddingTop() - shadowPad.top, (int) ((getWidth() - getPaddingRight() + shadowPad.right) * rt), getHeight() - getPaddingBottom() + shadowPad.bottom); shadow.draw(canvas); canvas.restoreToCount(s); @@ -312,18 +300,31 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio float sc = transitionProgress / SCALE_PROGRESS; canvas.scale(sc, sc, pivotX, getHeight() / 2f); } + + if (transitionProgress != 0) { + int delay = 0; + for (int i = 0; i < recyclerListView.getChildCount(); i++) { + ReactionHolderView view = (ReactionHolderView) recyclerListView.getChildAt(i); + checkPressedProgress(canvas, view); + if (view.backupImageView.getImageReceiver().getLottieAnimation() == null) { + continue; + } + if (view.getX() + view.getMeasuredWidth() / 2f > 0 && view.getX() + view.getMeasuredWidth() / 2f < recyclerListView.getWidth()) { + if (!lastVisibleViewsTmp.contains(view)) { + view.play(delay); + delay += 30; + } + lastVisibleViews.add(view); + } else if (!view.isEnter) { + view.resetAnimation(); + } + } + } + canvas.clipPath(mPath); canvas.translate((LocaleController.isRTL ? -1 : 1) * getWidth() * (1f - transitionProgress), 0); super.dispatchDraw(canvas); - canvas.restoreToCount(s); - s = canvas.save(); - if (LocaleController.isRTL) rt = Math.max(CLIP_PROGRESS, Math.min(1, transitionProgress)); - else lt = 1f - Math.max(CLIP_PROGRESS, Math.min(1f, transitionProgress)); - rect.set(getPaddingLeft() + (getWidth() - getPaddingRight()) * lt, getPaddingTop(), (getWidth() - getPaddingRight()) * rt, getHeight() - getPaddingBottom()); - mPath.rewind(); - mPath.addRoundRect(rect, radius, radius, Path.Direction.CW); - canvas.clipPath(mPath); if (leftShadowPaint != null) { leftShadowPaint.setAlpha((int) (leftAlpha * transitionProgress * 0xFF)); canvas.drawRect(rect, leftShadowPaint); @@ -334,6 +335,73 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio } canvas.restoreToCount(s); + canvas.save(); + canvas.clipRect(0, rect.bottom, getMeasuredWidth(), getMeasuredHeight()); + float cx = LocaleController.isRTL ? bigCircleOffset : getWidth() - bigCircleOffset, cy = getHeight() - getPaddingBottom(); + int sPad = AndroidUtilities.dp(3); + shadow.setBounds((int) (cx - br - sPad * cPr), (int) (cy - br - sPad * cPr), (int) (cx + br + sPad * cPr), (int) (cy + br + sPad * cPr)); + shadow.draw(canvas); + canvas.drawCircle(cx, cy, br, bgPaint); + + cx = LocaleController.isRTL ? bigCircleOffset - bigCircleRadius : getWidth() - bigCircleOffset + bigCircleRadius; + cy = getHeight() - smallCircleRadius - sPad; + sPad = -AndroidUtilities.dp(1); + shadow.setBounds((int) (cx - br - sPad * cPr), (int) (cy - br - sPad * cPr), (int) (cx + br + sPad * cPr), (int) (cy + br + sPad * cPr)); + shadow.draw(canvas); + canvas.drawCircle(cx, cy, sr, bgPaint); + canvas.restore(); + } + + private void checkPressedProgress(Canvas canvas, ReactionHolderView view) { + if (view.currentReaction.reaction.equals(pressedReaction)) { + view.setPivotX(view.getMeasuredWidth() >> 1); + view.setPivotY(view.backupImageView.getY() + view.backupImageView.getMeasuredHeight()); + view.setScaleX(pressedViewScale); + view.setScaleY(pressedViewScale); + + if (!clicked) { + if (cancelPressedAnimation == null) { + view.pressedBackupImageView.setVisibility(View.VISIBLE); + view.pressedBackupImageView.setAlpha(1f); + if (view.pressedBackupImageView.getImageReceiver().hasBitmapImage()) { + view.backupImageView.setAlpha(0f); + } + } else { + view.pressedBackupImageView.setAlpha(1f - cancelPressedProgress); + view.backupImageView.setAlpha(cancelPressedProgress); + } + if (pressedProgress == 1f) { + clicked = true; + delegate.onReactionClicked(view, view.currentReaction, true); + } + } + + canvas.save(); + canvas.translate(recyclerListView.getX() + view.getX(), recyclerListView.getY() + view.getY()); + canvas.scale(view.getScaleX(), view.getScaleY(), view.getPivotX(), view.getPivotY()); + view.draw(canvas); + canvas.restore(); + } else { + int position = recyclerListView.getChildAdapterPosition(view); + float translationX; + translationX = (view.getMeasuredWidth() * (pressedViewScale - 1f)) / 3f - view.getMeasuredWidth() * (1f - otherViewsScale) * (Math.abs(pressedReactionPosition - position) - 1); + + if (position < pressedReactionPosition) { + view.setPivotX(0); + view.setTranslationX(-translationX); + } else { + view.setPivotX(view.getMeasuredWidth()); + view.setTranslationX(translationX); + } + view.setPivotY(view.backupImageView.getY() + view.backupImageView.getMeasuredHeight()); + view.setScaleX(otherViewsScale); + view.setScaleY(otherViewsScale); + view.backupImageView.setScaleX(view.sideScale); + view.backupImageView.setScaleY(view.sideScale); + view.pressedBackupImageView.setVisibility(View.INVISIBLE); + + view.backupImageView.setAlpha(1f); + } } @Override @@ -451,7 +519,9 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio public final class ReactionHolderView extends FrameLayout { public BackupImageView backupImageView; + public BackupImageView pressedBackupImageView; public TLRPC.TL_availableReaction currentReaction; + public float sideScale; private boolean isEnter; Runnable playRunnable = new Runnable() { @@ -460,6 +530,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio if (backupImageView.getImageReceiver().getLottieAnimation() != null && !backupImageView.getImageReceiver().getLottieAnimation().isRunning() && !backupImageView.getImageReceiver().getLottieAnimation().isGeneratingCache()) { backupImageView.getImageReceiver().getLottieAnimation().start(); } + } }; @@ -475,7 +546,16 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio }; backupImageView.getImageReceiver().setAutoRepeat(0); backupImageView.getImageReceiver().setAllowStartLottieAnimation(false); + + pressedBackupImageView = new BackupImageView(context) { + @Override + public void invalidate() { + super.invalidate(); + ReactionsContainerLayout.this.invalidate(); + } + }; addView(backupImageView, LayoutHelper.createFrame(34, 34, Gravity.CENTER)); + addView(pressedBackupImageView, LayoutHelper.createFrame(34, 34, Gravity.CENTER)); } private void setReaction(TLRPC.TL_availableReaction react) { @@ -486,6 +566,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio currentReaction = react; SvgHelper.SvgDrawable svgThumb = DocumentObject.getSvgThumb(currentReaction.activate_animation, Theme.key_windowBackgroundGray, 1.0f); backupImageView.getImageReceiver().setImage(ImageLocation.getForDocument(currentReaction.appear_animation), "60_60_nolimit", null, null, svgThumb, 0, "tgs", react, 0); + pressedBackupImageView.getImageReceiver().setImage(ImageLocation.getForDocument(currentReaction.select_animation), "60_60_nolimit", null, null, svgThumb, 0, "tgs", react, 0); } @Override @@ -532,10 +613,80 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio } isEnter = false; } + + Runnable longPressRunnable = new Runnable() { + @Override + public void run() { + performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); + pressedReactionPosition = reactionsList.indexOf(currentReaction); + pressedReaction = currentReaction.reaction; + ReactionsContainerLayout.this.invalidate(); + } + }; + float pressedX, pressedY; + boolean pressed; + @Override + public boolean onTouchEvent(MotionEvent event) { + if (cancelPressedAnimation != null) { + return false; + } + if (event.getAction() == MotionEvent.ACTION_DOWN) { + pressed = true; + pressedX = event.getX(); + pressedY = event.getY(); + if (sideScale == 1f) { + AndroidUtilities.runOnUIThread(longPressRunnable, ViewConfiguration.getLongPressTimeout()); + } + } + float touchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop() * 2f; + boolean cancelByMove = event.getAction() == MotionEvent.ACTION_MOVE && (Math.abs(pressedX - event.getX()) > touchSlop || Math.abs(pressedY - event.getY()) > touchSlop); + if (cancelByMove || event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) { + if (event.getAction() == MotionEvent.ACTION_UP && pressed && (pressedReaction == null || pressedProgress > 0.8f) && delegate != null) { + clicked = true; + delegate.onReactionClicked(this, currentReaction, pressedProgress > 0.8f); + } + if (!clicked) { + cancelPressed(); + } + + AndroidUtilities.cancelRunOnUIThread(longPressRunnable); + pressed = false; + } + return true; + } + } + + private void cancelPressed() { + if (pressedReaction != null) { + cancelPressedProgress = 0f; + float fromProgress = pressedProgress; + cancelPressedAnimation = ValueAnimator.ofFloat(0, 1f); + cancelPressedAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + cancelPressedProgress = (float) valueAnimator.getAnimatedValue(); + pressedProgress = fromProgress * (1f - cancelPressedProgress); + ReactionsContainerLayout.this.invalidate(); + } + }); + cancelPressedAnimation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + cancelPressedAnimation = null; + pressedProgress = 0; + pressedReaction = null; + ReactionsContainerLayout.this.invalidate(); + } + }); + cancelPressedAnimation.setDuration(150); + cancelPressedAnimation.setInterpolator(CubicBezierInterpolator.DEFAULT); + cancelPressedAnimation.start(); + } } public interface ReactionsContainerDelegate { - void onReactionClicked(View v, TLRPC.TL_availableReaction reaction); + void onReactionClicked(View v, TLRPC.TL_availableReaction reaction, boolean longpress); } @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayout.java index 48b1a6ff1..2c853d896 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayout.java @@ -8,8 +8,16 @@ package org.telegram.ui.Components; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapShader; import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Matrix; +import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Shader; import android.graphics.drawable.BitmapDrawable; @@ -21,12 +29,17 @@ import android.view.View; import android.widget.FrameLayout; import org.telegram.messenger.AndroidUtilities; +import org.telegram.messenger.DispatchQueue; +import org.telegram.messenger.FileLog; import org.telegram.messenger.SharedConfig; +import org.telegram.messenger.Utilities; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarLayout; import org.telegram.ui.ActionBar.AdjustPanLayoutHelper; import org.telegram.ui.ActionBar.Theme; +import java.util.ArrayList; + public class SizeNotifierFrameLayout extends FrameLayout { private Rect rect = new Rect(); @@ -51,6 +64,11 @@ public class SizeNotifierFrameLayout extends FrameLayout { private boolean skipBackgroundDrawing; SnowflakesEffect snowflakesEffect; + public void invalidateBlur() { + invalidateBlur = true; + } + + public interface SizeNotifierFrameLayoutDelegate { void onSizeChanged(int keyboardHeight, boolean isWidthGreater); } @@ -337,7 +355,7 @@ public class SizeNotifierFrameLayout extends FrameLayout { } private void checkSnowflake(Canvas canvas) { - if (SharedConfig.drawSnowInChat || Theme.canStartHolidayAnimation()) { + if (Theme.canStartHolidayAnimation()) { if (snowflakesEffect == null) { snowflakesEffect = new SnowflakesEffect(1); } @@ -366,4 +384,265 @@ public class SizeNotifierFrameLayout extends FrameLayout { protected boolean verifyDrawable(Drawable who) { return who == getBackgroundImage() || super.verifyDrawable(who); } + + + public boolean needBlur; + public boolean blurIsRunning; + public boolean blurGeneratingTuskIsRunning; + BlurBitmap currentBitmap; + public ArrayList unusedBitmaps = new ArrayList<>(10); + public ArrayList blurBehindViews = new ArrayList<>(); + + Matrix matrix = new Matrix(); + public Paint blurPaintTop = new Paint(); + public Paint blurPaintTop2 = new Paint(); + public Paint blurPaintBottom = new Paint(); + public Paint blurPaintBottom2 = new Paint(); + public float blurCrossfadeProgress; + private final float DOWN_SCALE = 12f; + private static DispatchQueue blurQueue; + ValueAnimator blurCrossfade; + public boolean invalidateBlur; + + int count; + int times; + + public void startBlur() { + if (!blurIsRunning || blurGeneratingTuskIsRunning || !invalidateBlur || !SharedConfig.chatBlurEnabled()) { + return; + } + invalidateBlur = false; + blurGeneratingTuskIsRunning = true; + int lastW = getMeasuredWidth(); + int lastH = ActionBar.getCurrentActionBarHeight() + AndroidUtilities.statusBarHeight + AndroidUtilities.dp(100); + + int bitmapH = (int) (lastH / DOWN_SCALE) + 10; + int bitmapW = (int) (lastW / DOWN_SCALE); + + BlurBitmap bitmap = null; + if (unusedBitmaps.size() > 0) { + bitmap = unusedBitmaps.remove(unusedBitmaps.size() - 1); + } + + if (bitmap == null) { + bitmap = new BlurBitmap(); + bitmap.topBitmap = Bitmap.createBitmap(bitmapW, bitmapH, Bitmap.Config.ARGB_8888); + bitmap.topCanvas = new Canvas(bitmap.topBitmap); + + bitmap.bottomBitmap = Bitmap.createBitmap(bitmapW, bitmapH, Bitmap.Config.ARGB_8888); + bitmap.bottomCanvas = new Canvas(bitmap.bottomBitmap); + } + bitmap.topBitmap.eraseColor(Color.TRANSPARENT); + bitmap.bottomBitmap.eraseColor(Color.TRANSPARENT); + + BlurBitmap finalBitmap = bitmap; + + float sX = (float) finalBitmap.topBitmap.getWidth() / (float) lastW; + float sY = (float) (finalBitmap.topBitmap.getHeight() - 10) / (float) lastH; + finalBitmap.topCanvas.save(); + finalBitmap.topCanvas.clipRect(0, 10 * sY, finalBitmap.topBitmap.getWidth(), finalBitmap.topBitmap.getHeight()); + finalBitmap.topCanvas.scale(sX, sY); + finalBitmap.topScaleX = 1f / sX; + finalBitmap.topScaleY = 1f / sY; + + // finalBitmap.pixelFixOffset = getScrollOffset() % (int) DOWN_SCALE; + finalBitmap.topCanvas.translate(0, finalBitmap.pixelFixOffset); + drawList(finalBitmap.topCanvas, true); + finalBitmap.topCanvas.restore(); + + sX = (float) finalBitmap.bottomBitmap.getWidth() / (float) lastW; + sY = (float) (finalBitmap.bottomBitmap.getHeight() - 10) / (float) lastH; + finalBitmap.bottomOffset = getBottomOffset() - lastH; + finalBitmap.bottomCanvas.save(); + finalBitmap.bottomCanvas.clipRect(0, 10 * sY, finalBitmap.bottomBitmap.getWidth(), finalBitmap.bottomBitmap.getHeight()); + finalBitmap.bottomCanvas.scale(sX, sY); + finalBitmap.bottomCanvas.translate(0, 10 - finalBitmap.bottomOffset); + finalBitmap.bottomScaleX = 1f / sX; + finalBitmap.bottomScaleY = 1f / sY; + + drawList(finalBitmap.bottomCanvas, false); + finalBitmap.bottomCanvas.restore(); + + + int radius = (int) (Math.max(6, Math.max(lastH, lastW) / 180) * 2.5f); + if (blurQueue == null) { + blurQueue = new DispatchQueue("BlurQueue"); + } + blurQueue.postRunnable(new Runnable() { + @Override + public void run() { + long time = System.currentTimeMillis(); + Utilities.stackBlurBitmap(finalBitmap.topBitmap, radius); + Utilities.stackBlurBitmap(finalBitmap.bottomBitmap, radius); + times += System.currentTimeMillis() - time; + count++; + if (count > 1000) { + FileLog.d("chat blur generating average time" + (times / (float) count)); + count = 0; + times = 0; + } + + AndroidUtilities.runOnUIThread(() -> { + BlurBitmap oldBitmap = currentBitmap; + blurPaintTop2.setShader(blurPaintTop.getShader()); + blurPaintBottom2.setShader(blurPaintBottom.getShader()); + + BitmapShader bitmapShader = new BitmapShader(finalBitmap.topBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); + blurPaintTop.setShader(bitmapShader); + + bitmapShader = new BitmapShader(finalBitmap.bottomBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); + blurPaintBottom.setShader(bitmapShader); + + blurCrossfadeProgress = 0; + if (blurCrossfade != null) { + blurCrossfade.cancel(); + } + blurCrossfade = ValueAnimator.ofFloat(0, 1f); + blurCrossfade.addUpdateListener(valueAnimator -> { + blurCrossfadeProgress = (float) valueAnimator.getAnimatedValue(); + for (int i = 0; i < blurBehindViews.size(); i++) { + blurBehindViews.get(i).invalidate(); + } + }); + blurCrossfade.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + unusedBitmaps.add(oldBitmap); + super.onAnimationEnd(animation); + } + }); + blurCrossfade.setDuration(50); + blurCrossfade.start(); + for (int i = 0; i < blurBehindViews.size(); i++) { + blurBehindViews.get(i).invalidate(); + } + currentBitmap = finalBitmap; + + AndroidUtilities.runOnUIThread(() -> { + blurGeneratingTuskIsRunning = false; + startBlur(); + }, 32); + + }); + } + }); + } + + protected float getBottomOffset() { + return getMeasuredHeight(); + } + + protected Theme.ResourcesProvider getResourceProvider() { + return null; + } + + protected void drawList(Canvas blurCanvas, boolean top) { + + + } + + protected int getScrollOffset() { + return 0; + } + + @Override + protected void dispatchDraw(Canvas canvas) { + if (blurIsRunning) { + startBlur(); + } + super.dispatchDraw(canvas); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + if (needBlur && !blurIsRunning) { + blurIsRunning = true; + invalidateBlur = true; + } + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + blurPaintTop.setShader(null); + blurPaintTop2.setShader(null); + blurPaintBottom.setShader(null); + blurPaintBottom2.setShader(null); + if (blurCrossfade != null) { + blurCrossfade.cancel(); + } + if (currentBitmap != null) { + currentBitmap.recycle(); + currentBitmap = null; + } + for (int i = 0; i < unusedBitmaps.size(); i++) { + if (unusedBitmaps.get(i) != null) { + unusedBitmaps.get(i).recycle(); + } + } + unusedBitmaps.clear(); + blurIsRunning = false; + } + + public void drawBlur(Canvas canvas, float y, Rect rectTmp, Paint blurScrimPaint, boolean top) { + if (currentBitmap == null || !SharedConfig.chatBlurEnabled()) { + canvas.drawRect(rectTmp, blurScrimPaint); + return; + } + Paint blurPaint = top ? blurPaintTop : blurPaintBottom; + Paint blurPaint2 = top ? blurPaintTop2 : blurPaintBottom2; + + if (blurPaint.getShader() != null) { + matrix.reset(); + if (!top) { + matrix.setTranslate(0, -y + currentBitmap.bottomOffset - currentBitmap.pixelFixOffset); + matrix.preScale(currentBitmap.bottomScaleX, currentBitmap.bottomScaleY); + } else { + matrix.setTranslate(0, -y); + matrix.preScale(currentBitmap.topScaleX, currentBitmap.topScaleY); + } + + + blurPaint.getShader().setLocalMatrix(matrix); + if (blurPaint2.getShader() != null) { + blurPaint2.getShader().setLocalMatrix(matrix); + } + } + if (blurCrossfadeProgress != 1f && blurPaint2.getShader() != null) { + canvas.drawRect(rectTmp, blurScrimPaint); + canvas.drawRect(rectTmp, blurPaint2); + canvas.saveLayerAlpha(rectTmp.left, rectTmp.top, rectTmp.right, rectTmp.bottom, (int) (blurCrossfadeProgress * 255), Canvas.ALL_SAVE_FLAG); +// blurScrimPaint.setAlpha((int) (blurCrossfadeProgress * 255)); +// blurPaint.setAlpha((int) (blurCrossfadeProgress * 255)); + canvas.drawRect(rectTmp, blurScrimPaint); + canvas.drawRect(rectTmp, blurPaint); + canvas.restore(); + } else { + canvas.drawRect(rectTmp, blurScrimPaint); + canvas.drawRect(rectTmp, blurPaint); + } + + + blurScrimPaint.setAlpha(Color.alpha(Theme.getColor(Theme.key_chat_BlurAlpha))); + canvas.drawRect(rectTmp, blurScrimPaint); + } + + private static class BlurBitmap { + int pixelFixOffset; + Canvas topCanvas; + Bitmap topBitmap; + float topScaleX, topScaleY; + float bottomScaleX, bottomScaleY; + float bottomOffset; + + Canvas bottomCanvas; + Bitmap bottomBitmap; + + public void recycle() { + topBitmap.recycle(); + bottomBitmap.recycle(); + } + } + } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/TranslateAlert.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/TranslateAlert.java index b0b58a49f..731a628d2 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/TranslateAlert.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/TranslateAlert.java @@ -78,8 +78,10 @@ import org.telegram.messenger.Emoji; import org.telegram.messenger.FileLog; import org.telegram.messenger.LocaleController; import org.telegram.messenger.MessageObject; +import org.telegram.messenger.MessagesController; import org.telegram.messenger.R; import org.telegram.messenger.browser.Browser; +import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.TLRPC; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.BackDrawable; @@ -87,6 +89,7 @@ import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ActionBar.BottomSheet; import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ChatActivity; +import org.telegram.ui.Components.Paint.Input; import java.io.BufferedReader; import java.io.IOException; @@ -269,8 +272,15 @@ public class TranslateAlert extends Dialog { private boolean noforwards; private OnLinkPress onLinkPress = null; public TranslateAlert(BaseFragment fragment, Context context, String fromLanguage, String toLanguage, CharSequence text, boolean noforwards, OnLinkPress onLinkPress) { + this(fragment, context, -1, null, -1, fromLanguage, toLanguage, text, noforwards, onLinkPress); + } + public TranslateAlert(BaseFragment fragment, Context context, int currentAccount, TLRPC.InputPeer peer, int msgId, String fromLanguage, String toLanguage, CharSequence text, boolean noforwards, OnLinkPress onLinkPress) { super(context, R.style.TransparentDialog); + if (peer != null) { + translateText(currentAccount, peer, msgId, fromLanguage != null && fromLanguage.equals("und") ? null : fromLanguage, toLanguage); + } + this.onLinkPress = onLinkPress; this.noforwards = noforwards; this.fragment = fragment; @@ -1345,7 +1355,39 @@ public class TranslateAlert extends Dialog { } }.start(); } + private static void translateText(int currentAccount, TLRPC.InputPeer peer, int msg_id, String from_lang, String to_lang) { + TLRPC.TL_messages_translateText req = new TLRPC.TL_messages_translateText(); + req.peer = peer; + req.msg_id = msg_id; + req.flags |= 1; + + if (from_lang != null) { + req.from_lang = from_lang; + req.flags |= 4; + } + + req.to_lang = to_lang; + + try { + ConnectionsManager.getInstance(currentAccount).sendRequest(req, (error, res) -> { + // TODO + }); + } catch (Exception e) { + FileLog.e(e); + } + } + + public static void showAlert(Context context, BaseFragment fragment, int currentAccount, TLRPC.InputPeer peer, int msgId, String fromLanguage, String toLanguage, CharSequence text, boolean noforwards, OnLinkPress onLinkPress) { + TranslateAlert alert = new TranslateAlert(fragment, context, currentAccount, peer, msgId, fromLanguage, toLanguage, text, noforwards, onLinkPress); + if (fragment != null) { + if (fragment.getParentActivity() != null) { + fragment.showDialog(alert); + } + } else { + alert.show(); + } + } public static void showAlert(Context context, BaseFragment fragment, String fromLanguage, String toLanguage, CharSequence text, boolean noforwards, OnLinkPress onLinkPress) { TranslateAlert alert = new TranslateAlert(fragment, context, fromLanguage, toLanguage, text, noforwards, onLinkPress); if (fragment != null) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/UndoView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/UndoView.java index fa119c202..0a604dc57 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/UndoView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/UndoView.java @@ -12,6 +12,7 @@ import android.graphics.PorterDuffColorFilter; import android.graphics.RectF; import android.graphics.Typeface; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.SystemClock; import android.text.Layout; import android.text.Selection; @@ -431,6 +432,9 @@ public class UndoView extends FrameLayout { } public void showWithAction(ArrayList dialogIds, int action, Object infoObject, Object infoObject2, Runnable actionRunnable, Runnable cancelRunnable) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && currentAction == ACTION_MESSAGE_COPIED || currentAction == ACTION_USERNAME_COPIED || currentAction == ACTION_HASHTAG_COPIED || currentAction == ACTION_TEXT_COPIED || currentAction == ACTION_LINK_COPIED || currentAction == ACTION_PHONE_COPIED || currentAction == ACTION_EMAIL_COPIED || currentAction == ACTION_VOIP_LINK_COPIED) { + return; + } if (currentActionRunnable != null) { currentActionRunnable.run(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java index cbcfcda2f..4d0d1f5d6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java @@ -564,7 +564,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } public void setCaption(CharSequence caption) { - hasCaptionForAllMedia = !TextUtils.isEmpty(caption); + hasCaptionForAllMedia = true;//!TextUtils.isEmpty(caption); captionForAllMedia = caption; } @@ -1903,6 +1903,11 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat public boolean validateGroupId(long groupId) { return true; } + + @Override + public void onApplyCaption(CharSequence caption) { + + } } public interface PhotoViewerProvider { @@ -1939,6 +1944,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat void onCaptionChanged(CharSequence caption); boolean closeKeyboard(); boolean validateGroupId(long groupId); + void onApplyCaption(CharSequence caption); } private class FrameLayoutDrawer extends SizeNotifierFrameLayoutPhoto { @@ -6755,6 +6761,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (captionEditText.getFieldCharSequence().length() != 0 && !placeProvider.isPhotoChecked(currentIndex)) { setPhotoChecked(); } + if (placeProvider != null) { + placeProvider.onApplyCaption(caption); + } setCurrentCaption(null, result[0], false); } captionEditText.setTag(null); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java index cdc368087..45314246d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java @@ -14,7 +14,6 @@ import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; -import android.app.Activity; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; @@ -113,7 +112,6 @@ import org.telegram.tgnet.SerializedData; import org.telegram.tgnet.TLObject; import org.telegram.tgnet.TLRPC; import org.telegram.ui.ActionBar.ActionBar; -import org.telegram.ui.ActionBar.ActionBarLayout; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; import org.telegram.ui.ActionBar.AlertDialog; @@ -2729,7 +2727,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. Build.VERSION.SDK_INT >= 21 ? (SharedConfig.noStatusBar ? "Show status bar background" : "Hide status bar background") : null, BuildVars.DEBUG_PRIVATE_VERSION ? "Clean app update" : null, BuildVars.DEBUG_PRIVATE_VERSION ? "Reset suggestions" : null, - SharedConfig.drawSnowInChat ? "Hide snow in chat" : "Show snow in chat" + SharedConfig.canBlurChat() ? (SharedConfig.chatBlur ? "Disable blur in chat" : "Enable blur in chat") : null }; builder.setItems(items, (dialog, which) -> { if (which == 0) { @@ -2801,7 +2799,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. suggestions.add("VALIDATE_PASSWORD"); getNotificationCenter().postNotificationName(NotificationCenter.newSuggestionsAvailable); } else if (which == 17) { - SharedConfig.toggleDrawSnowInChat(); + SharedConfig.toggleDebugChatBlur(); } }); builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/VoIPFragment.java b/TMessagesProj/src/main/java/org/telegram/ui/VoIPFragment.java index f582e0306..b2537a1c0 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/VoIPFragment.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/VoIPFragment.java @@ -1698,7 +1698,7 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent buf.write(service.getGA()); auth_key = buf.toByteArray(); } catch (Exception checkedExceptionsAreBad) { - FileLog.e(checkedExceptionsAreBad); + FileLog.e(checkedExceptionsAreBad, false); } if (auth_key == null) { return; diff --git a/TMessagesProj/src/main/res/values/strings.xml b/TMessagesProj/src/main/res/values/strings.xml index c00fb44a4..7d9271dbc 100644 --- a/TMessagesProj/src/main/res/values/strings.xml +++ b/TMessagesProj/src/main/res/values/strings.xml @@ -4937,7 +4937,6 @@ Dino Quick Reactions Double tap this message for a quck reaction. - Snow in chat un1 changed chat reactions \nfrom: %1$s \nto: %2$s Nobody viewed QR Code