diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java index 63052129f..c490cee4d 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java @@ -24,8 +24,8 @@ 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 = 3098; - public static String BUILD_VERSION_STRING = "9.4.0"; + public static int BUILD_VERSION = 3102; + public static String BUILD_VERSION_STRING = "9.4.1"; public static int APP_ID = 4; public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103"; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/CacheByChatsController.java b/TMessagesProj/src/main/java/org/telegram/messenger/CacheByChatsController.java index 537e1456a..a74be4ff6 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/CacheByChatsController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/CacheByChatsController.java @@ -125,12 +125,12 @@ public class CacheByChatsController { SharedConfig.getPreferences().edit().putInt("keep_media_type_" + type, keepMedia).apply(); } - public void lookupFiles(ArrayList keepMediaFiles) { + public void lookupFiles(ArrayList keepMediaFiles) { LongSparseArray> filesByDialogId = FileLoader.getInstance(currentAccount).getFileDatabase().lookupFiles(keepMediaFiles); LongSparseArray exceptionsByType = getKeepMediaExceptionsByDialogs(); for (int i = 0; i < filesByDialogId.size(); i++) { long dialogId = filesByDialogId.keyAt(i); - ArrayList files = filesByDialogId.valueAt(i); + ArrayList files = filesByDialogId.valueAt(i); int type; if (dialogId >= 0) { type = KEEP_MEDIA_TYPE_USER; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FilePathDatabase.java b/TMessagesProj/src/main/java/org/telegram/messenger/FilePathDatabase.java index 929c237d3..67318700f 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FilePathDatabase.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FilePathDatabase.java @@ -399,7 +399,7 @@ public class FilePathDatabase { }); } - public LongSparseArray> lookupFiles(ArrayList keepMediaFiles) { + public LongSparseArray> lookupFiles(ArrayList keepMediaFiles) { CountDownLatch syncLatch = new CountDownLatch(1); LongSparseArray> filesByDialogId = new LongSparseArray<>(); dispatchQueue.postRunnable(() -> { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java index f1574ff36..75175dba7 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java @@ -110,6 +110,7 @@ public class FileUploadOperation { return; } state = 1; + SharedConfig.lockFile(uploadingFilePath); Utilities.stageQueue.postRunnable(() -> { preferences = ApplicationLoader.applicationContext.getSharedPreferences("uploadinfo", Activity.MODE_PRIVATE); slowNetwork = ApplicationLoader.isConnectionSlow(); @@ -170,6 +171,7 @@ public class FileUploadOperation { ConnectionsManager.getInstance(currentAccount).cancelRequest(requestTokens.valueAt(a), true); } }); + SharedConfig.unlockFile(uploadingFilePath); delegate.didFailedUploadingFile(this); cleanup(); } @@ -193,6 +195,7 @@ public class FileUploadOperation { } catch (Exception e) { FileLog.e(e); } + SharedConfig.unlockFile(uploadingFilePath); } protected void checkNewDataAvailable(final long newAvailableSize, final long finalSize) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MediaController.java b/TMessagesProj/src/main/java/org/telegram/messenger/MediaController.java index c6bee0115..0e5e2afce 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MediaController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MediaController.java @@ -3582,6 +3582,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener, SharedConfig.saveConfig(); recordingAudioFile = new File(FileLoader.getDirectory(FileLoader.MEDIA_DIR_CACHE), FileLoader.getAttachFileName(recordingAudio)); + SharedConfig.lockFile(recordingAudioFile); try { if (startRecord(recordingAudioFile.getAbsolutePath(), sampleRate) == 0) { @@ -3607,6 +3608,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener, FileLog.e(e); recordingAudio = null; stopRecord(); + SharedConfig.unlockFile(recordingAudioFile); recordingAudioFile.delete(); recordingAudioFile = null; try { @@ -3670,9 +3672,13 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener, if (send != 0) { final TLRPC.TL_document audioToSend = recordingAudio; final File recordingAudioFileToSend = recordingAudioFile; + if (BuildVars.LOGS_ENABLED) { + FileLog.d("stop recording internal " + recordingAudioFileToSend.exists() + recordingAudioFileToSend.length()); + } fileEncodingQueue.postRunnable(() -> { stopRecord(); AndroidUtilities.runOnUIThread(() -> { + audioToSend.date = ConnectionsManager.getInstance(recordingCurrentAccount).getCurrentTime(); audioToSend.size = (int) recordingAudioFileToSend.length(); TLRPC.TL_documentAttributeAudio attributeAudio = new TLRPC.TL_documentAttributeAudio(); @@ -3691,12 +3697,14 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener, NotificationCenter.getInstance(recordingCurrentAccount).postNotificationName(NotificationCenter.audioDidSent, recordingGuid, send == 2 ? audioToSend : null, send == 2 ? recordingAudioFileToSend.getAbsolutePath() : null); } else { NotificationCenter.getInstance(recordingCurrentAccount).postNotificationName(NotificationCenter.audioRecordTooShort, recordingGuid, false, (int) duration); + SharedConfig.unlockFile(recordingAudioFileToSend); recordingAudioFileToSend.delete(); } requestAudioFocus(false); }); }); } else { + SharedConfig.unlockFile(recordingAudioFile); if (recordingAudioFile != null) { recordingAudioFile.delete(); } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java index 3c04a5a1c..ce94f91c3 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java @@ -18,6 +18,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; +import android.graphics.Paint; import android.location.Location; import android.os.Build; import android.os.Bundle; @@ -26,7 +27,6 @@ import android.os.SystemClock; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Base64; -import android.util.Log; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.SparseIntArray; @@ -7264,11 +7264,14 @@ public class MessagesController extends BaseController implements NotificationCe type = 0; } } - if (text != null && ApplicationLoader.applicationContext != null) { - if (Theme.dialogs_messageNamePaint == null) { - Theme.createDialogsResources(ApplicationLoader.applicationContext); + if (text != null) { + Paint paint = Theme.dialogs_messageNamePaint; + if (paint == null) { + paint = new Paint(); + paint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + paint.setTextSize(AndroidUtilities.dp(14)); } - text = Emoji.replaceEmoji(text, Theme.dialogs_messageNamePaint.getFontMetricsInt(), false); + text = Emoji.replaceEmoji(text, paint.getFontMetricsInt(), false); newPrintingStrings.put(threadId, text); newPrintingStringsTypes.put(threadId, type); } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java index e19fd6d6f..aff743304 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java @@ -14043,7 +14043,17 @@ public class MessagesStorage extends BaseController { } ArrayList fullUsers = null; if (!dialogUsers.isEmpty()) { - fullUsers = loadUserInfos(dialogUsers); + HashSet fullUsersToLoad = new HashSet<>(); + for (Long did : dialogUsers) { + for (int i = 0; i < dialogs.users.size(); i++) { + if (dialogs.users.get(i).id == did && dialogs.users.get(i).premium) { + fullUsersToLoad.add(did); + } + } + } + if (!fullUsersToLoad.isEmpty()) { + fullUsers = loadUserInfos(fullUsersToLoad); + } } getMessagesController().processLoadedDialogs(dialogs, encryptedChats, fullUsers, folderId, offset, count, 1, false, false, true); } catch (Exception e) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java b/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java index 782480a6b..bbb5890a9 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java @@ -43,6 +43,8 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; public class SharedConfig { /** @@ -197,6 +199,7 @@ public class SharedConfig { public static boolean isFloatingDebugActive; public static LiteMode liteMode; + public static Set usingFilePaths = Collections.newSetFromMap(new ConcurrentHashMap<>()); static { loadConfig(); @@ -776,13 +779,17 @@ public class SharedConfig { public static void checkKeepMedia() { int time = (int) (System.currentTimeMillis() / 1000); - if (!BuildVars.DEBUG_PRIVATE_VERSION && Math.abs(time - lastKeepMediaCheckTime) < 60 * 60) { + if (!BuildVars.DEBUG_PRIVATE_VERSION && Math.abs(time - lastKeepMediaCheckTime) < 24 * 60 * 60) { return; } lastKeepMediaCheckTime = time; File cacheDir = FileLoader.checkDirectory(FileLoader.MEDIA_DIR_CACHE); Utilities.cacheClearQueue.postRunnable(() -> { + long startTime = System.currentTimeMillis(); + if (BuildVars.LOGS_ENABLED) { + FileLog.d("checkKeepMedia start task"); + } boolean hasExceptions = false; ArrayList cacheByChatsControllers = new ArrayList<>(); for (int account = 0; account < UserConfig.MAX_ACCOUNT_COUNT; account++) { @@ -811,6 +818,13 @@ public class SharedConfig { if (hasExceptions) { allKeepMediaTypesForever = false; } + int autoDeletedFiles = 0; + long autoDeletedFilesSize = 0; + + int deletedFilesBySize = 0; + long deletedFilesBySizeSize = 0; + int skippedFiles = 0; + if (!allKeepMediaTypesForever) { //long currentTime = time - 60 * 60 * 24 * days; final SparseArray paths = ImageLoader.getInstance().createMediaPaths(); @@ -824,6 +838,9 @@ public class SharedConfig { File[] files = dir.listFiles(); ArrayList keepMediaFiles = new ArrayList<>(); for (int i = 0; i < files.length; i++) { + if (usingFilePaths.contains(files[i].getAbsolutePath())) { + continue; + } keepMediaFiles.add(new CacheByChatsController.KeepMediaFile(files[i])); } for (int i = 0; i < cacheByChatsControllers.size(); i++) { @@ -835,9 +852,7 @@ public class SharedConfig { continue; } long seconds; - boolean isException = false; if (file.keepMedia >= 0) { - isException = true; seconds = CacheByChatsController.getDaysInSeconds(file.keepMedia); } else if (file.dialogType >= 0) { seconds = CacheByChatsController.getDaysInSeconds(keepMediaByTypes[file.dialogType]); @@ -854,6 +869,10 @@ public class SharedConfig { boolean needDelete = lastUsageTime < timeLocal; if (needDelete) { try { + if (BuildVars.LOGS_ENABLED) { + autoDeletedFiles++; + autoDeletedFilesSize += file.file.length(); + } file.file.delete(); } catch (Exception exception) { FileLog.e(exception); @@ -885,6 +904,9 @@ public class SharedConfig { File dir = paths.valueAt(a); fillFilesRecursive(dir, allFiles); } + for (int i = 0; i < cacheByChatsControllers.size(); i++) { + cacheByChatsControllers.get(i).lookupFiles(allFiles); + } Collections.sort(allFiles, (o1, o2) -> { if (o2.lastUsageDate > o1.lastUsageDate) { return -1; @@ -893,10 +915,21 @@ public class SharedConfig { } return 0; }); + for (int i = 0; i < allFiles.size(); i++) { + if (allFiles.get(i).keepMedia == CacheByChatsController.KEEP_MEDIA_FOREVER) { + continue; + } + if (allFiles.get(i).lastUsageDate <= 0) { + skippedFiles++; + continue; + } long size = allFiles.get(i).file.length(); totalSize -= size; + try { + deletedFilesBySize++; + deletedFilesBySizeSize += size; allFiles.get(i).file.delete(); } catch (Exception e) { @@ -907,12 +940,8 @@ public class SharedConfig { } } } - } - - //TODO now every day generating cache for reactions and cleared it after one day -\_(-_-)_/- - //need fix File stickersPath = new File(cacheDir, "acache"); if (stickersPath.exists()) { long currentTime = time - 60 * 60 * 24; @@ -925,6 +954,10 @@ public class SharedConfig { MessagesController.getGlobalMainSettings().edit() .putInt("lastKeepMediaCheckTime", lastKeepMediaCheckTime) .apply(); + + if (BuildVars.LOGS_ENABLED) { + FileLog.d("checkKeepMedia task end time " + (System.currentTimeMillis() - startTime) + "auto deleted info: files " + autoDeletedFiles + " size " + AndroidUtilities.formatFileSize(autoDeletedFilesSize) + " deleted by size limit info: files " + deletedFilesBySize + " size " + AndroidUtilities.formatFileSize(deletedFilesBySizeSize) + " unknownTimeFiles " + skippedFiles); + } }); } @@ -943,6 +976,9 @@ public class SharedConfig { if (fileEntry.getName().equals(".nomedia")) { continue; } + if (usingFilePaths.contains(fileEntry.getAbsolutePath())) { + continue; + } fileInfoList.add(new FileInfoInternal(fileEntry)); } } @@ -1571,17 +1607,15 @@ public class SharedConfig { return ApplicationLoader.applicationContext.getSharedPreferences("userconfing", Context.MODE_PRIVATE); } - private static class FileInfoInternal { - final File file; + private static class FileInfoInternal extends CacheByChatsController.KeepMediaFile { final long lastUsageDate; private FileInfoInternal(File file) { - this.file = file; + super(file); this.lastUsageDate = Utilities.getLastUsageFileTime(file.getAbsolutePath()); } } - public static class LiteMode { private boolean enabled; @@ -1617,4 +1651,32 @@ public class SharedConfig { return !enabled; } } + + public static void lockFile(File file) { + if (file == null) { + return; + } + lockFile(file.getAbsolutePath()); + } + + public static void unlockFile(File file) { + if (file == null) { + return; + } + unlockFile(file.getAbsolutePath()); + } + + public static void lockFile(String file) { + if (file == null) { + return; + } + usingFilePaths.add(file); + } + + public static void unlockFile(String file) { + if (file == null) { + return; + } + usingFilePaths.remove(file); + } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/utils/BitmapsCache.java b/TMessagesProj/src/main/java/org/telegram/messenger/utils/BitmapsCache.java index 2b2c7f295..6a8bd100b 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/utils/BitmapsCache.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/utils/BitmapsCache.java @@ -36,6 +36,7 @@ public class BitmapsCache { public final static int FRAME_RESULT_NO_FRAME = -1; public static final int COMPRESS_QUALITY_DEFAULT = 60; private final Cacheable source; + private static boolean mkdir; String fileName; int w; int h; @@ -87,6 +88,10 @@ public class BitmapsCache { } File fileTmo = new File(FileLoader.checkDirectory(FileLoader.MEDIA_DIR_CACHE), "acache"); + if (!mkdir) { + fileTmo.mkdir(); + mkdir = true; + } file = new File(fileTmo, fileName + "_" + w + "_" + h + (noLimit ? "_nolimit" : " ") + ".pcache2"); useSharedBuffers = w < AndroidUtilities.dp(60) && h < AndroidUtilities.dp(60); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java index 5da7538bf..697d3dc14 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java @@ -1751,7 +1751,7 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F layoutToIgnore = containerView; onCloseAnimationEndRunnable = () -> { - removeFragmentFromStackInternal(currentFragment); + removeFragmentFromStackInternal(currentFragment, false); setVisibility(GONE); if (backgroundView != null) { backgroundView.setVisibility(GONE); @@ -1784,7 +1784,7 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F }); currentAnimation.start(); } else { - removeFragmentFromStackInternal(currentFragment); + removeFragmentFromStackInternal(currentFragment, false); setVisibility(GONE); if (backgroundView != null) { backgroundView.setVisibility(GONE); @@ -1853,29 +1853,40 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F bringToFront(fragmentsStack.size() - 1); } - private void removeFragmentFromStackInternal(BaseFragment fragment) { - fragment.onPause(); - fragment.onFragmentDestroy(); - fragment.setParentLayout(null); - fragmentsStack.remove(fragment); - onFragmentStackChanged(); + private void removeFragmentFromStackInternal(BaseFragment fragment, boolean allowFinishFragment) { + if (!fragmentsStack.contains(fragment)) { + return; + } + if (allowFinishFragment && fragmentsStack.get(fragmentsStack.size() - 1) == fragment) { + fragment.finishFragment(); + } else { + fragment.onPause(); + fragment.onFragmentDestroy(); + fragment.setParentLayout(null); + fragmentsStack.remove(fragment); + onFragmentStackChanged(); + } } @Override public void removeFragmentFromStack(BaseFragment fragment) { + if ((fragmentsStack.size() > 0 && fragmentsStack.get(fragmentsStack.size() - 1) == fragment) || (fragmentsStack.size() > 1 && fragmentsStack.get(fragmentsStack.size() - 2) == fragment)) { + onOpenAnimationEnd(); + onCloseAnimationEnd(); + } if (useAlphaAnimations && fragmentsStack.size() == 1 && AndroidUtilities.isTablet()) { closeLastFragment(true); } else { if (delegate != null && fragmentsStack.size() == 1 && AndroidUtilities.isTablet()) { delegate.needCloseLastFragment(this); } - removeFragmentFromStackInternal(fragment); + removeFragmentFromStackInternal(fragment, true); } } public void removeAllFragments() { for (int a = 0; a < fragmentsStack.size(); a++) { - removeFragmentFromStackInternal(fragmentsStack.get(a)); + removeFragmentFromStackInternal(fragmentsStack.get(a), false); a--; } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarPopupWindow.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarPopupWindow.java index 5d6066159..02522538a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarPopupWindow.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarPopupWindow.java @@ -114,6 +114,7 @@ public class ActionBarPopupWindow extends PopupWindow { private int gapEndY = -1000000; private Rect bgPaddings = new Rect(); private onSizeChangedListener onSizeChangedListener; + private float reactionsEnterProgress = 1f; private PopupSwipeBackLayout swipeBackLayout; private ScrollView scrollView; @@ -128,6 +129,7 @@ public class ActionBarPopupWindow extends PopupWindow { protected ActionBarPopupWindow window; public int subtractBackgroundHeight; + Rect rect; public ActionBarPopupWindowLayout(Context context) { this(context, null); @@ -440,11 +442,6 @@ public class ActionBarPopupWindow extends PopupWindow { setTranslationY(yOffset); } } - super.dispatchDraw(canvas); - } - - @Override - protected void onDraw(Canvas canvas) { if (backgroundDrawable != null) { int start = gapStartY - scrollView.getScrollY(); int end = gapEndY - scrollView.getScrollY(); @@ -473,12 +470,12 @@ public class ActionBarPopupWindow extends PopupWindow { backgroundDrawable.setAlpha(applyAlpha ? backAlpha : 255); if (shownFromBottom) { final int height = getMeasuredHeight(); - backgroundDrawable.setBounds(0, (int) (height * (1.0f - backScaleY)), (int) (getMeasuredWidth() * backScaleX), height); + AndroidUtilities.rectTmp2.set(0, (int) (height * (1.0f - backScaleY)), (int) (getMeasuredWidth() * backScaleX), height); } else { if (start > -AndroidUtilities.dp(16)) { int h = (int) (getMeasuredHeight() * backScaleY); if (a == 0) { - backgroundDrawable.setBounds(0, -scrollView.getScrollY() + (gapStartY != -1000000 ? AndroidUtilities.dp(1) : 0), (int) (getMeasuredWidth() * backScaleX), (gapStartY != -1000000 ? Math.min(h, start + AndroidUtilities.dp(16)) : h) - subtractBackgroundHeight); + AndroidUtilities.rectTmp2.set(0, -scrollView.getScrollY() + (gapStartY != -1000000 ? AndroidUtilities.dp(1) : 0), (int) (getMeasuredWidth() * backScaleX), (gapStartY != -1000000 ? Math.min(h, start + AndroidUtilities.dp(16)) : h) - subtractBackgroundHeight); } else { if (h < end) { if (gapStartY != -1000000) { @@ -486,13 +483,20 @@ public class ActionBarPopupWindow extends PopupWindow { } continue; } - backgroundDrawable.setBounds(0, end, (int) (getMeasuredWidth() * backScaleX), h - subtractBackgroundHeight); + AndroidUtilities.rectTmp2.set(0, end, (int) (getMeasuredWidth() * backScaleX), h - subtractBackgroundHeight); } } else { - backgroundDrawable.setBounds(0, (gapStartY < 0 ? 0 : -AndroidUtilities.dp(16)), (int) (getMeasuredWidth() * backScaleX), (int) (getMeasuredHeight() * backScaleY) - subtractBackgroundHeight); + AndroidUtilities.rectTmp2.set(0, (gapStartY < 0 ? 0 : -AndroidUtilities.dp(16)), (int) (getMeasuredWidth() * backScaleX), (int) (getMeasuredHeight() * backScaleY) - subtractBackgroundHeight); } } - + if (reactionsEnterProgress != 1f) { + if (rect == null) { + rect = new Rect(); + } + rect.set(AndroidUtilities.rectTmp2.right, AndroidUtilities.rectTmp2.top, AndroidUtilities.rectTmp2.right, AndroidUtilities.rectTmp2.top); + AndroidUtilities.lerp(rect, AndroidUtilities.rectTmp2, reactionsEnterProgress, AndroidUtilities.rectTmp2); + } + backgroundDrawable.setBounds(AndroidUtilities.rectTmp2); backgroundDrawable.draw(canvas); if (hasGap) { canvas.save(); @@ -525,6 +529,15 @@ public class ActionBarPopupWindow extends PopupWindow { } } } + if (reactionsEnterProgress != 1f) { + canvas.saveLayerAlpha((float) AndroidUtilities.rectTmp2.left, (float) AndroidUtilities.rectTmp2.top, AndroidUtilities.rectTmp2.right, AndroidUtilities.rectTmp2.bottom, (int) (255 * reactionsEnterProgress), Canvas.ALL_SAVE_FLAG); + float scale = 0.5f + reactionsEnterProgress * 0.5f; + canvas.scale(scale, scale, AndroidUtilities.rectTmp2.right, AndroidUtilities.rectTmp2.top); + super.dispatchDraw(canvas); + canvas.restore(); + } else { + super.dispatchDraw(canvas); + } } public Drawable getBackgroundDrawable() { @@ -618,6 +631,11 @@ public class ActionBarPopupWindow extends PopupWindow { public void setParentWindow(ActionBarPopupWindow popupWindow) { window = popupWindow; } + + public void setReactionsTransitionProgress(float transitionEnterProgress) { + this.reactionsEnterProgress = transitionEnterProgress; + invalidate(); + } } public ActionBarPopupWindow() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index 6e6805280..be2bd32a0 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -6909,7 +6909,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not topViewSeparator2 = new View(context); topViewSeparator2.setVisibility(View.GONE); topViewSeparator2.setBackgroundColor(getThemedColor(Theme.key_divider)); - topChatPanelView.addView(topViewSeparator2, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 1f / AndroidUtilities.density, Gravity.LEFT | Gravity.TOP, 10, 50, 10, 1)); + topChatPanelView.addView(topViewSeparator2, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 1f / AndroidUtilities.density, Gravity.LEFT | Gravity.TOP, 10, 48, 10, 1)); topViewSeparator3 = new View(context); topViewSeparator3.setVisibility(View.GONE); topViewSeparator3.setBackgroundColor(getThemedColor(Theme.key_divider)); @@ -14838,7 +14838,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not fillEditingMediaWithCaption(photos.get(0).caption, photos.get(0).entities); SendMessagesHelper.prepareSendingMedia(getAccountInstance(), photos, dialog_id, replyingMessageObject, getThreadMessage(), null, forceDocument, true, null, notify, scheduleDate, photos.get(0).updateStickersOrder); afterMessageSend(); - chatActivityEnterView.setFieldText(""); + if (chatActivityEnterView != null) { + chatActivityEnterView.setFieldText(""); + } } if (scheduleDate != 0) { if (scheduledMessagesCount == -1) { @@ -21935,7 +21937,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } emojiStatusSpamHint.setText(text); emojiStatusSpamHint.measure(View.MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.x - AndroidUtilities.dp(50), View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(99999, View.MeasureSpec.AT_MOST)); - topChatPanelHeight += AndroidUtilities.dp(6); + topChatPanelHeight += AndroidUtilities.dp(4); emojiStatusSpamHint.setTranslationY(topChatPanelHeight); topChatPanelHeight += AndroidUtilities.dp(10) + emojiStatusSpamHint.getMeasuredHeight(); } else { @@ -21944,10 +21946,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not topViewSeparator2.setVisibility(View.GONE); } if (showTranslate) { - if (restartTopicButton.getVisibility() == View.VISIBLE) { -// topChatPanelHeight += AndroidUtilities.dp(48); - topViewSeparator3.setVisibility(View.VISIBLE); - } else if (addToContactsButton.getVisibility() == View.VISIBLE || user != null && !TextUtils.isEmpty(chatWithAdmin)) { + if (restartTopicButton.getVisibility() == View.VISIBLE || + reportSpamButton.getVisibility() == View.VISIBLE || + addToContactsButton.getVisibility() == View.VISIBLE || + user != null && !TextUtils.isEmpty(chatWithAdmin) + ) { topViewSeparator3.setVisibility(View.VISIBLE); } else { topChatPanelHeight -= AndroidUtilities.dp(48); @@ -24336,6 +24339,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } ReactionsContainerLayout finalReactionsLayout1 = reactionsLayout; + reactionsLayout.setParentLayout(scrimPopupContainerLayout); scrimPopupWindow = new ActionBarPopupWindow(scrimPopupContainerLayout, LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT) { @Override public void dismiss() { @@ -24373,7 +24377,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not scrimPopupWindow.setDismissAnimationDuration(220); scrimPopupWindow.setOutsideTouchable(true); scrimPopupWindow.setClippingEnabled(true); - scrimPopupWindow.setAnimationStyle(R.style.PopupContextAnimation); + if (reactionsLayout == null) { + scrimPopupWindow.setAnimationStyle(R.style.PopupContextAnimation); + } else { + scrimPopupWindow.setAnimationStyle(0); + } scrimPopupWindow.setFocusable(true); scrimPopupContainerLayout.measure(View.MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(1000), View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(1000), View.MeasureSpec.AT_MOST)); scrimPopupWindow.setInputMethodMode(ActionBarPopupWindow.INPUT_METHOD_NOT_NEEDED); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/AnimatedEmojiDrawable.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/AnimatedEmojiDrawable.java index 3ca5453b8..ff3e99079 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/AnimatedEmojiDrawable.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/AnimatedEmojiDrawable.java @@ -522,7 +522,7 @@ public class AnimatedEmojiDrawable extends Drawable { } else if (cacheType == STANDARD_LOTTIE_FRAME) { imageReceiver.setImage(null, null, mediaLocation, mediaFilter, null, null, thumbDrawable, document.size, null, document, 1); } else { - if (SharedConfig.getLiteMode().enabled()) { + if (SharedConfig.getLiteMode().enabled() && cacheType != CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW) { if ("video/webm".equals(document.mime_type)) { imageReceiver.setImage(null, null, ImageLocation.getForDocument(thumb, document), sizedp + "_" + sizedp, null, null, thumbDrawable, document.size, null, document, 1); } else { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarConstructorFragment.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarConstructorFragment.java index 5568e12bb..0bf034852 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarConstructorFragment.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarConstructorFragment.java @@ -92,8 +92,15 @@ public class AvatarConstructorFragment extends BaseFragment { Paint actionBarPaint = new Paint(); private int gradientBackgroundItemWidth; - public String[] keys_avatar_background = {Theme.key_avatar_backgroundBlue, Theme.key_avatar_backgroundCyan, Theme.key_avatar_backgroundGreen, Theme.key_avatar_backgroundOrange, Theme.key_avatar_backgroundRed, Theme.key_avatar_backgroundPink, Theme.key_avatar_backgroundViolet}; - public String[] keys_avatar_background2 = {Theme.key_avatar_background2Blue, Theme.key_avatar_background2Cyan, Theme.key_avatar_background2Green, Theme.key_avatar_background2Orange, Theme.key_avatar_background2Red, Theme.key_avatar_background2Pink, Theme.key_avatar_background2Violet}; + public static final int[][] defaultColors = new int[][]{ + new int[]{0xFF4D8DFF, 0xFF2BBFFF, 0xFF20E2CD, 0xFF0EE1F1}, + new int[]{0xFF5EB6FB, 0xFF1FCEEB, 0xFF45F7B7, 0xFF1FF1D9}, + new int[]{0xFF09D260, 0xFF5EDC40, 0xFFC1E526, 0xFF80DF2B}, + new int[]{0xFFF5694E, 0xFFF5772C, 0xFFFFD412, 0xFFFFA743}, + new int[]{0xFFF64884, 0xFFEF5B41, 0xFFF6A730, 0xFFFF7742}, + new int[]{0xFFF94BA0, 0xFFFB5C80, 0xFFFFB23A, 0xFFFE7E62}, + new int[]{0xFF837CFF, 0xFFB063FF, 0xFFFF72A9, 0xFFE269FF} + }; public boolean finishOnDone = true; private ActionBarMenuItem setPhotoItem; private BottomSheet bottomSheet; @@ -426,6 +433,7 @@ public class AvatarConstructorFragment extends BaseFragment { wasChanged = true; } }; + selectAnimatedEmojiDialog.forUser = !forGroup; selectAnimatedEmojiDialog.setAnimationsEnabled(fragmentBeginToShow); selectAnimatedEmojiDialog.setClipChildren(false); @@ -829,11 +837,13 @@ public class AvatarConstructorFragment extends BaseFragment { LinearLayoutManager layoutManager = new LinearLayoutManager(context); layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); setLayoutManager(layoutManager); - for (int i = 0; i < keys_avatar_background.length; i++) { + for (int i = 0; i < defaultColors.length; i++) { BackgroundGradient backgroundGradient = new BackgroundGradient(); backgroundGradient.stableId = stableIdPointer++; - backgroundGradient.color1 = Theme.getColor(keys_avatar_background[i]); - backgroundGradient.color2 = Theme.getColor(keys_avatar_background2[i]); + backgroundGradient.color1 = defaultColors[i][0]; + backgroundGradient.color2 = defaultColors[i][1]; + backgroundGradient.color3 = defaultColors[i][2]; + backgroundGradient.color4 = defaultColors[i][3]; gradients.add(backgroundGradient); } setOnItemClickListener((view, position) -> { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarConstructorPreviewCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarConstructorPreviewCell.java index c7ac86256..d844a7bd7 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarConstructorPreviewCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarConstructorPreviewCell.java @@ -26,8 +26,8 @@ public class AvatarConstructorPreviewCell extends FrameLayout { BackupImageView currentImage; BackupImageView nextImage; - Drawable currentBackgroundDrawable; - Drawable nextBackgroundDrawable; + GradientTools currentBackgroundDrawable; + GradientTools nextBackgroundDrawable; TextView textView; TLRPC.TL_emojiList emojiList; @@ -54,17 +54,20 @@ public class AvatarConstructorPreviewCell extends FrameLayout { if (emojiIndex > emojiList.document_id.size() - 1) { emojiIndex = 0; } - if (backgroundIndex > Theme.keys_avatar_background.length - 1) { + if (backgroundIndex > AvatarConstructorFragment.defaultColors.length - 1) { backgroundIndex = 0; } animatedEmojiDrawable = new AnimatedEmojiDrawable(AnimatedEmojiDrawable.CACHE_TYPE_ALERT_PREVIEW_LARGE, currentAccount, emojiList.document_id.get(emojiIndex)); nextImage.setAnimatedEmojiDrawable(animatedEmojiDrawable); - int color1 = Theme.getColor(Theme.keys_avatar_background[backgroundIndex]); - int color2 = Theme.getColor(Theme.keys_avatar_background2[backgroundIndex]); + int color1 = AvatarConstructorFragment.defaultColors[backgroundIndex][0]; + int color2 = AvatarConstructorFragment.defaultColors[backgroundIndex][1]; + int color3 = AvatarConstructorFragment.defaultColors[backgroundIndex][2]; + int color4 = AvatarConstructorFragment.defaultColors[backgroundIndex][3]; - nextBackgroundDrawable = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, new int[]{color1, color2}); + nextBackgroundDrawable = new GradientTools(); + nextBackgroundDrawable.setColors(color1, color2, color3, color4); progressToNext = 0f; invalidate(); @@ -116,10 +119,14 @@ public class AvatarConstructorPreviewCell extends FrameLayout { animatedEmojiDrawable = new AnimatedEmojiDrawable(AnimatedEmojiDrawable.CACHE_TYPE_ALERT_PREVIEW_LARGE, currentAccount, emojiList.document_id.get(0)); currentImage.setAnimatedEmojiDrawable(animatedEmojiDrawable); } - int color1 = Theme.getColor(Theme.keys_avatar_background[backgroundIndex]); - int color2 = Theme.getColor(Theme.keys_avatar_background2[backgroundIndex]); - currentBackgroundDrawable = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, new int[]{color1, color2}); + int color1 = AvatarConstructorFragment.defaultColors[backgroundIndex][0]; + int color2 = AvatarConstructorFragment.defaultColors[backgroundIndex][1]; + int color3 = AvatarConstructorFragment.defaultColors[backgroundIndex][2]; + int color4 = AvatarConstructorFragment.defaultColors[backgroundIndex][3]; + + currentBackgroundDrawable = new GradientTools(); + currentBackgroundDrawable.setColors(color1, color2, color3, color4); textView = new TextView(context); textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12); @@ -155,8 +162,8 @@ public class AvatarConstructorPreviewCell extends FrameLayout { nextBackgroundDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight()); } if (progressToNext == 1f) { - currentBackgroundDrawable.setAlpha(255); - currentBackgroundDrawable.draw(canvas); + currentBackgroundDrawable.paint.setAlpha(255); + canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), currentBackgroundDrawable.paint); currentImage.setAlpha(1f); currentImage.setScaleX(1f); currentImage.setScaleY(1f); @@ -164,10 +171,10 @@ public class AvatarConstructorPreviewCell extends FrameLayout { } else { float progressInternal = CubicBezierInterpolator.DEFAULT.getInterpolation(progressToNext); - currentBackgroundDrawable.setAlpha(255); - currentBackgroundDrawable.draw(canvas); - nextBackgroundDrawable.setAlpha((int) (255 * progressInternal)); - nextBackgroundDrawable.draw(canvas); + currentBackgroundDrawable.paint.setAlpha(255); + canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), currentBackgroundDrawable.paint); + nextBackgroundDrawable.paint.setAlpha((int) (255 * progressInternal)); + canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), nextBackgroundDrawable.paint); progressToNext += 16 / 250f; @@ -206,8 +213,12 @@ public class AvatarConstructorPreviewCell extends FrameLayout { public AvatarConstructorFragment.BackgroundGradient getBackgroundGradient() { AvatarConstructorFragment.BackgroundGradient backgroundGradient = new AvatarConstructorFragment.BackgroundGradient(); - backgroundGradient.color1 = Theme.getColor(Theme.keys_avatar_background[backgroundIndex]); - backgroundGradient.color2 = Theme.getColor(Theme.keys_avatar_background2[backgroundIndex]); + + backgroundGradient.color1 = AvatarConstructorFragment.defaultColors[backgroundIndex][0]; + backgroundGradient.color2 = AvatarConstructorFragment.defaultColors[backgroundIndex][1]; + backgroundGradient.color3 = AvatarConstructorFragment.defaultColors[backgroundIndex][2]; + backgroundGradient.color4 = AvatarConstructorFragment.defaultColors[backgroundIndex][3]; + return backgroundGradient; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/CacheChart.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/CacheChart.java index 9b6ed55c3..383932f3d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/CacheChart.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/CacheChart.java @@ -357,6 +357,7 @@ public class CacheChart extends View { public CacheChart(Context context, int count, String[] colorKeys, int type, int[] particles) { super(context); + setLayerType(LAYER_TYPE_HARDWARE, null); this.sectionsCount = count; this.colorKeys = colorKeys; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatScrimPopupContainerLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatScrimPopupContainerLayout.java index 6188e9d4c..b83620244 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatScrimPopupContainerLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatScrimPopupContainerLayout.java @@ -168,4 +168,8 @@ public class ChatScrimPopupContainerLayout extends LinearLayout { bottomView.setAlpha(aplha); } } + + public ActionBarPopupWindow.ActionBarPopupWindowLayout getPopupWindowLayout() { + return popupWindowLayout; + } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/DrawingInBackgroundThreadDrawable.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/DrawingInBackgroundThreadDrawable.java index 53d6fe0ad..64d825ba7 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/DrawingInBackgroundThreadDrawable.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/DrawingInBackgroundThreadDrawable.java @@ -28,7 +28,7 @@ public class DrawingInBackgroundThreadDrawable implements NotificationCenter.Not private boolean bitmapUpdating; - public int currentLayerNum = 1; + private int currentLayerNum = 1; private int currentOpenedLayerFlags; protected boolean paused; @@ -299,6 +299,13 @@ public class DrawingInBackgroundThreadDrawable implements NotificationCenter.Not } return queue; } + } + public void setLayerNum(int value) { + currentLayerNum = value; + if (attachedToWindow) { + currentOpenedLayerFlags = NotificationCenter.getGlobalInstance().getCurrentHeavyOperationFlags(); + currentOpenedLayerFlags &= ~currentLayerNum; + } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiPacksAlert.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiPacksAlert.java index 2eaeaf810..3fc50eac3 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiPacksAlert.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiPacksAlert.java @@ -361,7 +361,7 @@ public class EmojiPacksAlert extends BottomSheet implements NotificationCenter.N drawable = unusedLineDrawables.remove(unusedLineDrawables.size() - 1); } else { drawable = new DrawingInBackgroundLine(); - drawable.currentLayerNum = 7; + drawable.setLayerNum(7); } drawable.position = position; drawable.onAttachToWindow(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/RLottieDrawable.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/RLottieDrawable.java index 62945b8a5..2977a3b89 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/RLottieDrawable.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/RLottieDrawable.java @@ -236,19 +236,7 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma if (destroyWhenDone) { checkRunningTasks(); if (loadFrameTask == null && cacheGenerateTask == null && nativePtr != 0) { - long nativePtrFinal = nativePtr; - long secondNativePtrFinal = secondNativePtr; - nativePtr = 0; - secondNativePtr = 0; - DispatchQueuePoolBackground.execute(() -> { - if (nativePtrFinal != 0) { - destroy(nativePtrFinal); - } - if (secondNativePtrFinal != 0) { - destroy(secondNativePtrFinal); - } - }); - + recycleNativePtr(); } } if ((nativePtr == 0 || fallbackCache) && secondNativePtr == 0 && bitmapsCache == null) { @@ -262,6 +250,22 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma scheduleNextGetFrame(); } + private void recycleNativePtr() { + long nativePtrFinal = nativePtr; + long secondNativePtrFinal = secondNativePtr; + + nativePtr = 0; + secondNativePtr = 0; + DispatchQueuePoolBackground.execute(() -> { + if (nativePtrFinal != 0) { + destroy(nativePtrFinal); + } + if (secondNativePtrFinal != 0) { + destroy(secondNativePtrFinal); + } + }); + } + protected void recycleResources() { ArrayList bitmapToRecycle = new ArrayList<>(); bitmapToRecycle.add(renderingBitmap); @@ -531,7 +535,13 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma try { LottieMetadata lottieMetadata; if (file != null) { - lottieMetadata = gson.fromJson(new FileReader(file.getAbsolutePath()), LottieMetadata.class); + FileReader reader = new FileReader(file.getAbsolutePath()); + lottieMetadata = gson.fromJson(reader, LottieMetadata.class); + try { + reader.close(); + } catch (Exception e) { + + } } else { lottieMetadata = gson.fromJson(json, LottieMetadata.class); } @@ -814,14 +824,7 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma if (loadingInBackground || secondLoadingInBackground) { destroyAfterLoading = true; } else if (loadFrameTask == null && cacheGenerateTask == null && !generatingCache) { - if (nativePtr != 0) { - destroy(nativePtr); - nativePtr = 0; - } - if (secondNativePtr != 0) { - destroy(secondNativePtr); - secondNativePtr = 0; - } + recycleNativePtr(); if (bitmapsCache != null) { bitmapsCache.recycle(); bitmapsCache = null; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Reactions/CustomEmojiReactionsWindow.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Reactions/CustomEmojiReactionsWindow.java index 15603f285..97c60c327 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Reactions/CustomEmojiReactionsWindow.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Reactions/CustomEmojiReactionsWindow.java @@ -18,6 +18,7 @@ import android.view.HapticFeedbackConstants; import android.view.KeyEvent; import android.view.View; import android.view.WindowManager; +import android.view.animation.OvershootInterpolator; import android.widget.FrameLayout; import androidx.annotation.NonNull; @@ -34,7 +35,6 @@ import org.telegram.tgnet.TLRPC; import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ChatActivity; -import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.Components.Bulletin; import org.telegram.ui.Components.BulletinFactory; import org.telegram.ui.Components.CubicBezierInterpolator; @@ -44,6 +44,7 @@ import org.telegram.ui.Components.ReactionsContainerLayout; import org.telegram.ui.PremiumPreviewFragment; import org.telegram.ui.SelectAnimatedEmojiDialog; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -76,6 +77,9 @@ public class CustomEmojiReactionsWindow { float yTranslation; float keyboardHeight; private boolean wasFocused; + private int account; + private boolean cascadeAnimation; + private ValueAnimator valueAnimator; public CustomEmojiReactionsWindow(BaseFragment baseFragment, List reactions, HashSet selectedReactions, ReactionsContainerLayout reactionsContainerLayout, Theme.ResourcesProvider resourcesProvider) { this.reactions = reactions; @@ -242,7 +246,7 @@ public class CustomEmojiReactionsWindow { reactionsContainerLayout.getLocationOnScreen(location); } windowView.getLocationOnScreen(windowLocation); - float y = location[1] - windowLocation[1] - AndroidUtilities.dp(44); + float y = location[1] - windowLocation[1] - AndroidUtilities.dp(44) - AndroidUtilities.dp(52) - (selectAnimatedEmojiDialog.includeHint ? AndroidUtilities.dp(26) : 0); if (y + containerView.getMeasuredHeight() > windowView.getMeasuredHeight() - AndroidUtilities.dp(32)) { y = windowView.getMeasuredHeight() - AndroidUtilities.dp(32) - containerView.getMeasuredHeight(); } @@ -263,16 +267,28 @@ public class CustomEmojiReactionsWindow { reactionsContainerLayout.setCustomEmojiEnterProgress(enterTransitionProgress); if (enter) { + cascadeAnimation = false;//SharedConfig.getDevicePerformanceClass() >= SharedConfig.PERFORMANCE_CLASS_HIGH; enterTransitionFinished = false; + } else { + cascadeAnimation = false; } - int account = UserConfig.selectedAccount; + if (cascadeAnimation) { + updateCascadeEnter(0); + } + selectAnimatedEmojiDialog.setEnterAnimationInProgress(true); + account = UserConfig.selectedAccount; animationIndex = NotificationCenter.getInstance(account).setAnimationInProgress(animationIndex, null); - ValueAnimator valueAnimator = ValueAnimator.ofFloat(enterTransitionProgress, enter ? 1f : 0); + valueAnimator = ValueAnimator.ofFloat(enterTransitionProgress, enter ? 1f : 0); valueAnimator.addUpdateListener(animation -> { + valueAnimator = null; enterTransitionProgress = (float) animation.getAnimatedValue(); - reactionsContainerLayout.setCustomEmojiEnterProgress(enterTransitionProgress); + reactionsContainerLayout.setCustomEmojiEnterProgress(Utilities.clamp(enterTransitionProgress,1f, 0)); invalidatePath = true; containerView.invalidate(); + + if (cascadeAnimation) { + updateCascadeEnter(enterTransitionProgress); + } }); if (!enter) { syncReactionFrames(enter); @@ -280,7 +296,7 @@ public class CustomEmojiReactionsWindow { valueAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - NotificationCenter.getInstance(account).onAnimationFinish(animationIndex); + checkAnimationEnd(); enterTransitionProgress = enter ? 1f : 0f; if (enter) { enterTransitionFinished = true; @@ -288,7 +304,7 @@ public class CustomEmojiReactionsWindow { reactionsContainerLayout.onCustomEmojiWindowOpened(); containerView.invalidate(); } - reactionsContainerLayout.setCustomEmojiEnterProgress(enterTransitionProgress); + reactionsContainerLayout.setCustomEmojiEnterProgress(Utilities.clamp(enterTransitionProgress, 1f, 0f)); if (enter) { syncReactionFrames(enter); } @@ -301,9 +317,100 @@ public class CustomEmojiReactionsWindow { } }); valueAnimator.setStartDelay(30); - valueAnimator.setDuration(350); - valueAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT); + if (cascadeAnimation) { + valueAnimator.setDuration(450); + valueAnimator.setInterpolator(new OvershootInterpolator(1f)); + } else { + valueAnimator.setDuration(350); + valueAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT); + } valueAnimator.start(); + containerView.invalidate(); + } + + HashSet animatingEnterChild = new HashSet<>(); + ArrayList animators = new ArrayList<>(); + + private void updateCascadeEnter(float progress) { + int fullHeight = selectAnimatedEmojiDialog.contentView.getHeight(); + int parentTop = (int) (selectAnimatedEmojiDialog.getY() + selectAnimatedEmojiDialog.contentView.getY() + selectAnimatedEmojiDialog.emojiGridView.getY()); + ArrayList animatedViews = null; + boolean updated = false; + for (int i = 0; i < selectAnimatedEmojiDialog.emojiGridView.getChildCount(); i++) { + View child = selectAnimatedEmojiDialog.emojiGridView.getChildAt(i); + if (animatingEnterChild.contains(child)) { + continue; + } + float cy = parentTop + child.getTop() + child.getMeasuredHeight() / 2f; + if (cy < drawingRect.bottom && cy > drawingRect.top && progress != 0) { + if (animatedViews == null) { + animatedViews = new ArrayList<>(); + } + animatedViews.add(child); + animatingEnterChild.add(child); + } else { + child.setScaleX(0f); + child.setScaleY(0f); + updated = true; + } + } + parentTop = (int) (selectAnimatedEmojiDialog.getY() + selectAnimatedEmojiDialog.contentView.getY() + selectAnimatedEmojiDialog.emojiTabs.getY()); + for (int i = 0; i < selectAnimatedEmojiDialog.emojiTabs.contentView.getChildCount(); i++) { + View child = selectAnimatedEmojiDialog.emojiTabs.contentView.getChildAt(i); + if (animatingEnterChild.contains(child)) { + continue; + } + float cy = parentTop + child.getTop() + child.getMeasuredHeight() / 2f; + if (cy < drawingRect.bottom && cy > drawingRect.top && progress != 0) { + if (animatedViews == null) { + animatedViews = new ArrayList<>(); + } + animatedViews.add(child); + animatingEnterChild.add(child); + } else { + child.setScaleX(0f); + child.setScaleY(0f); + updated = true; + } + } + if (updated) { + selectAnimatedEmojiDialog.emojiGridView.invalidate(); + selectAnimatedEmojiDialog.contentView.invalidate(); + selectAnimatedEmojiDialog.emojiTabs.contentView.invalidate(); + } + if (animatedViews != null) { + ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1f); + ArrayList finalAnimatedViews = animatedViews; + valueAnimator.addUpdateListener(animation -> { + float s = (float) animation.getAnimatedValue(); + for (int i = 0; i < finalAnimatedViews.size(); i++) { + finalAnimatedViews.get(i).setScaleX(s); + finalAnimatedViews.get(i).setScaleY(s); + } + selectAnimatedEmojiDialog.emojiGridView.invalidate(); + selectAnimatedEmojiDialog.contentView.invalidate(); + selectAnimatedEmojiDialog.emojiTabs.contentView.invalidate(); + }); + animators.add(valueAnimator); + valueAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + animators.remove(valueAnimator); + checkAnimationEnd(); + } + }); + valueAnimator.setDuration(350); + valueAnimator.setInterpolator(new OvershootInterpolator(1f)); + valueAnimator.start(); + } + } + + private void checkAnimationEnd() { + if (animators.isEmpty()) { + NotificationCenter.getInstance(account).onAnimationFinish(animationIndex); + selectAnimatedEmojiDialog.setEnterAnimationInProgress(false); + } } private void syncReactionFrames(boolean enter) { @@ -416,16 +523,17 @@ public class CustomEmojiReactionsWindow { @Override protected void dispatchDraw(Canvas canvas) { - if (!isShowing) { + if (!isShowing) { return; } - dimPaint.setAlpha((int) (0.2f * enterTransitionProgress * 255)); + float progressClpamped = Utilities.clamp(enterTransitionProgress,1f, 0f); + dimPaint.setAlpha((int) (0.2f * progressClpamped * 255)); canvas.drawPaint(dimPaint); AndroidUtilities.rectTmp.set(0, 0, getMeasuredWidth(), getMeasuredHeight()); AndroidUtilities.lerp(fromRect, AndroidUtilities.rectTmp, enterTransitionProgress, drawingRect); float radius = AndroidUtilities.lerp(fromRadius, AndroidUtilities.dp(8), enterTransitionProgress); - shadow.setAlpha((int) (Utilities.clamp(enterTransitionProgress / 0.05f, 1f, 0f) * 255)); + shadow.setAlpha((int) (Utilities.clamp(progressClpamped / 0.05f, 1f, 0f) * 255)); shadow.setBounds((int) drawingRect.left - shadowPad.left, (int) drawingRect.top - shadowPad.top, (int) drawingRect.right + shadowPad.right, (int) drawingRect.bottom + shadowPad.bottom); shadow.draw(canvas); @@ -579,7 +687,7 @@ public class CustomEmojiReactionsWindow { } else { if (holderView.hasEnterAnimation && holderView.loopImageView.getImageReceiver().getLottieAnimation() == null) { float oldAlpha = holderView.enterImageView.getImageReceiver().getAlpha(); - holderView.enterImageView.getImageReceiver().setAlpha(oldAlpha * (1f - enterTransitionProgress)); + holderView.enterImageView.getImageReceiver().setAlpha(oldAlpha * (1f - progressClpamped)); holderView.enterImageView.draw(canvas); holderView.enterImageView.getImageReceiver().setAlpha(oldAlpha); } else { @@ -588,14 +696,14 @@ public class CustomEmojiReactionsWindow { imageReceiver = holderView.loopImageView.animatedEmojiDrawable.getImageReceiver(); } float oldAlpha = imageReceiver.getAlpha(); - imageReceiver.setAlpha(oldAlpha * (1f - enterTransitionProgress)); + imageReceiver.setAlpha(oldAlpha * (1f - progressClpamped)); holderView.loopImageView.draw(canvas); imageReceiver.setAlpha(oldAlpha); } } } else { canvas.translate(child.getX() + drawingRect.width() - reactionsContainerLayout.rect.width(), child.getY() + fromRect.top - drawingRect.top); - canvas.saveLayerAlpha(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight(), (int) (255 * (1f - enterTransitionProgress)), Canvas.ALL_SAVE_FLAG); + canvas.saveLayerAlpha(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight(), (int) (255 * (1f - progressClpamped)), Canvas.ALL_SAVE_FLAG); canvas.scale(1f - enterTransitionProgress, 1f - enterTransitionProgress, child.getMeasuredWidth() >> 1, child.getMeasuredHeight() >> 1); child.draw(canvas); canvas.restore(); @@ -612,9 +720,11 @@ public class CustomEmojiReactionsWindow { } canvas.save(); canvas.clipPath(pathToClip); - canvas.translate(enterTransitionOffsetX, enterTransitionOffsetY); + canvas.translate(cascadeAnimation ? 0 : enterTransitionOffsetX, enterTransitionOffsetY); canvas.scale(enterTransitionScale, enterTransitionScale, enterTransitionScalePx, enterTransitionScalePy); - selectAnimatedEmojiDialog.setAlpha(enterTransitionProgress); + if (!cascadeAnimation) { + selectAnimatedEmojiDialog.setAlpha(enterTransitionProgress); + } super.dispatchDraw(canvas); canvas.restore(); @@ -626,19 +736,12 @@ public class CustomEmojiReactionsWindow { } selectAnimatedEmojiDialog.drawBigReaction(canvas, this); + if (valueAnimator != null) { + invalidate(); + } } } - private boolean imageIsEquals(BackupImageView loopImageView, SelectAnimatedEmojiDialog.ImageViewEmoji toImageView) { - if (toImageView.span == null && loopImageView.getImageReceiver().getLottieAnimation() != null && toImageView.imageReceiver.getLottieAnimation() != null) { - return true; - } - if (loopImageView.animatedEmojiDrawable != null) { - return toImageView.span.getDocumentId() == loopImageView.animatedEmojiDrawable.getDocumentId(); - } - return false; - } - public void setRecentReactions(List reactions) { selectAnimatedEmojiDialog.setRecentReactions(reactions); } 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 affc86f77..15d2a6a03 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ReactionsContainerLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ReactionsContainerLayout.java @@ -18,6 +18,7 @@ import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Shader; import android.graphics.drawable.Drawable; +import android.provider.Settings; import android.util.Property; import android.view.Gravity; import android.view.HapticFeedbackConstants; @@ -54,6 +55,7 @@ import org.telegram.messenger.SvgHelper; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; import org.telegram.tgnet.TLRPC; +import org.telegram.ui.ActionBar.ActionBarPopupWindow; import org.telegram.ui.ActionBar.AlertDialog; import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ActionBar.Theme; @@ -90,6 +92,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio private final static float SCALE_PROGRESS = 0.75f; private final static float CLIP_PROGRESS = 0.25f; public final RecyclerListView recyclerListView; + public final float durationScale; private Paint bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private Paint leftShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG), @@ -158,9 +161,11 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio private boolean allReactionsAvailable; private boolean allReactionsIsDefault; private Paint selectedPaint; + ChatScrimPopupContainerLayout parentLayout; public ReactionsContainerLayout(BaseFragment fragment, @NonNull Context context, int currentAccount, Theme.ResourcesProvider resourcesProvider) { super(context); + durationScale = Settings.Global.getFloat(context.getContentResolver(), Settings.Global.ANIMATOR_DURATION_SCALE, 1.0f); selectedPaint = new Paint(Paint.ANTI_ALIAS_FLAG); selectedPaint.setColor(Theme.getColor(Theme.key_listSelector, resourcesProvider)); this.resourcesProvider = resourcesProvider; @@ -591,9 +596,6 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio float cPr = (Math.max(CLIP_PROGRESS, Math.min(transitionProgress, 1f)) - CLIP_PROGRESS) / (1f - CLIP_PROGRESS); float br = bigCircleRadius * cPr, sr = smallCircleRadius * cPr; -// if (customEmojiReactionsEnterProgress != 0) { -// return; -// } lastVisibleViewsTmp.clear(); lastVisibleViewsTmp.addAll(lastVisibleViews); @@ -620,8 +622,8 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio int s = canvas.save(); float pivotX = LocaleController.isRTL || mirrorX ? getWidth() * 0.125f : getWidth() * 0.875f; - if (transitionProgress <= SCALE_PROGRESS) { - float sc = transitionProgress / SCALE_PROGRESS; + if (transitionProgress != 1f) { + float sc = transitionProgress; canvas.scale(sc, sc, pivotX, getHeight() / 2f); } @@ -636,7 +638,8 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio if (chatScrimPopupContainerLayout != null) { chatScrimPopupContainerLayout.setExpandSize(expandSize); } - rect.set(getPaddingLeft() + (getWidth() - getPaddingRight()) * lt, getPaddingTop() + recyclerListView.getMeasuredHeight() * (1f - otherViewsScale) - expandSize, (getWidth() - getPaddingRight()) * rt, getHeight() - getPaddingBottom() + expandSize); + float transitionLeftOffset = (getWidth() - getPaddingRight()) * Math.min(1f, lt); + rect.set(getPaddingLeft() + transitionLeftOffset, getPaddingTop() + recyclerListView.getMeasuredHeight() * (1f - otherViewsScale) - expandSize, (getWidth() - getPaddingRight()) * rt, getHeight() - getPaddingBottom() + expandSize); radius = (rect.height() - expandSize * 2f) / 2f; shadow.setAlpha((int) (Utilities.clamp(1f - (customEmojiReactionsEnterProgress / 0.05f), 1f, 0f) * 255)); shadow.setBounds((int) (getPaddingLeft() + (getWidth() - getPaddingRight() + shadowPad.right) * lt - shadowPad.left), getPaddingTop() - shadowPad.top - (int) expandSize, (int) ((getWidth() - getPaddingRight() + shadowPad.right) * rt), getHeight() - getPaddingBottom() + shadowPad.bottom + (int) expandSize); @@ -646,8 +649,8 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio if (!skipDraw) { s = canvas.save(); - if (transitionProgress <= SCALE_PROGRESS) { - float sc = transitionProgress / SCALE_PROGRESS; + if (transitionProgress != 1f) { + float sc = transitionProgress; canvas.scale(sc, sc, pivotX, getHeight() / 2f); } canvas.drawRoundRect(rect, radius, radius, bgPaint); @@ -658,8 +661,8 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio mPath.addRoundRect(rect, radius, radius, Path.Direction.CW); s = canvas.save(); - if (transitionProgress <= SCALE_PROGRESS) { - float sc = transitionProgress / SCALE_PROGRESS; + if (transitionProgress != 1f) { + float sc = transitionProgress; canvas.scale(sc, sc, pivotX, getHeight() / 2f); } @@ -668,6 +671,10 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio int lastReactionX = 0; for (int i = 0; i < recyclerListView.getChildCount(); i++) { View child = recyclerListView.getChildAt(i); + if (transitionProgress != 1f) { + float childCenterX = child.getLeft() + child.getMeasuredWidth() / 2f; + delay = (int) (200 * ((Math.abs(childCenterX / (float) recyclerListView.getMeasuredWidth() - 0.8f)))); + } if (child instanceof ReactionHolderView) { ReactionHolderView view = (ReactionHolderView) recyclerListView.getChildAt(i); checkPressedProgress(canvas, view); @@ -690,6 +697,9 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio if (child == premiumLockContainer) { if (child.getX() + child.getMeasuredWidth() / 2f > 0 && child.getX() + child.getMeasuredWidth() / 2f < recyclerListView.getWidth()) { if (!lastVisibleViewsTmp.contains(child)) { + if (transitionProgress != 1f) { + premiumLockIconView.resetAnimation(); + } premiumLockIconView.play(delay); delay += 30; } @@ -701,6 +711,9 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio if (child == customReactionsContainer) { if (child.getX() + child.getMeasuredWidth() / 2f > 0 && child.getX() + child.getMeasuredWidth() / 2f < recyclerListView.getWidth()) { if (!lastVisibleViewsTmp.contains(child)) { + if (transitionProgress != 1f) { + customEmojiReactionsIconView.resetAnimation(); + } customEmojiReactionsIconView.play(delay); delay += 30; } @@ -726,7 +739,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio float scale = Utilities.clamp(progress, 1f, 0f); nextRecentReaction.setScaleX(scale); nextRecentReaction.setScaleY(scale); - nextRecentReaction.setTranslationX(recyclerListView.getLeft() + left - pullingOffsetX - AndroidUtilities.dp(20)); + nextRecentReaction.setTranslationX(recyclerListView.getX() + left - pullingOffsetX - AndroidUtilities.dp(20)); nextRecentReaction.setVisibility(View.VISIBLE); } else { nextRecentReaction.setVisibility(View.GONE); @@ -739,9 +752,6 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio if (skipDraw && reactionsWindow != null) { int alpha = (int) (Utilities.clamp(1f - (customEmojiReactionsEnterProgress / 0.2f), 1f, 0f) * (1f - customEmojiReactionsEnterProgress) * 255); canvas.save(); - //canvas.translate(rect.left - reactionsWindow.drawingRect.left + (rect.width() - reactionsWindow.drawingRect.width()), rect.top - reactionsWindow.drawingRect.top + (rect.height() - reactionsWindow.drawingRect.height())); - - // canvas.translate(rect.width() - reactionsWindow.drawingRect.width(), (reactionsWindow.drawingRect.bottom() - rect.height())); drawBubbles(canvas, br, cPr, sr, alpha); canvas.restore(); return; @@ -749,6 +759,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio canvas.clipPath(mPath); canvas.translate((LocaleController.isRTL || mirrorX ? -1 : 1) * getWidth() * (1f - transitionProgress), 0); + recyclerListView.setTranslationX(-transitionLeftOffset); super.dispatchDraw(canvas); if (leftShadowPaint != null) { @@ -776,7 +787,8 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio private void drawBubbles(Canvas canvas, float br, float cPr, float sr, int alpha) { canvas.save(); - canvas.clipRect(0, AndroidUtilities.lerp(rect.bottom, 0, CubicBezierInterpolator.DEFAULT.getInterpolation(flipVerticalProgress)), getMeasuredWidth(), AndroidUtilities.lerp(getMeasuredHeight() + AndroidUtilities.dp(8), getPaddingTop() - expandSize(), CubicBezierInterpolator.DEFAULT.getInterpolation(flipVerticalProgress))); + float scale = transitionProgress; + canvas.clipRect(0, AndroidUtilities.lerp(rect.bottom, 0, CubicBezierInterpolator.DEFAULT.getInterpolation(flipVerticalProgress)) - (int) Math.ceil(rect.height() / 2f * (1f - transitionProgress)), getMeasuredWidth(), AndroidUtilities.lerp(getMeasuredHeight() + AndroidUtilities.dp(8), getPaddingTop() - expandSize(), CubicBezierInterpolator.DEFAULT.getInterpolation(flipVerticalProgress))); float cx = LocaleController.isRTL || mirrorX ? bigCircleOffset : getWidth() - bigCircleOffset; float cy = getHeight() - getPaddingBottom() + expandSize(); cy = AndroidUtilities.lerp(cy, getPaddingTop() - expandSize(), CubicBezierInterpolator.DEFAULT.getInterpolation(flipVerticalProgress)); @@ -816,7 +828,6 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio view.setScaleY(otherViewsScale); } - private void checkPressedProgress(Canvas canvas, ReactionHolderView view) { float pullingOffsetX = 0; if (pullingLeftOffset != 0) { @@ -913,10 +924,12 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio public void setTransitionProgress(float transitionProgress) { this.transitionProgress = transitionProgress; + if (parentLayout != null && parentLayout.getPopupWindowLayout() != null) { + parentLayout.getPopupWindowLayout().setReactionsTransitionProgress(transitionProgress); + } invalidate(); } - public void setMessage(MessageObject message, TLRPC.ChatFull chatFull) { this.messageObject = message; TLRPC.ChatFull reactionsChat = chatFull; @@ -971,7 +984,6 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio } } - private void fillRecentReactionsList(List visibleReactions) { if (!allReactionsAvailable) { //fill default reactions @@ -1037,8 +1049,8 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio public void startEnterAnimation() { setTransitionProgress(0); setAlpha(1f); - ObjectAnimator animator = ObjectAnimator.ofFloat(this, ReactionsContainerLayout.TRANSITION_PROGRESS_VALUE, 0f, 1f).setDuration(400); - animator.setInterpolator(new OvershootInterpolator(1.004f)); + ObjectAnimator animator = ObjectAnimator.ofFloat(this, ReactionsContainerLayout.TRANSITION_PROGRESS_VALUE, 0f, 1f).setDuration(350); + animator.setInterpolator(new OvershootInterpolator(0.5f)); animator.start(); } @@ -1198,6 +1210,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio public boolean selected; public boolean drawSelected = true; public int position; + public boolean waitingAnimation; Runnable playRunnable = new Runnable() { @Override @@ -1205,6 +1218,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio if (enterImageView.getImageReceiver().getLottieAnimation() != null && !enterImageView.getImageReceiver().getLottieAnimation().isRunning() && !enterImageView.getImageReceiver().getLottieAnimation().isGeneratingCache()) { enterImageView.getImageReceiver().getLottieAnimation().start(); } + waitingAnimation = false; } }; @@ -1230,7 +1244,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); - if (imageReceiver.getLottieAnimation() != null) { + if (imageReceiver.getLottieAnimation() != null && !waitingAnimation) { imageReceiver.getLottieAnimation().start(); } if (shouldSwitchToLoopView && !switchedToLoopView && imageReceiver.getLottieAnimation() != null && imageReceiver.getLottieAnimation().isLastFrame() && loopImageView.imageReceiver.getLottieAnimation() != null && loopImageView.imageReceiver.getLottieAnimation().hasBitmap()) { @@ -1336,6 +1350,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio } pressedBackupImageView.getImageReceiver().setImage(ImageLocation.getForDocument(defaultReaction.select_animation), ReactionsUtils.SELECT_ANIMATION_FILTER, null, null, svgThumb, 0, "tgs", react, 0); + preloadImageReceiver.setAllowStartLottieAnimation(false); MediaDataController.getInstance(currentAccount).preloadImage(preloadImageReceiver, ImageLocation.getForDocument(defaultReaction.around_animation), ReactionsEffectOverlay.getFilterForAroundAnimation()); } } @@ -1370,10 +1385,13 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio if (enterImageView.getImageReceiver().getLottieAnimation() != null && !enterImageView.getImageReceiver().getLottieAnimation().isGeneratingCache() && !isEnter) { isEnter = true; if (delay == 0) { + waitingAnimation = false; enterImageView.getImageReceiver().getLottieAnimation().stop(); enterImageView.getImageReceiver().getLottieAnimation().setCurrentFrame(0, false); playRunnable.run(); + } else { + waitingAnimation = true; enterImageView.getImageReceiver().getLottieAnimation().stop(); enterImageView.getImageReceiver().getLottieAnimation().setCurrentFrame(0, false); AndroidUtilities.runOnUIThread(playRunnable, delay); @@ -1389,7 +1407,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio if (!isEnter) { loopImageView.setScaleY(0); loopImageView.setScaleX(0); - loopImageView.animate().scaleX(1f).scaleY(1).setDuration(150).setStartDelay(delay).start(); + loopImageView.animate().scaleX(1f).scaleY(1).setDuration(150).setStartDelay((long) (delay * durationScale)).start(); isEnter = true; } } @@ -1586,15 +1604,13 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio valueAnimator = ValueAnimator.ofFloat(getScaleX(), 1f); valueAnimator.setInterpolator(AndroidUtilities.overshootInterpolator); - valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float s = (float) animation.getAnimatedValue(); - setScaleX(s); - setScaleY(s); - customReactionsContainer.invalidate(); - } + valueAnimator.addUpdateListener(animation -> { + float s = (float) animation.getAnimatedValue(); + setScaleX(s); + setScaleY(s); + customReactionsContainer.invalidate(); }); + valueAnimator.setStartDelay((long) (delay * durationScale)); valueAnimator.setDuration(300); valueAnimator.start(); } @@ -1647,4 +1663,8 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio public float expandSize() { return (int) (getPullingLeftProgress() * AndroidUtilities.dp(6)); } + + public void setParentLayout(ChatScrimPopupContainerLayout layout) { + parentLayout = layout; + } } \ No newline at end of file diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/TranslateAlert2.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/TranslateAlert2.java index 7ae9144ac..dc22bf5f1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/TranslateAlert2.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/TranslateAlert2.java @@ -975,16 +975,30 @@ public class TranslateAlert2 extends BottomSheet implements NotificationCenter.N } public static String languageName(String locale) { - if (locale == null || locale.equals("und") || locale.equals("auto")) { + return languageName(locale, null); + } + + public static String languageName(String locale, boolean[] accusative) { + if (locale == null || locale.equals(TranslateController.UNKNOWN_LANGUAGE) || locale.equals("auto")) { return null; } - LocaleController.LocaleInfo currentLanguageInfo = LocaleController.getInstance().getCurrentLocaleInfo(); + + String simplifiedLocale = locale.split("_")[0]; + if ("nb".equals(simplifiedLocale)) { + simplifiedLocale = "no"; + } + + // getting localized language name in accusative case + if (accusative != null) { + String localed = LocaleController.getString("TranslateLanguage" + simplifiedLocale.toUpperCase()); + if (accusative[0] = (localed != null && !localed.startsWith("LOC_ERR"))) { + return localed; + } + } + + // getting language name from system try { Locale[] allLocales = Locale.getAvailableLocales(); - String simplifiedLocale = locale.split("_")[0]; - if ("nb".equals(simplifiedLocale)) { - simplifiedLocale = "no"; - } Locale found = null; for (int i = 0; i < allLocales.length; ++i) { if (TextUtils.equals(simplifiedLocale, allLocales[i].getLanguage())) { @@ -995,21 +1009,18 @@ public class TranslateAlert2 extends BottomSheet implements NotificationCenter.N if (found != null) { return found.getDisplayLanguage(Locale.getDefault()); } - } catch (Exception e) {} + } catch (Exception ignore) {} + + // getting language name from lang packs if ("no".equals(locale)) { locale = "nb"; } - LocaleController.LocaleInfo thisLanguageInfo = LocaleController.getInstance().getBuiltinLanguageByPlural(locale); + final LocaleController.LocaleInfo currentLanguageInfo = LocaleController.getInstance().getCurrentLocaleInfo(); + final LocaleController.LocaleInfo thisLanguageInfo = LocaleController.getInstance().getBuiltinLanguageByPlural(locale); if (thisLanguageInfo == null) { return null; } boolean isCurrentLanguageEnglish = currentLanguageInfo != null && "en".equals(currentLanguageInfo.pluralLangCode); -// try { -// String lang = LocaleController.getString("PassportLanguage_" + thisLanguageInfo.pluralLangCode.toUpperCase()); -// if (lang != null && !lang.startsWith("LOC_ERR")) { -// return lang; -// } -// } catch (Exception ignore) {} if (isCurrentLanguageEnglish) { return thisLanguageInfo.nameEnglish; } else { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/TranslateButton.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/TranslateButton.java index c82ee9583..b2c110351 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/TranslateButton.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/TranslateButton.java @@ -1,6 +1,7 @@ package org.telegram.ui.Components; import android.content.Context; +import android.graphics.Canvas; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; @@ -10,6 +11,7 @@ import android.text.TextUtils; import android.text.style.DynamicDrawableSpan; import android.text.style.ImageSpan; import android.view.Gravity; +import android.view.View; import android.view.WindowManager; import android.widget.FrameLayout; import android.widget.ImageView; @@ -45,6 +47,8 @@ public class TranslateButton extends FrameLayout { private ImageView menuView; + private boolean[] accusative = new boolean[1]; + public TranslateButton(Context context, ChatActivity chatActivity, Theme.ResourcesProvider resourcesProvider) { this(context, chatActivity.getCurrentAccount(), chatActivity.getDialogId(), chatActivity, resourcesProvider); } @@ -98,7 +102,38 @@ public class TranslateButton extends FrameLayout { LinearLayout swipeBack = new LinearLayout(getContext()); swipeBack.setOrientation(LinearLayout.VERTICAL); - ScrollView swipeBackScrollView = new ScrollView(getContext()); + ScrollView swipeBackScrollView = new ScrollView(getContext()) { + Drawable topShadowDrawable; + AnimatedFloat alphaFloat = new AnimatedFloat(this, 350, CubicBezierInterpolator.EASE_OUT_QUINT); + private boolean wasCanScrollVertically; + + @Override + public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) { + super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed); + boolean canScrollVertically = canScrollVertically(-1); + if (wasCanScrollVertically != canScrollVertically) { + invalidate(); + wasCanScrollVertically = canScrollVertically; + } + } + + @Override + protected void dispatchDraw(Canvas canvas) { + super.dispatchDraw(canvas); + + float alpha = .5f * alphaFloat.set(canScrollVertically(-1) ? 1 : 0); + if (alpha > 0) { + if (topShadowDrawable == null) { + topShadowDrawable = getContext().getResources().getDrawable(R.drawable.header_shadow); + } + topShadowDrawable.setBounds( + 0, getScrollY(), getWidth(), getScrollY() + topShadowDrawable.getIntrinsicHeight() + ); + topShadowDrawable.setAlpha((int) (0xFF * alpha)); + topShadowDrawable.draw(canvas); + } + } + }; LinearLayout swipeBackScroll = new LinearLayout(getContext()); swipeBackScrollView.addView(swipeBackScroll); swipeBackScroll.setOrientation(LinearLayout.VERTICAL); @@ -117,15 +152,16 @@ public class TranslateButton extends FrameLayout { backButton.setOnClickListener(e -> popupLayout.getSwipeBack().closeForeground()); swipeBack.addView(backButton); - swipeBack.addView(new ActionBarPopupWindow.GapView(getContext(), resourcesProvider), LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 8)); swipeBack.addView(swipeBackScrollView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 420)); String detectedLanguage = translateController.getDialogDetectedLanguage(dialogId); String detectedLanguageName = TranslateAlert2.languageName(detectedLanguage); + String detectedLanguageNameAccusative = TranslateAlert2.languageName(detectedLanguage, accusative); String currentTranslateTo = translateController.getDialogTranslateTo(dialogId); ArrayList suggestedLanguages = TranslateController.getSuggestedLanguages(currentTranslateTo); ArrayList allLanguages = TranslateController.getLanguages(); + swipeBackScroll.addView(new ActionBarPopupWindow.GapView(getContext(), resourcesProvider), LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 8)); if (currentTranslateTo != null) { String displayName = TranslateAlert2.capitalFirst(TranslateAlert2.languageName(currentTranslateTo)); if (displayName != null) { @@ -185,15 +221,13 @@ public class TranslateButton extends FrameLayout { popupLayout.addView(new ActionBarPopupWindow.GapView(getContext(), resourcesProvider), LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 8)); - if (detectedLanguageName != null && detectedLanguage != null) { + if (detectedLanguageNameAccusative != null) { ActionBarMenuSubItem dontTranslateButton = new ActionBarMenuSubItem(getContext(), true, false, resourcesProvider); String text; - String lang = LocaleController.getString("TranslateLanguage" + detectedLanguage.toUpperCase()); - if (lang == null || lang.startsWith("LOC_ERR")) { - lang = detectedLanguageName; - text = LocaleController.formatString("DoNotTranslateLanguageOther", R.string.DoNotTranslateLanguageOther, lang); + if (accusative[0]) { + text = LocaleController.formatString("DoNotTranslateLanguage", R.string.DoNotTranslateLanguage, detectedLanguageNameAccusative); } else { - text = LocaleController.formatString("DoNotTranslateLanguage", R.string.DoNotTranslateLanguage, lang); + text = LocaleController.formatString("DoNotTranslateLanguageOther", R.string.DoNotTranslateLanguageOther, detectedLanguageNameAccusative); } dontTranslateButton.setTextAndIcon(text, R.drawable.msg_block2); dontTranslateButton.setOnClickListener(e -> { @@ -249,12 +283,11 @@ public class TranslateButton extends FrameLayout { lng = "en"; } String text; - String lang = LocaleController.getString("TranslateLanguage" + lng.toUpperCase()); - if (lang == null || lang.startsWith("LOC_ERR")) { - lang = TranslateAlert2.languageName(lng); - text = LocaleController.formatString("TranslateToButtonOther", R.string.TranslateToButtonOther, lang); - } else { + String lang = TranslateAlert2.languageName(lng, accusative); + if (accusative[0]) { text = LocaleController.formatString("TranslateToButton", R.string.TranslateToButton, lang); + } else { + text = LocaleController.formatString("TranslateToButtonOther", R.string.TranslateToButtonOther, lang); } textView.setText(TextUtils.concat(translateIcon, " ", text)); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java index 253b85884..0be379c5a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java @@ -6222,6 +6222,9 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. if (fragmentView != null) { fragmentView.invalidate(); } + if (dialogsHintCell != null) { + dialogsHintCell.setAlpha(1f - progress); + } if (full) { // // if (show) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java index 30acc549b..0afb8c329 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java @@ -219,11 +219,12 @@ public class LanguageSelectActivity extends BaseFragment implements Notification } final boolean currentFullValue = getContextValue() || getChatValue(); if (currentFullValue != prevFullValue) { - listAdapter.notifyItemChanged(2); + int start = 1 + (!getMessagesController().premiumLocked ? 1 : 0); + listAdapter.notifyItemChanged(start); if (currentFullValue) { - listAdapter.notifyItemInserted(3); + listAdapter.notifyItemInserted(start + 1); } else { - listAdapter.notifyItemRemoved(3); + listAdapter.notifyItemRemoved(start + 1); } } return; @@ -236,7 +237,7 @@ public class LanguageSelectActivity extends BaseFragment implements Notification } boolean search = listView.getAdapter() == searchListViewAdapter; if (!search) { - position -= (getChatValue() || getContextValue()) ? 7 : 6; + position -= (7 - (!(getChatValue() || getContextValue()) ? 1 : 0) - (getMessagesController().premiumLocked ? 1 : 0)); } LocaleController.LocaleInfo localeInfo; if (search) { @@ -299,7 +300,7 @@ public class LanguageSelectActivity extends BaseFragment implements Notification } boolean search = listView.getAdapter() == searchListViewAdapter; if (!search) { - position -= (getChatValue() || getContextValue()) ? 7 : 6; + position -= (7 - (!(getChatValue() || getContextValue()) ? 1 : 0) - (getMessagesController().premiumLocked ? 1 : 0)); } LocaleController.LocaleInfo localeInfo; if (search) { @@ -812,7 +813,7 @@ public class LanguageSelectActivity extends BaseFragment implements Notification if (!unofficialLanguages.isEmpty()) { count += unofficialLanguages.size() + 1; } - return 5 + (getChatValue() || getContextValue() ? 1 : 0) + 1 + count; + return 4 + (getMessagesController().premiumLocked ? 0 : 1) + (getChatValue() || getContextValue() ? 1 : 0) + 1 + count; } } @@ -858,7 +859,7 @@ public class LanguageSelectActivity extends BaseFragment implements Notification switch (holder.getItemViewType()) { case VIEW_TYPE_LANGUAGE: { if (!search) { - position -= (getChatValue() || getContextValue()) ? 7 : 6; + position -= (7 - (!(getChatValue() || getContextValue()) ? 1 : 0) - (getMessagesController().premiumLocked ? 1 : 0)); } TextRadioCell textSettingsCell = (TextRadioCell) holder.itemView; LocaleController.LocaleInfo localeInfo = null; @@ -907,8 +908,9 @@ public class LanguageSelectActivity extends BaseFragment implements Notification final String doNotTranslateCellName = LocaleController.getString("DoNotTranslate", R.string.DoNotTranslate); String doNotTranslateCellValue = null; try { + boolean[] accusative = new boolean[1]; if (langCodes.size() == 1) { - doNotTranslateCellValue = TranslateAlert2.capitalFirst(TranslateAlert2.languageName(langCodes.iterator().next())); + doNotTranslateCellValue = TranslateAlert2.capitalFirst(TranslateAlert2.languageName(langCodes.iterator().next(), accusative)); } else { Iterator iterator = langCodes.iterator(); boolean first = true; @@ -918,7 +920,7 @@ public class LanguageSelectActivity extends BaseFragment implements Notification if (!first) { string.append(", "); } - string.append(TranslateAlert2.capitalFirst(TranslateAlert2.languageName(lang))); + string.append(TranslateAlert2.capitalFirst(TranslateAlert2.languageName(lang, accusative))); first = false; } doNotTranslateCellValue = string.toString(); @@ -973,14 +975,16 @@ public class LanguageSelectActivity extends BaseFragment implements Notification } else { if (i-- == 0) return VIEW_TYPE_HEADER; if (i-- == 0) return VIEW_TYPE_SWITCH; - if (i-- == 0) return VIEW_TYPE_SWITCH; + if (!getMessagesController().premiumLocked) { + if (i-- == 0) return VIEW_TYPE_SWITCH; + } if (getChatValue() || getContextValue()) { if (i-- == 0) return VIEW_TYPE_SETTINGS; } if (i-- == 0) return VIEW_TYPE_INFO; if (i-- == 0) return VIEW_TYPE_INFO; if (i-- == 0) return VIEW_TYPE_HEADER; - if (!unofficialLanguages.isEmpty() && (i == unofficialLanguages.size() || i == unofficialLanguages.size() + 1 + sortedLanguages.size() + 1) || unofficialLanguages.isEmpty() && i == sortedLanguages.size()) { + if (!unofficialLanguages.isEmpty() && (i == unofficialLanguages.size() || i == unofficialLanguages.size() + sortedLanguages.size() + 1) || unofficialLanguages.isEmpty() && i == sortedLanguages.size()) { return VIEW_TYPE_SHADOW; } return VIEW_TYPE_LANGUAGE; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java index c8a67e934..37e260dd7 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java @@ -6627,7 +6627,11 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } profileTransitionInProgress = true; ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1f); - valueAnimator.addUpdateListener(valueAnimator1 -> fragmentView.invalidate()); + valueAnimator.addUpdateListener(valueAnimator1 -> { + if (fragmentView != null) { + fragmentView.invalidate(); + } + }); animatorSet.playTogether(valueAnimator); animatorSet.addListener(new AnimatorListenerAdapter() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/QrActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/QrActivity.java index bf48fba10..7c33bb5e9 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/QrActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/QrActivity.java @@ -374,7 +374,9 @@ public class QrActivity extends BaseFragment { fragmentView = rootLayout; Utilities.themeQueue.postRunnable(() -> { homeTheme.loadPreviewColors(currentAccount); - + if (fragmentView == null) { + return; + } fragmentView.postDelayed(() -> { onItemSelected(currentTheme, 0, true); }, 17); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SelectAnimatedEmojiDialog.java b/TMessagesProj/src/main/java/org/telegram/ui/SelectAnimatedEmojiDialog.java index d9a9490d9..6a92bc344 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SelectAnimatedEmojiDialog.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SelectAnimatedEmojiDialog.java @@ -164,8 +164,9 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati private ImageViewEmoji forumIconImage; private boolean animationsEnabled; private boolean showStickers; - private boolean forUser; + public boolean forUser; private ArrayList stickerSets = new ArrayList<>(); + private boolean enterAnimationInProgress; public void putAnimatedEmojiToCache(AnimatedEmojiDrawable animatedEmojiDrawable) { emojiGridView.animatedEmojiDrawables.put(animatedEmojiDrawable.getDocumentId(), animatedEmojiDrawable); @@ -326,10 +327,10 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati private final static int currentAccount = UserConfig.selectedAccount; private int type; - private FrameLayout contentView; + public FrameLayout contentView; private View backgroundView; private EmojiTabsStrip[] cachedEmojiTabs = new EmojiTabsStrip[2]; - private EmojiTabsStrip emojiTabs; + public EmojiTabsStrip emojiTabs; private View emojiTabsShadow; private SearchBox searchBox; public FrameLayout gridViewContainer; @@ -365,7 +366,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati private ArrayList frozenEmojiPacks = new ArrayList<>(); private ArrayList packs = new ArrayList<>(); private boolean includeEmpty = false; - private boolean includeHint = false; + public boolean includeHint = false; private Integer hintExpireDate; private boolean drawBackground = true; private List recentReactionsToSet; @@ -403,7 +404,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati this.type = type; this.includeEmpty = includeEmpty; this.baseFragment = baseFragment; - this.includeHint = MessagesController.getGlobalMainSettings().getInt("emoji"+(type==TYPE_EMOJI_STATUS?"status":"reaction")+"usehint", 0) < 3; + this.includeHint = MessagesController.getGlobalMainSettings().getInt("emoji" + (type == TYPE_EMOJI_STATUS ? "status" : "reaction") + "usehint", 0) < 3; selectorPaint.setColor(Theme.getColor(Theme.key_listSelector, resourcesProvider)); selectorAccentPaint.setColor(ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_windowBackgroundWhiteBlueIcon, resourcesProvider), 30)); @@ -474,7 +475,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati path.rewind(); path.addRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(12), AndroidUtilities.dp(12), Path.Direction.CW); canvas.drawPath(path, paint); -// if (showAnimator != null && showAnimator.isRunning()) { +// if (enterAnimationInProgress() { canvas.clipPath(path); // } super.dispatchDraw(canvas); @@ -1288,6 +1289,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati gridSwitchAnimator.start(); ((View) emojiGridView.getParent()).animate() .translationY(gridSearch && liftUp ? -AndroidUtilities.dp(36) : 0) + .setUpdateListener(anm -> invalidateParent()) .setInterpolator(CubicBezierInterpolator.DEFAULT) .setDuration(160) .start(); @@ -1699,7 +1701,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } else { view = new ImageViewEmoji(getContext()); } - if (showAnimator != null && showAnimator.isRunning()) { + if (enterAnimationInProgress()) { view.setScaleX(0); view.setScaleY(0); } @@ -1982,7 +1984,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } else { view = new ImageViewEmoji(getContext()); } - if (showAnimator != null && showAnimator.isRunning()) { + if (enterAnimationInProgress()) { view.setScaleX(0); view.setScaleY(0); } @@ -2300,6 +2302,10 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } } + private boolean enterAnimationInProgress() { + return enterAnimationInProgress || (showAnimator != null && showAnimator.isRunning()); + } + private void clearRecent() { if (type == TYPE_REACTIONS && onRecentClearedListener != null) { onRecentClearedListener.onRecentCleared(); @@ -2565,6 +2571,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati public int skewIndex; public boolean isStaticIcon; private float selectedProgress; + final AnimatedEmojiSpan.InvalidateHolder invalidateHolder = new AnimatedEmojiSpan.InvalidateHolder() { @Override public void invalidate() { @@ -2851,7 +2858,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati totalCount++; } } else { - TLRPC.TL_emojiList emojiList = forUser ? MediaDataController.getInstance(currentAccount).profileAvatarConstructorDefault : MediaDataController.getInstance(currentAccount).groupAvatarConstructorDefault; + TLRPC.TL_emojiList emojiList = forUser ? MediaDataController.getInstance(currentAccount). profileAvatarConstructorDefault : MediaDataController.getInstance(currentAccount).groupAvatarConstructorDefault; if (emojiList != null && emojiList.document_id != null && !emojiList.document_id.isEmpty()) { for (int i = 0; i < emojiList.document_id.size(); ++i) { recent.add(new AnimatedEmojiSpan(emojiList.document_id.get(i), null)); @@ -3262,8 +3269,8 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati SparseArray> viewsGroupedByLines = new SparseArray<>(); ArrayList> unusedArrays = new ArrayList<>(); ArrayList unusedLineDrawables = new ArrayList<>(); - ArrayList lineDrawables = new ArrayList<>(); - ArrayList lineDrawablesTmp = new ArrayList<>(); + ArrayList lineDrawables = new ArrayList<>(); + ArrayList lineDrawablesTmp = new ArrayList<>(); private LongSparseArray animatedEmojiDrawables = new LongSparseArray<>(); @@ -3424,6 +3431,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati drawable = unusedLineDrawables.remove(unusedLineDrawables.size() - 1); } else { drawable = new DrawingInBackgroundLine(); + drawable.setLayerNum(7); } drawable.position = position; drawable.onAttachToWindow(); @@ -3499,7 +3507,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati skewAlpha = .25f + .75f * skewAlpha; } } - boolean drawInUi = skewAlpha < 1 || isAnimating() || imageViewEmojis.size() <= 4 || SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_LOW || (showAnimator != null && showAnimator.isRunning()) || SharedConfig.getLiteMode().enabled() || type == TYPE_AVATAR_CONSTRUCTOR; + boolean drawInUi = skewAlpha < 1 || isAnimating() || imageViewEmojis.size() <= 4 || SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_LOW || enterAnimationInProgress() || SharedConfig.getLiteMode().enabled() || type == TYPE_AVATAR_CONSTRUCTOR; if (!drawInUi) { boolean animatedExpandIn = animateExpandStartTime > 0 && (SystemClock.elapsedRealtime() - animateExpandStartTime) < animateExpandDuration(); for (int i = 0; i < imageViewEmojis.size(); i++) { @@ -3824,6 +3832,16 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati if (this == emojiGridView) { bigReactionImageReceiver.onDetachedFromWindow(); } + release(unusedLineDrawables); + release(lineDrawables); + release(lineDrawablesTmp); + } + + private void release(ArrayList lineDrawables) { + for (int i = 0; i < lineDrawables.size(); i++) { + lineDrawables.get(i).onDetachFromWindow(); + } + lineDrawables.clear(); } } @@ -4986,4 +5004,8 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati public void setAnimationsEnabled(boolean aniationsEnabled) { this.animationsEnabled = aniationsEnabled; } + + public void setEnterAnimationInProgress(boolean enterAnimationInProgress) { + this.enterAnimationInProgress = enterAnimationInProgress; + } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/TopicsFragment.java b/TMessagesProj/src/main/java/org/telegram/ui/TopicsFragment.java index 61debde21..238e450e0 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/TopicsFragment.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/TopicsFragment.java @@ -39,6 +39,7 @@ import android.view.ViewOutlineProvider; import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.EditText; import android.widget.FrameLayout; +import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; @@ -266,6 +267,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N private FrameLayout topView; private RLottieImageView floatingButton; private boolean canShowProgress; + private ImageView closeReportSpam; @Override public View getFullscreenView() { @@ -875,6 +877,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N recyclerListView.setLayoutManager(layoutManager = new LinearLayoutManager(context) { private boolean fixOffset; + @Override public void scrollToPositionWithOffset(int position, int offset) { if (fixOffset) { @@ -1190,6 +1193,20 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N bottomOverlayProgress.setVisibility(View.INVISIBLE); bottomOverlayContainer.addView(bottomOverlayProgress, LayoutHelper.createFrame(30, 30, Gravity.CENTER)); + closeReportSpam = new ImageView(context); + closeReportSpam.setImageResource(R.drawable.miniplayer_close); + closeReportSpam.setContentDescription(LocaleController.getString("Close", R.string.Close)); + if (Build.VERSION.SDK_INT >= 21) { + closeReportSpam.setBackground(Theme.AdaptiveRipple.circle(getThemedColor(Theme.key_chat_topPanelClose))); + } + closeReportSpam.setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_chat_topPanelClose), PorterDuff.Mode.MULTIPLY)); + closeReportSpam.setScaleType(ImageView.ScaleType.CENTER); + bottomOverlayContainer.addView(closeReportSpam, LayoutHelper.createFrame(36, 36, Gravity.RIGHT | Gravity.TOP, 0, 6, 2, 0)); + closeReportSpam.setOnClickListener(v -> { + getMessagesController().hidePeerSettingsBar(-chatId, null, getCurrentChat()); + updateChatInfo(); + }); + updateChatInfo(); fullscreenView = new FrameLayout(context) { @@ -1280,7 +1297,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N for (BaseFragment fragment : getParentLayout().getFragmentStack()) { if (fragment instanceof DialogsActivity && ((DialogsActivity) fragment).isMainDialogList()) { MessagesStorage.TopicKey topicKey = ((DialogsActivity) fragment).getOpenedDialogId(); - if (topicKey.dialogId == -chatId ) { + if (topicKey.dialogId == -chatId) { selectedTopicForTablet = topicKey.topicId; break; } @@ -1304,7 +1321,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N spannableStringBuilder.setSpan(coloredImageSpan, 0, 1, 0); if (ChatObject.canUserDoAdminAction(getCurrentChat(), ChatObject.ACTION_MANAGE_TOPICS)) { topicsEmptyView.subtitle.setText( - AndroidUtilities.replaceCharSequence("%s", AndroidUtilities.replaceTags(LocaleController.getString("NoTopicsDescription", R.string.NoTopicsDescription)), spannableStringBuilder) + AndroidUtilities.replaceCharSequence("%s", AndroidUtilities.replaceTags(LocaleController.getString("NoTopicsDescription", R.string.NoTopicsDescription)), spannableStringBuilder) ); } else { String general = LocaleController.getString("General", R.string.General); @@ -1313,7 +1330,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N general = topic.title; } topicsEmptyView.subtitle.setText( - AndroidUtilities.replaceTags(LocaleController.formatString("NoTopicsDescriptionUser", R.string.NoTopicsDescriptionUser, general)) + AndroidUtilities.replaceTags(LocaleController.formatString("NoTopicsDescriptionUser", R.string.NoTopicsDescriptionUser, general)) ); } } @@ -1359,6 +1376,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N private AvatarDrawable parentAvatarDrawable; private BackupImageView parentAvatarImageView; + private void openParentSearch() { if (parentDialogsActivity != null && parentDialogsActivity.getSearchItem() != null) { if (parentAvatarImageView == null) { @@ -1371,7 +1389,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N parentDialogsActivity.getSearchItem().setSearchPaddingStart(52); parentDialogsActivity.getActionBar().setSearchAvatarImageView(parentAvatarImageView); parentDialogsActivity.getActionBar().onSearchFieldVisibilityChanged( - parentDialogsActivity.getSearchItem().toggleSearch(true) + parentDialogsActivity.getSearchItem().toggleSearch(true) ); } } @@ -1392,6 +1410,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N } float transitionPadding; + public void setTransitionPadding(int transitionPadding) { this.transitionPadding = transitionPadding; updateFloatingButtonOffset(); @@ -2319,7 +2338,9 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N avatarContainer.setChatAvatar(chatLocal); + long dialog_id = -chatId; SharedPreferences preferences = MessagesController.getNotificationsSettings(currentAccount); + boolean show = preferences.getInt("dialog_bar_vis3" + dialog_id, 0) == 2; boolean showReport = preferences.getBoolean("dialog_bar_report" + (-chatId), false); boolean showBlock = preferences.getBoolean("dialog_bar_block" + (-chatId), false); @@ -2376,7 +2397,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N AndroidUtilities.updateViewVisibilityAnimated(bottomOverlayProgress, showProgress, 0.5f, animated); AndroidUtilities.updateViewVisibilityAnimated(bottomOverlayChatText, !showProgress, 0.5f, animated); setButtonType(BOTTOM_BUTTON_TYPE_JOIN); - } else if (showBlock || showReport) { + } else if (show && (showBlock || showReport)) { bottomOverlayChatText.setText(LocaleController.getString("ReportSpamAndLeave", R.string.ReportSpamAndLeave)); bottomOverlayChatText.setClickable(true); bottomOverlayChatText.setEnabled(true); @@ -2421,6 +2442,8 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N if (this.bottomButtonType != bottomButtonType) { this.bottomButtonType = bottomButtonType; bottomOverlayChatText.setTextColorKey(bottomButtonType == BOTTOM_BUTTON_TYPE_JOIN ? Theme.key_chat_fieldOverlayText : Theme.key_chat_reportSpam); + closeReportSpam.setVisibility(bottomButtonType == BOTTOM_BUTTON_TYPE_REPORT ? View.VISIBLE : View.GONE); + updateChatInfo(); } } @@ -2612,7 +2635,8 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N } else if (id == NotificationCenter.closeChats) { removeSelfFromStack(); - } if (id == NotificationCenter.openedChatChanged) { + } + if (id == NotificationCenter.openedChatChanged) { if (getParentActivity() == null || !(inPreviewMode && AndroidUtilities.isTablet())) { return; } @@ -2692,6 +2716,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N } else if (viewType == VIEW_TYPE_EMPTY) { return new RecyclerListView.Holder(emptyView = new View(getContext()) { HashMap precalcEllipsized = new HashMap<>(); + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = MeasureSpec.getSize(widthMeasureSpec); @@ -2706,8 +2731,8 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N if (oneline == null) { int nameLeft = AndroidUtilities.dp(!LocaleController.isRTL ? (isInPreviewMode() ? 11 : 50) + 4 : 18); int nameWidth = !LocaleController.isRTL ? - width - nameLeft - AndroidUtilities.dp(14 + 8) : - width - nameLeft - AndroidUtilities.dp((isInPreviewMode() ? 11 : 50) + 5 + 8); + width - nameLeft - AndroidUtilities.dp(14 + 8) : + width - nameLeft - AndroidUtilities.dp((isInPreviewMode() ? 11 : 50) + 5 + 8); nameWidth -= (int) Math.ceil(Theme.dialogs_timePaint.measureText("00:00")); oneline = Theme.dialogs_namePaint[0].measureText(title) <= nameWidth; precalcEllipsized.put(title, oneline); @@ -2950,6 +2975,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N private Boolean hidden; private float hiddenT; private ValueAnimator hiddenAnimator; + private void updateHidden(boolean hidden, boolean animated) { if (this.hidden == null) { animated = false; @@ -2974,15 +3000,16 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N setHiddenT(); } } + private void setHiddenT() { if (forumIcon instanceof ForumUtilities.GeneralTopicDrawable) { ((ForumUtilities.GeneralTopicDrawable) forumIcon).setColor( - ColorUtils.blendARGB(getThemedColor(Theme.key_chats_archivePullDownBackground), getThemedColor(Theme.key_avatar_background2Saved), hiddenT) + ColorUtils.blendARGB(getThemedColor(Theme.key_chats_archivePullDownBackground), getThemedColor(Theme.key_avatar_background2Saved), hiddenT) ); } if (topicIconInName != null && topicIconInName[0] instanceof ForumUtilities.GeneralTopicDrawable) { ((ForumUtilities.GeneralTopicDrawable) topicIconInName[0]).setColor( - ColorUtils.blendARGB(getThemedColor(Theme.key_chats_archivePullDownBackground), getThemedColor(Theme.key_avatar_background2Saved), hiddenT) + ColorUtils.blendARGB(getThemedColor(Theme.key_chats_archivePullDownBackground), getThemedColor(Theme.key_avatar_background2Saved), hiddenT) ); } invalidate(); @@ -3259,7 +3286,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N return downloadsContainer; } else { FilteredSearchView filteredSearchView = new FilteredSearchView(TopicsFragment.this); - filteredSearchView.setChatPreviewDelegate(chatPreviewDelegate); + filteredSearchView.setChatPreviewDelegate(chatPreviewDelegate); filteredSearchView.setUiCallback(MessagesSearchContainer.this); filteredSearchView.recyclerListView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override @@ -3639,7 +3666,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N } }); if (inPreviewMode && !getMessagesController().isForum(-chatId)) { - finishFragment(); + finishFragment(); } } diff --git a/gradle.properties b/gradle.properties index 3061e15e9..0053fac57 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,8 +13,8 @@ # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true #Sat Mar 12 05:53:50 MSK 2016 -APP_VERSION_NAME=9.4.0 -APP_VERSION_CODE=3098 +APP_VERSION_NAME=9.4.1 +APP_VERSION_CODE=3102 APP_PACKAGE=org.telegram.messenger RELEASE_KEY_PASSWORD=android RELEASE_KEY_ALIAS=androidkey