From e9a35cea54c06277c69d41b8e25d94b5d7ede065 Mon Sep 17 00:00:00 2001 From: xaxtix Date: Wed, 21 Sep 2022 18:20:30 +0400 Subject: [PATCH] update to 9.0.2 --- TMessagesProj/build.gradle | 37 +- .../telegram/messenger/AndroidUtilities.java | 47 +- .../telegram/messenger/ApplicationLoader.java | 25 + .../org/telegram/messenger/BuildVars.java | 11 +- .../org/telegram/messenger/FileLoader.java | 2 +- .../org/telegram/messenger/ImageReceiver.java | 7 +- .../messenger/MediaDataController.java | 118 +- .../org/telegram/messenger/MessageObject.java | 6 + .../messenger/MessagesController.java | 5 +- .../telegram/messenger/MessagesStorage.java | 1 + .../messenger/NotificationsController.java | 5 +- .../messenger/PushListenerController.java | 21 +- .../org/telegram/messenger/SharedConfig.java | 24 +- .../org/telegram/messenger/UserConfig.java | 7 +- .../messenger/utils/BitmapsCache.java | 8 +- .../main/java/org/telegram/tgnet/TLRPC.java | 220 +++- .../ui/ActionBar/ActionBarPopupWindow.java | 16 + .../telegram/ui/ActionBar/AlertDialog.java | 1 + .../telegram/ui/ActionBar/BottomSheet.java | 5 +- .../telegram/ui/ActionBar/SimpleTextView.java | 4 + .../org/telegram/ui/ActionIntroActivity.java | 4 +- .../java/org/telegram/ui/ArticleViewer.java | 6 +- .../telegram/ui/BasePermissionsActivity.java | 3 +- .../org/telegram/ui/Cells/AboutLinkCell.java | 2 +- .../org/telegram/ui/Cells/BotHelpCell.java | 4 +- .../org/telegram/ui/Cells/DialogCell.java | 26 +- .../telegram/ui/Cells/StickerEmojiCell.java | 3 +- .../telegram/ui/ChannelAdminLogActivity.java | 2 +- .../telegram/ui/ChannelCreateActivity.java | 4 +- .../java/org/telegram/ui/ChatActivity.java | 26 +- .../telegram/ui/Components/AlertsCreator.java | 1 + .../ui/Components/AnimatedEmojiDrawable.java | 4 +- .../telegram/ui/Components/AnimatedFloat.java | 2 +- .../ui/Components/ChatActivityEnterView.java | 3 +- .../ChatAttachAlertContactsLayout.java | 12 +- .../ui/Components/ChatAvatarContainer.java | 5 +- .../ui/Components/CloseProgressDrawable2.java | 6 +- .../ui/Components/EditTextBoldCursor.java | 12 +- .../ui/Components/InstantCameraView.java | 10 +- .../Components/MotionBackgroundDrawable.java | 41 +- .../telegram/ui/Components/PasscodeView.java | 153 ++- .../ui/Components/PhonebookShareAlert.java | 4 +- .../ui/Components/PhotoViewerWebView.java | 58 +- .../Premium/DoubleLimitsPageView.java | 55 + .../Premium/DoubledLimitsBottomSheet.java | 328 +++-- .../Premium/PremiumFeatureBottomSheet.java | 248 +++- .../Premium/PremiumPreviewBottomSheet.java | 10 +- .../ui/Components/ReactedUsersListView.java | 11 +- .../Reactions/CustomEmojiReactionsWindow.java | 130 +- .../Components/ReactionsContainerLayout.java | 4 +- .../Components/SearchDownloadsContainer.java | 12 +- .../telegram/ui/Components/SeekBarView.java | 59 +- .../Components/SizeNotifierFrameLayout.java | 2 +- .../org/telegram/ui/Components/Switch.java | 20 +- .../ui/Components/VideoPlayerSeekBar.java | 30 +- .../java/org/telegram/ui/DialogsActivity.java | 5 +- .../telegram/ui/GroupCreateFinalActivity.java | 4 +- .../java/org/telegram/ui/LaunchActivity.java | 13 +- .../org/telegram/ui/PaymentFormActivity.java | 27 + .../java/org/telegram/ui/PhotoViewer.java | 131 +- .../telegram/ui/PremiumPreviewFragment.java | 13 +- .../telegram/ui/PrivacySettingsActivity.java | 6 +- .../java/org/telegram/ui/ProfileActivity.java | 102 +- .../ui/SelectAnimatedEmojiDialog.java | 1154 ++++++++++++++--- .../java/org/telegram/ui/ThemeActivity.java | 102 +- .../res/drawable-hdpi/msg_calls_regular.png | Bin 0 -> 1063 bytes .../res/drawable-mdpi/msg_calls_regular.png | Bin 0 -> 757 bytes .../res/drawable-xhdpi/msg_calls_regular.png | Bin 0 -> 1663 bytes .../res/drawable-xxhdpi/msg_calls_regular.png | Bin 0 -> 2025 bytes TMessagesProj/src/main/res/raw/info.json | 1 + TMessagesProj/src/main/res/values/strings.xml | 9 + TMessagesProj_App/build.gradle | 26 +- .../messenger/GoogleVoiceClientService.java | 35 +- TMessagesProj_AppHockeyApp/.gitignore | 1 + TMessagesProj_AppHockeyApp/build.gradle | 171 +++ .../google-services.json | 98 ++ .../src/main/AndroidManifest.xml | 19 + .../messenger/ApplicationLoaderImpl.java | 65 + .../messenger/GoogleVoiceClientActivity.java | 19 + .../messenger/GoogleVoiceClientService.java | 22 + gradle.properties | 4 +- settings.gradle | 1 + 82 files changed, 3160 insertions(+), 738 deletions(-) create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/DoubleLimitsPageView.java create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/msg_calls_regular.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/msg_calls_regular.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/msg_calls_regular.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/msg_calls_regular.png create mode 100644 TMessagesProj/src/main/res/raw/info.json create mode 100644 TMessagesProj_AppHockeyApp/.gitignore create mode 100644 TMessagesProj_AppHockeyApp/build.gradle create mode 100644 TMessagesProj_AppHockeyApp/google-services.json create mode 100644 TMessagesProj_AppHockeyApp/src/main/AndroidManifest.xml create mode 100644 TMessagesProj_AppHockeyApp/src/main/java/org/telegram/messenger/ApplicationLoaderImpl.java create mode 100644 TMessagesProj_AppHockeyApp/src/main/java/org/telegram/messenger/GoogleVoiceClientActivity.java create mode 100644 TMessagesProj_AppHockeyApp/src/main/java/org/telegram/messenger/GoogleVoiceClientService.java diff --git a/TMessagesProj/build.gradle b/TMessagesProj/build.gradle index 4ab052f38..f5ef40b64 100644 --- a/TMessagesProj/build.gradle +++ b/TMessagesProj/build.gradle @@ -100,15 +100,33 @@ android { multiDexEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro' ndk.debugSymbolLevel = 'FULL' + buildConfigField "String", "APP_CENTER_HASH", "\"\"" + buildConfigField "boolean", "DEBUG_VERSION", "true" + buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "false" } - HA { + HA_private { debuggable false jniDebuggable false minifyEnabled true multiDexEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro' ndk.debugSymbolLevel = 'FULL' + buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_PRIVATE") + "\"" + buildConfigField "boolean", "DEBUG_VERSION", "true" + buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "true" + } + + HA_public { + debuggable false + jniDebuggable false + minifyEnabled true + multiDexEnabled true + proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro' + ndk.debugSymbolLevel = 'FULL' + buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_PUBLIC") + "\"" + buildConfigField "boolean", "DEBUG_VERSION", "true" + buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "false" } standalone { @@ -118,6 +136,9 @@ android { multiDexEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro' ndk.debugSymbolLevel = 'FULL' + buildConfigField "String", "APP_CENTER_HASH", "\"\"" + buildConfigField "boolean", "DEBUG_VERSION", "false" + buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "false" } release { @@ -128,8 +149,22 @@ android { multiDexEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro' ndk.debugSymbolLevel = 'FULL' + buildConfigField "String", "APP_CENTER_HASH", "\"\"" + buildConfigField "boolean", "DEBUG_VERSION", "false" + buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "false" } } } + +def getProps(String propName) { + def propsFile = rootProject.file('local.properties') + if (propsFile.exists()) { + def props = new Properties() + props.load(new FileInputStream(propsFile)) + return props[propName] + } else { + return ""; + } +} apply plugin: 'com.google.gms.google-services' diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java b/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java index f6f9d1114..0f4c9d9e8 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java @@ -46,6 +46,7 @@ import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; +import android.os.Bundle; import android.os.Environment; import android.os.PowerManager; import android.os.SystemClock; @@ -474,6 +475,40 @@ public class AndroidUtilities { } } + public static void googleVoiceClientService_performAction(Intent intent, boolean isVerified, Bundle options) { + if (!isVerified) { + return; + } + AndroidUtilities.runOnUIThread(() -> { + try { + int currentAccount = UserConfig.selectedAccount; + ApplicationLoader.postInitApplication(); + if (AndroidUtilities.needShowPasscode() || SharedConfig.isWaitingForPasscodeEnter) { + return; + } + String text = intent.getStringExtra("android.intent.extra.TEXT"); + if (!TextUtils.isEmpty(text)) { + String contactUri = intent.getStringExtra("com.google.android.voicesearch.extra.RECIPIENT_CONTACT_URI"); + String id = intent.getStringExtra("com.google.android.voicesearch.extra.RECIPIENT_CONTACT_CHAT_ID"); + long uid = Long.parseLong(id); + TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(uid); + if (user == null) { + user = MessagesStorage.getInstance(currentAccount).getUserSync(uid); + if (user != null) { + MessagesController.getInstance(currentAccount).putUser(user, true); + } + } + if (user != null) { + ContactsController.getInstance(currentAccount).markAsContacted(contactUri); + SendMessagesHelper.getInstance(currentAccount).sendMessage(text, user.id, null, null, null, true, null, null, null, true, 0, null, false); + } + } + } catch (Exception e) { + FileLog.e(e); + } + }); + } + private static class LinkSpec { String url; int start; @@ -2528,18 +2563,8 @@ public class AndroidUtilities { } }*/ - public static void startAppCenter(Activity context) { - - } - - private static long lastUpdateCheckTime; - - public static void checkForUpdates() { - - } - public static void appCenterLog(Throwable e) { - + ApplicationLoader.appCenterLog(e); } public static boolean shouldShowClipboardToast() { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java index 93be51e07..fe3c053ab 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java @@ -523,4 +523,29 @@ public class ApplicationLoader extends Application { } return result; } + + public static void startAppCenter(Activity context) { + applicationLoaderInstance.startAppCenterInternal(context); + } + + public static void checkForUpdates() { + applicationLoaderInstance.checkForUpdatesInternal(); + } + + public static void appCenterLog(Throwable e) { + applicationLoaderInstance.appCenterLogInternal(e); + } + + protected void appCenterLogInternal(Throwable e) { + + } + + protected void checkForUpdatesInternal() { + + } + + protected void startAppCenterInternal(Activity context) { + + } + } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java index 5286dab0b..bf34f3247 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java @@ -18,17 +18,16 @@ import java.util.Objects; public class BuildVars { - public static boolean DEBUG_VERSION = true; - public static boolean LOGS_ENABLED = true; - public static boolean DEBUG_PRIVATE_VERSION = false; + public static boolean DEBUG_VERSION = BuildConfig.DEBUG_VERSION; + public static boolean LOGS_ENABLED = BuildConfig.DEBUG_VERSION; + public static boolean DEBUG_PRIVATE_VERSION = BuildConfig.DEBUG_PRIVATE_VERSION; 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 = 2800; - public static String BUILD_VERSION_STRING = "9.0.1"; + public static int BUILD_VERSION = 2808; + public static String BUILD_VERSION_STRING = "9.0.2"; public static int APP_ID = 4; public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103"; - public static String APPCENTER_HASH = "f9726602-67c9-48d2-b5d0-4761f1c1a8f3"; public static String SMS_HASH = isStandaloneApp() ? "w0lkcmTZkKh" : (DEBUG_VERSION ? "O2P2z+/jBpJ" : "oLeq9AcOZkT"); public static String PLAYSTORE_APP_URL = "https://play.google.com/store/apps/details?id=org.telegram.messenger"; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java index d368883df..dc1cd6af3 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java @@ -81,7 +81,7 @@ public class FileLoader extends BaseController { public static final int IMAGE_TYPE_SVG_WHITE = 4; public static final int IMAGE_TYPE_THEME_PREVIEW = 5; - private final FileLoaderPriorityQueue largeFilesQueue = new FileLoaderPriorityQueue("large files queue", 1); + private final FileLoaderPriorityQueue largeFilesQueue = new FileLoaderPriorityQueue("large files queue", 2); private final FileLoaderPriorityQueue filesQueue = new FileLoaderPriorityQueue("files queue", 3); private final FileLoaderPriorityQueue imagesQueue = new FileLoaderPriorityQueue("imagesQueue queue", 6); private final FileLoaderPriorityQueue audioQueue = new FileLoaderPriorityQueue("audioQueue queue", 3); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ImageReceiver.java b/TMessagesProj/src/main/java/org/telegram/messenger/ImageReceiver.java index 783d057f8..eb795496b 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ImageReceiver.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ImageReceiver.java @@ -26,15 +26,12 @@ import android.graphics.Shader; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Build; -import android.util.Log; import android.view.View; import androidx.annotation.Keep; import org.telegram.tgnet.TLObject; import org.telegram.tgnet.TLRPC; -import org.telegram.ui.ActionBar.Theme; -import org.telegram.ui.Components.AnimatedEmojiDrawable; import org.telegram.ui.Components.AnimatedFileDrawable; import org.telegram.ui.Components.LoadingStickerDrawable; import org.telegram.ui.Components.RLottieDrawable; @@ -711,6 +708,10 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg public void setLayerNum(int value) { currentLayerNum = value; + if (attachedToWindow) { + currentOpenedLayerFlags = NotificationCenter.getGlobalInstance().getCurrentHeavyOperationFlags(); + currentOpenedLayerFlags &= ~currentLayerNum; + } } public void setImageBitmap(Bitmap bitmap) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java b/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java index 0b5a4b9a3..35ecc2456 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java @@ -65,6 +65,7 @@ import org.telegram.ui.Components.Bulletin; import org.telegram.ui.Components.ChatThemeBottomSheet; import org.telegram.ui.Components.RLottieDrawable; import org.telegram.ui.Components.Reactions.ReactionsEffectOverlay; +import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble; import org.telegram.ui.Components.Reactions.ReactionsUtils; import org.telegram.ui.Components.StickerSetBulletinLayout; import org.telegram.ui.Components.StickersArchiveAlert; @@ -1781,6 +1782,7 @@ public class MediaDataController extends BaseController { if (res != null && hash != 0) { loadFeaturedHash[emoji ? 1 : 0] = hash; } + loadingFeaturedStickers[emoji ? 1 : 0] = false; loadFeaturedStickers(emoji, false, false); }, res == null && !cache ? 1000 : 0); if (res == null) { @@ -6668,11 +6670,68 @@ public class MediaDataController extends BaseController { }); } + public void getAnimatedEmojiByKeywords(String query, Utilities.Callback> onResult) { + if (query == null) { + if (onResult != null) { + onResult.run(new ArrayList<>()); + } + return; + } + final ArrayList stickerSets = getStickerSets(TYPE_EMOJIPACKS); + final ArrayList featuredStickerSets = getFeaturedEmojiSets(); + Utilities.searchQueue.postRunnable(() -> { + ArrayList fullMatch = new ArrayList<>(); + ArrayList halfMatch = new ArrayList<>(); + String queryLowercased = query.toLowerCase(); + for (int i = 0; i < stickerSets.size(); ++i) { + if (stickerSets.get(i).keywords != null) { + ArrayList keywords = stickerSets.get(i).keywords; + for (int j = 0; j < keywords.size(); ++j) { + for (int k = 0; k < keywords.get(j).keyword.size(); ++k) { + String keyword = keywords.get(j).keyword.get(k); + if (queryLowercased.equals(keyword)) { + fullMatch.add(keywords.get(j).document_id); + } else if (queryLowercased.contains(keyword) || keyword.contains(queryLowercased)) { + halfMatch.add(keywords.get(j).document_id); + } + } + } + } + } + + for (int i = 0; i < featuredStickerSets.size(); ++i) { + if (featuredStickerSets.get(i) instanceof TLRPC.TL_stickerSetFullCovered && + ((TLRPC.TL_stickerSetFullCovered) featuredStickerSets.get(i)).keywords != null) { + ArrayList keywords = ((TLRPC.TL_stickerSetFullCovered) featuredStickerSets.get(i)).keywords; + for (int j = 0; j < keywords.size(); ++j) { + for (int k = 0; k < keywords.get(j).keyword.size(); ++k) { + String keyword = keywords.get(j).keyword.get(k); + if (queryLowercased.equals(keyword)) { + fullMatch.add(keywords.get(j).document_id); + } else if (queryLowercased.contains(keyword) || keyword.contains(queryLowercased)) { + halfMatch.add(keywords.get(j).document_id); + } + } + } + } + } + + fullMatch.addAll(halfMatch); + if (onResult != null) { + onResult.run(fullMatch); + } + }); + } + public void getEmojiSuggestions(String[] langCodes, String keyword, boolean fullMatch, KeywordResultCallback callback, boolean allowAnimated) { - getEmojiSuggestions(langCodes, keyword, fullMatch, callback, null, allowAnimated); + getEmojiSuggestions(langCodes, keyword, fullMatch, callback, null, allowAnimated, null); } public void getEmojiSuggestions(String[] langCodes, String keyword, boolean fullMatch, KeywordResultCallback callback, final CountDownLatch sync, boolean allowAnimated) { + getEmojiSuggestions(langCodes, keyword, fullMatch, callback, sync, allowAnimated, null); + } + + public void getEmojiSuggestions(String[] langCodes, String keyword, boolean fullMatch, KeywordResultCallback callback, final CountDownLatch sync, boolean allowAnimated, Integer maxAnimatedPerEmoji) { if (callback == null) { return; } @@ -6784,7 +6843,7 @@ public class MediaDataController extends BaseController { }); String aliasFinal = alias; if (allowAnimated && SharedConfig.suggestAnimatedEmoji) { - fillWithAnimatedEmoji(result, null, () -> { + fillWithAnimatedEmoji(result, maxAnimatedPerEmoji, () -> { if (sync != null) { callback.run(result, aliasFinal); sync.countDown(); @@ -6826,7 +6885,8 @@ public class MediaDataController extends BaseController { ArrayList animatedResult = new ArrayList<>(); ArrayList animatedEmoji = new ArrayList<>(); final int maxAnimatedPerEmoji = maxAnimatedPerEmojiInput == null ? (result.size() > 5 ? 1 : (result.size() > 2 ? 2 : 3)) : maxAnimatedPerEmojiInput; - for (int i = 0; i < Math.min(15, result.size()); ++i) { + int len = maxAnimatedPerEmojiInput == null ? Math.min(15, result.size()) : result.size(); + for (int i = 0; i < len; ++i) { String emoji = result.get(i).emoji; if (emoji == null) { continue; @@ -6859,17 +6919,6 @@ public class MediaDataController extends BaseController { for (int d = 0; d < set.documents.size(); ++d) { TLRPC.Document document = set.documents.get(d); if (document != null && document.attributes != null && !animatedEmoji.contains(document)) { - boolean duplicate = false; - for (int l = 0; l < animatedEmoji.size(); ++l) { - if (animatedEmoji.get(l).id == document.id) { - duplicate = true; - break; - } - } - if (duplicate) { - continue; - } - TLRPC.TL_documentAttributeCustomEmoji attribute = null; for (int k = 0; k < document.attributes.size(); ++k) { TLRPC.DocumentAttribute attr = document.attributes.get(k); @@ -6880,9 +6929,18 @@ public class MediaDataController extends BaseController { } if (attribute != null && emoji.equals(attribute.alt) && (isPremium || attribute.free)) { - animatedEmoji.add(document); - if (animatedEmoji.size() >= maxAnimatedPerEmoji) { - break; + boolean duplicate = false; + for (int l = 0; l < animatedEmoji.size(); ++l) { + if (animatedEmoji.get(l).id == document.id) { + duplicate = true; + break; + } + } + if (!duplicate) { + animatedEmoji.add(document); + if (animatedEmoji.size() >= maxAnimatedPerEmoji) { + break; + } } } } @@ -6906,17 +6964,6 @@ public class MediaDataController extends BaseController { for (int d = 0; d < documents.size(); ++d) { TLRPC.Document document = documents.get(d); if (document != null && document.attributes != null && !animatedEmoji.contains(document)) { - boolean duplicate = false; - for (int l = 0; l < animatedEmoji.size(); ++l) { - if (animatedEmoji.get(l).id == document.id) { - duplicate = true; - break; - } - } - if (duplicate) { - continue; - } - TLRPC.TL_documentAttributeCustomEmoji attribute = null; for (int k = 0; k < document.attributes.size(); ++k) { TLRPC.DocumentAttribute attr = document.attributes.get(k); @@ -6927,9 +6974,18 @@ public class MediaDataController extends BaseController { } if (attribute != null && emoji.equals(attribute.alt) && (isPremium || attribute.free)) { - animatedEmoji.add(document); - if (animatedEmoji.size() >= maxAnimatedPerEmoji) { - break; + boolean duplicate = false; + for (int l = 0; l < animatedEmoji.size(); ++l) { + if (animatedEmoji.get(l).id == document.id) { + duplicate = true; + break; + } + } + if (!duplicate) { + animatedEmoji.add(document); + if (animatedEmoji.size() >= maxAnimatedPerEmoji) { + break; + } } } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java index 80b0ccafd..2f98c549d 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java @@ -358,6 +358,12 @@ public class MessageObject { } } } + isSpoilersRevealed = old.isSpoilersRevealed; + if (isSpoilersRevealed && textLayoutBlocks != null) { + for (TextLayoutBlock block : textLayoutBlocks) { + block.spoilers.clear(); + } + } } public ArrayList getChoosenReactions() { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java index da249a58a..2a74dac0a 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java @@ -32,8 +32,6 @@ import androidx.collection.LongSparseArray; import androidx.core.app.NotificationManagerCompat; import androidx.core.util.Consumer; -import com.google.android.exoplayer2.util.Log; - import org.telegram.SQLite.SQLiteCursor; import org.telegram.SQLite.SQLiteException; import org.telegram.SQLite.SQLitePreparedStatement; @@ -13653,7 +13651,6 @@ public class MessagesController extends BaseController implements NotificationCe updatesOnMainThread = new ArrayList<>(); } updatesOnMainThread.add(baseUpdate); - Log.d("kek", "TL_updateMoveStickerSetToTop"); } else if (baseUpdate instanceof TLRPC.TL_updateSavedGifs) { if (updatesOnMainThread == null) { updatesOnMainThread = new ArrayList<>(); @@ -14934,7 +14931,7 @@ public class MessagesController extends BaseController implements NotificationCe } } } - getNotificationsController().removeDeletedMessagesFromNotifications(deletedMessagesFinal); + getNotificationsController().removeDeletedMessagesFromNotifications(deletedMessagesFinal, false); } if (scheduledDeletedMessagesFinal != null) { for (int a = 0, size = scheduledDeletedMessagesFinal.size(); a < size; a++) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java index 6d744c39e..7611ad47b 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java @@ -2145,6 +2145,7 @@ public class MessagesStorage extends BaseController { database.executeFast("DELETE FROM downloading_documents").stepThis().dispose(); database.executeFast("DELETE FROM attach_menu_bots").stepThis().dispose(); database.executeFast("DELETE FROM animated_emoji").stepThis().dispose(); + database.executeFast("DELETE FROM stickers_v2").stepThis().dispose(); cursor = database.queryFinalized("SELECT did FROM dialogs WHERE 1"); while (cursor.next()) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/NotificationsController.java b/TMessagesProj/src/main/java/org/telegram/messenger/NotificationsController.java index e31e781d7..d286c3c2a 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/NotificationsController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/NotificationsController.java @@ -418,7 +418,7 @@ public class NotificationsController extends BaseController { }); } - public void removeDeletedMessagesFromNotifications(LongSparseArray> deletedMessages) { + public void removeDeletedMessagesFromNotifications(LongSparseArray> deletedMessages, boolean isReactions) { ArrayList popupArrayRemove = new ArrayList<>(0); notificationsQueue.postRunnable(() -> { int old_unread_count = total_unread_count; @@ -434,6 +434,9 @@ public class NotificationsController extends BaseController { int mid = mids.get(b); MessageObject messageObject = sparseArray.get(mid); if (messageObject != null) { + if (isReactions && !messageObject.isReactionPush) { + continue; + } long dialogId = messageObject.getDialogId(); Integer currentCount = pushDialogs.get(dialogId); if (currentCount == null) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/PushListenerController.java b/TMessagesProj/src/main/java/org/telegram/messenger/PushListenerController.java index 3ec2d19b6..7d671c815 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/PushListenerController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/PushListenerController.java @@ -3,6 +3,7 @@ package org.telegram.messenger; import android.os.SystemClock; import android.text.TextUtils; import android.util.Base64; +import android.util.SparseBooleanArray; import androidx.annotation.IntDef; import androidx.collection.LongSparseArray; @@ -329,12 +330,30 @@ public class PushListenerController { ids.add(Utilities.parseInt(messagesArgs[a])); } deletedMessages.put(-channel_id, ids); - NotificationsController.getInstance(currentAccount).removeDeletedMessagesFromNotifications(deletedMessages); + NotificationsController.getInstance(currentAccount).removeDeletedMessagesFromNotifications(deletedMessages, false); MessagesController.getInstance(currentAccount).deleteMessagesByPush(dialogId, ids, channel_id); if (BuildVars.LOGS_ENABLED) { FileLog.d(tag + " received " + loc_key + " for dialogId = " + dialogId + " mids = " + TextUtils.join(",", ids)); } + } else if ("READ_REACTION".equals(loc_key)) { + String messages = custom.getString("messages"); + String[] messagesArgs = messages.split(","); + LongSparseArray> deletedMessages = new LongSparseArray<>(); + ArrayList ids = new ArrayList<>(); + SparseBooleanArray sparseBooleanArray = new SparseBooleanArray(); + for (int a = 0; a < messagesArgs.length; a++) { + int messageId = Utilities.parseInt(messagesArgs[a]); + ids.add(messageId); + sparseBooleanArray.put(messageId, false); + } + deletedMessages.put(-channel_id, ids); + NotificationsController.getInstance(currentAccount).removeDeletedMessagesFromNotifications(deletedMessages, true); + + MessagesController.getInstance(currentAccount).checkUnreadReactions(dialogId, sparseBooleanArray); + if (BuildVars.LOGS_ENABLED) { + FileLog.d(tag + " received " + loc_key + " for dialogId = " + dialogId + " mids = " + TextUtils.join(",", ids)); + } } else if (!TextUtils.isEmpty(loc_key)) { int msg_id; if (custom.has("msg_id")) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java b/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java index 9c55c6604..b2781924d 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java @@ -115,7 +115,7 @@ public class SharedConfig { public static boolean autoplayGifs = true; public static boolean autoplayVideo = true; public static boolean raiseToSpeak = false; - public static boolean recordViaSco = true; + public static boolean recordViaSco = false; public static boolean customTabs = true; public static boolean directShare = true; public static boolean inappCamera = true; @@ -142,6 +142,7 @@ public class SharedConfig { public static boolean allowBigEmoji; public static boolean useSystemEmoji; public static int fontSize = 16; + public static boolean fontSizeIsDefault; public static int bubbleRadius = 17; public static int ivFontSize = 16; public static int messageSeenHintCount; @@ -368,7 +369,7 @@ public class SharedConfig { autoplayVideo = preferences.getBoolean("autoplay_video", true); mapPreviewType = preferences.getInt("mapPreviewType", 2); raiseToSpeak = preferences.getBoolean("raise_to_speak", false); - recordViaSco = preferences.getBoolean("record_via_sco", true); + recordViaSco = preferences.getBoolean("record_via_sco", false); customTabs = preferences.getBoolean("custom_tabs", true); directShare = preferences.getBoolean("direct_share", true); shuffleMusic = preferences.getBoolean("shuffleMusic", false); @@ -378,6 +379,7 @@ public class SharedConfig { roundCamera16to9 = true;//preferences.getBoolean("roundCamera16to9", false); repeatMode = preferences.getInt("repeatMode", 0); fontSize = preferences.getInt("fons_size", AndroidUtilities.isTablet() ? 18 : 16); + fontSizeIsDefault = !preferences.contains("fons_size"); bubbleRadius = preferences.getInt("bubbleRadius", 17); ivFontSize = preferences.getInt("iv_font_size", fontSize); allowBigEmoji = preferences.getBoolean("allowBigEmoji", true); @@ -441,9 +443,11 @@ public class SharedConfig { } public static void updateTabletConfig() { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("userconfing", Context.MODE_PRIVATE); - fontSize = preferences.getInt("fons_size", AndroidUtilities.isTablet() ? 18 : 16); - ivFontSize = preferences.getInt("iv_font_size", fontSize); + if (fontSizeIsDefault) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("userconfing", Context.MODE_PRIVATE); + fontSize = preferences.getInt("fons_size", AndroidUtilities.isTablet() ? 18 : 16); + ivFontSize = preferences.getInt("iv_font_size", fontSize); + } } public static void increaseBadPasscodeTries() { @@ -939,14 +943,6 @@ public class SharedConfig { editor.commit(); } - public static void toggleRecordViaSco() { - recordViaSco = !recordViaSco; - SharedPreferences preferences = MessagesController.getGlobalMainSettings(); - SharedPreferences.Editor editor = preferences.edit(); - editor.putBoolean("record_via_sco", recordViaSco); - editor.commit(); - } - public static void toggleCustomTabs() { customTabs = !customTabs; SharedPreferences preferences = MessagesController.getGlobalMainSettings(); @@ -1273,7 +1269,7 @@ public class SharedConfig { devicePerformanceClass = PERFORMANCE_CLASS_HIGH; } if (BuildVars.LOGS_ENABLED) { - FileLog.d("device performance info selected_class = " + devicePerformanceClass + " (cpu_count = " + cpuCount + ", freq = " + maxCpuFreq + ", memoryClass = " + memoryClass + ", android version " + androidVersion + ")"); + FileLog.d("device performance info selected_class = " + devicePerformanceClass + " (cpu_count = " + cpuCount + ", freq = " + maxCpuFreq + ", memoryClass = " + memoryClass + ", android version " + androidVersion + ", manufacture " + Build.MANUFACTURER + ")"); } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java index 2bcc38355..3b5ed7d7e 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java @@ -259,11 +259,11 @@ public class UserConfig extends BaseController { TLRPC.User oldUser = currentUser; currentUser = user; clientUserId = user.id; - checkPremium(oldUser, user); + checkPremiumSelf(oldUser, user); } } - private void checkPremium(TLRPC.User oldUser, TLRPC.User newUser) { + private void checkPremiumSelf(TLRPC.User oldUser, TLRPC.User newUser) { if (oldUser == null || (newUser != null && oldUser.premium != newUser.premium)) { AndroidUtilities.runOnUIThread(() -> { getMessagesController().updatePremium(newUser.premium); @@ -271,6 +271,7 @@ public class UserConfig extends BaseController { NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.premiumStatusChangedGlobal); getMediaDataController().loadPremiumPromo(false); + getMediaDataController().loadReactions(false, true); }); } } @@ -368,7 +369,7 @@ public class UserConfig extends BaseController { } } if (currentUser != null) { - checkPremium(null, currentUser); + checkPremiumSelf(null, currentUser); clientUserId = currentUser.id; } configLoaded = true; 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 ab70b6032..df7c2ad5c 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/utils/BitmapsCache.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/utils/BitmapsCache.java @@ -3,7 +3,6 @@ package org.telegram.messenger.utils; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Build; -import android.util.Log; import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.BuildVars; @@ -70,6 +69,7 @@ public class BitmapsCache { volatile boolean recycled; RandomAccessFile cachedFile; + BitmapFactory.Options options; public void createCache() { try { @@ -327,7 +327,7 @@ public class BitmapsCache { selectedFrame = frameOffsets.get(index); randomAccessFile.seek(selectedFrame.frameOffset); if (bufferTmp == null || bufferTmp.length < selectedFrame.frameSize) { - bufferTmp = new byte[selectedFrame.frameSize]; + bufferTmp = new byte[(int) (selectedFrame.frameSize * 1.3f)]; } randomAccessFile.readFully(bufferTmp, 0, selectedFrame.frameSize); if (!recycled) { @@ -337,7 +337,9 @@ public class BitmapsCache { randomAccessFile.close(); } } - BitmapFactory.Options options = new BitmapFactory.Options(); + if (options == null) { + options = new BitmapFactory.Options(); + } options.inBitmap = bitmap; BitmapFactory.decodeByteArray(bufferTmp, 0, selectedFrame.frameSize, options); return FRAME_RESULT_OK; diff --git a/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java b/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java index ebfc5896e..5a2db99ba 100644 --- a/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java +++ b/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java @@ -67,7 +67,7 @@ public class TLRPC { public static final int MESSAGE_FLAG_HAS_BOT_ID = 0x00000800; public static final int MESSAGE_FLAG_EDITED = 0x00008000; - public static final int LAYER = 146; + public static final int LAYER = 147; public static class TL_stats_megagroupStats extends TLObject { public static int constructor = 0xef7ff916; @@ -9787,14 +9787,18 @@ public class TLRPC { public StickerSet set; public ArrayList packs = new ArrayList<>(); + public ArrayList keywords = new ArrayList<>(); public ArrayList documents = new ArrayList<>(); public static TL_messages_stickerSet TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) { TL_messages_stickerSet result = null; switch (constructor) { - case 0xb60a24a6: + case 0x6e153f16: result = new TL_messages_stickerSet(); break; + case 0xb60a24a6: + result = new TL_messages_stickerSet_layer146(); + break; case 0xd3f924eb: result = new TL_messages_stickerSetNotModified(); break; @@ -9809,7 +9813,7 @@ public class TLRPC { } } - public static class TL_messages_stickerSet extends messages_StickerSet { + public static class TL_messages_stickerSet_layer146 extends TL_messages_stickerSet { public static int constructor = 0xb60a24a6; public void readParams(AbstractSerializedData stream, boolean exception) { @@ -9864,6 +9868,82 @@ public class TLRPC { } } + public static class TL_messages_stickerSet extends messages_StickerSet { + public static int constructor = 0x6e153f16; + + public void readParams(AbstractSerializedData stream, boolean exception) { + set = StickerSet.TLdeserialize(stream, stream.readInt32(exception), exception); + int magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + int count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + TL_stickerPack object = TL_stickerPack.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + packs.add(object); + } + magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + TL_stickerKeyword object = TL_stickerKeyword.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + keywords.add(object); + } + magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + Document object = Document.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + documents.add(object); + } + } + + public void serializeToStream(AbstractSerializedData stream) { + stream.writeInt32(constructor); + set.serializeToStream(stream); + stream.writeInt32(0x1cb5c415); + int count = packs.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + packs.get(a).serializeToStream(stream); + } + stream.writeInt32(0x1cb5c415); + count = keywords.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + keywords.get(a).serializeToStream(stream); + } + stream.writeInt32(0x1cb5c415); + count = documents.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + documents.get(a).serializeToStream(stream); + } + } + } + public static class TL_messages_stickerSetNotModified extends TL_messages_stickerSet { public static int constructor = 0xd3f924eb; @@ -29122,6 +29202,9 @@ public class TLRPC { result = new TL_stickerSetMultiCovered(); break; case 0x1aed5ee5: + result = new TL_stickerSetFullCovered_layer146(); + break; + case 0x40d13c0e: result = new TL_stickerSetFullCovered(); break; case 0x6410a5d2: @@ -29173,11 +29256,54 @@ public class TLRPC { } } - public static class TL_stickerSetFullCovered extends StickerSetCovered { - public static int constructor = 0x1aed5ee5; + public static class TL_stickerKeyword extends TLObject { + public static int constructor = 0xfcfeb29c; - public ArrayList packs = new ArrayList<>(); - public ArrayList documents = new ArrayList<>(); + public long document_id; + public ArrayList keyword = new ArrayList<>(); + + public static TL_stickerKeyword TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) { + if (TL_stickerKeyword.constructor != constructor) { + if (exception) { + throw new RuntimeException(String.format("can't parse magic %x in TL_stickerKeyword", constructor)); + } else { + return null; + } + } + TL_stickerKeyword result = new TL_stickerKeyword(); + result.readParams(stream, exception); + return result; + } + + public void readParams(AbstractSerializedData stream, boolean exception) { + document_id = stream.readInt64(exception); + int magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + int count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + keyword.add(stream.readString(exception)); + } + } + + public void serializeToStream(AbstractSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt64(document_id); + stream.writeInt32(0x1cb5c415); + int count = keyword.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + stream.writeString(keyword.get(a)); + } + } + } + + public static class TL_stickerSetFullCovered_layer146 extends TL_stickerSetFullCovered { + public static int constructor = 0x1aed5ee5; public void readParams(AbstractSerializedData stream, boolean exception) { set = StickerSet.TLdeserialize(stream, stream.readInt32(exception), exception); @@ -29231,6 +29357,86 @@ public class TLRPC { } } + public static class TL_stickerSetFullCovered extends StickerSetCovered { + public static int constructor = 0x40d13c0e; + + public ArrayList packs = new ArrayList<>(); + public ArrayList keywords = new ArrayList<>(); + public ArrayList documents = new ArrayList<>(); + + public void readParams(AbstractSerializedData stream, boolean exception) { + set = StickerSet.TLdeserialize(stream, stream.readInt32(exception), exception); + int magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + int count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + TL_stickerPack object = TL_stickerPack.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + packs.add(object); + } + magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + TL_stickerKeyword object = TL_stickerKeyword.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + keywords.add(object); + } + magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + Document object = Document.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + documents.add(object); + } + } + + public void serializeToStream(AbstractSerializedData stream) { + stream.writeInt32(constructor); + set.serializeToStream(stream); + stream.writeInt32(0x1cb5c415); + int count = packs.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + packs.get(a).serializeToStream(stream); + } + stream.writeInt32(0x1cb5c415); + count = keywords.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + keywords.get(a).serializeToStream(stream); + } + stream.writeInt32(0x1cb5c415); + count = documents.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + documents.get(a).serializeToStream(stream); + } + } + } + public static class TL_stickerSetCovered extends StickerSetCovered { public static int constructor = 0x6410a5d2; 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 851023a8c..7a8006a6e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarPopupWindow.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarPopupWindow.java @@ -706,6 +706,22 @@ public class ActionBarPopupWindow extends PopupWindow { wm.updateViewLayout(container, p); } + public void setFocusableFlag(boolean enable) { + View container = getContentView().getRootView(); + Context context = getContentView().getContext(); + WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + WindowManager.LayoutParams p = (WindowManager.LayoutParams) container.getLayoutParams(); + + if (p != null) { + if (enable) { + p.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; + } else { + p.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; + } + wm.updateViewLayout(container, p); + } + } + private void dismissDim() { View container = getContentView().getRootView(); Context context = getContentView().getContext(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AlertDialog.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AlertDialog.java index 84d2679fd..c48c0d828 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AlertDialog.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AlertDialog.java @@ -1302,6 +1302,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback { alertDialog.topBackgroundColor = backgroundColor; return this; } + public Builder setTopAnimation(int resId, int backgroundColor) { return setTopAnimation(resId, 94, true, backgroundColor); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BottomSheet.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BottomSheet.java index 31cde2bd5..abc0aff9c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BottomSheet.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BottomSheet.java @@ -178,6 +178,7 @@ public class BottomSheet extends Dialog { private float hideSystemVerticalInsetsProgress; public boolean useBackgroundTopPadding = true; + protected int customViewGravity = Gravity.LEFT | Gravity.TOP; protected class ContainerView extends FrameLayout implements NestedScrollingParent { @@ -1090,9 +1091,9 @@ public class BottomSheet extends Dialog { containerView.setClipChildren(false); container.setClipToPadding(false); container.setClipChildren(false); - containerView.addView(customView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 0, -backgroundPaddingTop + topOffset, 0, 0)); + containerView.addView(customView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, customViewGravity, 0, -backgroundPaddingTop + topOffset, 0, 0)); } else { - containerView.addView(customView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 0, topOffset, 0, 0)); + containerView.addView(customView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, customViewGravity, 0, topOffset, 0, 0)); } } else { if (items != null) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/SimpleTextView.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/SimpleTextView.java index 513d5258f..e234065f7 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/SimpleTextView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/SimpleTextView.java @@ -972,6 +972,10 @@ public class SimpleTextView extends View implements Drawable.Callback { rightDrawableOutside = outside; } + public boolean getRightDrawableOutside() { + return rightDrawableOutside; + } + public void setRightDrawableOnClick(OnClickListener onClickListener) { rightDrawableOnClickListener = onClickListener; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionIntroActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionIntroActivity.java index e523820fa..7c82d64ae 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionIntroActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionIntroActivity.java @@ -160,7 +160,7 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl imageView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec((int) (height * 0.399f), MeasureSpec.EXACTLY)); titleTextView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED)); descriptionText.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED)); - buttonTextView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(86), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(42), MeasureSpec.EXACTLY)); + buttonTextView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(72), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(50), MeasureSpec.EXACTLY)); } break; } @@ -602,7 +602,7 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl buttonTextView.setTextColor(Theme.getColor(Theme.key_featuredStickers_buttonText)); buttonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); buttonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); - int buttonRadiusDp = currentType == ACTION_TYPE_SET_PASSCODE || currentType == ACTION_TYPE_CHANGE_PHONE_NUMBER ? 6 : 4; + int buttonRadiusDp = currentType == ACTION_TYPE_SET_PASSCODE || currentType == ACTION_TYPE_CHANGE_PHONE_NUMBER || currentType == ACTION_TYPE_CHANNEL_CREATE ? 6 : 4; buttonTextView.setBackground(Theme.AdaptiveRipple.filledRect(Theme.key_featuredStickers_addButton, buttonRadiusDp)); viewGroup.addView(buttonTextView); buttonTextView.setOnClickListener(v -> { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ArticleViewer.java b/TMessagesProj/src/main/java/org/telegram/ui/ArticleViewer.java index 5d6c5dbf5..2772b168d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ArticleViewer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ArticleViewer.java @@ -518,7 +518,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg sizeBar = new SeekBarView(context); sizeBar.setReportChanges(true); -// sizeBar.setSeparatorsCount(endFontSize - startFontSize); + sizeBar.setSeparatorsCount(endFontSize - startFontSize + 1); sizeBar.setDelegate(new SeekBarView.SeekBarViewDelegate() { @Override public void onSeekBarDrag(boolean stop, float progress) { @@ -1294,7 +1294,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg deleteView.setOnClickListener(v -> { if (pressedLinkOwnerLayout != null) { AndroidUtilities.addToClipboard(pressedLinkOwnerLayout.getText()); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + if (AndroidUtilities.shouldShowClipboardToast()) { Toast.makeText(parentActivity, LocaleController.getString("TextCopied", R.string.TextCopied), Toast.LENGTH_SHORT).show(); } } @@ -3700,7 +3700,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg @Override public void onTextCopied() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + if (AndroidUtilities.shouldShowClipboardToast()) { BulletinFactory.of(containerView, null).createCopyBulletin(LocaleController.getString("TextCopied", R.string.TextCopied)).show(); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/BasePermissionsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/BasePermissionsActivity.java index 801374207..36307bbfe 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/BasePermissionsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/BasePermissionsActivity.java @@ -30,7 +30,8 @@ public class BasePermissionsActivity extends Activity { REQUEST_CODE_OPEN_CAMERA = 20, REQUEST_CODE_VIDEO_MESSAGE = 150, REQUEST_CODE_EXTERNAL_STORAGE_FOR_AVATAR = 151, - REQUEST_CODE_SIGN_IN_WITH_GOOGLE = 200; + REQUEST_CODE_SIGN_IN_WITH_GOOGLE = 200, + REQUEST_CODE_PAYMENT_FORM = 210; protected int currentAccount = -1; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/AboutLinkCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/AboutLinkCell.java index 3449fc70e..8650d3452 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/AboutLinkCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/AboutLinkCell.java @@ -407,7 +407,7 @@ public class AboutLinkCell extends FrameLayout { onLinkClick(pressedLinkFinal); } else if (which == 1) { AndroidUtilities.addToClipboard(url); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + if (AndroidUtilities.shouldShowClipboardToast()) { if (url.startsWith("@")) { BulletinFactory.of(parentFragment).createSimpleBulletin(R.raw.copy, LocaleController.getString("UsernameCopied", R.string.UsernameCopied)).show(); } else if (url.startsWith("#") || url.startsWith("$")) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/BotHelpCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/BotHelpCell.java index 3730df322..7e540d98c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/BotHelpCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/BotHelpCell.java @@ -327,7 +327,9 @@ public class BotHelpCell extends View { @Override public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); - info.setText(textLayout.getText()); + if (textLayout != null) { + info.setText(textLayout.getText()); + } } public boolean animating() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java index 84bd5d362..9db8a0d07 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java @@ -76,6 +76,7 @@ import org.telegram.ui.Components.ForegroundColorSpanThemable; import org.telegram.ui.Components.Premium.PremiumGradient; import org.telegram.ui.Components.PullForegroundDrawable; import org.telegram.ui.Components.RLottieDrawable; +import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble; import org.telegram.ui.Components.StaticLayoutEx; import org.telegram.ui.Components.StatusDrawable; import org.telegram.ui.Components.SwipeGestureSettingsView; @@ -990,7 +991,30 @@ public class DialogCell extends BaseCell { fromChat = MessagesController.getInstance(currentAccount).getChat(-fromId); } drawCount2 = true; - if (dialogsType == 2) { + boolean lastMessageIsReaction = false; + if (currentDialogId > 0 && message.isOutOwner() && message.messageOwner.reactions != null && message.messageOwner.reactions.recent_reactions != null && !message.messageOwner.reactions.recent_reactions.isEmpty()) { + TLRPC.MessagePeerReaction lastReaction = message.messageOwner.reactions.recent_reactions.get(0); + if (lastReaction.peer_id.user_id != 0 &&lastReaction.peer_id.user_id != UserConfig.getInstance(currentAccount).clientUserId) { + lastMessageIsReaction = true; + ReactionsLayoutInBubble.VisibleReaction visibleReaction = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(lastReaction.reaction); + currentMessagePaint = Theme.dialogs_messagePrintingPaint[paintIndex]; + if (visibleReaction.emojicon != null) { + messageString = LocaleController.formatString("ReactionInDialog", R.string.ReactionInDialog, visibleReaction.emojicon); + } else { + String string = LocaleController.formatString("ReactionInDialog", R.string.ReactionInDialog, "**reaction**"); + int i = string.indexOf("**reaction**"); + string = string.replace("**reaction**", "d"); + + SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(string); + spannableStringBuilder.setSpan(new AnimatedEmojiSpan(visibleReaction.documentId, currentMessagePaint == null ? null : currentMessagePaint.getFontMetricsInt()), i, i + 1, 0); + + messageString = spannableStringBuilder; + } + } + } + if (lastMessageIsReaction) { + + } else if (dialogsType == 2) { if (chat != null) { if (ChatObject.isChannel(chat) && !chat.megagroup) { if (chat.participants_count != 0) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/StickerEmojiCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/StickerEmojiCell.java index eb220b8ff..b9eae2232 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/StickerEmojiCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/StickerEmojiCell.java @@ -235,7 +235,8 @@ public class StickerEmojiCell extends FrameLayout implements NotificationCenter. if (!UserConfig.getInstance(currentAccount).isPremium()) { layoutParams.height = layoutParams.width = AndroidUtilities.dp(24); layoutParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; - layoutParams.bottomMargin = layoutParams.rightMargin = 0; + layoutParams.rightMargin = 0; + layoutParams.bottomMargin = AndroidUtilities.dp(8); premiumIconView.setPadding(AndroidUtilities.dp(4), AndroidUtilities.dp(4), AndroidUtilities.dp(4), AndroidUtilities.dp(4)); } else { layoutParams.height = layoutParams.width = AndroidUtilities.dp(16); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChannelAdminLogActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChannelAdminLogActivity.java index 9ca956713..2868aa189 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChannelAdminLogActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChannelAdminLogActivity.java @@ -2170,7 +2170,7 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio MessageObject messageObject = cell.getMessageObject(); if (url instanceof URLSpanMono) { ((URLSpanMono) url).copyToClipboard(); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + if (AndroidUtilities.shouldShowClipboardToast()) { Toast.makeText(getParentActivity(), LocaleController.getString("TextCopied", R.string.TextCopied), Toast.LENGTH_SHORT).show(); } } else if (url instanceof URLSpanUserMention) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChannelCreateActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChannelCreateActivity.java index ac623dc0f..e7df5caab 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChannelCreateActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChannelCreateActivity.java @@ -587,8 +587,8 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC avatarEditor.setAnimation(cameraDrawable); avatarEditor.setEnabled(false); avatarEditor.setClickable(false); - avatarEditor.setPadding(AndroidUtilities.dp(2), 0, 0, AndroidUtilities.dp(1)); - frameLayout.addView(avatarEditor, LayoutHelper.createFrame(64, 64, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), LocaleController.isRTL ? 0 : 16, 12, LocaleController.isRTL ? 16 : 0, 12)); + avatarEditor.setPadding(AndroidUtilities.dp(0), 0, 0, AndroidUtilities.dp(1)); + frameLayout.addView(avatarEditor, LayoutHelper.createFrame(64, 64, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), LocaleController.isRTL ? 0 : 15, 12, LocaleController.isRTL ? 15 : 0, 12)); avatarProgressView = new RadialProgressView(context); avatarProgressView.setSize(AndroidUtilities.dp(30)); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index 87e4372c0..74f05aa0f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -6289,7 +6289,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not reportSpamButton.setSingleLine(true); reportSpamButton.setMaxLines(1); reportSpamButton.setGravity(Gravity.CENTER); - topChatPanelView.addView(reportSpamButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 50, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 1)); + topChatPanelView.addView(reportSpamButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 1)); reportSpamButton.setOnClickListener(v2 -> AlertsCreator.showBlockReportSpamAlert(ChatActivity.this, dialog_id, currentUser, currentChat, currentEncryptedChat, reportSpamButton.getTag(R.id.object_tag) != null, chatInfo, param -> { if (param == 0) { updateTopPanel(true); @@ -6354,7 +6354,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (Build.VERSION.SDK_INT >= 21) { addToContactsButton.setBackground(Theme.createSelectorDrawable(getThemedColor(Theme.key_chat_addContact) & 0x19ffffff, 3)); } - topChatPanelView.addView(addToContactsButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 50, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 1)); + topChatPanelView.addView(addToContactsButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 1)); addToContactsButton.setOnClickListener(v -> { if (addToContactsButtonArchive) { getMessagesController().addDialogToFolder(dialog_id, 0, 0, 0); @@ -6402,11 +6402,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not closeReportSpam.setImageResource(R.drawable.miniplayer_close); closeReportSpam.setContentDescription(LocaleController.getString("Close", R.string.Close)); if (Build.VERSION.SDK_INT >= 21) { - closeReportSpam.setBackground(Theme.createSelectorDrawable(getThemedColor(Theme.key_chat_topPanelClose) & 0x19ffffff)); + 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); - topChatPanelView.addView(closeReportSpam, LayoutHelper.createFrame(36, 48, Gravity.RIGHT | Gravity.TOP, 0, 0, 2, 0)); + topChatPanelView.addView(closeReportSpam, LayoutHelper.createFrame(36, 36, Gravity.RIGHT | Gravity.TOP, 0, 6, 2, 0)); closeReportSpam.setOnClickListener(v -> { long did = dialog_id; if (currentEncryptedChat != null) { @@ -6616,7 +6616,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not @Override public boolean needSend() { - return false; + return true; } @Override @@ -13520,7 +13520,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } - private void updateTitle(boolean animated) { + public void updateTitle(boolean animated) { if (avatarContainer == null) { return; } @@ -13551,7 +13551,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not avatarContainer.setTitle(LocaleController.getString("SavedMessages", R.string.SavedMessages)); } else if (!MessagesController.isSupportUser(currentUser) && getContactsController().contactsDict.get(currentUser.id) == null && (getContactsController().contactsDict.size() != 0 || !getContactsController().isLoadingContacts())) { if (!TextUtils.isEmpty(currentUser.phone)) { - avatarContainer.setTitle(PhoneFormat.getInstance().format("+" + currentUser.phone)); + avatarContainer.setTitle(PhoneFormat.getInstance().format("+" + currentUser.phone), currentUser.scam, currentUser.fake, currentUser.verified, getMessagesController().isPremiumUser(currentUser), currentUser.emoji_status, animated); } else { avatarContainer.setTitle(UserObject.getUserName(currentUser), currentUser.scam, currentUser.fake, currentUser.verified, getMessagesController().isPremiumUser(currentUser), currentUser.emoji_status, animated); } @@ -13635,7 +13635,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } - private void checkAndUpdateAvatar() { + public void checkAndUpdateAvatar() { if (currentUser != null) { TLRPC.User user = getMessagesController().getUser(currentUser.id); if (user == null) { @@ -15817,7 +15817,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (currentChat instanceof TLRPC.TL_channelForbidden) { builder.setMessage(LocaleController.getString("ChannelCantOpenBannedByAdmin", R.string.ChannelCantOpenBannedByAdmin)); } else { - builder.setTitle(LocaleController.getString("ChannelPrivate", R.string.ChannelPrivate)); + builder.setTitle(LocaleController.getString(R.string.ChannelPrivate)); builder.setMessage(LocaleController.getString("ChannelCantOpenPrivate2", R.string.ChannelCantOpenPrivate2)); } } else if (reason == 1) { @@ -15825,7 +15825,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } else if (reason == 2) { builder.setMessage(LocaleController.getString("ChannelCantOpenBanned", R.string.ChannelCantOpenBanned)); } else if (reason == 3) { - builder.setTitle(LocaleController.getString("ChannelPrivate", R.string.ChannelPrivate)); + builder.setTitle(LocaleController.getString(R.string.ChannelPrivate)); builder.setMessage(LocaleController.getString("JoinByPeekChannelText", R.string.JoinByPeekChannelText)); } builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null); @@ -20150,7 +20150,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not chatWithAdminTextView.setGravity(Gravity.CENTER_VERTICAL); chatWithAdminTextView.setPadding(AndroidUtilities.dp(14), 0, AndroidUtilities.dp(46), 0); chatWithAdminTextView.setBackground(Theme.createSelectorDrawable(getThemedColor(Theme.key_listSelector), 2)); - topChatPanelView.addView(chatWithAdminTextView, 0, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 50, 0, 0, 0, 0, 1)); + topChatPanelView.addView(chatWithAdminTextView, 0, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, 0, 0, 0, 0, 1)); chatWithAdminTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText)); chatWithAdminTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); chatWithAdminTextView.setOnClickListener(new View.OnClickListener() { @@ -22563,7 +22563,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } - if (stickerSets.size() > 0) { + if (stickerSets.size() > 0 && !getMessagesController().premiumLocked) { View gap = new FrameLayout(contentView.getContext()); gap.setBackgroundColor(getThemedColor(Theme.key_actionBarDefaultSubmenuSeparator)); popupLayout.addView(gap, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 8)); @@ -22626,7 +22626,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not 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); - scrimPopupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED); + scrimPopupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING); scrimPopupWindow.getContentView().setFocusableInTouchMode(true); popupLayout.setFitItems(true); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java index 677686979..06df0c870 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java @@ -125,6 +125,7 @@ import java.util.concurrent.atomic.AtomicBoolean; public class AlertsCreator { public final static int PERMISSIONS_REQUEST_TOP_ICON_SIZE = 72; + public final static int NEW_DENY_DIALOG_TOP_ICON_SIZE = 52; public static Dialog createForgotPasscodeDialog(Context ctx) { return new AlertDialog.Builder(ctx) 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 8c76e9c61..e82c6938d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/AnimatedEmojiDrawable.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/AnimatedEmojiDrawable.java @@ -427,7 +427,7 @@ public class AnimatedEmojiDrawable extends Drawable { thumbDrawable = svgThumb; } else if ("application/x-tgsticker".equals(document.mime_type)) { String probableCacheKey = (cacheType != 0 ? cacheType + "_" : "") + documentId + "@" + filter; - if (cacheType == CACHE_TYPE_KEYBOARD || !ImageLoader.getInstance().hasLottieMemCache(probableCacheKey)) { + if (SharedConfig.getDevicePerformanceClass() != SharedConfig.PERFORMANCE_CLASS_LOW || (cacheType == CACHE_TYPE_KEYBOARD || !ImageLoader.getInstance().hasLottieMemCache(probableCacheKey))) { SvgHelper.SvgDrawable svgThumb = DocumentObject.getSvgThumb(document.thumbs, Theme.key_windowBackgroundWhiteGrayIcon, 0.2f); if (svgThumb != null && MessageObject.isAnimatedStickerDocument(document, true)) { svgThumb.overrideWidthAndHeight(512, 512); @@ -644,7 +644,7 @@ public class AnimatedEmojiDrawable extends Drawable { TLRPC.InputStickerSet set = MessageObject.getInputStickerSet(document); return canOverrideColorCached = ( set instanceof TLRPC.TL_inputStickerSetEmojiDefaultStatuses || - set instanceof TLRPC.TL_inputStickerSetID && set.id == 773947703670341676L + set instanceof TLRPC.TL_inputStickerSetID && (set.id == 773947703670341676L || set.id == 2964141614563343L) ); } return false; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/AnimatedFloat.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/AnimatedFloat.java index 61d4c8968..9424466df 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/AnimatedFloat.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/AnimatedFloat.java @@ -121,7 +121,7 @@ public class AnimatedFloat { public float set(float mustBe, boolean force) { final long now = SystemClock.elapsedRealtime(); - if (force || firstSet) { + if (force || transitionDuration <= 0 || firstSet) { value = targetValue = mustBe; transition = false; firstSet = false; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java index 30f466d05..f86913ee7 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java @@ -4854,7 +4854,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific public boolean processSendingText(CharSequence text, boolean notify, int scheduleDate) { int[] emojiOnly = new int[1]; Emoji.parseEmojis(text, emojiOnly); - boolean hasOnlyEmoji = emojiOnly[0] <= 100; + boolean hasOnlyEmoji = emojiOnly[0] > 0; if (!hasOnlyEmoji) { text = AndroidUtilities.getTrimmedString(text); } @@ -8269,6 +8269,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific } if (messageEditText != null) { messageEditText.postInvalidate(); + messageEditText.invalidateForce(); } } else if (id == NotificationCenter.recordProgressChanged) { int guid = (Integer) args[0]; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlertContactsLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlertContactsLayout.java index 83ba88994..dac313e65 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlertContactsLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlertContactsLayout.java @@ -22,6 +22,10 @@ import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.LinearSmoothScroller; +import androidx.recyclerview.widget.RecyclerView; + import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.ContactsController; @@ -41,10 +45,6 @@ import org.telegram.ui.ActionBar.ThemeDescription; import java.util.ArrayList; import java.util.HashMap; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.LinearSmoothScroller; -import androidx.recyclerview.widget.RecyclerView; - public class ChatAttachAlertContactsLayout extends ChatAttachAlert.AttachAlertLayout implements NotificationCenter.NotificationCenterDelegate { private FrameLayout frameLayout; @@ -801,7 +801,7 @@ public class ChatAttachAlertContactsLayout extends ChatAttachAlert.AttachAlertLa } else if (name.startsWith(q) || name.contains(" " + q) || tName != null && (tName.startsWith(q) || tName.contains(" " + q))) { found = 3; } - if (found != 0) { + if (found != 0 && (!contact.phones.isEmpty() || !contact.shortPhones.isEmpty())) { if (found == 3) { resultArrayNames.add(AndroidUtilities.generateSearchName(contact.first_name, contact.last_name, q)); } else if (found == 1) { @@ -838,7 +838,7 @@ public class ChatAttachAlertContactsLayout extends ChatAttachAlert.AttachAlertLa found = 2; } - if (found != 0) { + if (found != 0 && user.phone != null) { if (found == 1) { resultArrayNames.add(AndroidUtilities.generateSearchName(user.first_name, user.last_name, q)); } else { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAvatarContainer.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAvatarContainer.java index 276797638..b253f6b62 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAvatarContainer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAvatarContainer.java @@ -181,7 +181,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent subtitleTextView.setTag(Theme.key_actionBarDefaultSubtitle); subtitleTextView.setTextSize(14); subtitleTextView.setGravity(Gravity.LEFT); - subtitleTextView.setPadding(0, 0, AndroidUtilities.dp(12), 0); + subtitleTextView.setPadding(0, 0, AndroidUtilities.dp(10), 0); addView(subtitleTextView); if (parentFragment != null) { @@ -231,7 +231,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent } public void setTitleExpand(boolean titleExpand) { - int newRightPadding = titleExpand ? AndroidUtilities.dp(16) : 0; + int newRightPadding = titleExpand ? AndroidUtilities.dp(10) : 0; if (titleTextView.getPaddingRight() != newRightPadding) { titleTextView.setPadding(0, AndroidUtilities.dp(6), newRightPadding, AndroidUtilities.dp(12)); requestLayout(); @@ -401,6 +401,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent titleTextLargerCopyView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); titleTextLargerCopyView.setLeftDrawableTopPadding(-AndroidUtilities.dp(1.3f)); titleTextLargerCopyView.setRightDrawable(titleTextView.getRightDrawable()); + titleTextLargerCopyView.setRightDrawableOutside(titleTextView.getRightDrawableOutside()); titleTextLargerCopyView.setLeftDrawable(titleTextView.getLeftDrawable()); titleTextLargerCopyView.setText(titleTextView.getText()); titleTextLargerCopyView.animate().alpha(0).setDuration(350).setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT).withEndAction(() -> { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/CloseProgressDrawable2.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/CloseProgressDrawable2.java index f7e705e91..f9d532272 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/CloseProgressDrawable2.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/CloseProgressDrawable2.java @@ -34,9 +34,13 @@ public class CloseProgressDrawable2 extends Drawable { private int currentColor; public CloseProgressDrawable2() { + this(2); + } + + public CloseProgressDrawable2(float widthDp) { super(); paint.setColor(0xffffffff); - paint.setStrokeWidth(AndroidUtilities.dp(2)); + paint.setStrokeWidth(AndroidUtilities.dp(widthDp)); paint.setStrokeCap(Paint.Cap.ROUND); paint.setStyle(Paint.Style.STROKE); side = AndroidUtilities.dp(8); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/EditTextBoldCursor.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/EditTextBoldCursor.java index 92179118c..94bc96d17 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/EditTextBoldCursor.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/EditTextBoldCursor.java @@ -639,17 +639,21 @@ public class EditTextBoldCursor extends EditTextEffects { } public void invalidateForce() { + invalidate(); if (!isHardwareAccelerated()) { - invalidate(); return; } try { // on hardware accelerated edittext to invalidate imagespan display list must be invalidated - if (mEditorInvalidateDisplayList != null && editor != null) { - mEditorInvalidateDisplayList.invoke(editor); + if (mEditorInvalidateDisplayList != null) { + if (editor == null) { + editor = mEditor.get(this); + } + if (editor != null) { + mEditorInvalidateDisplayList.invoke(editor); + } } } catch (Exception ignore) {}; - invalidate(); } @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/InstantCameraView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/InstantCameraView.java index 87e858245..6285bee50 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/InstantCameraView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/InstantCameraView.java @@ -986,10 +986,16 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter } } if (sortedSizes.isEmpty() || SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_LOW || SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_AVERAGE) { + ArrayList sizes = sortedSizes; if (!sortedSizes.isEmpty()) { - return CameraController.chooseOptimalSize(sortedSizes, 480, 270, aspectRatio); + sizes = sortedSizes; } else { - return CameraController.chooseOptimalSize(previewSizes, 480, 270, aspectRatio); + sizes = previewSizes; + } + if (Build.MANUFACTURER.equalsIgnoreCase("Xiaomi")) { + return CameraController.chooseOptimalSize(sizes, 640, 480, aspectRatio); + } else { + return CameraController.chooseOptimalSize(sizes, 480, 270, aspectRatio); } } Collections.sort(sortedSizes, (o1, o2) -> { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/MotionBackgroundDrawable.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/MotionBackgroundDrawable.java index 7e5f1a891..662f13b37 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/MotionBackgroundDrawable.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/MotionBackgroundDrawable.java @@ -27,6 +27,7 @@ import androidx.core.graphics.ColorUtils; import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.FileLog; +import org.telegram.messenger.GenericProvider; import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.Utilities; @@ -88,6 +89,8 @@ public class MotionBackgroundDrawable extends Drawable { private GradientDrawable gradientDrawable = new GradientDrawable(); private boolean invalidateLegacy; + private GenericProvider animationProgressProvider; + private boolean rotationBack; private boolean rotatingPreview; @@ -233,6 +236,15 @@ public class MotionBackgroundDrawable extends Drawable { Utilities.generateGradient(currentBitmap, true, phase, interpolator.getInterpolation(posAnimationProgress), currentBitmap.getWidth(), currentBitmap.getHeight(), currentBitmap.getRowBytes(), colors); } + public float getPosAnimationProgress() { + return posAnimationProgress; + } + + public void setPosAnimationProgress(float posAnimationProgress) { + this.posAnimationProgress = posAnimationProgress; + updateAnimation(true); + } + public void switchToNextPosition() { switchToNextPosition(false); } @@ -826,6 +838,11 @@ public class MotionBackgroundDrawable extends Drawable { updateAnimation(true); } + public void setAnimationProgressProvider(GenericProvider animationProgressProvider) { + this.animationProgressProvider = animationProgressProvider; + updateAnimation(true); + } + public void updateAnimation(boolean invalidate) { long newTime = SystemClock.elapsedRealtime(); long dt = newTime - lastUpdateTime; @@ -865,11 +882,19 @@ public class MotionBackgroundDrawable extends Drawable { } else { stageBefore = 3; } - posAnimationProgress += dt / (rotationBack ? 1000.0f : 2000.0f); + if (animationProgressProvider != null) { + posAnimationProgress = animationProgressProvider.provide(this); + } else { + posAnimationProgress += dt / (rotationBack ? 1000.0f : 2000.0f); + } if (posAnimationProgress > 1.0f) { posAnimationProgress = 1.0f; } - progress = interpolator.getInterpolation(posAnimationProgress); + if (animationProgressProvider == null) { + progress = interpolator.getInterpolation(posAnimationProgress); + } else { + progress = posAnimationProgress; + } if (stageBefore == 0 && progress > 0.25f || stageBefore == 1 && progress > 0.5f || stageBefore == 2 && progress > 0.75f) { @@ -906,11 +931,19 @@ public class MotionBackgroundDrawable extends Drawable { } } } else { - posAnimationProgress += dt / (fastAnimation ? 300.0f : 500.0f); + if (animationProgressProvider != null) { + posAnimationProgress = animationProgressProvider.provide(this); + } else { + posAnimationProgress += dt / (fastAnimation ? 300.0f : 500.0f); + } if (posAnimationProgress > 1.0f) { posAnimationProgress = 1.0f; } - progress = interpolator.getInterpolation(posAnimationProgress); + if (animationProgressProvider == null) { + progress = interpolator.getInterpolation(posAnimationProgress); + } else { + progress = posAnimationProgress; + } if (rotationBack) { progress = 1.0f - progress; if (posAnimationProgress >= 1.0f) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/PasscodeView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PasscodeView.java index 5d0cff807..5cd382fb1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/PasscodeView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PasscodeView.java @@ -50,6 +50,9 @@ import android.widget.TextView; import androidx.annotation.IdRes; import androidx.core.os.CancellationSignal; +import androidx.dynamicanimation.animation.FloatValueHolder; +import androidx.dynamicanimation.animation.SpringAnimation; +import androidx.dynamicanimation.animation.SpringForce; import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.ApplicationLoader; @@ -64,9 +67,13 @@ import org.telegram.ui.ActionBar.AlertDialog; import org.telegram.ui.ActionBar.Theme; import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; import java.util.Locale; public class PasscodeView extends FrameLayout implements NotificationCenter.NotificationCenterDelegate { + private final static float BACKGROUND_SPRING_STIFFNESS = 300f; @Override public void didReceivedNotification(int id, int account, Object... args) { @@ -438,6 +445,10 @@ public class PasscodeView extends FrameLayout implements NotificationCenter.Noti private final static int id_fingerprint_textview = 1000; private final static int id_fingerprint_imageview = 1001; + private SpringAnimation backgroundAnimationSpring; + private LinkedList backgroundSpringQueue = new LinkedList<>(); + private LinkedList backgroundSpringNextQueue = new LinkedList<>(); + private static class InnerAnimator { private AnimatorSet animatorSet; private float startRadius; @@ -547,13 +558,59 @@ public class PasscodeView extends FrameLayout implements NotificationCenter.Noti return false; }); passwordEditText.addTextChangedListener(new TextWatcher() { + @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { if (backgroundDrawable instanceof MotionBackgroundDrawable) { + boolean needAnimation = false; + MotionBackgroundDrawable motionBackgroundDrawable = (MotionBackgroundDrawable) backgroundDrawable; + motionBackgroundDrawable.setAnimationProgressProvider(null); + float progress = motionBackgroundDrawable.getPosAnimationProgress(); + boolean next; if (count == 0 && after == 1) { - ((MotionBackgroundDrawable) backgroundDrawable).switchToNextPosition(true); + motionBackgroundDrawable.switchToNextPosition(true); + needAnimation = true; + next = true; } else if (count == 1 && after == 0) { - ((MotionBackgroundDrawable) backgroundDrawable).switchToPrevPosition(true); + motionBackgroundDrawable.switchToPrevPosition(true); + needAnimation = true; + next = false; + } else { + next = false; + } + + if (needAnimation) { + if (progress >= 1f) { + animateBackground(motionBackgroundDrawable); + } else { + backgroundSpringQueue.offer(()-> { + if (next) { + motionBackgroundDrawable.switchToNextPosition(true); + } else { + motionBackgroundDrawable.switchToPrevPosition(true); + } + animateBackground(motionBackgroundDrawable); + }); + backgroundSpringNextQueue.offer(next); + + List remove = new ArrayList<>(); + List removeIndex = new ArrayList<>(); + for (int i = 0; i < backgroundSpringQueue.size(); i++) { + Runnable callback = backgroundSpringQueue.get(i); + boolean qNext = backgroundSpringNextQueue.get(i); + + if (qNext != next) { + remove.add(callback); + removeIndex.add(i); + } + } + for (Runnable callback : remove) { + backgroundSpringQueue.remove(callback); + } + for (int i : removeIndex) { + backgroundSpringNextQueue.remove(i); + } + } } } } @@ -759,13 +816,59 @@ public class PasscodeView extends FrameLayout implements NotificationCenter.Noti } if (tag == 11) { - } else if (tag == 10) { - if (erased && backgroundDrawable instanceof MotionBackgroundDrawable) { - ((MotionBackgroundDrawable) backgroundDrawable).switchToPrevPosition(true); - } } else { if (backgroundDrawable instanceof MotionBackgroundDrawable) { - ((MotionBackgroundDrawable) backgroundDrawable).switchToNextPosition(true); + MotionBackgroundDrawable motionBackgroundDrawable = (MotionBackgroundDrawable) backgroundDrawable; + motionBackgroundDrawable.setAnimationProgressProvider(null); + boolean needAnimation = false; + float progress = motionBackgroundDrawable.getPosAnimationProgress(); + boolean next; + if (tag == 10) { + if (erased) { + motionBackgroundDrawable.switchToPrevPosition(true); + needAnimation = true; + } + next = false; + } else { + motionBackgroundDrawable.switchToNextPosition(true); + needAnimation = true; + next = true; + } + + if (needAnimation) { + if (progress >= 1f) { + animateBackground(motionBackgroundDrawable); + } else { + backgroundSpringQueue.offer(()-> { + if (next) { + motionBackgroundDrawable.switchToNextPosition(true); + } else { + motionBackgroundDrawable.switchToPrevPosition(true); + } + animateBackground(motionBackgroundDrawable); + }); + backgroundSpringNextQueue.offer(next); + + List remove = new ArrayList<>(); + List removeIndex = new ArrayList<>(); + for (int i = 0; i < backgroundSpringQueue.size(); i++) { + Runnable callback = backgroundSpringQueue.get(i); + Boolean qNext = backgroundSpringNextQueue.get(i); + + if (qNext != null && qNext != next) { + remove.add(callback); + removeIndex.add(i); + } + } + for (Runnable callback : remove) { + backgroundSpringQueue.remove(callback); + } + Collections.sort(removeIndex, (o1, o2) -> o2 - o1); + for (int i : removeIndex) { + backgroundSpringNextQueue.remove(i); + } + } + } } } }); @@ -777,6 +880,33 @@ public class PasscodeView extends FrameLayout implements NotificationCenter.Noti } } + private void animateBackground(MotionBackgroundDrawable motionBackgroundDrawable) { + if (backgroundAnimationSpring != null && backgroundAnimationSpring.isRunning()) { + backgroundAnimationSpring.cancel(); + } + + FloatValueHolder animationValue = new FloatValueHolder(0); + motionBackgroundDrawable.setAnimationProgressProvider(obj -> animationValue.getValue() / 100f); + backgroundAnimationSpring = new SpringAnimation(animationValue) + .setSpring(new SpringForce(100) + .setStiffness(BACKGROUND_SPRING_STIFFNESS) + .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY)); + backgroundAnimationSpring.addEndListener((animation, canceled, value, velocity) -> { + backgroundAnimationSpring = null; + motionBackgroundDrawable.setAnimationProgressProvider(null); + + if (!canceled) { + motionBackgroundDrawable.setPosAnimationProgress(1f); + if (!backgroundSpringQueue.isEmpty()) { + backgroundSpringQueue.poll().run(); + backgroundSpringNextQueue.poll(); + } + } + }); + backgroundAnimationSpring.addUpdateListener((animation, value, velocity) -> motionBackgroundDrawable.updateAnimation(true)); + backgroundAnimationSpring.start(); + } + private void setNextFocus(View view, @IdRes int nextId) { view.setNextFocusForwardId(nextId); if (Build.VERSION.SDK_INT >= 22) { @@ -812,7 +942,14 @@ public class PasscodeView extends FrameLayout implements NotificationCenter.Noti passwordEditText2.eraseAllCharacters(true); onPasscodeError(); if (backgroundDrawable instanceof MotionBackgroundDrawable) { - ((MotionBackgroundDrawable) backgroundDrawable).rotatePreview(true); + MotionBackgroundDrawable motionBackgroundDrawable = (MotionBackgroundDrawable) backgroundDrawable; + if (backgroundAnimationSpring != null) { + backgroundAnimationSpring.cancel(); + motionBackgroundDrawable.setPosAnimationProgress(1f); + } + if (motionBackgroundDrawable.getPosAnimationProgress() >= 1f) { + motionBackgroundDrawable.rotatePreview(true); + } } return; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhonebookShareAlert.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhonebookShareAlert.java index 008f0f2df..6305c222d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhonebookShareAlert.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhonebookShareAlert.java @@ -506,7 +506,7 @@ public class PhonebookShareAlert extends BottomSheet { android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); android.content.ClipData clip = android.content.ClipData.newPlainText("label", item.getValue(false)); clipboard.setPrimaryClip(clip); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + if (AndroidUtilities.shouldShowClipboardToast()) { Toast.makeText(this.parentFragment.getParentActivity(), LocaleController.getString("TextCopied", R.string.TextCopied), Toast.LENGTH_SHORT).show(); } } catch (Exception e) { @@ -564,7 +564,7 @@ public class PhonebookShareAlert extends BottomSheet { layout.textView.setText(LocaleController.getString("TextCopied", R.string.TextCopied)); layout.imageView.setImageResource(R.drawable.msg_info); } - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + if (AndroidUtilities.shouldShowClipboardToast()) { Bulletin.make((FrameLayout) containerView, layout, Bulletin.DURATION_SHORT).show(); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoViewerWebView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoViewerWebView.java index c3052cfda..437ed7ccc 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoViewerWebView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoViewerWebView.java @@ -320,6 +320,10 @@ public class PhotoViewerWebView extends FrameLayout { youtubeStoryboards.clear(); + if (duration <= 15) { + return; + } + String[] specParts = url.split("\\|"); String baseUrl = specParts[0].split("\\$")[0] + "2/"; String sgpPart = specParts[0].split("\\$N")[1]; @@ -333,13 +337,17 @@ public class PhotoViewerWebView extends FrameLayout { sighPart = specParts[3].split("M#")[1]; } - int boardsCount = 0; + int boardsCount; - if (duration < 250) { + if (duration <= 100) { + boardsCount = (int) Math.ceil(duration / 25f); + } else if (duration <= 250) { boardsCount = (int) Math.ceil((duration / 2f) / 25); - } else if (duration >= 250 && duration < 1000) { + } else if (duration <= 500) { boardsCount = (int) Math.ceil((duration / 4f) / 25); - } else if (duration >= 1000) { + } else if (duration <= 1000) { + boardsCount = (int) Math.ceil((duration / 5f) / 25); + } else { boardsCount = (int) Math.ceil((duration / 10f) / 25); } @@ -353,15 +361,19 @@ public class PhotoViewerWebView extends FrameLayout { if (index != -1) { if (index == youtubeStoryboards.size() - 1) { int duration = getVideoDuration() / 1000; - int totalImages = 0; - if (duration < 250) { + int totalImages; + if (duration <= 100) { + totalImages = (int) Math.ceil(duration); + } else if (duration <= 250) { totalImages = (int) Math.ceil(duration / 2f); - } else if (duration >= 250 && duration < 1000) { + } else if (duration <= 500) { totalImages = (int) Math.ceil(duration / 4f); - } else if (duration >= 1000) { + } else if (duration <= 1000) { + totalImages = (int) Math.ceil(duration / 5f); + } else { totalImages = (int) Math.ceil(duration / 10f); } - return totalImages - (youtubeStoryboards.size() - 1) * 25; + return Math.min(25, totalImages - (youtubeStoryboards.size() - 1) * 25 + 1); } return 25; } @@ -371,26 +383,34 @@ public class PhotoViewerWebView extends FrameLayout { public String getYoutubeStoryboard(int position) { int duration = getVideoDuration() / 1000; - int i = -1; - if (duration < 250) { + int i; + if (duration <= 100) { + i = (int) (position / 25f); + } else if (duration <= 250) { i = (int) (position / 2f) / 25; - } else if (duration >= 250 && duration < 1000) { + } else if (duration <= 500) { i = (int) (position / 4f) / 25; - } else if (duration >= 1000) { + } else if (duration <= 1000) { + i = (int) (position / 5f) / 25; + } else { i = (int) ((position / 10f) / 25); } - return i != -1 && i < youtubeStoryboards.size() ? youtubeStoryboards.get(i) : null; + return i < youtubeStoryboards.size() ? youtubeStoryboards.get(i) : null; } public int getYoutubeStoryboardImageIndex(int position) { int duration = getVideoDuration() / 1000; - int i = -1; - if (duration < 250) { + int i; + if (duration <= 100) { + i = (int) Math.ceil(position) % 25; + } else if (duration <= 250) { i = (int) Math.ceil(position / 2f) % 25; - } else if (duration >= 250 && duration < 1000) { + } else if (duration <= 500) { i = (int) Math.ceil(position / 4f) % 25; - } else if (duration >= 1000) { + } else if (duration <= 1000) { + i = (int) Math.ceil(position / 5f) % 25; + } else { i = (int) Math.ceil(position / 10f) % 25; } return i; @@ -676,6 +696,8 @@ public class PhotoViewerWebView extends FrameLayout { webView.stopLoading(); webView.loadUrl("about:blank"); webView.destroy(); + videoDuration = 0; + currentPosition = 0; AndroidUtilities.cancelRunOnUIThread(progressRunnable); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/DoubleLimitsPageView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/DoubleLimitsPageView.java new file mode 100644 index 000000000..58d48b769 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/DoubleLimitsPageView.java @@ -0,0 +1,55 @@ +package org.telegram.ui.Components.Premium; + +import android.content.Context; +import android.graphics.Canvas; +import android.widget.FrameLayout; + +import androidx.recyclerview.widget.LinearLayoutManager; + +import org.telegram.messenger.UserConfig; +import org.telegram.ui.ActionBar.Theme; +import org.telegram.ui.Components.LayoutHelper; +import org.telegram.ui.Components.RecyclerListView; + +public class DoubleLimitsPageView extends FrameLayout implements PagerHeaderView { + + final RecyclerListView recyclerListView; + final LinearLayoutManager layoutManager; + DoubledLimitsBottomSheet.Adapter adapter; + + public DoubleLimitsPageView(Context context) { + super(context); + recyclerListView = new RecyclerListView(context); + adapter = new DoubledLimitsBottomSheet.Adapter(UserConfig.selectedAccount, true); + recyclerListView.setAdapter(adapter); + recyclerListView.setLayoutManager(layoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)); + recyclerListView.setClipToPadding(false); + adapter.containerView = this; + addView(recyclerListView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + adapter.measureGradient(getContext(), getMeasuredWidth(), getMeasuredHeight()); + } + + @Override + protected void dispatchDraw(Canvas canvas) { + super.dispatchDraw(canvas); + canvas.drawLine(0, getMeasuredHeight() - 1, getMeasuredWidth(), getMeasuredHeight() - 1, Theme.dividerPaint); + } + + @Override + public void setOffset(float translationX) { + float progress = Math.abs(translationX / getMeasuredWidth()); + if (progress == 1f) { + recyclerListView.scrollToPosition(0); + } + + } + + public void setTopOffset(int topOffset) { + recyclerListView.setPadding(0, topOffset, 0, 0); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/DoubledLimitsBottomSheet.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/DoubledLimitsBottomSheet.java index d38a0b3e3..be397511b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/DoubledLimitsBottomSheet.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/DoubledLimitsBottomSheet.java @@ -35,14 +35,6 @@ import java.util.ArrayList; public class DoubledLimitsBottomSheet extends BottomSheetWithRecyclerListView implements NotificationCenter.NotificationCenterDelegate { - final ArrayList limits = new ArrayList<>(); - - int rowCount; - int headerRow; - int limitsStartRow; - int limitsStartEnd; - int lastViewRow; - FrameLayout titleLayout; TextView titleView; ImageView titleImage; @@ -52,12 +44,11 @@ public class DoubledLimitsBottomSheet extends BottomSheetWithRecyclerListView im float titleProgress; - PremiumGradient.GradientTools gradientTools; - private int totalGradientHeight; private BaseFragment baseFragment; private View divider; private PremiumPreviewFragment.SubscriptionTier selectedTier; + private Adapter adapter; public DoubledLimitsBottomSheet(BaseFragment fragment, int currentAccount) { this(fragment, currentAccount, null); @@ -67,71 +58,8 @@ public class DoubledLimitsBottomSheet extends BottomSheetWithRecyclerListView im super(fragment, false, false); this.selectedTier = subscriptionTier; this.baseFragment = fragment; - gradientTools = new PremiumGradient.GradientTools(Theme.key_premiumGradient1, Theme.key_premiumGradient2, Theme.key_premiumGradient3, Theme.key_premiumGradient4); - gradientTools.x1 = 0; - gradientTools.y1 = 0; - gradientTools.x2 = 0; - gradientTools.y2 = 1f; clipToActionBar = true; - MessagesController messagesController = MessagesController.getInstance(currentAccount); - limits.add(new Limit( - LocaleController.getString("GroupsAndChannelsLimitTitle", R.string.GroupsAndChannelsLimitTitle), - LocaleController.formatString("GroupsAndChannelsLimitSubtitle", R.string.GroupsAndChannelsLimitSubtitle, messagesController.channelsLimitPremium), - messagesController.channelsLimitDefault, messagesController.channelsLimitPremium - )); - limits.add(new Limit( - LocaleController.getString("PinChatsLimitTitle", R.string.PinChatsLimitTitle), - LocaleController.formatString("PinChatsLimitSubtitle", R.string.PinChatsLimitSubtitle, messagesController.dialogFiltersPinnedLimitPremium), - messagesController.dialogFiltersPinnedLimitDefault, messagesController.dialogFiltersPinnedLimitPremium - )); - limits.add(new Limit( - LocaleController.getString("PublicLinksLimitTitle", R.string.PublicLinksLimitTitle), - LocaleController.formatString("PublicLinksLimitSubtitle", R.string.PublicLinksLimitSubtitle, messagesController.publicLinksLimitPremium), - messagesController.publicLinksLimitDefault, messagesController.publicLinksLimitPremium - )); - limits.add(new Limit( - LocaleController.getString("SavedGifsLimitTitle", R.string.SavedGifsLimitTitle), - LocaleController.formatString("SavedGifsLimitSubtitle", R.string.SavedGifsLimitSubtitle, messagesController.savedGifsLimitPremium), - messagesController.savedGifsLimitDefault, messagesController.savedGifsLimitPremium - )); - limits.add(new Limit( - LocaleController.getString("FavoriteStickersLimitTitle", R.string.FavoriteStickersLimitTitle), - LocaleController.formatString("FavoriteStickersLimitSubtitle", R.string.FavoriteStickersLimitSubtitle, messagesController.stickersFavedLimitPremium), - messagesController.stickersFavedLimitDefault, messagesController.stickersFavedLimitPremium - )); - limits.add(new Limit( - LocaleController.getString("BioLimitTitle", R.string.BioLimitTitle), - LocaleController.formatString("BioLimitSubtitle", R.string.BioLimitSubtitle, messagesController.stickersFavedLimitPremium), - messagesController.aboutLengthLimitDefault, messagesController.aboutLengthLimitPremium - )); - limits.add(new Limit( - LocaleController.getString("CaptionsLimitTitle", R.string.CaptionsLimitTitle), - LocaleController.formatString("CaptionsLimitSubtitle", R.string.CaptionsLimitSubtitle, messagesController.stickersFavedLimitPremium), - messagesController.captionLengthLimitDefault, messagesController.captionLengthLimitPremium - )); - limits.add(new Limit( - LocaleController.getString("FoldersLimitTitle", R.string.FoldersLimitTitle), - LocaleController.formatString("FoldersLimitSubtitle", R.string.FoldersLimitSubtitle, messagesController.dialogFiltersLimitPremium), - messagesController.dialogFiltersLimitDefault, messagesController.dialogFiltersLimitPremium - )); - limits.add(new Limit( - LocaleController.getString("ChatPerFolderLimitTitle", R.string.ChatPerFolderLimitTitle), - LocaleController.formatString("ChatPerFolderLimitSubtitle", R.string.ChatPerFolderLimitSubtitle, messagesController.dialogFiltersChatsLimitPremium), - messagesController.dialogFiltersChatsLimitDefault, messagesController.dialogFiltersChatsLimitPremium - )); - limits.add(new Limit( - LocaleController.getString("ConnectedAccountsLimitTitle", R.string.ConnectedAccountsLimitTitle), - LocaleController.formatString("ConnectedAccountsLimitSubtitle", R.string.ConnectedAccountsLimitSubtitle, 4), - UserConfig.MAX_ACCOUNT_DEFAULT_COUNT, UserConfig.MAX_ACCOUNT_COUNT - )); - - rowCount = 0; - headerRow = rowCount++; - limitsStartRow = rowCount; - rowCount += limits.size(); - limitsStartEnd = rowCount; - //lastViewRow = rowCount++; titleLayout = new FrameLayout(getContext()); titleView = new TextView(getContext()); @@ -184,7 +112,7 @@ public class DoubledLimitsBottomSheet extends BottomSheetWithRecyclerListView im @Override protected void onPreMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onPreMeasure(widthMeasureSpec, heightMeasureSpec); - measureGradient(View.MeasureSpec.getSize(widthMeasureSpec), View.MeasureSpec.getSize(heightMeasureSpec)); + adapter.measureGradient(getContext(), View.MeasureSpec.getSize(widthMeasureSpec), View.MeasureSpec.getSize(heightMeasureSpec)); } @Override @@ -228,61 +156,9 @@ public class DoubledLimitsBottomSheet extends BottomSheetWithRecyclerListView im @Override protected RecyclerListView.SelectionAdapter createAdapter() { - return new RecyclerListView.SelectionAdapter() { - @Override - public boolean isEnabled(RecyclerView.ViewHolder holder) { - return false; - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - Context context = parent.getContext(); - View view; - switch (viewType) { - default: - case 0: - LimitCell limitCell = new LimitCell(context); - limitCell.previewView.setParentViewForGradien(containerView); - limitCell.previewView.setStaticGradinet(gradientTools); - view = limitCell; - break; - case 1: - view = new FixedHeightEmptyCell(context, 40 + 24); - break; - case 2: - view = new FixedHeightEmptyCell(context, 16); - break; - } - view.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); - return new RecyclerListView.Holder(view); - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if (holder.getItemViewType() == 0) { - LimitCell limitCell = (LimitCell) holder.itemView; - limitCell.setData(limits.get(position - limitsStartRow)); - limitCell.previewView.gradientYOffset = limits.get(position - limitsStartRow).yOffset; - limitCell.previewView.gradientTotalHeight = totalGradientHeight; - } - } - - @Override - public int getItemCount() { - return rowCount; - } - - @Override - public int getItemViewType(int position) { - if (position == headerRow) { - return 1; - } else if (position == lastViewRow) { - return 2; - } - return 0; - } - }; + adapter = new Adapter(currentAccount, false); + adapter.containerView = containerView; + return adapter; } public void setParentFragment(PremiumPreviewFragment premiumPreviewFragment) { @@ -317,7 +193,7 @@ public class DoubledLimitsBottomSheet extends BottomSheetWithRecyclerListView im } - private class LimitCell extends LinearLayout { + private static class LimitCell extends LinearLayout { TextView title; TextView subtitle; @@ -352,19 +228,6 @@ public class DoubledLimitsBottomSheet extends BottomSheetWithRecyclerListView im } } - private void measureGradient(int w, int h) { - int yOffset = 0; - LimitCell dummyCell = new LimitCell(getContext()); - for (int i = 0; i < limits.size(); i++) { - dummyCell.setData(limits.get(i)); - dummyCell.measure(View.MeasureSpec.makeMeasureSpec(w, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(h, View.MeasureSpec.AT_MOST)); - limits.get(i).yOffset = yOffset; - yOffset += dummyCell.getMeasuredHeight(); - } - - totalGradientHeight = yOffset; - } - private static class Limit { final String title; @@ -381,4 +244,183 @@ public class DoubledLimitsBottomSheet extends BottomSheetWithRecyclerListView im this.premiumLimit = premiumLimit; } } + + public static class Adapter extends RecyclerListView.SelectionAdapter { + + int rowCount; + int headerRow; + int limitsStartRow; + int limitsStartEnd; + int lastViewRow; + + final ArrayList limits = new ArrayList<>(); + + PremiumGradient.GradientTools gradientTools; + private int totalGradientHeight; + + ViewGroup containerView; + boolean drawHeader; + + public Adapter(int currentAccount, boolean drawHeader) { + this.drawHeader = drawHeader; + gradientTools = new PremiumGradient.GradientTools(Theme.key_premiumGradient1, Theme.key_premiumGradient2, Theme.key_premiumGradient3, Theme.key_premiumGradient4); + gradientTools.x1 = 0; + gradientTools.y1 = 0; + gradientTools.x2 = 0; + gradientTools.y2 = 1f; + + MessagesController messagesController = MessagesController.getInstance(currentAccount); + limits.add(new Limit( + LocaleController.getString("GroupsAndChannelsLimitTitle", R.string.GroupsAndChannelsLimitTitle), + LocaleController.formatString("GroupsAndChannelsLimitSubtitle", R.string.GroupsAndChannelsLimitSubtitle, messagesController.channelsLimitPremium), + messagesController.channelsLimitDefault, messagesController.channelsLimitPremium + )); + limits.add(new Limit( + LocaleController.getString("PinChatsLimitTitle", R.string.PinChatsLimitTitle), + LocaleController.formatString("PinChatsLimitSubtitle", R.string.PinChatsLimitSubtitle, messagesController.dialogFiltersPinnedLimitPremium), + messagesController.dialogFiltersPinnedLimitDefault, messagesController.dialogFiltersPinnedLimitPremium + )); + limits.add(new Limit( + LocaleController.getString("PublicLinksLimitTitle", R.string.PublicLinksLimitTitle), + LocaleController.formatString("PublicLinksLimitSubtitle", R.string.PublicLinksLimitSubtitle, messagesController.publicLinksLimitPremium), + messagesController.publicLinksLimitDefault, messagesController.publicLinksLimitPremium + )); + limits.add(new Limit( + LocaleController.getString("SavedGifsLimitTitle", R.string.SavedGifsLimitTitle), + LocaleController.formatString("SavedGifsLimitSubtitle", R.string.SavedGifsLimitSubtitle, messagesController.savedGifsLimitPremium), + messagesController.savedGifsLimitDefault, messagesController.savedGifsLimitPremium + )); + limits.add(new Limit( + LocaleController.getString("FavoriteStickersLimitTitle", R.string.FavoriteStickersLimitTitle), + LocaleController.formatString("FavoriteStickersLimitSubtitle", R.string.FavoriteStickersLimitSubtitle, messagesController.stickersFavedLimitPremium), + messagesController.stickersFavedLimitDefault, messagesController.stickersFavedLimitPremium + )); + limits.add(new Limit( + LocaleController.getString("BioLimitTitle", R.string.BioLimitTitle), + LocaleController.formatString("BioLimitSubtitle", R.string.BioLimitSubtitle, messagesController.stickersFavedLimitPremium), + messagesController.aboutLengthLimitDefault, messagesController.aboutLengthLimitPremium + )); + limits.add(new Limit( + LocaleController.getString("CaptionsLimitTitle", R.string.CaptionsLimitTitle), + LocaleController.formatString("CaptionsLimitSubtitle", R.string.CaptionsLimitSubtitle, messagesController.stickersFavedLimitPremium), + messagesController.captionLengthLimitDefault, messagesController.captionLengthLimitPremium + )); + limits.add(new Limit( + LocaleController.getString("FoldersLimitTitle", R.string.FoldersLimitTitle), + LocaleController.formatString("FoldersLimitSubtitle", R.string.FoldersLimitSubtitle, messagesController.dialogFiltersLimitPremium), + messagesController.dialogFiltersLimitDefault, messagesController.dialogFiltersLimitPremium + )); + limits.add(new Limit( + LocaleController.getString("ChatPerFolderLimitTitle", R.string.ChatPerFolderLimitTitle), + LocaleController.formatString("ChatPerFolderLimitSubtitle", R.string.ChatPerFolderLimitSubtitle, messagesController.dialogFiltersChatsLimitPremium), + messagesController.dialogFiltersChatsLimitDefault, messagesController.dialogFiltersChatsLimitPremium + )); + limits.add(new Limit( + LocaleController.getString("ConnectedAccountsLimitTitle", R.string.ConnectedAccountsLimitTitle), + LocaleController.formatString("ConnectedAccountsLimitSubtitle", R.string.ConnectedAccountsLimitSubtitle, 4), + UserConfig.MAX_ACCOUNT_DEFAULT_COUNT, UserConfig.MAX_ACCOUNT_COUNT + )); + + rowCount = 0; + headerRow = rowCount++; + limitsStartRow = rowCount; + rowCount += limits.size(); + limitsStartEnd = rowCount; + } + + @Override + public boolean isEnabled(RecyclerView.ViewHolder holder) { + return false; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + Context context = parent.getContext(); + View view; + switch (viewType) { + default: + case 0: + LimitCell limitCell = new LimitCell(context); + limitCell.previewView.setParentViewForGradien(containerView); + limitCell.previewView.setStaticGradinet(gradientTools); + view = limitCell; + break; + case 1: + if (drawHeader) { + FrameLayout titleLayout = new FrameLayout(context) { + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(86), MeasureSpec.EXACTLY)); + } + }; + LinearLayout linearLayout = new LinearLayout(context); + linearLayout.setOrientation(LinearLayout.HORIZONTAL); + + ImageView titleImage = new ImageView(context); + titleImage.setImageDrawable(PremiumGradient.getInstance().createGradientDrawable(ContextCompat.getDrawable(context, R.drawable.other_2x_large))); + linearLayout.addView(titleImage, LayoutHelper.createFrame(40, 28, Gravity.CENTER_VERTICAL, 0, 0, 8, 0)); + + TextView titleView = new TextView(context); + titleView.setText(LocaleController.getString("DoubledLimits", R.string.DoubledLimits)); + titleView.setGravity(Gravity.CENTER); + titleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); + titleView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText)); + titleView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + linearLayout.addView(titleView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL)); + + + titleLayout.addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER)); + view = titleLayout; + } else { + view = new FixedHeightEmptyCell(context, 40 + 24); + } + break; + case 2: + view = new FixedHeightEmptyCell(context, 16); + break; + } + view.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + return new RecyclerListView.Holder(view); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder.getItemViewType() == 0) { + LimitCell limitCell = (LimitCell) holder.itemView; + limitCell.setData(limits.get(position - limitsStartRow)); + limitCell.previewView.gradientYOffset = limits.get(position - limitsStartRow).yOffset; + limitCell.previewView.gradientTotalHeight = totalGradientHeight; + } + } + + @Override + public int getItemCount() { + return rowCount; + } + + @Override + public int getItemViewType(int position) { + if (position == headerRow) { + return 1; + } else if (position == lastViewRow) { + return 2; + } + return 0; + } + + public void measureGradient(Context context, int w, int h) { + int yOffset = 0; + LimitCell dummyCell = new LimitCell(context); + for (int i = 0; i < limits.size(); i++) { + dummyCell.setData(limits.get(i)); + dummyCell.measure(View.MeasureSpec.makeMeasureSpec(w, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(h, View.MeasureSpec.AT_MOST)); + limits.get(i).yOffset = yOffset; + yOffset += dummyCell.getMeasuredHeight(); + } + + totalGradientHeight = yOffset; + } + } + } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumFeatureBottomSheet.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumFeatureBottomSheet.java index 33b446a8f..05515c55c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumFeatureBottomSheet.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumFeatureBottomSheet.java @@ -6,6 +6,7 @@ import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.TypedValue; import android.view.Gravity; @@ -19,7 +20,9 @@ import android.widget.ScrollView; import android.widget.TextView; import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; import androidx.core.graphics.ColorUtils; +import androidx.recyclerview.widget.RecyclerView; import androidx.viewpager.widget.PagerAdapter; import androidx.viewpager.widget.ViewPager; @@ -30,6 +33,7 @@ import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.SvgHelper; import org.telegram.messenger.UserConfig; +import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ActionBar.BottomSheet; import org.telegram.ui.ActionBar.Theme; @@ -44,22 +48,29 @@ import java.util.ArrayList; public class PremiumFeatureBottomSheet extends BottomSheet implements NotificationCenter.NotificationCenterDelegate { + private final BaseFragment baseFragment; private PremiumButtonView premiumButtonView; ArrayList premiumFeatures = new ArrayList<>(); float containerViewsProgress; + float progressToFullscreenView; boolean containerViewsForward; ViewPager viewPager; FrameLayout content; int contentHeight; private FrameLayout buttonContainer; + FrameLayout closeLayout; boolean enterAnimationIsRunning; SvgHelper.SvgDrawable svgIcon; private final int startType; private final boolean onlySelectedType; private PremiumPreviewFragment.SubscriptionTier selectedTier; + private int gradientAlpha = 255; + int topGlobalOffset; + int topCurrentOffset; + ActionBar actionBar; public PremiumFeatureBottomSheet(BaseFragment fragment, int startType, boolean onlySelectedType) { this(fragment, startType, onlySelectedType, null); @@ -75,6 +86,7 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati public PremiumFeatureBottomSheet(BaseFragment fragment, Context context, int currentAccount, int startType, boolean onlySelectedType, PremiumPreviewFragment.SubscriptionTier subscriptionTier) { super(context, false); + this.baseFragment = fragment; if (fragment == null) { throw new RuntimeException("fragmnet can't be null"); } @@ -103,11 +115,11 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati int selectedPosition = 0; for (int i = 0; i < premiumFeatures.size(); i++) { - if (premiumFeatures.get(i).type == PremiumPreviewFragment.PREMIUM_FEATURE_LIMITS) { - premiumFeatures.remove(i); - i--; - continue; - } +// if (premiumFeatures.get(i).type == PremiumPreviewFragment.PREMIUM_FEATURE_LIMITS) { +// premiumFeatures.remove(i); +// i--; +// continue; +// } if (premiumFeatures.get(i).type == startType) { selectedPosition = i; break; @@ -145,13 +157,14 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati AndroidUtilities.rectTmp.set(0, AndroidUtilities.dp(2), getMeasuredWidth(), getMeasuredHeight() + AndroidUtilities.dp(18)); canvas.save(); canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight()); + gradientTools.paint.setAlpha(gradientAlpha); canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(12) - 1, AndroidUtilities.dp(12) - 1, gradientTools.paint); canvas.restore(); super.dispatchDraw(canvas); } }; - FrameLayout closeLayout = new FrameLayout(getContext()); + closeLayout = new FrameLayout(getContext()); ImageView closeImage = new ImageView(getContext()); closeImage.setImageResource(R.drawable.msg_close); closeImage.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(12), ColorUtils.setAlphaComponent(Color.WHITE, 40), ColorUtils.setAlphaComponent(Color.WHITE, 100))); @@ -168,7 +181,7 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati getChildAt(0).measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); h = getChildAt(0).getMeasuredHeight(); } - super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY)); + super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(h + topGlobalOffset, MeasureSpec.EXACTLY)); } @Override @@ -188,6 +201,7 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati return super.onTouchEvent(ev); } }; + viewPager.setOverScrollMode(View.OVER_SCROLL_NEVER); viewPager.setOffscreenPageLimit(0); PagerAdapter pagerAdapter = new PagerAdapter() { @Override @@ -263,6 +277,19 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati } containerViewsProgress = progress; containerViewsForward = toPosition > selectedPosition; + if (premiumFeatures.get(selectedPosition).type == PremiumPreviewFragment.PREMIUM_FEATURE_LIMITS) { + progressToFullscreenView = 1f - progress; + } else if (premiumFeatures.get(toPosition).type == PremiumPreviewFragment.PREMIUM_FEATURE_LIMITS) { + progressToFullscreenView = progress; + } else { + progressToFullscreenView = 0; + } + int localGradientAlpha = (int) (255 * (1f - progressToFullscreenView)); + if (localGradientAlpha != gradientAlpha) { + gradientAlpha = localGradientAlpha; + content.invalidate(); + checkTopOffset(); + } } @Override @@ -315,8 +342,79 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati MediaDataController.getInstance(currentAccount).preloadPremiumPreviewStickers(); setButtonText(); + customViewGravity = Gravity.LEFT | Gravity.BOTTOM; + + Drawable headerShadowDrawable = ContextCompat.getDrawable(getContext(), R.drawable.header_shadow).mutate(); + + containerView = new FrameLayout(getContext()) { + + @Override + public boolean hasOverlappingRendering() { + return false; + } + + @Override + public void setTranslationY(float translationY) { + super.setTranslationY(translationY); + onContainerTranslationYChanged(translationY); + } + + int lastSize; + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int size = widthMeasureSpec + heightMeasureSpec << 16; + // if (size != lastSize) { + lastSize = size; + topGlobalOffset = 0; + scrollView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.AT_MOST)); + + topGlobalOffset = MeasureSpec.getSize(heightMeasureSpec) - scrollView.getMeasuredHeight() + backgroundPaddingTop; + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + checkTopOffset(); +// } else { +// super.onMeasure(widthMeasureSpec, heightMeasureSpec); +// } + } + + @Override + protected void dispatchDraw(Canvas canvas) { + shadowDrawable.setBounds(0, topCurrentOffset - backgroundPaddingTop + AndroidUtilities.dp(2), getMeasuredWidth(), getMeasuredHeight()); + shadowDrawable.draw(canvas); + super.dispatchDraw(canvas); + if (actionBar != null && actionBar.getVisibility() == View.VISIBLE && actionBar.getAlpha() != 0) { + headerShadowDrawable.setBounds(0, actionBar.getBottom(), getMeasuredWidth(), actionBar.getBottom() + headerShadowDrawable.getIntrinsicHeight()); + headerShadowDrawable.setAlpha((int) (255 * actionBar.getAlpha())); + headerShadowDrawable.draw(canvas); + } + } + + @Override + protected boolean drawChild(Canvas canvas, View child, long drawingTime) { + if (child == scrollView) { + canvas.save(); + canvas.clipRect(0, topCurrentOffset + AndroidUtilities.dp(2), getMeasuredWidth(), getMeasuredHeight()); + super.drawChild(canvas, child, drawingTime); + canvas.restore(); + return true; + } + return super.drawChild(canvas, child, drawingTime); + } + + @Override + public boolean dispatchTouchEvent(MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + if (event.getY() < topCurrentOffset - backgroundPaddingTop + AndroidUtilities.dp(2)) { + dismiss(); + } + } + return super.dispatchTouchEvent(event); + } + }; + containerView.setPadding(backgroundPaddingLeft, backgroundPaddingTop - 1, backgroundPaddingLeft, 0); } + private void setButtonText() { if (onlySelectedType) { if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_REACTIONS) { @@ -346,6 +444,40 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.billingProductDetailsUpdated); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.premiumPromoUpdated); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.currentUserPremiumStatusChanged); + + actionBar = new ActionBar(getContext()) { + @Override + public void setAlpha(float alpha) { + if (getAlpha() != alpha) { + super.setAlpha(alpha); + containerView.invalidate(); + } + } + + @Override + public void setTag(Object tag) { + super.setTag(tag); + updateStatusBar(); + } + }; + actionBar.setBackgroundColor(getThemedColor(Theme.key_dialogBackground)); + actionBar.setTitleColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText)); + actionBar.setItemsBackgroundColor(getThemedColor(Theme.key_actionBarActionModeDefaultSelector), false); + actionBar.setItemsColor(getThemedColor(Theme.key_actionBarActionModeDefaultIcon), false); + + actionBar.setCastShadows(true); + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setTitle(LocaleController.getString("DoubledLimits", R.string.DoubledLimits)); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + dismiss(); + } + } + }); + containerView.addView(actionBar, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, -backgroundPaddingTop, 0, 0)); + AndroidUtilities.updateViewVisibilityAnimated(actionBar, false, 1f, false); } @Override @@ -380,6 +512,7 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati TextView description; PagerHeaderView topHeader; View topView; + boolean topViewOnFullHeight; public ViewPage(Context context, int p) { super(context); @@ -409,6 +542,10 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + title.setVisibility(View.VISIBLE); + if (topView instanceof DoubleLimitsPageView) { + ((DoubleLimitsPageView) topView).setTopOffset(topGlobalOffset); + } topView.getLayoutParams().height = contentHeight; description.setVisibility(isPortrait ? View.VISIBLE : View.GONE); MarginLayoutParams layoutParams = (MarginLayoutParams) title.getLayoutParams(); @@ -419,13 +556,26 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati layoutParams.topMargin = AndroidUtilities.dp(10); layoutParams.bottomMargin = AndroidUtilities.dp(10); } + ((MarginLayoutParams) topView.getLayoutParams()).bottomMargin = 0; super.onMeasure(widthMeasureSpec, heightMeasureSpec); + if (topViewOnFullHeight) { + topView.getLayoutParams().height = getMeasuredHeight() - AndroidUtilities.dp(16); + ((MarginLayoutParams) topView.getLayoutParams()).bottomMargin = AndroidUtilities.dp(16); + title.setVisibility(View.GONE); + description.setVisibility(View.GONE); + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } } @Override protected boolean drawChild(Canvas canvas, View child, long drawingTime) { if (child == topView) { - if (child instanceof CarouselView) { + if (child instanceof DoubleLimitsPageView) { + setTranslationY(0); + } else { + setTranslationY(topGlobalOffset); + } + if (child instanceof CarouselView || child instanceof DoubleLimitsPageView) { return super.drawChild(canvas, child, drawingTime); } canvas.save(); @@ -439,27 +589,45 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati } void setFeatureDate(PremiumPreviewFragment.PremiumFeatureData featureData) { - - if (onlySelectedType) { + if (featureData.type == PremiumPreviewFragment.PREMIUM_FEATURE_LIMITS) { + title.setText(""); + description.setText(""); + topViewOnFullHeight = true; + } else if (onlySelectedType) { if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_REACTIONS) { title.setText(LocaleController.getString("AdditionalReactions", R.string.AdditionalReactions)); description.setText(LocaleController.getString("AdditionalReactionsDescription", R.string.AdditionalReactionsDescription)); } else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_ADS) { title.setText(LocaleController.getString("PremiumPreviewNoAds", R.string.PremiumPreviewNoAds)); description.setText(LocaleController.getString("PremiumPreviewNoAdsDescription2", R.string.PremiumPreviewNoAdsDescription2)); - } else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_APPLICATION_ICONS) { + } else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_APPLICATION_ICONS) { title.setText(LocaleController.getString("PremiumPreviewAppIcon", R.string.PremiumPreviewAppIcon)); description.setText(LocaleController.getString("PremiumPreviewAppIconDescription2", R.string.PremiumPreviewAppIconDescription2)); } + topViewOnFullHeight = false; } else { title.setText(featureData.title); description.setText(featureData.description); + topViewOnFullHeight = false; } + requestLayout(); + } } View getViewForPosition(Context context, int position) { PremiumPreviewFragment.PremiumFeatureData featureData = premiumFeatures.get(position); + if (featureData.type == PremiumPreviewFragment.PREMIUM_FEATURE_LIMITS) { + DoubleLimitsPageView doubleLimitsPagerView = new DoubleLimitsPageView(context); + doubleLimitsPagerView.recyclerListView.setOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + checkTopOffset(); + } + }); + return doubleLimitsPagerView; + } if (featureData.type == PremiumPreviewFragment.PREMIUM_FEATURE_STICKERS) { PremiumStickersPreviewRecycler recyclerListView = new PremiumStickersPreviewRecycler(context, currentAccount) { @Override @@ -507,4 +675,62 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati } return super.onCustomOpenAnimation(); } + + void checkTopOffset() { + int viewOffset = -1; + for (int i = 0; i < viewPager.getChildCount(); i++) { + if (((ViewPage) viewPager.getChildAt(i)).topView instanceof DoubleLimitsPageView) { + DoubleLimitsPageView doubleLimitsPagerView = (DoubleLimitsPageView) ((ViewPage) viewPager.getChildAt(i)).topView; + View view = doubleLimitsPagerView.layoutManager.findViewByPosition(0); + if (view == null) { + viewOffset = 0; + } else { + viewOffset = view.getTop(); + if (viewOffset < 0) { + viewOffset = 0; + } + } + break; + } + } + int localOffset; + if (viewOffset >= 0) { + localOffset = (int) (viewOffset * progressToFullscreenView + topGlobalOffset * (1f - progressToFullscreenView)); + } else { + localOffset = topGlobalOffset; + } + closeLayout.setAlpha(1f - progressToFullscreenView); + if (progressToFullscreenView == 1) { + closeLayout.setVisibility(View.INVISIBLE); + } else { + closeLayout.setVisibility(View.VISIBLE); + } + content.setTranslationX(content.getMeasuredWidth() * progressToFullscreenView); + if (localOffset != topCurrentOffset) { + topCurrentOffset = localOffset; + for (int i = 0; i < viewPager.getChildCount(); i++) { + if (!((ViewPage) viewPager.getChildAt(i)).topViewOnFullHeight) { + viewPager.getChildAt(i).setTranslationY(topCurrentOffset); + } + } + + content.setTranslationY(topCurrentOffset); + closeLayout.setTranslationY(topCurrentOffset); + containerView.invalidate(); + boolean showActionBar = topCurrentOffset < AndroidUtilities.dp(30); + AndroidUtilities.updateViewVisibilityAnimated(actionBar, showActionBar, 1f, true); + } + } + + private void updateStatusBar() { + if (actionBar != null && actionBar.getTag() != null) { + AndroidUtilities.setLightStatusBar(getWindow(), isLightStatusBar()); + } else if (baseFragment != null) { + AndroidUtilities.setLightStatusBar(getWindow(), baseFragment.isLightStatusBar()); + } + } + + private boolean isLightStatusBar() { + return ColorUtils.calculateLuminance(Theme.getColor(Theme.key_dialogBackground)) > 0.7f; + } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumPreviewBottomSheet.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumPreviewBottomSheet.java index 0c52c80fa..a28c32cc2 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumPreviewBottomSheet.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumPreviewBottomSheet.java @@ -146,12 +146,12 @@ public class PremiumPreviewBottomSheet extends BottomSheetWithRecyclerListView i if (view instanceof PremiumFeatureCell) { PremiumFeatureCell cell = (PremiumFeatureCell) view; PremiumPreviewFragment.sentShowFeaturePreview(currentAccount, cell.data.type); - if (cell.data.type == PremiumPreviewFragment.PREMIUM_FEATURE_LIMITS) { - DoubledLimitsBottomSheet bottomSheet = new DoubledLimitsBottomSheet(fragment, currentAccount); - showDialog(bottomSheet); - } else { +// if (cell.data.type == PremiumPreviewFragment.PREMIUM_FEATURE_LIMITS) { +// DoubledLimitsBottomSheet bottomSheet = new DoubledLimitsBottomSheet(fragment, currentAccount); +// showDialog(bottomSheet); +// } else { showDialog(new PremiumFeatureBottomSheet(fragment, cell.data.type, false)); - } + // } } }); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ReactedUsersListView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ReactedUsersListView.java index 0ee429dd8..04507d8b0 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ReactedUsersListView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ReactedUsersListView.java @@ -145,7 +145,7 @@ public class ReactedUsersListView extends FrameLayout { @Override public int getItemCount() { - return userReactions.size() + (!customReactionsEmoji.isEmpty() ? 1 : 0); + return userReactions.size() + (!customReactionsEmoji.isEmpty() && !MessagesController.getInstance(currentAccount).premiumLocked ? 1 : 0); } @Override @@ -183,14 +183,14 @@ public class ReactedUsersListView extends FrameLayout { loadingView = new FlickerLoadingView(context, resourcesProvider) { @Override public int getAdditionalHeight() { - return !customReactionsEmoji.isEmpty() ? messageContainsEmojiButton.getMeasuredHeight() + AndroidUtilities.dp(8) : 0; + return !customReactionsEmoji.isEmpty() && messageContainsEmojiButton != null ? messageContainsEmojiButton.getMeasuredHeight() + AndroidUtilities.dp(8) : 0; } }; loadingView.setIsSingleCell(true); loadingView.setItemsCount(predictiveCount); addView(loadingView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); - if (!addPadding && filter != null && filter instanceof TLRPC.TL_reactionCustomEmoji) { + if (!addPadding && filter != null && filter instanceof TLRPC.TL_reactionCustomEmoji && !MessagesController.getInstance(currentAccount).premiumLocked) { customReactionsEmoji.clear(); customReactionsEmoji.add(ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(filter)); updateCustomReactionsButton(); @@ -325,6 +325,7 @@ public class ReactedUsersListView extends FrameLayout { } private void updateCustomReactionsButton() { + customEmojiStickerSets.clear(); ArrayList sets = new ArrayList<>(); HashSet setIds = new HashSet<>(); for (int i = 0; i < customReactionsEmoji.size(); i++) { @@ -334,7 +335,9 @@ public class ReactedUsersListView extends FrameLayout { setIds.add(stickerSet.id); } } - customEmojiStickerSets.clear(); + if (MessagesController.getInstance(currentAccount).premiumLocked) { + return; + } customEmojiStickerSets.addAll(sets); messageContainsEmojiButton = new MessageContainsEmojiButton(currentAccount, getContext(), resourcesProvider, sets, MessageContainsEmojiButton.REACTIONS_TYPE); messageContainsEmojiButton.checkWidth = false; 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 f59c9339a..bc754f9bd 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 @@ -5,7 +5,6 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Canvas; -import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PixelFormat; @@ -17,7 +16,6 @@ import android.graphics.drawable.Drawable; import android.view.Gravity; import android.view.HapticFeedbackConstants; import android.view.KeyEvent; -import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.FrameLayout; @@ -25,6 +23,8 @@ import android.widget.FrameLayout; import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; +import com.google.android.exoplayer2.util.Log; + import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.ImageReceiver; import org.telegram.messenger.LocaleController; @@ -40,7 +40,6 @@ import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.Components.Bulletin; import org.telegram.ui.Components.BulletinFactory; import org.telegram.ui.Components.CubicBezierInterpolator; -import org.telegram.ui.Components.EditTextBoldCursor; import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.Premium.PremiumFeatureBottomSheet; import org.telegram.ui.Components.ReactionsContainerLayout; @@ -75,6 +74,10 @@ public class CustomEmojiReactionsWindow { BaseFragment baseFragment; Theme.ResourcesProvider resourcesProvider; + float yTranslation; + float keyboardHeight; + private boolean wasFocused; + public CustomEmojiReactionsWindow(BaseFragment baseFragment, List reactions, HashSet selectedReactions, ReactionsContainerLayout reactionsContainerLayout, Theme.ResourcesProvider resourcesProvider) { this.reactions = reactions; this.baseFragment = baseFragment; @@ -87,21 +90,45 @@ public class CustomEmojiReactionsWindow { dismiss(); return true; } - return false; + return super.dispatchKeyEvent(event); } @Override protected void dispatchSetPressed(boolean pressed) { } + + @Override + protected boolean fitSystemWindows(Rect insets) { + if (keyboardHeight != insets.bottom && wasFocused) { + keyboardHeight = insets.bottom; + updateWindowPosition(); + } + return super.fitSystemWindows(insets); + } + }; windowView.setOnClickListener(v -> dismiss()); + // sizeNotifierFrameLayout.setFitsSystemWindows(true); + containerView = new ContainerView(context); selectAnimatedEmojiDialog = new SelectAnimatedEmojiDialog(baseFragment, context, false, null, SelectAnimatedEmojiDialog.TYPE_REACTIONS, resourcesProvider) { + @Override + protected void onInputFocus() { + if (!wasFocused) { + wasFocused = true; + windowManager.updateViewLayout(windowView, createLayoutParams(true)); + if (baseFragment instanceof ChatActivity) { + ((ChatActivity) baseFragment).needEnterText(); + } + } + } + @Override protected void onReactionClick(ImageViewEmoji emoji, ReactionsLayoutInBubble.VisibleReaction reaction) { reactionsContainerLayout.onReactionClicked(emoji, reaction, false); + AndroidUtilities.hideKeyboard(windowView); } @Override @@ -117,6 +144,7 @@ public class CustomEmojiReactionsWindow { return; } reactionsContainerLayout.onReactionClicked(emojiView, ReactionsLayoutInBubble.VisibleReaction.fromCustomEmoji(documentId), false); + AndroidUtilities.hideKeyboard(windowView); } }; selectAnimatedEmojiDialog.setOnLongPressedListener(new SelectAnimatedEmojiDialog.onLongPressedListener() { @@ -142,31 +170,7 @@ public class CustomEmojiReactionsWindow { containerView.addView(selectAnimatedEmojiDialog, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 0, 0, 0)); windowView.addView(containerView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP, 16, 16, 16, 16)); windowView.setClipChildren(false); - EditTextBoldCursor editTextBoldCursor = new EditTextBoldCursor(context) { - - boolean focusable = false; - - @Override - public boolean dispatchTouchEvent(MotionEvent event) { - if (!focusable) { - WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); - lp.width = lp.height = WindowManager.LayoutParams.MATCH_PARENT; - lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; - lp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; - lp.format = PixelFormat.TRANSLUCENT; - windowManager.updateViewLayout(windowView, lp); - } - return super.dispatchTouchEvent(event); - } - }; - editTextBoldCursor.setBackgroundColor(Color.BLACK); - //containerView.addView(editTextBoldCursor, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 50)); - - WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); - lp.width = lp.height = WindowManager.LayoutParams.MATCH_PARENT; - lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; - lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; - lp.format = PixelFormat.TRANSLUCENT; + WindowManager.LayoutParams lp = createLayoutParams(false); windowManager = baseFragment.getParentActivity().getWindowManager(); windowManager.addView(windowView, lp); @@ -184,18 +188,52 @@ public class CustomEmojiReactionsWindow { NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.stopAllHeavyOperations, 7); } + private void updateWindowPosition() { + if (dismissed) { + return; + } + float y = yTranslation; + if (y + containerView.getMeasuredHeight() > windowView.getMeasuredHeight() - keyboardHeight - AndroidUtilities.dp(32)) { + y = windowView.getMeasuredHeight() - keyboardHeight - containerView.getMeasuredHeight() - AndroidUtilities.dp(32); + } + if (y < 0) { + y = 0; + } + containerView.animate().translationY(y).setDuration(250).setInterpolator(CubicBezierInterpolator.DEFAULT).start(); + } + + private WindowManager.LayoutParams createLayoutParams(boolean focusable) { + WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); + lp.width = lp.height = WindowManager.LayoutParams.MATCH_PARENT; + lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; + lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; + if (focusable) { + lp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; + } else { + lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; + } + lp.format = PixelFormat.TRANSLUCENT; + return lp; + } + private void showUnlockPremiumAlert() { if (baseFragment instanceof ChatActivity) { baseFragment.showDialog(new PremiumFeatureBottomSheet(baseFragment, PremiumPreviewFragment.PREMIUM_FEATURE_ANIMATED_EMOJI, false)); } } + int[] location = new int[2]; + private void createTransition(boolean enter) { fromRect.set(reactionsContainerLayout.rect); fromRadius = reactionsContainerLayout.radius; - int[] location = new int[2]; - reactionsContainerLayout.getLocationOnScreen(location); - float y = location[1] - AndroidUtilities.dp(44) - AndroidUtilities.dp(34); + + int[] windowLocation = new int[2]; + if (enter) { + reactionsContainerLayout.getLocationOnScreen(location); + } + windowView.getLocationOnScreen(windowLocation); + float y = location[1] - windowLocation[1] - AndroidUtilities.dp(44) - AndroidUtilities.dp(34); if (y + containerView.getMeasuredHeight() > windowView.getMeasuredHeight() - AndroidUtilities.dp(32)) { y = windowView.getMeasuredHeight() - AndroidUtilities.dp(32) - containerView.getMeasuredHeight(); } @@ -203,9 +241,17 @@ public class CustomEmojiReactionsWindow { y = AndroidUtilities.dp(16); } - containerView.setTranslationX(location[0] - AndroidUtilities.dp(2)); - containerView.setTranslationY(y); - fromRect.offset(location[0] - containerView.getX(), location[1] - containerView.getY()); + containerView.setTranslationX(location[0] - windowLocation[0] - AndroidUtilities.dp(2)); + if (!enter) { + yTranslation = containerView.getTranslationY(); + } else { + yTranslation = y; + containerView.setTranslationY(yTranslation); + } + + + Log.d("kek", "" + reactionsContainerLayout.rect.top + " " + location[1] + " " + windowLocation[1] + " " + containerView.getY()); + fromRect.offset(location[0] - windowLocation[0] - containerView.getX(), location[1] - windowLocation[1] - containerView.getY()); reactionsContainerLayout.setCustomEmojiEnterProgress(enterTransitionProgress); @@ -267,7 +313,11 @@ public class CustomEmojiReactionsWindow { } Bulletin.hideVisible(); dismissed = true; + AndroidUtilities.hideKeyboard(windowView); createTransition(false); + if (wasFocused && baseFragment instanceof ChatActivity) { + ((ChatActivity) baseFragment).onEditTextDialogClose(true, true); + } } public void onDismissListener(Runnable onDismiss) { @@ -412,12 +462,12 @@ public class CustomEmojiReactionsWindow { fromY -= reactionsContainerLayout.recyclerListView.getY(); } float toX = toImageView.getX() + selectAnimatedEmojiDialog.getX() + selectAnimatedEmojiDialog.emojiGridView.getX(); - float toY = toImageView.getY() + selectAnimatedEmojiDialog.getY() + selectAnimatedEmojiDialog.emojiGridView.getY(); + float toY = toImageView.getY() + selectAnimatedEmojiDialog.getY() + selectAnimatedEmojiDialog.gridViewContainer.getY() + selectAnimatedEmojiDialog.emojiGridView.getY(); float toImageViewSize = toImageView.getMeasuredWidth(); if (toImageView.selected) { float sizeAfterScale = toImageViewSize * (0.8f + 0.2f * 0.3f); - toX += (toImageViewSize - sizeAfterScale) /2f; - toY += (toImageViewSize - sizeAfterScale) /2f; + toX += (toImageViewSize - sizeAfterScale) / 2f; + toY += (toImageViewSize - sizeAfterScale) / 2f; toImageViewSize = sizeAfterScale; } @@ -472,7 +522,7 @@ public class CustomEmojiReactionsWindow { (int) AndroidUtilities.lerp(fromRoundRadiusRt, toRoundRadiusRt, enterTransitionProgress), (int) AndroidUtilities.lerp(fromRoundRadiusRb, toRoundRadiusRb, enterTransitionProgress), (int) AndroidUtilities.lerp(fromRoundRadiusLb, toRoundRadiusLb, enterTransitionProgress) - ); + ); holderView.loopImageView.draw(canvas); holderView.loopImageView.draw(canvas); imageReceiver.setRoundRadius(radiusTmp); @@ -491,7 +541,7 @@ public class CustomEmojiReactionsWindow { holderView.enterImageView.getImageReceiver().setAlpha(oldAlpha); } else { ImageReceiver imageReceiver = holderView.loopImageView.getImageReceiver(); - if (holderView.loopImageView.animatedEmojiDrawable != null && holderView.loopImageView.animatedEmojiDrawable.getImageReceiver() != null) { + if (holderView.loopImageView.animatedEmojiDrawable != null && holderView.loopImageView.animatedEmojiDrawable.getImageReceiver() != null) { imageReceiver = holderView.loopImageView.animatedEmojiDrawable.getImageReceiver(); } float oldAlpha = imageReceiver.getAlpha(); 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 9e478ee58..a4f705b60 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ReactionsContainerLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ReactionsContainerLayout.java @@ -484,7 +484,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio } public boolean showCustomEmojiReaction() { - return allReactionsAvailable; + return !MessagesController.getInstance(currentAccount).premiumLocked && allReactionsAvailable; } private boolean showUnlockPremiumButton() { @@ -1076,7 +1076,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio for (int i = 0; i < recyclerListView.getChildCount(); i++) { if (recyclerListView.getChildAt(i) instanceof ReactionHolderView) { ReactionHolderView holderView = (ReactionHolderView) recyclerListView.getChildAt(i); - if (holderView.hasEnterAnimation) { + if (holderView.hasEnterAnimation && (holderView.loopImageView.getImageReceiver().getLottieAnimation() != null || holderView.loopImageView.getImageReceiver().getAnimation() != null)) { holderView.loopImageView.setVisibility(View.VISIBLE); holderView.enterImageView.setVisibility(View.INVISIBLE); if (holderView.shouldSwitchToLoopView) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/SearchDownloadsContainer.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SearchDownloadsContainer.java index da0afd47c..e4572713b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/SearchDownloadsContainer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SearchDownloadsContainer.java @@ -427,10 +427,18 @@ public class SearchDownloadsContainer extends FrameLayout implements Notificatio private void updateRows(ArrayList currentLoadingFilesTmp, ArrayList recentLoadingFilesTmp) { currentLoadingFiles.clear(); - currentLoadingFiles.addAll(currentLoadingFilesTmp); + for (MessageObject object : currentLoadingFilesTmp) { + if (!object.isRoundVideo() && !object.isVoice()) { + currentLoadingFiles.add(object); + } + } recentLoadingFiles.clear(); - recentLoadingFiles.addAll(recentLoadingFilesTmp); + for (MessageObject object : recentLoadingFilesTmp) { + if (!object.isRoundVideo() && !object.isVoice()) { + recentLoadingFiles.add(object); + } + } rowCount = 0; downloadingFilesHeader = -1; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/SeekBarView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SeekBarView.java index 1d82fa314..5454d87f1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/SeekBarView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SeekBarView.java @@ -15,6 +15,7 @@ import android.graphics.drawable.Drawable; import android.os.Build; import android.os.SystemClock; import android.util.StateSet; +import android.view.HapticFeedbackConstants; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; @@ -34,7 +35,7 @@ public class SeekBarView extends FrameLayout { private int thumbSize; private int selectorWidth; private int thumbX; - private AnimatedFloat animatedThumbX = new AnimatedFloat(this, 150, CubicBezierInterpolator.DEFAULT); + private AnimatedFloat animatedThumbX = new AnimatedFloat(this, 0, 80, CubicBezierInterpolator.EASE_OUT); private int thumbDX; private float progressToSet = -100; private boolean pressed; @@ -101,9 +102,7 @@ public class SeekBarView extends FrameLayout { public void setProgress(float progress) { pressed = true; SeekBarView.this.setProgress(progress); - if (delegate != null) { - delegate.onSeekBarDrag(true, progress); - } + setSeekBarDrag(true, progress); pressed = false; } @@ -203,12 +202,12 @@ public class SeekBarView extends FrameLayout { if (twoSided) { float w = (getMeasuredWidth() - selectorWidth) / 2; if (thumbX >= w) { - delegate.onSeekBarDrag(false, (thumbX - w) / w); + setSeekBarDrag(false, (thumbX - w) / w); } else { - delegate.onSeekBarDrag(false, -Math.max(0.01f, 1.0f - (w - thumbX) / w)); + setSeekBarDrag(false, -Math.max(0.01f, 1.0f - (w - thumbX) / w)); } } else { - delegate.onSeekBarDrag(true, (float) thumbX / (float) (getMeasuredWidth() - selectorWidth)); + setSeekBarDrag(true, (float) thumbX / (float) (getMeasuredWidth() - selectorWidth)); } } if (Build.VERSION.SDK_INT >= 21 && hoverDrawable != null) { @@ -261,12 +260,12 @@ public class SeekBarView extends FrameLayout { if (twoSided) { float w = (getMeasuredWidth() - selectorWidth) / 2; if (thumbX >= w) { - delegate.onSeekBarDrag(false, (thumbX - w) / w); + setSeekBarDrag(false, (thumbX - w) / w); } else { - delegate.onSeekBarDrag(false, -Math.max(0.01f, 1.0f - (w - thumbX) / w)); + setSeekBarDrag(false, -Math.max(0.01f, 1.0f - (w - thumbX) / w)); } } else { - delegate.onSeekBarDrag(false, (float) thumbX / (float) (getMeasuredWidth() - selectorWidth)); + setSeekBarDrag(false, (float) thumbX / (float) (getMeasuredWidth() - selectorWidth)); } } if (Build.VERSION.SDK_INT >= 21 && hoverDrawable != null) { @@ -280,6 +279,22 @@ public class SeekBarView extends FrameLayout { return false; } + int lastValue; + private void setSeekBarDrag(boolean stop, float progress) { + if (delegate != null) { + delegate.onSeekBarDrag(stop, progress); + } + if (separatorsCount > 1) { + int value = Math.round((separatorsCount - 1) * progress); + if (!stop && value != lastValue) { + try { + performHapticFeedback(HapticFeedbackConstants.TEXT_HANDLE_MOVE, HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); + } catch (Exception ignore) {} + } + lastValue = value; + } + } + public float getProgress() { if (getMeasuredWidth() == 0) { return progressToSet; @@ -357,16 +372,6 @@ public class SeekBarView extends FrameLayout { int y = (getMeasuredHeight() - thumbSize) / 2; innerPaint1.setColor(getThemedColor(Theme.key_player_progressBackground)); canvas.drawRect(selectorWidth / 2, getMeasuredHeight() / 2 - AndroidUtilities.dp(1), getMeasuredWidth() - selectorWidth / 2, getMeasuredHeight() / 2 + AndroidUtilities.dp(1), innerPaint1); - if (!twoSided && separatorsCount > 1) { - for (int i = 0; i < separatorsCount; ++i) { - canvas.drawCircle( - AndroidUtilities.lerp(selectorWidth / 2, getMeasuredWidth() - selectorWidth / 2, i / ((float) separatorsCount - 1f)), - getMeasuredHeight() / 2, - AndroidUtilities.dp(1.6f), - innerPaint1 - ); - } - } if (bufferedProgress > 0) { innerPaint1.setColor(getThemedColor(Theme.key_player_progressCachedBackground)); canvas.drawRect(selectorWidth / 2, getMeasuredHeight() / 2 - AndroidUtilities.dp(1), selectorWidth / 2 + bufferedProgress * (getMeasuredWidth() - selectorWidth), getMeasuredHeight() / 2 + AndroidUtilities.dp(1), innerPaint1); @@ -380,20 +385,6 @@ public class SeekBarView extends FrameLayout { } } else { canvas.drawRect(selectorWidth / 2, getMeasuredHeight() / 2 - AndroidUtilities.dp(1), selectorWidth / 2 + thumbX, getMeasuredHeight() / 2 + AndroidUtilities.dp(1), outerPaint1); - if (separatorsCount > 1) { - for (int i = 0; i < separatorsCount; ++i) { - float cx = AndroidUtilities.lerp(selectorWidth / 2, getMeasuredWidth() - selectorWidth / 2, i / ((float) separatorsCount - 1f)); - if (cx > thumbX + selectorWidth / 2) { - break; - } - canvas.drawCircle( - cx, - getMeasuredHeight() / 2, - AndroidUtilities.dp(1.4f), - outerPaint1 - ); - } - } } if (hoverDrawable != null) { int dx = thumbX + selectorWidth / 2 - AndroidUtilities.dp(16); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayout.java index 5eaeb9533..fb7285fc2 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayout.java @@ -58,7 +58,7 @@ public class SizeNotifierFrameLayout extends FrameLayout { private boolean paused = true; private Drawable oldBackgroundDrawable; private ActionBarLayout parentLayout; - protected AdjustPanLayoutHelper adjustPanLayoutHelper; + public AdjustPanLayoutHelper adjustPanLayoutHelper; private int emojiHeight; private float emojiOffset; private boolean animationInProgress; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Switch.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Switch.java index dfc0f0142..e5f41c3ff 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Switch.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Switch.java @@ -25,22 +25,17 @@ import android.graphics.PorterDuffXfermode; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.graphics.drawable.RippleDrawable; -import android.media.AudioManager; import android.os.Build; -import androidx.annotation.Keep; - import android.os.VibrationEffect; import android.os.Vibrator; import android.util.StateSet; -import android.view.HapticFeedbackConstants; import android.view.View; import android.view.accessibility.AccessibilityNodeInfo; -import org.telegram.messenger.AndroidUtilities; -import org.telegram.messenger.OneUIUtilities; -import org.telegram.ui.ActionBar.Theme; +import androidx.annotation.Keep; -import java.lang.reflect.Method; +import org.telegram.messenger.AndroidUtilities; +import org.telegram.ui.ActionBar.Theme; public class Switch extends View { @@ -549,13 +544,8 @@ public class Switch extends View { private void vibrateChecked(boolean toCheck) { try { if (isHapticFeedbackEnabled() && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) { - final Vibrator vibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE); - int slightAmplitude = OneUIUtilities.isOneUI() ? 5 : 15; - VibrationEffect vibrationEffect = VibrationEffect.createWaveform( - toCheck ? new long[] { 80, 25, 15 } : new long[] { 25, 80, 10 }, - toCheck ? new int[] { slightAmplitude, 0, 255 } : new int[] { 0, slightAmplitude, 140 }, - -1 - ); + Vibrator vibrator = AndroidUtilities.getVibrator(); + VibrationEffect vibrationEffect = VibrationEffect.createWaveform(new long[]{75,10,5,10}, new int[] {5,20,110,20}, -1); vibrator.cancel(); vibrator.vibrate(vibrationEffect); semHaptics = true; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/VideoPlayerSeekBar.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/VideoPlayerSeekBar.java index 7b6d00fc8..ca7150624 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/VideoPlayerSeekBar.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/VideoPlayerSeekBar.java @@ -223,6 +223,10 @@ public class VideoPlayerSeekBar { public void setSize(int w, int h) { width = w; height = h; + + if (parentView != null) { + parentView.invalidate(); + } } public int getWidth() { @@ -253,21 +257,25 @@ public class VideoPlayerSeekBar { private CharSequence lastCaption; private long lastVideoDuration; + public void clearTimestamps() { + timestamps = null; + currentTimestamp = -1; + timestampsAppearing = 0; + if (timestampLabel != null) { + timestampLabel[0] = timestampLabel[1] = null; + } + lastCaption = null; + lastVideoDuration = -1; + } + public void updateTimestamps(MessageObject messageObject, long videoDuration) { if (messageObject == null || videoDuration < 0) { - timestamps = null; - currentTimestamp = -1; - timestampsAppearing = 0; - if (timestampLabel != null) { - timestampLabel[0] = timestampLabel[1] = null; - } - lastCaption = null; - lastVideoDuration = -1; + clearTimestamps(); return; } CharSequence text = messageObject.caption; if (messageObject.isYouTubeVideo()) { - if (messageObject.youtubeDescription == null) { + if (messageObject.youtubeDescription == null && messageObject.messageOwner.media.webpage.description != null) { messageObject.youtubeDescription = SpannableString.valueOf(messageObject.messageOwner.media.webpage.description); MessageObject.addUrlsByPattern(messageObject.isOut(), messageObject.youtubeDescription, false, 3, (int) videoDuration, false); } @@ -502,6 +510,10 @@ public class VideoPlayerSeekBar { for (int i = start; i <= end; ++i) { float from = i == start ? 0 : timestamps.get(i - 1).first; float to = i == end ? 1 : timestamps.get(i).first; + while (i != end && i != 0 && i < timestamps.size() - 1 && timestamps.get(i).first - from <= minDur) { + i++; + to = timestamps.get(i).first; + } AndroidUtilities.rectTmp.left = AndroidUtilities.lerp(left, right, from) + (i > 0 ? halfGap : 0); AndroidUtilities.rectTmp.right = AndroidUtilities.lerp(left, right, to) - (i < end ? halfGap : 0); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java index e15dc9ca3..9a3e9e819 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java @@ -922,6 +922,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. childTop = lp.topMargin; } + if (commentView != null && commentView.isPopupView(child)) { if (AndroidUtilities.isInMultiwindow) { childTop = commentView.getTop() - child.getMeasuredHeight() + AndroidUtilities.dp(1); @@ -945,6 +946,8 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. childTop += topPadding; } else if (child instanceof FragmentContextView) { childTop += actionBar.getMeasuredHeight(); + } else if (child == floatingButtonContainer && selectAnimatedEmojiDialog != null) { + childTop += keyboardSize; } child.layout(childLeft, childTop, childLeft + width, childTop + height); } @@ -3959,7 +3962,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. } public void showSelectStatusDialog() { - if (selectAnimatedEmojiDialog != null) { + if (selectAnimatedEmojiDialog != null || SharedConfig.appLocked) { return; } final SelectAnimatedEmojiDialog.SelectAnimatedEmojiDialogWindow[] popup = new SelectAnimatedEmojiDialog.SelectAnimatedEmojiDialogWindow[1]; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java index 69b95ce56..a63725485 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java @@ -498,8 +498,8 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati avatarEditor.setAnimation(cameraDrawable); avatarEditor.setEnabled(false); avatarEditor.setClickable(false); - avatarEditor.setPadding(AndroidUtilities.dp(2), 0, 0, AndroidUtilities.dp(1)); - editTextContainer.addView(avatarEditor, LayoutHelper.createFrame(64, 64, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), LocaleController.isRTL ? 0 : 16, 16, LocaleController.isRTL ? 16 : 0, 16)); + avatarEditor.setPadding(AndroidUtilities.dp(0), 0, 0, AndroidUtilities.dp(1)); + editTextContainer.addView(avatarEditor, LayoutHelper.createFrame(64, 64, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), LocaleController.isRTL ? 0 : 15, 16, LocaleController.isRTL ? 15 : 0, 16)); avatarProgressView = new RadialProgressView(context) { @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java index 0467fff4c..59b8c95fa 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java @@ -827,7 +827,7 @@ public class LaunchActivity extends BasePermissionsActivity implements ActionBar FileLog.e(e); } MediaController.getInstance().setBaseActivity(this, true); - AndroidUtilities.startAppCenter(this); + ApplicationLoader.startAppCenter(this); updateAppUpdateViews(false); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { @@ -1019,7 +1019,7 @@ public class LaunchActivity extends BasePermissionsActivity implements ActionBar } public void showSelectStatusDialog() { - if (selectAnimatedEmojiDialog != null) { + if (selectAnimatedEmojiDialog != null || SharedConfig.appLocked) { return; } BaseFragment fragment = actionBarLayout.getLastFragment(); @@ -1439,6 +1439,10 @@ public class LaunchActivity extends BasePermissionsActivity implements ActionBar passcodeView = new PasscodeView(this); drawerLayoutContainer.addView(passcodeView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); } + if (selectAnimatedEmojiDialog != null) { + selectAnimatedEmojiDialog.dismiss(); + selectAnimatedEmojiDialog = null; + } SharedConfig.appLocked = true; if (SecretMediaViewer.hasInstance() && SecretMediaViewer.getInstance().isVisible()) { SecretMediaViewer.getInstance().closePhoto(false, false); @@ -5168,6 +5172,11 @@ public class LaunchActivity extends BasePermissionsActivity implements ActionBar showTosActivity(account, (TLRPC.TL_help_termsOfService) args[1]); return; } + BaseFragment fragment = null; + if (!mainFragmentsStack.isEmpty()) { + fragment = mainFragmentsStack.get(mainFragmentsStack.size() - 1); + } + AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); if (reason != 2 && reason != 3) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PaymentFormActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PaymentFormActivity.java index 8615f5373..899fc6454 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PaymentFormActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PaymentFormActivity.java @@ -16,6 +16,7 @@ import android.animation.ObjectAnimator; import android.annotation.SuppressLint; import android.app.Activity; import android.app.Dialog; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -155,6 +156,14 @@ import java.util.Optional; import java.util.Scanner; public class PaymentFormActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate { + private final static List WEBVIEW_PROTOCOLS = Arrays.asList( + "http", + "https" + ); + private final static List BLACKLISTED_PROTOCOLS = Collections.singletonList( + "tg" + ); + private final static int STEP_SHIPPING_INFORMATION = 0, STEP_SHIPPING_METHODS = 1, STEP_PAYMENT_INFO = 2, @@ -2352,6 +2361,24 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen goToNextStep(); return true; } + + if (BLACKLISTED_PROTOCOLS.contains(uri.getScheme())) { + return true; + } + if (!WEBVIEW_PROTOCOLS.contains(uri.getScheme())) { + try { + if (getContext() instanceof Activity) { + ((Activity) getContext()).startActivityForResult(new Intent(Intent.ACTION_VIEW, uri), BasePermissionsActivity.REQUEST_CODE_PAYMENT_FORM); + } + } catch (ActivityNotFoundException e) { + new AlertDialog.Builder(context) + .setTitle(currentBotName) + .setMessage(LocaleController.getString(R.string.PaymentAppNotFoundForDeeplink)) + .setPositiveButton(LocaleController.getString(R.string.OK), null) + .show(); + } + return true; + } } catch (Exception ignore) { } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java index cb76e329b..524a2981c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java @@ -116,6 +116,7 @@ import androidx.core.math.MathUtils; import androidx.core.view.ViewCompat; import androidx.core.widget.NestedScrollView; import androidx.dynamicanimation.animation.DynamicAnimation; +import androidx.dynamicanimation.animation.FloatValueHolder; import androidx.dynamicanimation.animation.SpringAnimation; import androidx.dynamicanimation.animation.SpringForce; import androidx.exifinterface.media.ExifInterface; @@ -716,7 +717,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } else { bulletinMessage = LocaleController.getString("LinkCopied", R.string.LinkCopied); } - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + if (AndroidUtilities.shouldShowClipboardToast()) { BulletinFactory.of(containerView, resourcesProvider).createSimpleBulletin(R.raw.voip_invite, bulletinMessage).show(); } } @@ -1039,7 +1040,8 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat private MentionsAdapter mentionsAdapter; private RecyclerListView mentionListView; private LinearLayoutManager mentionLayoutManager; - private AnimatorSet mentionListAnimation; + private SpringAnimation mentionListAnimation; + private boolean mentionListViewVisible; private boolean allowMentions; private ActionBarPopupWindow sendPopupWindow; @@ -2443,7 +2445,8 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } if (child == mentionListView) { canvas.save(); - canvas.clipRect(child.getX(), child.getY(), child.getX() + child.getWidth(), child.getY() + child.getHeight()); + canvas.clipRect(child.getX(), child.getY(), child.getX() + child.getWidth(), captionEditText.getTop()); + canvas.drawColor(0x7f000000); boolean r = super.drawChild(canvas, child, drawingTime); canvas.restore(); return r; @@ -2571,6 +2574,23 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat private int parentWidth; private int parentHeight; + private int lastTimeWidth; + private FloatValueHolder timeValue = new FloatValueHolder(0); + private SpringAnimation timeSpring = new SpringAnimation(timeValue) + .setSpring(new SpringForce(0) + .setStiffness(750f) + .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY)) + .addUpdateListener((animation, value, velocity) -> { + int extraWidth; + if (parentWidth > parentHeight) { + extraWidth = AndroidUtilities.dp(48); + } else { + extraWidth = 0; + } + + videoPlayerSeekbar.setSize((int) (getMeasuredWidth() - AndroidUtilities.dp(2 + 14) - value - extraWidth), getMeasuredHeight()); + }); + public VideoPlayerControlFrameLayout(@NonNull Context context) { super(context); setWillNotDraw(false); @@ -2589,6 +2609,14 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat return true; } + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + + timeValue.setValue(0); + lastTimeWidth = 0; + } + @Override public void requestLayout() { if (ignoreLayout) { @@ -2638,7 +2666,15 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } int size = (int) Math.ceil(videoPlayerTime.getPaint().measureText(String.format(Locale.ROOT, "%1$s / %1$s", durationStr))); - videoPlayerSeekbar.setSize(getMeasuredWidth() - AndroidUtilities.dp(2 + 14) - size - extraWidth, getMeasuredHeight()); + timeSpring.cancel(); + if (lastTimeWidth != 0 && timeValue.getValue() != size) { + timeSpring.getSpring().setFinalPosition(size); + timeSpring.start(); + } else { + videoPlayerSeekbar.setSize(getMeasuredWidth() - AndroidUtilities.dp(2 + 14) - size - extraWidth, getMeasuredHeight()); + timeValue.setValue(size); + } + lastTimeWidth = size; } @Override @@ -6086,6 +6122,37 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat public boolean onTouchEvent(MotionEvent event) { return !bottomTouchEnabled && super.onTouchEvent(event); } + + @Override + public void setTranslationY(float translationY) { + super.setTranslationY(translationY); + invalidate(); + + if (getParent() != null) { + ((View) getParent()).invalidate(); + } + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + + if (mentionListViewVisible && getVisibility() == VISIBLE && mentionListAnimation == null) { + setTranslationY(h - oldh); + mentionListAnimation = new SpringAnimation(this, DynamicAnimation.TRANSLATION_Y) + .setMinValue(Math.min(h - oldh, 0)) + .setMaxValue(Math.max(h - oldh, 0)) + .setSpring(new SpringForce(0) + .setStiffness(750f) + .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY)); + mentionListAnimation.addEndListener((animation, canceled, value, velocity) -> { + if (mentionListAnimation == animation) { + mentionListAnimation = null; + } + }); + mentionListAnimation.start(); + } + } }; mentionListView.setTag(5); mentionLayoutManager = new LinearLayoutManager(activityContext) { @@ -6096,7 +6163,6 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat }; mentionLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); mentionListView.setLayoutManager(mentionLayoutManager); - mentionListView.setBackgroundColor(0x7f000000); mentionListView.setVisibility(View.GONE); mentionListView.setClipToPadding(true); mentionListView.setOverScrollMode(RecyclerListView.OVER_SCROLL_NEVER); @@ -6123,29 +6189,29 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } if (mentionListView.getVisibility() == View.VISIBLE) { - mentionListView.setAlpha(1.0f); + mentionListView.setTranslationY(0); return; } else { mentionLayoutManager.scrollToPositionWithOffset(0, 10000); } if (allowMentions) { mentionListView.setVisibility(View.VISIBLE); - mentionListAnimation = new AnimatorSet(); - mentionListAnimation.playTogether( - ObjectAnimator.ofFloat(mentionListView, View.ALPHA, 0.0f, 1.0f) - ); - mentionListAnimation.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - if (mentionListAnimation != null && mentionListAnimation.equals(animation)) { - mentionListAnimation = null; - } + mentionListViewVisible = true; + mentionListView.setTranslationY(AndroidUtilities.dp(height)); + mentionListAnimation = new SpringAnimation(mentionListView, DynamicAnimation.TRANSLATION_Y) + .setMinValue(0) + .setMaxValue(AndroidUtilities.dp(height)) + .setSpring(new SpringForce(0f) + .setStiffness(750f) + .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY)); + mentionListAnimation.addEndListener((animation, canceled, value, velocity) -> { + if (mentionListAnimation == animation) { + mentionListAnimation = null; } }); - mentionListAnimation.setDuration(200); mentionListAnimation.start(); } else { - mentionListView.setAlpha(1.0f); + mentionListView.setTranslationY(0); mentionListView.setVisibility(View.INVISIBLE); } } else { @@ -6158,20 +6224,19 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat return; } if (allowMentions) { - mentionListAnimation = new AnimatorSet(); - mentionListAnimation.playTogether( - ObjectAnimator.ofFloat(mentionListView, View.ALPHA, 0.0f) - ); - mentionListAnimation.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - if (mentionListAnimation != null && mentionListAnimation.equals(animation)) { - mentionListView.setVisibility(View.GONE); - mentionListAnimation = null; - } + mentionListViewVisible = false; + mentionListAnimation = new SpringAnimation(mentionListView, DynamicAnimation.TRANSLATION_Y) + .setMinValue(0) + .setMaxValue(mentionListView.getMeasuredHeight()) + .setSpring(new SpringForce(mentionListView.getMeasuredHeight()) + .setStiffness(750f) + .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY)); + mentionListAnimation.addEndListener((animation, canceled, value, velocity) -> { + if (mentionListAnimation == animation) { + mentionListView.setVisibility(View.GONE); + mentionListAnimation = null; } }); - mentionListAnimation.setDuration(200); mentionListAnimation.start(); } else { mentionListView.setVisibility(View.GONE); @@ -8238,10 +8303,13 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } } } - if (AndroidUtilities.displaySize.y > AndroidUtilities.displaySize.x && !(videoTextureView instanceof VideoEditTextureView) && w > h) { + if (AndroidUtilities.displaySize.y > AndroidUtilities.displaySize.x && w > h) { if (fullscreenButton[b].getVisibility() != View.VISIBLE) { fullscreenButton[b].setVisibility(View.VISIBLE); } + if (isActionBarVisible) { + fullscreenButton[b].setAlpha(1f); + } float scale = w / (float) containerView.getMeasuredWidth(); int height = (int) (h / scale); FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) fullscreenButton[b].getLayoutParams(); @@ -13563,6 +13631,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (photoViewerWebView.isControllable()) { setVideoPlayerControlVisible(true, true); } + videoPlayerSeekbar.clearTimestamps(); updateVideoPlayerTime(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PremiumPreviewFragment.java b/TMessagesProj/src/main/java/org/telegram/ui/PremiumPreviewFragment.java index 5bed87cf1..1c46890bb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PremiumPreviewFragment.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PremiumPreviewFragment.java @@ -71,7 +71,6 @@ import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.FillLastLinearLayoutManager; import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.Premium.AboutPremiumView; -import org.telegram.ui.Components.Premium.DoubledLimitsBottomSheet; import org.telegram.ui.Components.Premium.GLIcon.GLIconRenderer; import org.telegram.ui.Components.Premium.GLIcon.GLIconTextureView; import org.telegram.ui.Components.Premium.PremiumButtonView; @@ -508,13 +507,13 @@ public class PremiumPreviewFragment extends BaseFragment implements Notification if (view instanceof PremiumFeatureCell) { PremiumFeatureCell cell = (PremiumFeatureCell) view; PremiumPreviewFragment.sentShowFeaturePreview(currentAccount, cell.data.type); - if (cell.data.type == PREMIUM_FEATURE_LIMITS) { - DoubledLimitsBottomSheet bottomSheet = new DoubledLimitsBottomSheet(PremiumPreviewFragment.this, currentAccount, subscriptionTiers.get(selectedTierIndex)); - bottomSheet.setParentFragment(PremiumPreviewFragment.this); - showDialog(bottomSheet); - } else { +// if (cell.data.type == PREMIUM_FEATURE_LIMITS) { +// DoubledLimitsBottomSheet bottomSheet = new DoubledLimitsBottomSheet(PremiumPreviewFragment.this, currentAccount, subscriptionTiers.get(selectedTierIndex)); +// bottomSheet.setParentFragment(PremiumPreviewFragment.this); +// showDialog(bottomSheet); +// } else { showDialog(new PremiumFeatureBottomSheet(PremiumPreviewFragment.this, cell.data.type, false, subscriptionTiers.get(selectedTierIndex))); - } + // } } }); contentView.addView(listView); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PrivacySettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PrivacySettingsActivity.java index 622cb4838..c9389b5d7 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PrivacySettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PrivacySettingsActivity.java @@ -578,7 +578,11 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio callsRow = rowCount++; groupsRow = rowCount++; groupsDetailRow = -1; - voicesRow = rowCount++; + if (!getMessagesController().premiumLocked || getUserConfig().isPremium()) { + voicesRow = rowCount++; + } else { + voicesRow = -1; + } privacyShadowRow = rowCount++; securitySectionRow = rowCount++; passcodeRow = rowCount++; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java index f2daf43d3..609f3fbfc 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java @@ -48,7 +48,6 @@ import android.text.Spanned; import android.text.TextPaint; import android.text.TextUtils; import android.text.style.ForegroundColorSpan; -import android.util.Log; import android.util.Property; import android.util.SparseIntArray; import android.util.TypedValue; @@ -202,6 +201,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.List; import java.util.Locale; import java.util.Set; import java.util.concurrent.CountDownLatch; @@ -209,6 +209,10 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ProfileActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate, DialogsActivity.DialogsActivityDelegate, SharedMediaLayout.SharedMediaPreloaderDelegate, ImageUpdater.ImageUpdaterDelegate, SharedMediaLayout.Delegate { + private final static int PHONE_OPTION_CALL = 0, + PHONE_OPTION_COPY = 1, + PHONE_OPTION_TELEGRAM_CALL = 2, + PHONE_OPTION_TELEGRAM_VIDEO_CALL = 3; private RecyclerListView listView; private RecyclerListView searchListView; @@ -3499,7 +3503,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. nameTextView[a].setFocusable(a == 0); nameTextView[a].setEllipsizeByGradient(true); nameTextView[a].setRightDrawableOutside(a == 0); - avatarContainer2.addView(nameTextView[a], LayoutHelper.createFrame(a == 0 ? initialTitleWidth : LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 118, -6, (a == 0 ? rightMargin - (hasTitleExpanded ? 16 : 0) : 0), 0)); + avatarContainer2.addView(nameTextView[a], LayoutHelper.createFrame(a == 0 ? initialTitleWidth : LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 118, -6, (a == 0 ? rightMargin - (hasTitleExpanded ? 10 : 0) : 0), 0)); } for (int a = 0; a < onlineTextView.length; a++) { onlineTextView[a] = new SimpleTextView(context); @@ -4323,44 +4327,59 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity(), resourcesProvider); ArrayList items = new ArrayList<>(); - final ArrayList actions = new ArrayList<>(); + ArrayList actions = new ArrayList<>(); + List icons = new ArrayList<>(); if (position == phoneRow) { if (userInfo != null && userInfo.phone_calls_available) { + icons.add(R.drawable.msg_calls); items.add(LocaleController.getString("CallViaTelegram", R.string.CallViaTelegram)); - actions.add(2); + actions.add(PHONE_OPTION_TELEGRAM_CALL); if (Build.VERSION.SDK_INT >= 18 && userInfo.video_calls_available) { + icons.add(R.drawable.msg_videocall); items.add(LocaleController.getString("VideoCallViaTelegram", R.string.VideoCallViaTelegram)); - actions.add(3); + actions.add(PHONE_OPTION_TELEGRAM_VIDEO_CALL); } } + icons.add(R.drawable.msg_calls_regular); items.add(LocaleController.getString("Call", R.string.Call)); - actions.add(0); + actions.add(PHONE_OPTION_CALL); } + icons.add(R.drawable.msg_copy); items.add(LocaleController.getString("Copy", R.string.Copy)); - actions.add(1); - builder.setItems(items.toArray(new CharSequence[0]), (dialogInterface, i) -> { + actions.add(PHONE_OPTION_COPY); + + int[] iconsArr = new int[icons.size()]; + for (int i = 0; i < iconsArr.length; i++) { + iconsArr[i] = icons.get(i); + } + builder.setItems(items.toArray(new CharSequence[0]), iconsArr, (dialogInterface, i) -> { i = actions.get(i); - if (i == 0) { - try { - Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:+" + user.phone)); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - getParentActivity().startActivityForResult(intent, 500); - } catch (Exception e) { - FileLog.e(e); - } - } else if (i == 1) { - try { - android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); - android.content.ClipData clip = android.content.ClipData.newPlainText("label", "+" + user.phone); - clipboard.setPrimaryClip(clip); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { - BulletinFactory.of(this).createCopyBulletin(LocaleController.getString("PhoneCopied", R.string.PhoneCopied)).show(); + switch (i) { + case PHONE_OPTION_CALL: + try { + Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:+" + user.phone)); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + getParentActivity().startActivityForResult(intent, 500); + } catch (Exception e) { + FileLog.e(e); } - } catch (Exception e) { - FileLog.e(e); - } - } else if (i == 2 || i == 3) { - VoIPHelper.startCall(user, i == 3, userInfo != null && userInfo.video_calls_available, getParentActivity(), userInfo, getAccountInstance()); + break; + case PHONE_OPTION_COPY: + try { + android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); + android.content.ClipData clip = android.content.ClipData.newPlainText("label", "+" + user.phone); + clipboard.setPrimaryClip(clip); + if (AndroidUtilities.shouldShowClipboardToast()) { + BulletinFactory.of(this).createCopyBulletin(LocaleController.getString("PhoneCopied", R.string.PhoneCopied)).show(); + } + } catch (Exception e) { + FileLog.e(e); + } + break; + case PHONE_OPTION_TELEGRAM_CALL: + case PHONE_OPTION_TELEGRAM_VIDEO_CALL: + VoIPHelper.startCall(user, i == PHONE_OPTION_TELEGRAM_VIDEO_CALL, userInfo != null && userInfo.video_calls_available, getParentActivity(), userInfo, getAccountInstance()); + break; } }); showDialog(builder.create()); @@ -4395,7 +4414,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. return; } AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity(), resourcesProvider); - builder.setItems(withTranslate[0] ? new CharSequence[]{LocaleController.getString("Copy", R.string.Copy), LocaleController.getString("TranslateMessage", R.string.TranslateMessage)} : new CharSequence[]{LocaleController.getString("Copy", R.string.Copy)}, (dialogInterface, i) -> { + builder.setItems(withTranslate[0] ? new CharSequence[]{LocaleController.getString("Copy", R.string.Copy), LocaleController.getString("TranslateMessage", R.string.TranslateMessage)} : new CharSequence[]{LocaleController.getString("Copy", R.string.Copy)}, withTranslate[0] ? new int[] {R.drawable.msg_copy, R.drawable.msg_translate} : new int[] {R.drawable.msg_copy}, (dialogInterface, i) -> { try { if (i == 0) { AndroidUtilities.addToClipboard(finalText); @@ -6644,11 +6663,16 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } else if (user.verified) { rightIcon = getVerifiedCrossfadeDrawable(); nameTextViewRightDrawableContentDescription = LocaleController.getString("AccDescrVerified", R.string.AccDescrVerified); - } else if (getMessagesController().isPremiumUser(user)) { - rightIconIsStatus = user.emoji_status instanceof TLRPC.TL_emojiStatus || user.emoji_status instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) user.emoji_status).until > (int) (System.currentTimeMillis() / 1000); - rightIconIsPremium = !rightIconIsStatus; + } else if (user.emoji_status instanceof TLRPC.TL_emojiStatus || user.emoji_status instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) user.emoji_status).until > (int) (System.currentTimeMillis() / 1000)) { + rightIconIsStatus = true; + rightIconIsPremium = false; rightIcon = getEmojiStatusDrawable(user.emoji_status, false, false, a); nameTextViewRightDrawableContentDescription = LocaleController.getString("AccDescrPremium", R.string.AccDescrPremium); + } else if (getMessagesController().isPremiumUser(user)) { + rightIconIsStatus = false; + rightIconIsPremium = true; + rightIcon = getEmojiStatusDrawable(null, false, false, a); + nameTextViewRightDrawableContentDescription = LocaleController.getString("AccDescrPremium", R.string.AccDescrPremium); } else if (getMessagesController().isDialogMuted(dialogId != 0 ? dialogId : userId)) { rightIcon = getThemedDrawable(Theme.key_drawable_muteIconDrawable); nameTextViewRightDrawableContentDescription = LocaleController.getString("NotificationsMuted", R.string.NotificationsMuted); @@ -6661,10 +6685,14 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. rightIcon = getScamDrawable(user.scam ? 0 : 1); } else if (user.verified) { rightIcon = getVerifiedCrossfadeDrawable(); - } else if (getMessagesController().isPremiumUser(user)) { - rightIconIsStatus = user.emoji_status instanceof TLRPC.TL_emojiStatus || user.emoji_status instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) user.emoji_status).until > (int) (System.currentTimeMillis() / 1000); - rightIconIsPremium = !rightIconIsStatus; + } else if (user.emoji_status instanceof TLRPC.TL_emojiStatus || user.emoji_status instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) user.emoji_status).until > (int) (System.currentTimeMillis() / 1000)) { + rightIconIsStatus = true; + rightIconIsPremium = false; rightIcon = getEmojiStatusDrawable(user.emoji_status, true, true, a); + } else if (getMessagesController().isPremiumUser(user)) { + rightIconIsStatus = false; + rightIconIsPremium = true; + rightIcon = getEmojiStatusDrawable(null, true, true, a); } } nameTextView[a].setLeftDrawable(leftIcon); @@ -6733,7 +6761,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. }); } } - + if (previousTransitionFragment != null) { + previousTransitionFragment.checkAndUpdateAvatar(); + } avatarImage.getImageReceiver().setVisible(!PhotoViewer.isShowingImage(photoBig), false); } else if (chatId != 0) { TLRPC.Chat chat = getMessagesController().getChat(chatId); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SelectAnimatedEmojiDialog.java b/TMessagesProj/src/main/java/org/telegram/ui/SelectAnimatedEmojiDialog.java index f0a8c4076..e79886061 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SelectAnimatedEmojiDialog.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SelectAnimatedEmojiDialog.java @@ -13,6 +13,7 @@ import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.ColorFilter; +import android.graphics.Outline; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; @@ -22,7 +23,9 @@ import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Parcelable; import android.os.SystemClock; +import android.text.Editable; import android.text.TextUtils; +import android.text.TextWatcher; import android.util.LongSparseArray; import android.util.SparseArray; import android.util.SparseIntArray; @@ -33,11 +36,13 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; +import android.view.ViewOutlineProvider; import android.view.ViewTreeObserver; import android.view.Window; import android.view.WindowInsets; import android.view.WindowManager; import android.view.animation.OvershootInterpolator; +import android.view.inputmethod.EditorInfo; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; @@ -77,15 +82,20 @@ import org.telegram.tgnet.TLRPC; import org.telegram.ui.ActionBar.ActionBarMenuItem; import org.telegram.ui.ActionBar.ActionBarPopupWindow; import org.telegram.ui.ActionBar.AlertDialog; -import org.telegram.ui.ActionBar.BottomSheet; import org.telegram.ui.ActionBar.BaseFragment; +import org.telegram.ui.ActionBar.BottomSheet; import org.telegram.ui.ActionBar.Theme; +import org.telegram.ui.Cells.FixedHeightEmptyCell; import org.telegram.ui.Components.AlertsCreator; import org.telegram.ui.Components.AnimatedEmojiDrawable; import org.telegram.ui.Components.AnimatedEmojiSpan; import org.telegram.ui.Components.AnimatedTextView; +import org.telegram.ui.Components.BackupImageView; +import org.telegram.ui.Components.CloseProgressDrawable2; import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.DrawingInBackgroundThreadDrawable; +import org.telegram.ui.Components.EditTextCaption; +import org.telegram.ui.Components.EditTextEmoji; import org.telegram.ui.Components.EmojiPacksAlert; import org.telegram.ui.Components.EmojiTabsStrip; import org.telegram.ui.Components.EmojiView; @@ -98,9 +108,12 @@ import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble; import org.telegram.ui.Components.Reactions.ReactionsUtils; import org.telegram.ui.Components.RecyclerAnimationScrollHelper; import org.telegram.ui.Components.RecyclerListView; +import org.telegram.ui.Components.SizeNotifierFrameLayout; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -115,6 +128,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati private final int RECENT_MAX_LINES = 5; private final int EXPAND_MAX_LINES = 3; + private int searchRow; private int recentReactionsStartRow; private int recentReactionsEndRow; private int topReactionsStartRow; @@ -122,9 +136,9 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati private int recentReactionsSectionRow; private int popularSectionRow; private int longtapHintRow; + + private EmojiPackExpand recentExpandButton; - ArrayList lineDrawables = new ArrayList<>(); - ArrayList lineDrawablesTmp = new ArrayList<>(); public onLongPressedListener bigReactionListener; public SelectAnimatedEmojiDialog.onRecentClearedListener onRecentClearedListener; private boolean isAttached; @@ -134,7 +148,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati public Paint selectorAccentPaint = new Paint(Paint.ANTI_ALIAS_FLAG); public void putAnimatedEmojiToCache(AnimatedEmojiDrawable animatedEmojiDrawable) { - animatedEmojiDrawables.put(animatedEmojiDrawable.getDocumentId(), animatedEmojiDrawable); + emojiGridView.animatedEmojiDrawables.put(animatedEmojiDrawable.getDocumentId(), animatedEmojiDrawable); } public void setSelectedReactions(HashSet selectedReactions) { @@ -182,8 +196,8 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati setAnimationStyle(0); setOutsideTouchable(true); setClippingEnabled(true); - setInputMethodMode(ActionBarPopupWindow.INPUT_METHOD_NOT_NEEDED); - setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED); + setInputMethodMode(ActionBarPopupWindow.INPUT_METHOD_FROM_FOCUSABLE); + setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); if (superListenerField != null) { try { mSuperScrollListener = (ViewTreeObserver.OnScrollChangedListener) superListenerField.get(this); @@ -291,13 +305,20 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati private View backgroundView; private EmojiTabsStrip emojiTabs; private View emojiTabsShadow; - public RecyclerListView emojiGridView; + private SearchBox searchBox; + public FrameLayout gridViewContainer; + public EmojiListView emojiGridView; + public EmojiListView emojiSearchGridView; + public FrameLayout emojiSearchEmptyView; + private BackupImageView emojiSearchEmptyViewImageView; private View bubble1View; private View bubble2View; private View topGradientView; private View bottomGradientView; private Adapter adapter; + private SearchAdapter searchAdapter; private GridLayoutManager layoutManager; + private GridLayoutManager searchLayoutManager; private RecyclerAnimationScrollHelper scrollHelper; private View contentViewForeground; @@ -453,7 +474,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati if (smoothScrolling) { return false; } - int position = 0; + int position = searchRow == -1 ? 1 : 0; if (index > 0 && sectionToPosition.indexOfKey(index - 1) >= 0) { position = sectionToPosition.get(index - 1); } @@ -495,7 +516,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati }; emojiTabsShadow.setBackgroundColor(Theme.getColor(Theme.key_divider, resourcesProvider)); contentView.addView(emojiTabsShadow, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 1f / AndroidUtilities.density, Gravity.TOP, 0, 36, 0, 0)); - + AndroidUtilities.updateViewVisibilityAnimated(emojiTabsShadow, true, 1f, false); emojiGridView = new EmojiListView(context) { @Override public void onScrolled(int dx, int dy) { @@ -504,27 +525,21 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati if (!smoothScrolling) { updateTabsPosition(layoutManager.findFirstCompletelyVisibleItemPosition()); } + updateSearchBox(); + AndroidUtilities.updateViewVisibilityAnimated(emojiTabsShadow, emojiGridView.computeVerticalScrollOffset() != 0, 1f, true); } @Override public void onScrollStateChanged(int state) { if (state == RecyclerView.SCROLL_STATE_IDLE) { smoothScrolling = false; + if (searchRow != -1 && searchBox.getVisibility() == View.VISIBLE && searchBox.getTranslationY() > -AndroidUtilities.dp(51)) { + SelectAnimatedEmojiDialog.this.scrollToPosition(searchBox.getTranslationY() > -AndroidUtilities.dp(16) ? 0 : 1, 0); + } } super.onScrollStateChanged(state); } - - @Override - protected boolean canHighlightChildAt(View child, float x, float y) { - if (child instanceof ImageViewEmoji && (((ImageViewEmoji) child).empty || ((ImageViewEmoji) child).drawable instanceof AnimatedEmojiDrawable && ((AnimatedEmojiDrawable) ((ImageViewEmoji) child).drawable).canOverrideColor())) { - setSelectorDrawableColor(ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_windowBackgroundWhiteBlueIcon, resourcesProvider), 30)); - } else { - setSelectorDrawableColor(Theme.getColor(Theme.key_listSelector, resourcesProvider)); - } - return super.canHighlightChildAt(child, x, y); - } }; - emojiGridView.setDrawSelectorBehind(true); DefaultItemAnimator emojiItemAnimator = new DefaultItemAnimator() { @Override protected float animateByScale(View view) { @@ -538,8 +553,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati emojiItemAnimator.setMoveInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT); emojiItemAnimator.setDelayAnimations(false); emojiGridView.setItemAnimator(emojiItemAnimator); - emojiGridView.setPadding(dp(5), dp(2), dp(5), dp(2)); - emojiGridView.setClipToPadding(false); + emojiGridView.setPadding(dp(5), dp(2), dp(5), dp(2 + 36)); emojiGridView.setAdapter(adapter = new Adapter()); emojiGridView.setLayoutManager(layoutManager = new GridLayoutManager(context, 8) { @Override @@ -558,18 +572,71 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } } }); - emojiGridView.setSelectorRadius(AndroidUtilities.dp(4)); - emojiGridView.setSelectorDrawableColor(Theme.getColor(Theme.key_listSelector, resourcesProvider)); layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { - return (positionToSection.indexOfKey(position) >= 0 || positionToButton.indexOfKey(position) >= 0 || position == recentReactionsSectionRow || position == popularSectionRow || position == longtapHintRow) ? layoutManager.getSpanCount() : 1; + return (positionToSection.indexOfKey(position) >= 0 || positionToButton.indexOfKey(position) >= 0 || position == recentReactionsSectionRow || position == popularSectionRow || position == longtapHintRow || position == searchRow) ? layoutManager.getSpanCount() : 1; } }); - contentView.addView(emojiGridView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP, 0, 36 + (1 / AndroidUtilities.density), 0, 0)); + + gridViewContainer = new FrameLayout(context) { + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) + AndroidUtilities.dp(36), MeasureSpec.EXACTLY)); + } + }; + gridViewContainer.addView(emojiGridView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.FILL, 0, 0, 0, 0)); + + emojiSearchGridView = new EmojiListView(context); + if (emojiSearchGridView.getItemAnimator() != null) { + emojiSearchGridView.getItemAnimator().setDurations(180); + emojiSearchGridView.getItemAnimator().setMoveInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT); + } + TextView emptyViewText = new TextView(context); + emptyViewText.setText(type == TYPE_EMOJI_STATUS ? + LocaleController.getString("NoEmojiFound", R.string.NoEmojiFound) : + LocaleController.getString("NoReactionsFound", R.string.NoReactionsFound)); + emptyViewText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + emptyViewText.setTextColor(Theme.getColor(Theme.key_chat_emojiPanelEmptyText, resourcesProvider)); + emojiSearchEmptyViewImageView = new BackupImageView(context); + emojiSearchEmptyView = new FrameLayout(context); + emojiSearchEmptyView.addView(emojiSearchEmptyViewImageView, LayoutHelper.createFrame(36, 36, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 0, 16, 0, 0)); + emojiSearchEmptyView.addView(emptyViewText, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 0, 16 + 36 + 8, 0, 0)); + emojiSearchEmptyView.setVisibility(View.GONE); + emojiSearchEmptyView.setAlpha(0); + gridViewContainer.addView(emojiSearchEmptyView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL, 0, 0, 0, 0)); + emojiSearchGridView.setPadding(dp(5), dp(52 + 2), dp(5), dp(2)); + emojiSearchGridView.setAdapter(searchAdapter = new SearchAdapter()); + emojiSearchGridView.setLayoutManager(searchLayoutManager = new GridLayoutManager(context, 8) { + @Override + public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) { + try { + LinearSmoothScrollerCustom linearSmoothScroller = new LinearSmoothScrollerCustom(recyclerView.getContext(), LinearSmoothScrollerCustom.POSITION_TOP) { + @Override + public void onEnd() { + smoothScrolling = false; + } + }; + linearSmoothScroller.setTargetPosition(position); + startSmoothScroll(linearSmoothScroller); + } catch (Exception e) { + FileLog.e(e); + } + } + }); +// searchLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { +// @Override +// public int getSpanSize(int position) { +// return position == 0 ? layoutManager.getSpanCount() : 1; +// } +// }); + + emojiSearchGridView.setVisibility(View.GONE); + gridViewContainer.addView(emojiSearchGridView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.FILL, 0, 0, 0, 0)); + contentView.addView(gridViewContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP, 0, 36 + (1 / AndroidUtilities.density), 0, 0)); + scrollHelper = new RecyclerAnimationScrollHelper(emojiGridView, layoutManager); scrollHelper.setAnimationCallback(new RecyclerAnimationScrollHelper.AnimationCallback() { - @Override public void onPreAnimation() { smoothScrolling = true; @@ -579,15 +646,9 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati public void onEndAnimation() { smoothScrolling = false; } - -// @Override -// public void ignoreView(View view, boolean ignore) { -// if (view instanceof EmojiView.ImageViewEmoji) { -// ((EmojiView.ImageViewEmoji)view).ignoring = ignore; -// } -// } }); - emojiGridView.setOnItemLongClickListener(new RecyclerListView.OnItemLongClickListenerExtended() { + + RecyclerListView.OnItemLongClickListenerExtended onItemLongClick = new RecyclerListView.OnItemLongClickListenerExtended() { @Override public boolean onItemClick(View view, int position, float x, float y) { if (view instanceof ImageViewEmoji && type == TYPE_REACTIONS) { @@ -680,8 +741,10 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati cancelProgressAnimator.start(); } } - }, (long) (ViewConfiguration.getLongPressTimeout() * 0.25f)); - emojiGridView.setOnItemClickListener((view, position) -> { + }; + emojiGridView.setOnItemLongClickListener(onItemLongClick, (long) (ViewConfiguration.getLongPressTimeout() * 0.25f)); + emojiSearchGridView.setOnItemLongClickListener(onItemLongClick, (long) (ViewConfiguration.getLongPressTimeout() * 0.25f)); + RecyclerListView.OnItemClickListener onItemClick = (view, position) -> { if (view instanceof ImageViewEmoji) { ImageViewEmoji viewEmoji = (ImageViewEmoji) view; // viewEmoji.notDraw = true; @@ -714,7 +777,14 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } else if (view != null) { view.callOnClick(); } - }); + }; + emojiGridView.setOnItemClickListener(onItemClick); + emojiSearchGridView.setOnItemClickListener(onItemClick); + + searchBox = new SearchBox(context); + searchBox.setTranslationY(-AndroidUtilities.dp(4 + 52)); + searchBox.setVisibility(View.INVISIBLE); + gridViewContainer.addView(searchBox, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 52, Gravity.TOP, 0, 0, 0, 0)); topGradientView = new View(context) { @Override @@ -850,6 +920,31 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } } + private void updateSearchBox() { + if (searchBox == null) { + return; + } + if (searched) { + searchBox.clearAnimation(); + searchBox.setVisibility(View.VISIBLE); + searchBox.animate().translationY(-AndroidUtilities.dp(4)).start(); + } else { + if (emojiGridView.getChildCount() > 0) { + View first = emojiGridView.getChildAt(0); + if (emojiGridView.getChildAdapterPosition(first) == searchRow && "searchbox".equals(first.getTag())) { + searchBox.setVisibility(View.VISIBLE); + searchBox.setTranslationY(first.getY() - AndroidUtilities.dp(4)); + } else { +// searchBox.setVisibility(View.INVISIBLE); + searchBox.setTranslationY(-AndroidUtilities.dp(4 + 52)); + } + } else { +// searchBox.setVisibility(View.INVISIBLE); + searchBox.setTranslationY(-AndroidUtilities.dp(4 + 52)); + } + } + } + private Drawable premiumStar; private ColorFilter premiumStarColorFilter; @@ -1030,28 +1125,572 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } } - private class Adapter extends RecyclerListView.SelectionAdapter { + public boolean searching = false; + public boolean searched = false; + private String lastQuery; + private ArrayList searchResult; + private ValueAnimator gridSwitchAnimator; + + private boolean gridSearch = false; + public void switchGrids(boolean search) { + if (gridSearch == search) { + return; + } + gridSearch = search; + emojiGridView.setVisibility(View.VISIBLE); + emojiSearchGridView.setVisibility(View.VISIBLE); + if (gridSwitchAnimator != null) { + gridSwitchAnimator.cancel(); + } + if (searchEmptyViewAnimator != null) { + searchEmptyViewAnimator.cancel(); + searchEmptyViewAnimator = null; + } + gridSwitchAnimator = ValueAnimator.ofFloat(0, 1); + gridSwitchAnimator.addUpdateListener(anm -> { + float t = (float) anm.getAnimatedValue(); + if (!search) { + t = 1f - t; + } + emojiGridView.setAlpha(1f - t); + emojiSearchGridView.setAlpha(t); + emojiSearchEmptyView.setAlpha(emojiSearchGridView.getAlpha() * t); + }); + gridSwitchAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + emojiSearchGridView.setVisibility(search ? View.VISIBLE : View.GONE); + emojiGridView.setVisibility(search ? View.GONE : View.VISIBLE); + gridSwitchAnimator = null; + if (!search && searchResult != null) { + searchResult.clear(); + searchAdapter.updateRows(false); + } + } + }); + gridSwitchAnimator.setDuration(280); + gridSwitchAnimator.setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT); + gridSwitchAnimator.start(); + ((View) emojiGridView.getParent()).animate() + .translationY(gridSearch ? -AndroidUtilities.dp(36) : 0) + .setInterpolator(CubicBezierInterpolator.DEFAULT) + .setDuration(160) + .start(); + } + + private ArrayList emptyViewEmojis = new ArrayList(4); { + emptyViewEmojis.add("\uD83D\uDE16"); + emptyViewEmojis.add("\uD83D\uDE2B"); + emptyViewEmojis.add("\uD83E\uDEE0"); + emptyViewEmojis.add("\uD83D\uDE28"); + emptyViewEmojis.add("❓"); + }; + public void updateSearchEmptyViewImage() { + if (emojiSearchEmptyViewImageView == null) { + return; + } + + TLRPC.Document emoji = null; + ArrayList featuredSets = MediaDataController.getInstance(currentAccount).getFeaturedEmojiSets(); + List shuffledFeaturedSets = new ArrayList<>(featuredSets); + Collections.shuffle(shuffledFeaturedSets); + for (int i = 0; i < shuffledFeaturedSets.size(); ++i) { + if (shuffledFeaturedSets.get(i) instanceof TLRPC.TL_stickerSetFullCovered && ((TLRPC.TL_stickerSetFullCovered) shuffledFeaturedSets.get(i)).documents != null) { + List documents = new ArrayList<>(((TLRPC.TL_stickerSetFullCovered) shuffledFeaturedSets.get(i)).documents); + Collections.shuffle(documents); + for (int j = 0; j < documents.size(); ++j) { + TLRPC.Document document = documents.get(j); + if (document != null && emptyViewEmojis.contains(MessageObject.findAnimatedEmojiEmoticon(document, null))) { + emoji = document; + break; + } + } + } + if (emoji != null) { + break; + } + } + if (emoji == null) { + ArrayList sets = MediaDataController.getInstance(currentAccount).getStickerSets(MediaDataController.TYPE_EMOJIPACKS); + List shuffledSets = new ArrayList<>(sets); + Collections.shuffle(shuffledSets); + for (int i = 0; i < shuffledSets.size(); ++i) { + if (shuffledSets.get(i) != null && shuffledSets.get(i).documents != null) { + List documents = new ArrayList<>(shuffledSets.get(i).documents); + Collections.shuffle(documents); + for (int j = 0; j < documents.size(); ++j) { + TLRPC.Document document = documents.get(j); + if (document != null && emptyViewEmojis.contains(MessageObject.findAnimatedEmojiEmoticon(document, null))) { + emoji = document; + break; + } + } + } + if (emoji != null) { + break; + } + } + } + + if (emoji != null) { + TLRPC.Document document = emoji; + String filter = "36_36"; + ImageLocation mediaLocation; + String mediaFilter; + SvgHelper.SvgDrawable thumbDrawable = DocumentObject.getSvgThumb(document.thumbs, Theme.key_windowBackgroundWhiteGrayIcon, 0.2f); + TLRPC.PhotoSize thumb = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 90); + if ("video/webm".equals(document.mime_type)) { + mediaLocation = ImageLocation.getForDocument(document); + mediaFilter = filter + "_" + ImageLoader.AUTOPLAY_FILTER; + if (thumbDrawable != null) { + thumbDrawable.overrideWidthAndHeight(512, 512); + } + } else { + if (thumbDrawable != null && MessageObject.isAnimatedStickerDocument(document, false)) { + thumbDrawable.overrideWidthAndHeight(512, 512); + } + mediaLocation = ImageLocation.getForDocument(document); + mediaFilter = filter; + } + emojiSearchEmptyViewImageView.setLayerNum(7); + emojiSearchEmptyViewImageView.setRoundRadius(AndroidUtilities.dp(4)); + emojiSearchEmptyViewImageView.setImage(mediaLocation, mediaFilter, ImageLocation.getForDocument(thumb, document), "36_36", thumbDrawable, document); + } + } + + private boolean searchEmptyViewVisible = false; + private ValueAnimator searchEmptyViewAnimator; + public void switchSearchEmptyView(boolean empty) { + if (searchEmptyViewVisible == empty) { + return; + } + + searchEmptyViewVisible = empty; + if (searchEmptyViewAnimator != null) { + searchEmptyViewAnimator.cancel(); + } + searchEmptyViewAnimator = ValueAnimator.ofFloat(0, 1); + searchEmptyViewAnimator.addUpdateListener(anm -> { + float t = (float) anm.getAnimatedValue(); + if (!empty) { + t = 1f - t; + } + emojiSearchEmptyView.setAlpha(emojiSearchGridView.getAlpha() * t); + }); + searchEmptyViewAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + emojiSearchEmptyView.setVisibility(empty && emojiSearchGridView.getVisibility() == View.VISIBLE ? View.VISIBLE : View.GONE); + searchEmptyViewAnimator = null; + } + }); + searchEmptyViewAnimator.setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT); + searchEmptyViewAnimator.setDuration(100); + searchEmptyViewAnimator.start(); + + if (empty) { + updateSearchEmptyViewImage(); + } + } + + private static String[] lastSearchKeyboardLanguage; + private Runnable clearSearchRunnable; + private Runnable searchRunnable; + public void search(String query) { + if (clearSearchRunnable != null) { + AndroidUtilities.cancelRunOnUIThread(clearSearchRunnable); + clearSearchRunnable = null; + } + if (searchRunnable != null) { + AndroidUtilities.cancelRunOnUIThread(searchRunnable); + searchRunnable = null; + } + if (query == null) { + searching = false; + searched = false; + switchGrids(false); + if (searchBox != null && searchBox.clearDrawable != null) { + searchBox.clearDrawable.stopAnimation(); + } + searchAdapter.updateRows(true); + lastQuery = null; + } else { + boolean firstSearch = !searching; + searching = true; + searched = false; + if (searchBox != null && searchBox.clearDrawable != null) { + searchBox.clearDrawable.startAnimation(); + } + if (firstSearch) { + if (searchResult != null) { + searchResult.clear(); + } + searchAdapter.updateRows(false); + } else if (!query.equals(lastQuery)) { + AndroidUtilities.runOnUIThread(clearSearchRunnable = () -> { + if (searchResult != null) { + searchResult.clear(); + } + searchAdapter.updateRows(true); + }, 120); + } + lastQuery = query; + String[] newLanguage = AndroidUtilities.getCurrentKeyboardLanguage(); + if (!Arrays.equals(newLanguage, lastSearchKeyboardLanguage)) { + MediaDataController.getInstance(currentAccount).fetchNewEmojiKeywords(newLanguage); + } + lastSearchKeyboardLanguage = newLanguage; + AndroidUtilities.runOnUIThread(searchRunnable = () -> { + MediaDataController.getInstance(currentAccount).getAnimatedEmojiByKeywords(query, _documentIds -> { + final ArrayList documentIds = _documentIds == null ? new ArrayList<>() : _documentIds; + final HashMap availableReactions = MediaDataController.getInstance(currentAccount).getReactionsMap(); + if (Emoji.fullyConsistsOfEmojis(query)) { + ArrayList stickerSets = MediaDataController.getInstance(currentAccount).getStickerSets(MediaDataController.TYPE_EMOJIPACKS); + String emoticon; + + for (int i = 0; i < stickerSets.size(); ++i) { + if (stickerSets.get(i).documents != null) { + ArrayList documents = stickerSets.get(i).documents; + if (documents != null) { + for (int j = 0; j < documents.size(); ++j) { + emoticon = MessageObject.findAnimatedEmojiEmoticon(documents.get(j), null); + long id = documents.get(j).id; + if (emoticon != null && !documentIds.contains(id) && query.contains(emoticon.toLowerCase())) { + documentIds.add(id); + } + } + } + } + } + + ArrayList featuredStickerSets = MediaDataController.getInstance(currentAccount).getFeaturedEmojiSets(); + for (int i = 0; i < featuredStickerSets.size(); ++i) { + if (featuredStickerSets.get(i) instanceof TLRPC.TL_stickerSetFullCovered && + ((TLRPC.TL_stickerSetFullCovered) featuredStickerSets.get(i)).keywords != null) { + ArrayList documents = ((TLRPC.TL_stickerSetFullCovered) featuredStickerSets.get(i)).documents; + if (documents != null) { + for (int j = 0; j < documents.size(); ++j) { + emoticon = MessageObject.findAnimatedEmojiEmoticon(documents.get(j), null); + long id = documents.get(j).id; + if (emoticon != null && !documentIds.contains(id) && query.contains(emoticon)) { + documentIds.add(id); + } + } + } + } + } + AndroidUtilities.runOnUIThread(() -> { + if (clearSearchRunnable != null) { + AndroidUtilities.cancelRunOnUIThread(clearSearchRunnable); + clearSearchRunnable = null; + } + + if (query != lastQuery) { + return; + } + searched = true; + switchGrids(true); + if (searchBox != null && searchBox.clearDrawable != null) { + searchBox.clearDrawable.stopAnimation(); + } + if (searchResult == null) { + searchResult = new ArrayList<>(); + } else { + searchResult.clear(); + } + emojiSearchGridView.scrollToPosition(0); + searched = true; + if (type == TYPE_REACTIONS || type == TYPE_SET_DEFAULT_REACTION) { + TLRPC.TL_availableReaction reaction = availableReactions.get(query); + if (reaction != null) { + searchResult.add(ReactionsLayoutInBubble.VisibleReaction.fromEmojicon(reaction)); + } + } + for (int i = 0; i < documentIds.size(); ++i) { + searchResult.add(ReactionsLayoutInBubble.VisibleReaction.fromCustomEmoji(documentIds.get(i))); + } + searchAdapter.updateRows(!firstSearch); + }); + } else { + MediaDataController.getInstance(currentAccount).getEmojiSuggestions( + lastSearchKeyboardLanguage, + query, + false, + (result, alias) -> { + if (clearSearchRunnable != null) { + AndroidUtilities.cancelRunOnUIThread(clearSearchRunnable); + clearSearchRunnable = null; + } + if (query != lastQuery) { + return; + } + searched = true; + switchGrids(true); + if (searchBox != null && searchBox.clearDrawable != null) { + searchBox.clearDrawable.stopAnimation(); + } + if (searchResult == null) { + searchResult = new ArrayList<>(); + } else { + searchResult.clear(); + } + for (int i = 0; i < result.size(); ++i) { + try { + if (result.get(i).emoji.startsWith("animated_")) { + documentIds.add(Long.parseLong(result.get(i).emoji.substring(9))); + } else { + if (type == TYPE_REACTIONS || type == TYPE_SET_DEFAULT_REACTION) { + TLRPC.TL_availableReaction reaction = availableReactions.get(result.get(i).emoji); + if (reaction != null) { + searchResult.add(ReactionsLayoutInBubble.VisibleReaction.fromEmojicon(reaction)); + } + } + } + } catch (Exception ignore) {} + } + emojiSearchGridView.scrollToPosition(0); + searched = true; + for (int i = 0; i < documentIds.size(); ++i) { + searchResult.add(ReactionsLayoutInBubble.VisibleReaction.fromCustomEmoji(documentIds.get(i))); + } + searchAdapter.updateRows(!firstSearch); + }, + null, + true, + 30 + ); + } + }); + }, 425); + } + updateSearchBox(); + + if (searchBox != null && searchBox.clear != null) { + boolean showed = searchBox.clear.getAlpha() != 0; + if (searching != showed) { + searchBox.clear.animate() + .alpha(searching ? 1.0f : 0.0f) + .setDuration(150) + .scaleX(searching ? 1.0f : 0.1f) + .scaleY(searching ? 1.0f : 0.1f) + .start(); + } + } + } + + private class SearchAdapter extends RecyclerListView.SelectionAdapter { + + public int VIEW_TYPE_SEARCH = 7; + public int VIEW_TYPE_EMOJI = 3; + public int VIEW_TYPE_REACTION = 4; @Override public boolean isEnabled(RecyclerView.ViewHolder holder) { - return holder.getItemViewType() != 0 && holder.getItemViewType() != 5 && holder.getItemViewType() != 4 && holder.getItemViewType() != 6; - } + return holder.getItemViewType() == VIEW_TYPE_EMOJI || holder.getItemViewType() == VIEW_TYPE_REACTION; + } @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view; - if (viewType == 0) { - view = new HeaderView(getContext()); - } else if (viewType == 2) { - view = new ImageView(getContext()); - } else if (viewType == 3) { + if (viewType == VIEW_TYPE_SEARCH) { + view = new View(getContext()) { + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(52), MeasureSpec.EXACTLY)); + } + }; + view.setTag("searchbox"); + } else { view = new ImageViewEmoji(getContext()); - } else if (viewType == 4) { + } + if (showAnimator != null && showAnimator.isRunning()) { + view.setScaleX(0); + view.setScaleY(0); + } + return new RecyclerListView.Holder(view); + } + + @Override + public int getItemViewType(int position) { + if (searchResult == null || position < 0 || position >= searchResult.size() || searchResult.get(position).emojicon == null) { + return VIEW_TYPE_EMOJI; + } else { + return VIEW_TYPE_REACTION; + } + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder.getItemViewType() == VIEW_TYPE_REACTION) { + ImageViewEmoji imageView = (ImageViewEmoji) holder.itemView; + imageView.position = position; + if (searchResult == null || position < 0 || position >= searchResult.size()) { + return; + } + ReactionsLayoutInBubble.VisibleReaction currentReaction = searchResult.get(position); + + if (imageView.imageReceiver == null) { + imageView.imageReceiver = new ImageReceiver(); + imageView.imageReceiver.setLayerNum(7); + imageView.imageReceiver.onAttachedToWindow(); + } + imageView.imageReceiver.setParentView(emojiSearchGridView); + imageView.reaction = currentReaction; + imageView.setViewSelected(selectedReactions.contains(currentReaction)); + if (currentReaction.emojicon != null) { + imageView.isDefaultReaction = true; + TLRPC.TL_availableReaction reaction = MediaDataController.getInstance(currentAccount).getReactionsMap().get(currentReaction.emojicon); + if (reaction != null) { + SvgHelper.SvgDrawable svgThumb = DocumentObject.getSvgThumb(reaction.activate_animation, Theme.key_windowBackgroundWhiteGrayIcon, 0.2f); + imageView.imageReceiver.setImage(ImageLocation.getForDocument(reaction.select_animation), ReactionsUtils.SELECT_ANIMATION_FILTER, null, null, svgThumb, 0, "tgs", currentReaction, 0); + } else { + imageView.imageReceiver.clearImage(); + } + imageView.span = null; + imageView.document = null; + imageView.setDrawable(null); + if (imageView.premiumLockIconView != null) { + imageView.premiumLockIconView.setVisibility(View.GONE); + imageView.premiumLockIconView.setImageReceiver(null); + } + } else { + imageView.isDefaultReaction = false; + imageView.span = new AnimatedEmojiSpan(currentReaction.documentId, null); + imageView.document = null; + imageView.imageReceiver.clearImage(); + AnimatedEmojiDrawable drawable = emojiSearchGridView.animatedEmojiDrawables.get(imageView.span.getDocumentId()); +// + if (drawable == null) { + drawable = AnimatedEmojiDrawable.make(currentAccount, getCacheType(), imageView.span.getDocumentId()); + drawable.addView(emojiSearchGridView); + emojiSearchGridView.animatedEmojiDrawables.put(imageView.span.getDocumentId(), drawable); + } + imageView.setDrawable(drawable); + + if (!UserConfig.getInstance(currentAccount).isPremium()) { + if (imageView.premiumLockIconView == null) { + imageView.premiumLockIconView = new PremiumLockIconView(getContext(), PremiumLockIconView.TYPE_STICKERS_PREMIUM_LOCKED); + imageView.addView(imageView.premiumLockIconView, LayoutHelper.createFrame(12, 12, Gravity.RIGHT | Gravity.BOTTOM)); + } + imageView.premiumLockIconView.setVisibility(View.VISIBLE); + } + } + } else if (holder.getItemViewType() == VIEW_TYPE_EMOJI) { + ImageViewEmoji imageView = (ImageViewEmoji) holder.itemView; + imageView.empty = false; + imageView.position = position; + imageView.setPadding(AndroidUtilities.dp(1), AndroidUtilities.dp(1), AndroidUtilities.dp(1), AndroidUtilities.dp(1)); + boolean selected = false; + imageView.setDrawable(null); + if (searchResult != null && position >= 0 && position < searchResult.size()) { + final long documentId = searchResult.get(position).documentId; + imageView.span = new AnimatedEmojiSpan(documentId, null); + imageView.document = imageView.span.document; + selected = selectedDocumentIds.contains(documentId); + + AnimatedEmojiDrawable drawable = emojiSearchGridView.animatedEmojiDrawables.get(imageView.span.getDocumentId()); + if (drawable == null) { + drawable = AnimatedEmojiDrawable.make(currentAccount, getCacheType(), imageView.span.getDocumentId()); + drawable.addView(emojiSearchGridView); + emojiSearchGridView.animatedEmojiDrawables.put(imageView.span.getDocumentId(), drawable); + } + imageView.setDrawable(drawable); + } + imageView.setViewSelected(selected); + } + } + + private int count = 1; + private ArrayList rowHashCodes = new ArrayList<>(); + + @Override + public int getItemCount() { + return count; + } + + public void updateRows(boolean diff) { + ArrayList prevRowHashCodes = new ArrayList<>(rowHashCodes); + + count = 0; + rowHashCodes.clear(); + +// count++; +// rowHashCodes.add(132); + + if (searchResult != null) { + for (int i = 0; i < searchResult.size(); ++i) { + count++; + rowHashCodes.add(Objects.hash(-4342, searchResult.get(i))); + } + } + + if (diff) { + DiffUtil.calculateDiff(new DiffUtil.Callback() { + @Override + public int getOldListSize() { + return prevRowHashCodes.size(); + } + + @Override + public int getNewListSize() { + return rowHashCodes.size(); + } + + @Override + public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) { + return prevRowHashCodes.get(oldItemPosition).equals(rowHashCodes.get(newItemPosition)); + } + + @Override + public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) { + return true; + } + }, false).dispatchUpdatesTo(SearchAdapter.this); + } else { + this.notifyDataSetChanged(); + } + + switchSearchEmptyView(searched && count == 0); + } + } + + private class Adapter extends RecyclerListView.SelectionAdapter { + + public int VIEW_TYPE_HEADER = 0; + public int VIEW_TYPE_REACTION = 1; + public int VIEW_TYPE_IMAGE = 2; + public int VIEW_TYPE_EMOJI = 3; + public int VIEW_TYPE_EXPAND = 4; + public int VIEW_TYPE_BUTTON = 5; + public int VIEW_TYPE_HINT = 6; + public int VIEW_TYPE_SEARCH = 7; + + @Override + public boolean isEnabled(RecyclerView.ViewHolder holder) { + int viewType = holder.getItemViewType(); + return ( + viewType == VIEW_TYPE_IMAGE || + viewType == VIEW_TYPE_REACTION || + viewType == VIEW_TYPE_EMOJI + ); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view; + if (viewType == VIEW_TYPE_HEADER) { + view = new HeaderView(getContext()); + } else if (viewType == VIEW_TYPE_IMAGE) { + view = new ImageView(getContext()); + } else if (viewType == VIEW_TYPE_EMOJI || viewType == VIEW_TYPE_REACTION) { + view = new ImageViewEmoji(getContext()); + } else if (viewType == VIEW_TYPE_EXPAND) { view = new EmojiPackExpand(getContext(), null); - } else if (viewType == 5) { + } else if (viewType == VIEW_TYPE_BUTTON) { view = new EmojiPackButton(getContext()); - } else if (viewType == 6) { + } else if (viewType == VIEW_TYPE_HINT) { TextView textView = new TextView(getContext()) { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { @@ -1067,6 +1706,9 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati textView.setGravity(Gravity.CENTER); textView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText, resourcesProvider)); view = textView; + } else if (viewType == VIEW_TYPE_SEARCH) { + view = new FixedHeightEmptyCell(getContext(), 52); + view.setTag("searchbox"); } else { view = new ImageViewEmoji(getContext()); } @@ -1079,18 +1721,20 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati @Override public int getItemViewType(int position) { - if ((position >= recentReactionsStartRow && position < recentReactionsEndRow) || (position >= topReactionsStartRow && position < topReactionsEndRow)) { - return 3; + if (position == searchRow) { + return VIEW_TYPE_SEARCH; + } else if ((position >= recentReactionsStartRow && position < recentReactionsEndRow) || (position >= topReactionsStartRow && position < topReactionsEndRow)) { + return VIEW_TYPE_REACTION; } else if (positionToExpand.indexOfKey(position) >= 0) { - return 4; + return VIEW_TYPE_EXPAND; } else if (positionToButton.indexOfKey(position) >= 0) { - return 5; + return VIEW_TYPE_BUTTON; } else if (position == longtapHintRow) { - return 6; + return VIEW_TYPE_HINT; } else if (positionToSection.indexOfKey(position) >= 0 || position == recentReactionsSectionRow || position == popularSectionRow) { - return 0; + return VIEW_TYPE_HEADER; } else { - return 1; + return VIEW_TYPE_EMOJI; } } @@ -1101,14 +1745,12 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati holder.itemView.setScaleX(1); holder.itemView.setScaleY(1); } - if (viewType == 6) { + if (viewType == VIEW_TYPE_HINT) { TextView textView = (TextView) holder.itemView; if (hintExpireDate != null) { textView.setText(LocaleController.formatString("EmojiStatusExpireHint", R.string.EmojiStatusExpireHint, LocaleController.formatStatusExpireDateTime(hintExpireDate))); } - return; - } - if (viewType == 0) { + } else if (viewType == VIEW_TYPE_HEADER) { HeaderView header = (HeaderView) holder.itemView; if (position == recentReactionsSectionRow) { header.setText(LocaleController.getString("RecentlyUsed", R.string.RecentlyUsed), false); @@ -1131,7 +1773,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } else { header.setText(null, false); } - } else if (viewType == 3) { + } else if (viewType == VIEW_TYPE_REACTION) { ImageViewEmoji imageView = (ImageViewEmoji) holder.itemView; imageView.position = position; ReactionsLayoutInBubble.VisibleReaction currentReaction; @@ -1171,6 +1813,14 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati imageView.span = new AnimatedEmojiSpan(currentReaction.documentId, null); imageView.document = null; imageView.imageReceiver.clearImage(); + Drawable drawable = emojiGridView.animatedEmojiDrawables.get(imageView.span.getDocumentId()); + + if (drawable == null) { + drawable = AnimatedEmojiDrawable.make(currentAccount, getCacheType(), imageView.span.getDocumentId()); + emojiGridView.animatedEmojiDrawables.put(imageView.span.getDocumentId(), (AnimatedEmojiDrawable) drawable); + } + imageView.setDrawable(drawable); + if (!UserConfig.getInstance(currentAccount).isPremium()) { if (imageView.premiumLockIconView == null) { imageView.premiumLockIconView = new PremiumLockIconView(getContext(), PremiumLockIconView.TYPE_STICKERS_PREMIUM_LOCKED); @@ -1179,18 +1829,26 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati imageView.premiumLockIconView.setVisibility(View.VISIBLE); } } - } else if (viewType == 4) { + } else if (viewType == VIEW_TYPE_EXPAND) { EmojiPackExpand button = (EmojiPackExpand) holder.itemView; final int i = positionToExpand.get(position); EmojiView.EmojiPack pack = i >= 0 && i < packs.size() ? packs.get(i) : null; if (i == -1) { + recentExpandButton = button; final int maxlen = layoutManager.getSpanCount() * RECENT_MAX_LINES; button.textView.setText("+" + (recent.size() - maxlen + (includeEmpty ? 1 : 0) + 1)); } else if (pack != null) { + if (recentExpandButton == button) { + recentExpandButton = null; + } final int maxlen = layoutManager.getSpanCount() * EXPAND_MAX_LINES; button.textView.setText("+" + (pack.documents.size() - maxlen + 1)); + } else { + if (recentExpandButton == button) { + recentExpandButton = null; + } } - } else if (viewType == 5) { + } else if (viewType == VIEW_TYPE_BUTTON) { EmojiPackButton button = (EmojiPackButton) holder.itemView; final int packIndex = positionToButton.get(position); if (packIndex >= 0 && packIndex < packs.size()) { @@ -1224,6 +1882,8 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati }); } } + } else if (viewType == VIEW_TYPE_SEARCH) { + } else { ImageViewEmoji imageView = (ImageViewEmoji) holder.itemView; imageView.empty = false; @@ -1234,18 +1894,18 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati int recentSize = recent.size() > recentmaxlen && !recentExpanded ? recentmaxlen : recent.size() + (includeEmpty ? 1 : 0); boolean selected = false; imageView.setDrawable(null); - if (includeEmpty && position == (includeHint ? 1 : 0)) { + if (includeEmpty && position == (searchRow != -1 ? 1 : 0) + (includeHint ? 1 : 0)) { selected = selectedDocumentIds.contains(null); imageView.empty = true; imageView.setPadding(AndroidUtilities.dp(5), AndroidUtilities.dp(5), AndroidUtilities.dp(5), AndroidUtilities.dp(5)); imageView.span = null; imageView.document = null; - } else if (position - (includeHint ? 1 : 0) < recentSize) { - imageView.span = recent.get(position - (includeHint ? 1 : 0) - (includeEmpty ? 1 : 0)); + } else if (position - (searchRow != -1 ? 1 : 0) - (includeHint ? 1 : 0) < recentSize) { + imageView.span = recent.get(position - (searchRow != -1 ? 1 : 0) - (includeHint ? 1 : 0) - (includeEmpty ? 1 : 0)); imageView.document = imageView.span == null ? null : imageView.span.document; selected = imageView.span != null && selectedDocumentIds.contains(imageView.span.getDocumentId()); - } else if (!defaultStatuses.isEmpty() && position - (includeHint ? 1 : 0) - recentSize - 1 >= 0 && position - (includeHint ? 1 : 0) - recentSize - 1 < defaultStatuses.size()) { - int index = position - (includeHint ? 1 : 0) - recentSize - 1; + } else if (!defaultStatuses.isEmpty() && position - (searchRow != -1 ? 1 : 0) - (includeHint ? 1 : 0) - recentSize - 1 >= 0 && position - (searchRow != -1 ? 1 : 0) - (includeHint ? 1 : 0) - recentSize - 1 < defaultStatuses.size()) { + int index = position - (searchRow != -1 ? 1 : 0) - (includeHint ? 1 : 0) - recentSize - 1; imageView.span = defaultStatuses.get(index); imageView.document = imageView.span == null ? null : imageView.span.document; selected = imageView.span != null && selectedDocumentIds.contains(imageView.span.getDocumentId()); @@ -1268,6 +1928,17 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } selected = imageView.span != null && selectedDocumentIds.contains(imageView.span.getDocumentId()); } + + if (imageView.span != null) { + AnimatedEmojiDrawable drawable = emojiGridView.animatedEmojiDrawables.get(imageView.span.getDocumentId()); + if (drawable == null) { + drawable = AnimatedEmojiDrawable.make(currentAccount, getCacheType(), imageView.span.getDocumentId()); + emojiGridView.animatedEmojiDrawables.put(imageView.span.getDocumentId(), drawable); + } + imageView.setDrawable(drawable); + } else { + imageView.setDrawable(null); + } imageView.setViewSelected(selected); } } @@ -1495,6 +2166,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } private View animateExpandFromButton; + private float animateExpandFromButtonTranslate; private int animateExpandFromPosition = -1, animateExpandToPosition = -1; private long animateExpandStartTime = -1; @@ -1610,7 +2282,11 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati if (selected && !notDraw) { AndroidUtilities.rectTmp.set(0, 0, getMeasuredWidth(), getMeasuredHeight()); AndroidUtilities.rectTmp.inset(AndroidUtilities.dp(1), AndroidUtilities.dp(1)); - canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(4), AndroidUtilities.dp(4), empty || drawable instanceof AnimatedEmojiDrawable && ((AnimatedEmojiDrawable) drawable).canOverrideColor() ? selectorAccentPaint : selectorPaint); + Paint paint = empty || drawable instanceof AnimatedEmojiDrawable && ((AnimatedEmojiDrawable) drawable).canOverrideColor() ? selectorAccentPaint : selectorPaint; + int wasAlpha = paint.getAlpha(); + paint.setAlpha((int) (wasAlpha * getAlpha())); + canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(4), AndroidUtilities.dp(4), paint); + paint.setAlpha(wasAlpha); } } @@ -1729,6 +2405,12 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati rowHashCodes.clear(); positionToButton.clear(); + if (!installedEmojipacks.isEmpty()) { + searchRow = totalCount++; + } else { + searchRow = -1; + } + if (includeHint && type != TYPE_SET_DEFAULT_REACTION) { longtapHintRow = totalCount++; rowHashCodes.add(6); @@ -1786,9 +2468,13 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati rowHashCodes.add(2); } ArrayList defaultEmojiStatuses = MediaDataController.getInstance(currentAccount).getDefaultEmojiStatuses(); + final int maxrecentlen = layoutManager.getSpanCount() * (RECENT_MAX_LINES + 8); if (defaultSet.documents != null && !defaultSet.documents.isEmpty()) { for (int i = 0; i < Math.min(layoutManager.getSpanCount() - 1, defaultSet.documents.size()); ++i) { recent.add(new AnimatedEmojiSpan(defaultSet.documents.get(i), null)); + if (recent.size() + (includeEmpty ? 1 : 0) >= maxrecentlen) { + break; + } } } if (recentEmojiStatuses != null && !recentEmojiStatuses.isEmpty()) { @@ -1811,6 +2497,9 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati if (foundDuplicate) continue; recent.add(new AnimatedEmojiSpan(did, null)); + if (recent.size() + (includeEmpty ? 1 : 0) >= maxrecentlen) { + break; + } } } if (defaultEmojiStatuses != null && !defaultEmojiStatuses.isEmpty()) { @@ -1832,6 +2521,9 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } if (!foundDuplicate) { recent.add(new AnimatedEmojiSpan(did, null)); + if (recent.size() + (includeEmpty ? 1 : 0) >= maxrecentlen) { + break; + } } } } @@ -1844,6 +2536,9 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati totalCount++; } rowHashCodes.add(Objects.hash(-5531, -1, (recent.size() - maxlen + (includeEmpty ? 1 : 0) + 1))); + if (recentExpandButton != null) { + recentExpandButton.textView.setText("+" + (recent.size() - maxlen + (includeEmpty ? 1 : 0) + 1)); + } positionToExpand.put(totalCount, -1); totalCount++; } else { @@ -1962,12 +2657,12 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) { return true; } - }, true).dispatchUpdatesTo(adapter); + }, false).dispatchUpdatesTo(adapter); } else { adapter.notifyDataSetChanged(); } if (!emojiGridView.scrolledByUserOnce) { - emojiGridView.scrollToPosition(0); + emojiGridView.scrollToPosition(1); } } @@ -1977,6 +2672,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati boolean last; int maxlen; int fromCount, start, toCount; + animateExpandFromButtonTranslate = 0; if (index >= 0 && index < packs.size()) { maxlen = layoutManager.getSpanCount() * EXPAND_MAX_LINES; EmojiView.EmojiPack pack = packs.get(index); @@ -2000,10 +2696,11 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati return; } last = false; - start = (includeHint ? 1 : 0) + (includeEmpty ? 1 : 0); + start = (searchRow != -1 ? 1 : 0) + (includeHint ? 1 : 0) + (includeEmpty ? 1 : 0); fromCount = recentExpanded ? recent.size() : Math.min(maxlen - (includeEmpty ? 1 : 0) - 2, recent.size()); toCount = recent.size(); recentExpanded = true; + animateExpandFromButtonTranslate = AndroidUtilities.dp(8); } else { return; } @@ -2019,10 +2716,6 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati animateExpandFromPosition = from; animateExpandToPosition = from + count; animateExpandStartTime = SystemClock.elapsedRealtime(); -// notifyItemChanged(from - 1); -// notifyItemRangeInserted(from, count); -// adapter.notifyItemRangeInserted(from, count); -// adapter.notifyItemChanged(from); if (last) { final int scrollTo = from; @@ -2052,35 +2745,42 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } } - private LongSparseArray animatedEmojiDrawables = new LongSparseArray<>(); - - private AnimatedEmojiSpan[] getAnimatedEmojiSpans() { - AnimatedEmojiSpan[] spans = new AnimatedEmojiSpan[emojiGridView.getChildCount()]; - for (int i = 0; i < emojiGridView.getChildCount(); ++i) { - View child = emojiGridView.getChildAt(i); - if (child instanceof ImageViewEmoji) { - spans[i] = ((ImageViewEmoji) child).span; - } - } - return spans; - } - private int getCacheType() { return type == TYPE_EMOJI_STATUS || type == TYPE_SET_DEFAULT_REACTION ? AnimatedEmojiDrawable.CACHE_TYPE_KEYBOARD : AnimatedEmojiDrawable.CACHE_TYPE_ALERT_PREVIEW; } - public void updateEmojiDrawables() { - animatedEmojiDrawables = AnimatedEmojiSpan.update(getCacheType(), emojiGridView, getAnimatedEmojiSpans(), animatedEmojiDrawables); - } - - class EmojiListView extends RecyclerListView { + public class EmojiListView extends RecyclerListView { public EmojiListView(Context context) { super(context); + + setDrawSelectorBehind(true); + setClipToPadding(false); + setSelectorRadius(AndroidUtilities.dp(4)); + setSelectorDrawableColor(Theme.getColor(Theme.key_listSelector, resourcesProvider)); } SparseArray> viewsGroupedByLines = new SparseArray<>(); ArrayList> unusedArrays = new ArrayList<>(); ArrayList unusedLineDrawables = new ArrayList<>(); + ArrayList lineDrawables = new ArrayList<>(); + ArrayList lineDrawablesTmp = new ArrayList<>(); + + private LongSparseArray animatedEmojiDrawables = new LongSparseArray<>(); + + private AnimatedEmojiSpan[] getAnimatedEmojiSpans() { + AnimatedEmojiSpan[] spans = new AnimatedEmojiSpan[getChildCount()]; + for (int i = 0; i < getChildCount(); ++i) { + View child = getChildAt(i); + if (child instanceof ImageViewEmoji) { + spans[i] = ((ImageViewEmoji) child).span; + } + } + return spans; + } + + public void updateEmojiDrawables() { + animatedEmojiDrawables = AnimatedEmojiSpan.update(getCacheType(), this, getAnimatedEmojiSpans(), animatedEmojiDrawables); + } @Override public boolean drawChild(Canvas canvas, View child, long drawingTime) { @@ -2090,6 +2790,16 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati return super.drawChild(canvas, child, drawingTime); } + @Override + protected boolean canHighlightChildAt(View child, float x, float y) { + if (child instanceof ImageViewEmoji && (((ImageViewEmoji) child).empty || ((ImageViewEmoji) child).drawable instanceof AnimatedEmojiDrawable && ((AnimatedEmojiDrawable) ((ImageViewEmoji) child).drawable).canOverrideColor())) { + setSelectorDrawableColor(ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_windowBackgroundWhiteBlueIcon, resourcesProvider), 30)); + } else { + setSelectorDrawableColor(Theme.getColor(Theme.key_listSelector, resourcesProvider)); + } + return super.canHighlightChildAt(child, x, y); + } + @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); @@ -2103,6 +2813,12 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati @Override public void dispatchDraw(Canvas canvas) { + if (getVisibility() != View.VISIBLE) { + return; + } + + int restoreTo = canvas.getSaveCount(); + if (lastChildCount != getChildCount() && showAnimator != null && !showAnimator.isRunning()) { updateEmojiDrawables(); lastChildCount = getChildCount(); @@ -2126,9 +2842,9 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati viewsGroupedByLines.clear(); final boolean animatedExpandIn = animateExpandStartTime > 0 && (SystemClock.elapsedRealtime() - animateExpandStartTime) < animateExpandDuration(); final boolean drawButton = animatedExpandIn && animateExpandFromButton != null && animateExpandFromPosition >= 0; - if (animatedEmojiDrawables != null && emojiGridView != null) { - for (int i = 0; i < emojiGridView.getChildCount(); ++i) { - View child = emojiGridView.getChildAt(i); + if (animatedEmojiDrawables != null) { + for (int i = 0; i < getChildCount(); ++i) { + View child = getChildAt(i); if (child instanceof ImageViewEmoji) { ImageViewEmoji imageViewEmoji = (ImageViewEmoji) child; imageViewEmoji.updatePressedProgress(); @@ -2142,7 +2858,10 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati if (imageViewEmoji.getBackground() != null) { imageViewEmoji.getBackground().setBounds((int) imageViewEmoji.getX(), (int) imageViewEmoji.getY(), (int) imageViewEmoji.getX() + imageViewEmoji.getWidth(), (int) imageViewEmoji.getY() + imageViewEmoji.getHeight()); + int wasAlpha = 255; // imageViewEmoji.getBackground().getAlpha(); + imageViewEmoji.getBackground().setAlpha((int) (wasAlpha * imageViewEmoji.getAlpha())); imageViewEmoji.getBackground().draw(canvas); + imageViewEmoji.getBackground().setAlpha(wasAlpha); } if (arrayList == null) { @@ -2160,20 +2879,20 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } } } -// if (drawButton && child != null) { -// int position = getChildAdapterPosition(child); -// if (position == animateExpandFromPosition - 1) { -// float t = CubicBezierInterpolator.EASE_OUT.getInterpolation(MathUtils.clamp((SystemClock.elapsedRealtime() - animateExpandStartTime) / 140f, 0, 1)); -// if (t < 1) { -// canvas.saveLayerAlpha(child.getLeft(), child.getTop(), child.getRight(), child.getBottom(), (int) (255 * (1f - t)), Canvas.ALL_SAVE_FLAG); -// canvas.translate(child.getLeft(), child.getTop()); -// final float scale = .5f + .5f * (1f - t); -// canvas.scale(scale, scale, child.getWidth() / 2f, child.getHeight() / 2f); -// animateExpandFromButton.draw(canvas); -// canvas.restore(); -// } -// } -// } + if (drawButton && child != null) { + int position = getChildAdapterPosition(child); + if (position == animateExpandFromPosition - (animateExpandFromButtonTranslate > 0 ? 0 : 1)) { + float t = CubicBezierInterpolator.EASE_OUT.getInterpolation(MathUtils.clamp((SystemClock.elapsedRealtime() - animateExpandStartTime) / 200f, 0, 1)); + if (t < 1) { + canvas.saveLayerAlpha(child.getLeft(), child.getTop(), child.getRight(), child.getBottom(), (int) (255 * (1f - t)), Canvas.ALL_SAVE_FLAG); + canvas.translate(child.getLeft(), child.getTop() + animateExpandFromButtonTranslate); + final float scale = .5f + .5f * (1f - t); + canvas.scale(scale, scale, child.getWidth() / 2f, child.getHeight() / 2f); + animateExpandFromButton.draw(canvas); + canvas.restore(); + } + } + } } } @@ -2227,28 +2946,28 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } lineDrawablesTmp.clear(); - if (emojiGridView != null) { - for (int i = 0; i < emojiGridView.getChildCount(); ++i) { - View child = emojiGridView.getChildAt(i); - if (child instanceof ImageViewEmoji) { - ImageViewEmoji imageViewEmoji = (ImageViewEmoji) child; - if (imageViewEmoji.premiumLockIconView != null) { - canvas.save(); - canvas.translate( - (int) (imageViewEmoji.getX() + imageViewEmoji.premiumLockIconView.getX()), - (int) (imageViewEmoji.getY() + imageViewEmoji.premiumLockIconView.getY()) - ); - imageViewEmoji.premiumLockIconView.draw(canvas); - canvas.restore(); - } - } else if (child != null) { + for (int i = 0; i < getChildCount(); ++i) { + View child = getChildAt(i); + if (child instanceof ImageViewEmoji) { + ImageViewEmoji imageViewEmoji = (ImageViewEmoji) child; + if (imageViewEmoji.premiumLockIconView != null) { canvas.save(); - canvas.translate((int) child.getX(), (int) child.getY()); - child.draw(canvas); + canvas.translate( + (int) (imageViewEmoji.getX() + imageViewEmoji.premiumLockIconView.getX()), + (int) (imageViewEmoji.getY() + imageViewEmoji.premiumLockIconView.getY()) + ); + imageViewEmoji.premiumLockIconView.draw(canvas); canvas.restore(); } + } else if (child != null && child != animateExpandFromButton) { + canvas.save(); + canvas.translate((int) child.getX(), (int) child.getY()); + child.draw(canvas); + canvas.restore(); } } + + canvas.restoreToCount(restoreTo); } public class DrawingInBackgroundLine extends DrawingInBackgroundThreadDrawable { @@ -2269,12 +2988,12 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati skewBelow = false; if (!imageViewEmojis.isEmpty()) { View firstView = imageViewEmojis.get(0); - if (firstView.getY() > getHeight() - firstView.getHeight()) { - skewAlpha = MathUtils.clamp(-(firstView.getY() - getHeight()) / firstView.getHeight(), 0, 1); + if (firstView.getY() > getHeight() - getPaddingBottom() - firstView.getHeight()) { + skewAlpha = MathUtils.clamp(-(firstView.getY() - getHeight() + getPaddingBottom()) / firstView.getHeight(), 0, 1); skewAlpha = .25f + .75f * skewAlpha; } } - boolean drawInUi = skewAlpha < 1 || imageViewEmojis.size() <= 4 || SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_LOW || showAnimator != null && showAnimator.isRunning(); + boolean drawInUi = skewAlpha < 1 || isAnimating() || imageViewEmojis.size() <= 4 || SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_LOW || showAnimator != null && showAnimator.isRunning(); if (!drawInUi) { boolean animatedExpandIn = animateExpandStartTime > 0 && (SystemClock.elapsedRealtime() - animateExpandStartTime) < animateExpandDuration(); for (int i = 0; i < imageViewEmojis.size(); i++) { @@ -2285,6 +3004,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } } } +// canvas.drawRect(0,0,w,h,Theme.DEBUG_RED); if (drawInUi) { prepareDraw(System.currentTimeMillis()); drawInUiThread(canvas, alpha); @@ -2395,12 +3115,11 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati if (span == null) { continue; } - AnimatedEmojiDrawable drawable = animatedEmojiDrawables.get(imageView.span.getDocumentId()); - if (drawable == null && Math.min(imageView.getScaleX(), imageView.getScaleY()) * scale > 0 && imageView.getAlpha() * alpha > 0) { - drawable = AnimatedEmojiDrawable.make(currentAccount, getCacheType(), imageView.span.getDocumentId()); - drawable.setColorFilter(premiumStarColorFilter); - animatedEmojiDrawables.put(imageView.span.getDocumentId(), drawable); + AnimatedEmojiDrawable drawable = null; + if (imageView.drawable instanceof AnimatedEmojiDrawable) { + drawable = (AnimatedEmojiDrawable) imageView.drawable; } + if (drawable == null || drawable.getImageReceiver() == null) { continue; } @@ -2519,12 +3238,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati if (span == null || imageView.notDraw) { continue; } - drawable = animatedEmojiDrawables.get(imageView.span.getDocumentId()); - if (drawable == null && Math.min(imageView.getScaleX(), imageView.getScaleY()) * scale > 0 && imageView.getAlpha() * alpha > 0) { - drawable = AnimatedEmojiDrawable.make(currentAccount, getCacheType(), imageView.span.getDocumentId()); - imageView.setDrawable(drawable); - animatedEmojiDrawables.put(imageView.span.getDocumentId(), (AnimatedEmojiDrawable) drawable); - } + drawable = imageView.drawable; if (drawable == null) { continue; } @@ -2599,13 +3313,17 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); - bigReactionImageReceiver.onAttachedToWindow(); + if (this == emojiGridView) { + bigReactionImageReceiver.onAttachedToWindow(); + } } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - bigReactionImageReceiver.onDetachedFromWindow(); + if (this == emojiGridView) { + bigReactionImageReceiver.onDetachedFromWindow(); + } } } @@ -2707,20 +3425,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } emojiTabs.contentView.invalidate(); -// DefaultItemAnimator emojiItemAnimator = new DefaultItemAnimator() { -// @Override -// protected float animateByScale(View view) { -// return (view instanceof EmojiPackExpand ? .6f : 0f); -// } -// }; -// emojiItemAnimator.setAddDelay(0); -// emojiItemAnimator.setAddDuration(220); -// emojiItemAnimator.setMoveDuration(260); -// emojiItemAnimator.setChangeDuration(160); -// emojiItemAnimator.setMoveInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT); -// emojiGridView.setItemAnimator(emojiItemAnimator); - - updateEmojiDrawables(); + emojiGridView.updateEmojiDrawables(); } }); updateShow(0); @@ -2728,7 +3433,114 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati showAnimator.start(); } - private static CubicBezierInterpolator endslow = new CubicBezierInterpolator(0, 0, .65, 1.04); + private class SearchBox extends FrameLayout { + private FrameLayout box; + private ImageView search; + private ImageView clear; + private CloseProgressDrawable2 clearDrawable; + private EditTextCaption input; + public SearchBox(Context context) { + super(context); + + setBackgroundColor(Theme.getColor(Theme.key_actionBarDefaultSubmenuBackground, resourcesProvider)); + + box = new FrameLayout(context); + box.setBackground(Theme.createRoundRectDrawable(dp(18), Theme.getColor(Theme.key_chat_emojiPanelBackground, resourcesProvider))); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + box.setClipToOutline(true); + box.setOutlineProvider(new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), (int) dp(18)); + } + }); + } + addView(box, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 36, Gravity.TOP | Gravity.FILL_HORIZONTAL, 8, 4 + 8, 8, 8)); + + search = new ImageView(context); + search.setScaleType(ImageView.ScaleType.CENTER); + search.setImageResource(R.drawable.smiles_inputsearch); + search.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_chat_emojiSearchIcon, resourcesProvider), PorterDuff.Mode.MULTIPLY)); + box.addView(search, LayoutHelper.createFrame(36, 36, Gravity.LEFT | Gravity.TOP)); + + input = new EditTextCaption(context, resourcesProvider) { + + @Override + protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { + if (focused) { + onInputFocus(); + AndroidUtilities.runOnUIThread(() -> { + AndroidUtilities.showKeyboard(input); + }, 200); + + } + super.onFocusChanged(focused, direction, previouslyFocusedRect); + } + }; + input.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + public void afterTextChanged(Editable s) { + search(input.getText() == null || AndroidUtilities.trim(input.getText(), null).length() == 0 ? null : input.getText().toString()); + } + }); + input.setBackground(null); + input.setPadding(0, 0, AndroidUtilities.dp(4), 0); + input.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + input.setHint(type == TYPE_EMOJI_STATUS ? LocaleController.getString(R.string.SearchEmojiHint) : LocaleController.getString(R.string.SearchReactionsHint)); + input.setHintTextColor(Theme.getColor(Theme.key_chat_emojiSearchIcon, resourcesProvider)); + input.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider)); + input.setImeOptions(EditorInfo.IME_ACTION_SEARCH | EditorInfo.IME_FLAG_NO_EXTRACT_UI); + input.setCursorColor(Theme.getColor(Theme.key_featuredStickers_addedIcon, resourcesProvider)); + input.setCursorSize(dp(20)); + input.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL); + input.setCursorWidth(1.5f); + input.setMaxLines(1); + box.addView(input, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.FILL, 36, -1, 32, 0)); + + clear = new ImageView(context); + clear.setScaleType(ImageView.ScaleType.CENTER); + clear.setImageDrawable(clearDrawable = new CloseProgressDrawable2(1.25f) { + @Override + protected int getCurrentColor() { + return Theme.getColor(Theme.key_chat_emojiSearchIcon, resourcesProvider); + } + }); + clearDrawable.setSide(AndroidUtilities.dp(7)); + clear.setScaleX(0.1f); + clear.setScaleY(0.1f); + clear.setAlpha(0.0f); + box.addView(clear, LayoutHelper.createFrame(36, 36, Gravity.RIGHT | Gravity.TOP)); + clear.setOnClickListener(v -> { + input.setText(""); + search(null); + }); + + setOnClickListener(e -> { + onInputFocus(); + input.requestFocus(); + scrollToPosition(0, 0); + }); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(4 + 8+36+8), MeasureSpec.EXACTLY)); + } + } + + protected void onInputFocus() { + + } private void updateShow(float t) { if (bubble1View != null) { @@ -2837,6 +3649,10 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati hideAnimator.setDuration(200); hideAnimator.setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT); hideAnimator.start(); + + if (searchBox != null) { + AndroidUtilities.hideKeyboard(searchBox.input); + } } public void setDrawBackground(boolean drawBackground) { @@ -2849,8 +3665,8 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } public void resetBackgroundBitmaps() { - for (int i = 0; i < lineDrawables.size(); i++) { - EmojiListView.DrawingInBackgroundLine line = lineDrawables.get(i); + for (int i = 0; i < emojiGridView.lineDrawables.size(); i++) { + EmojiListView.DrawingInBackgroundLine line = emojiGridView.lineDrawables.get(i); for (int j = 0; j < line.imageViewEmojis.size(); j++) { if (line.imageViewEmojis.get(j).notDraw) { line.imageViewEmojis.get(j).notDraw = false; @@ -2860,6 +3676,17 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } } emojiGridView.invalidate(); + for (int i = 0; i < emojiSearchGridView.lineDrawables.size(); i++) { + EmojiListView.DrawingInBackgroundLine line = emojiSearchGridView.lineDrawables.get(i); + for (int j = 0; j < line.imageViewEmojis.size(); j++) { + if (line.imageViewEmojis.get(j).notDraw) { + line.imageViewEmojis.get(j).notDraw = false; + line.imageViewEmojis.get(j).invalidate(); + line.reset(); + } + } + } + emojiSearchGridView.invalidate(); } public void setSelected(Long documentId) { @@ -3235,7 +4062,12 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati clipBottom = (parentDialogY = tempLocation[1]) + parentDialogView.getHeight(); } + private boolean done = false; private void done(Integer date) { + if (done) { + return; + } + done = true; boolean showback; if (showback = changeToScrimColor = date != null && getOutBounds(from)) { parentDialogView.getLocationOnScreen(tempLocation); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ThemeActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ThemeActivity.java index c3801a7b3..b32b97440 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ThemeActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ThemeActivity.java @@ -11,6 +11,7 @@ package org.telegram.ui; import android.Manifest; import android.animation.ObjectAnimator; import android.app.Activity; +import android.app.Dialog; import android.app.TimePickerDialog; import android.content.Context; import android.content.DialogInterface; @@ -30,6 +31,7 @@ import android.os.Build; import android.os.Bundle; import android.text.TextPaint; import android.text.TextUtils; +import android.util.TypedValue; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; @@ -37,6 +39,7 @@ import android.view.ViewGroup; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.Button; import android.widget.FrameLayout; +import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.Keep; @@ -99,6 +102,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.concurrent.atomic.AtomicReference; public class ThemeActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate { @@ -136,6 +140,7 @@ public class ThemeActivity extends BaseFragment implements NotificationCenter.No private int saveToGalleryOption2Row; private int saveToGallerySectionRow; private int distanceRow; + private int bluetoothScoRow; private int enableAnimationsRow; private int settings2Row; @@ -255,7 +260,7 @@ public class ThemeActivity extends BaseFragment implements NotificationCenter.No sizeBar = new SeekBarView(context); sizeBar.setReportChanges(true); -// sizeBar.setSeparatorsCount(endFontSize - startFontSize); + sizeBar.setSeparatorsCount(endFontSize - startFontSize + 1); sizeBar.setDelegate(new SeekBarView.SeekBarViewDelegate() { @Override public void onSeekBarDrag(boolean stop, float progress) { @@ -339,7 +344,7 @@ public class ThemeActivity extends BaseFragment implements NotificationCenter.No sizeBar = new SeekBarView(context); sizeBar.setReportChanges(true); -// sizeBar.setSeparatorsCount(endRadius - startRadius); + sizeBar.setSeparatorsCount(endRadius - startRadius + 1); sizeBar.setDelegate(new SeekBarView.SeekBarViewDelegate() { @Override public void onSeekBarDrag(boolean stop, float progress) { @@ -512,6 +517,7 @@ public class ThemeActivity extends BaseFragment implements NotificationCenter.No saveToGalleryOption2Row = -1; saveToGallerySectionRow = -1; distanceRow = -1; + bluetoothScoRow = -1; settings2Row = -1; swipeGestureHeaderRow = -1; @@ -610,6 +616,7 @@ public class ThemeActivity extends BaseFragment implements NotificationCenter.No directShareRow = rowCount++; enableAnimationsRow = rowCount++; raiseToSpeakRow = rowCount++; + bluetoothScoRow = rowCount++; sendByEnterRow = rowCount++; if (SharedConfig.canBlurChat()) { chatBlurRow = rowCount++; @@ -1008,21 +1015,83 @@ public class ThemeActivity extends BaseFragment implements NotificationCenter.No if (getParentActivity() == null) { return; } - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("DistanceUnitsTitle", R.string.DistanceUnitsTitle)); - builder.setItems(new CharSequence[]{ - LocaleController.getString("DistanceUnitsAutomatic", R.string.DistanceUnitsAutomatic), - LocaleController.getString("DistanceUnitsKilometers", R.string.DistanceUnitsKilometers), - LocaleController.getString("DistanceUnitsMiles", R.string.DistanceUnitsMiles) - }, (dialog, which) -> { - SharedConfig.setDistanceSystemType(which); - RecyclerView.ViewHolder holder = listView.findViewHolderForAdapterPosition(distanceRow); + showDialog(new AlertDialog.Builder(getParentActivity()) + .setTitle(LocaleController.getString("DistanceUnitsTitle", R.string.DistanceUnitsTitle)) + .setItems(new CharSequence[]{ + LocaleController.getString("DistanceUnitsAutomatic", R.string.DistanceUnitsAutomatic), + LocaleController.getString("DistanceUnitsKilometers", R.string.DistanceUnitsKilometers), + LocaleController.getString("DistanceUnitsMiles", R.string.DistanceUnitsMiles) + }, (dialog, which) -> { + SharedConfig.setDistanceSystemType(which); + RecyclerView.ViewHolder holder = listView.findViewHolderForAdapterPosition(distanceRow); + if (holder != null) { + listAdapter.onBindViewHolder(holder, distanceRow); + } + }) + .setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null) + .create()); + } else if (position == bluetoothScoRow) { + if (getParentActivity() == null) { + return; + } + AtomicReference dialogRef = new AtomicReference<>(); + + LinearLayout linearLayout = new LinearLayout(context); + linearLayout.setOrientation(LinearLayout.VERTICAL); + + TextView textView = new TextView(context); + textView.setText(LocaleController.getString(R.string.MicrophoneForVoiceMessagesBuiltIn)); + textView.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText)); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + textView.setPadding(AndroidUtilities.dp(21), AndroidUtilities.dp(12), AndroidUtilities.dp(21), AndroidUtilities.dp(12)); + textView.setBackground(Theme.AdaptiveRipple.rect(getThemedColor(Theme.key_windowBackgroundWhite))); + textView.setOnClickListener(v -> { + SharedConfig.recordViaSco = false; + SharedConfig.saveConfig(); + dialogRef.get().dismiss(); + + RecyclerView.ViewHolder holder = listView.findViewHolderForAdapterPosition(bluetoothScoRow); if (holder != null) { - listAdapter.onBindViewHolder(holder, distanceRow); + listAdapter.onBindViewHolder(holder, bluetoothScoRow); } }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showDialog(builder.create()); + linearLayout.addView(textView); + + LinearLayout scoLinearLayout = new LinearLayout(context); + scoLinearLayout.setOrientation(LinearLayout.VERTICAL); + scoLinearLayout.setPadding(AndroidUtilities.dp(21), AndroidUtilities.dp(12), AndroidUtilities.dp(21), AndroidUtilities.dp(12)); + scoLinearLayout.setBackground(Theme.AdaptiveRipple.rect(getThemedColor(Theme.key_windowBackgroundWhite))); + scoLinearLayout.setOnClickListener(v -> { + SharedConfig.recordViaSco = true; + SharedConfig.saveConfig(); + dialogRef.get().dismiss(); + + RecyclerView.ViewHolder holder = listView.findViewHolderForAdapterPosition(bluetoothScoRow); + if (holder != null) { + listAdapter.onBindViewHolder(holder, bluetoothScoRow); + } + }); + linearLayout.addView(scoLinearLayout); + + textView = new TextView(context); + textView.setText(LocaleController.getString(R.string.MicrophoneForVoiceMessagesScoIfConnected)); + textView.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText)); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + scoLinearLayout.addView(textView); + + textView = new TextView(context); + textView.setText(LocaleController.getString(R.string.MicrophoneForVoiceMessagesScoHint)); + textView.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteGrayText)); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + scoLinearLayout.addView(textView); + + Dialog dialog = new AlertDialog.Builder(getParentActivity()) + .setTitle(LocaleController.getString(R.string.MicrophoneForVoiceMessages)) + .setView(linearLayout) + .setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null) + .create(); + dialogRef.set(dialog); + showDialog(dialog); } else if (position == customTabsRow) { SharedConfig.toggleCustomTabs(); if (view instanceof TextCheckCell) { @@ -2056,6 +2125,8 @@ public class ThemeActivity extends BaseFragment implements NotificationCenter.No value = LocaleController.getString("DistanceUnitsMiles", R.string.DistanceUnitsMiles); } cell.setTextAndValue(LocaleController.getString("DistanceUnits", R.string.DistanceUnits), value, false); + } else if (position == bluetoothScoRow) { + cell.setTextAndValue(LocaleController.getString(R.string.MicrophoneForVoiceMessages), LocaleController.getString(SharedConfig.recordViaSco ? R.string.MicrophoneForVoiceMessagesSco : R.string.MicrophoneForVoiceMessagesBuiltIn), true); } break; } @@ -2231,7 +2302,8 @@ public class ThemeActivity extends BaseFragment implements NotificationCenter.No public int getItemViewType(int position) { if (position == scheduleFromRow || position == distanceRow || position == scheduleToRow || position == scheduleUpdateLocationRow || - position == contactsReimportRow || position == contactsSortRow) { + position == contactsReimportRow || position == contactsSortRow || + position == bluetoothScoRow) { return TYPE_TEXT_SETTING; } else if (position == automaticBrightnessInfoRow || position == scheduleLocationInfoRow) { return TYPE_TEXT_INFO_PRIVACY; diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_calls_regular.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_calls_regular.png new file mode 100644 index 0000000000000000000000000000000000000000..2a33cb36a36c9dce85d2c5f8ed0d78318716e533 GIT binary patch literal 1063 zcmV+?1laqDP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91B%lKT1ONa40RR91Bme*a04fgS`~Uz0kx4{BR9Fe^mtAO%VHn5v+B8i* z+VT}4EkhGYNzo2iIFhm)tVmhgfi`EfkQ5~xi4r9%HjWg9!>N@J2{T1gEA7a_Vm@EL z|FipgcE8V_mv`?+4(zJ`dwu+`>$>mfe(vXfp0}uIT>j@3NG6lzpasmc97%Po!{ zn`?ZaNh$^h!2|FanDk;?2g_3mA`W~PFbO7wqsf?bSqXtrxyFT>qz<*`T%aL$1Cs?QBo4$1Fz6DlMfrUB6TC*#J^P(!2WBFXc#3h=#kVlA;%E-B z*o{iO7PN@Bnsm9wYX!7~Ci6qWGawr+0X@&70+X0-l}T2c+Fzj_Z-6D9?VEj`6F2E) z9&fg3QJL7oEx4>1c4_EluW@J+ul90wgoHETMr~AL*==g|r1-rX@LY5-$Io@VR8w3| zt}*|XsaLmaxGqiODlZGPqlf{+abF1(coiG;rwTtVdo@Q}h6VLCa zR&$y*xq+qXY(Q-Pb{?{L!8HR<0sTPI3npn$bP0F@BtO8mf=|WtfW=-*FU~&T^JV>!O0Xx~1b05@$9yx!I0k~rz?3MAvR0M7T zlaqci!AkJl$cXO4zX|RF*-^RV_sZC&i=Mh?Ubl(>k1cZV*O#-$!F6f)oQP<#VnX!ad#w=$-%e|Q_W?Y9lR5C(% zSu(>ewfnksd#(3iKFHSTp`g_AW?uR3Z-w)_Zxu#x%Uz3lA6fl&xBa=DqN4w&T0VdE zz-EghbI4SEfwc^-FD@C^DD#|-zUR8;dFz>o7WRNV)s|;FChR%fHEqqpS*P1{<8OJz zx?Ax*Z0XGZaJNA8SEB4b=U>?(hyR5gXb78d*C$<7VgK9E=T@h`hQDAg zR$E$rd2ySa32$eArhe9(^)B1_3Hy!T>ix4laeB%57SBIxIO^;_rYml9_4adn#Q&(W zBKwv}+^ju1FD`BCl?+cvivD=ozE5qp`0L-Dhs83_uxBif%)Rnp*U@6f$2-66U{SvG zVb`=>mJe_B3B2BEzu3U9^{&F}&5c`+tlq%D?xeVpFCuJ{)m@Fqi$$i>m$JV-t`u@u z%EyuE>w+3NzIM(vp6{YX`Y&s>Ig}lix_is(ZgI_?xibrQ3eS>hoxi|#E#ulJnkSy{ zKh4_~t>{~Il~=miOXGm|1m8oNk2(Jd*EEY4u)ivQJ^P|&4U18|?Z;UwG#D>GPd@B^ zuJ+jZL;0td#-B5}t-0`pg3pZw?G^RiAH*MU*R*akm=^K%dV;9f!}rf!FA7Sq-^~7y zZyXoB?Q!IS`|LMg8vL9$?~oS9{N&uT3{&dYUy`$V&3JQX$QfaS2TB?HQ};hGjA{Dv zSK(Uk<;2sQ@(a&-Zjt(XsQ*>Mw$AJSk7{4IdBW{+o#&hPx#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91FrWhf1ONa40RR91FaQ7m0NXcg3;+NH=}AOERA>e5m}`huRTPG2tkfwh zGt)E+9lM!b48&6V6GV|(8ATT&u>tE>5Tj8B5<~?BWr0+fG#V6ADJelW>W>PUXjJ5- z%t#%l8;xDGL~VNBZ_YZi&OZA)GxN>u&$r-Zuf5j0*52owb@txp)YMd^dIzd^pkMAl zTU*=d;09114v4K5%mg!}NBk49Uk^?TeL1obAYY9>2b>G)%ud@1z5;7%YioaU_OdFu zH0e#?Y;YVbAhwCN2A}4z9%w9y^tt%k)WP3CvmBfNTEI+vKhVa7fK$O*(3$)Np%I)I z&(vXs^J0)}zj?7=6Zq7f;rs^z|5Ed*9ppQS{u=GA5qoGFhT%D|h5^bx$t0+BH^T%4 zz9N2^G?>3;;?O7J%AHgF7hSyDc0DQ`XGmLx#2^No+L`d^>;)T{&P4MA@J zHlCiwc#F-oI3EWlf1r%ZkuYGN0(KdZ_9z$;UShq7z4{Vc{!&Zw<-p{Fj5Fv! z($lg#qnLRCrC++?J8+U4^@!7RDl5Sbj2oTfMyKagE^rQ50TzKFoq2*KwN5M+AUF1J5Q7MveLL1Ra*9bh@(1B*L(EWWppyjV%3IE zpxHU2_3!*r_qo3Ii*gdKYI7Y?`;GPolQAf=nRu>jnOxxor0X-pv0Sw_k0ROYoTK1p zO2hefI$i26*WZn<&CNu*Y$joB*f(COB&NGZCH2w{Z(hTHRluK^XO;4*j#mP$Y@5L) zo=0CxWpjf0fp0SQ&w*l_z+mss=s4?uUs*EAGGsb%_40X{8glx&pD7_$mVX%V8#k!0 zMQ2XcQK{Ch_)-X5ebdccKr)05T_%|~-i)rj)9FXiqxH!nQVFdBe*%?5tc0}ssEqD& zIrWr%38@Ury=U!V5M}`{Q+z_xA!s-D<)%|)RN!eH_p;fD79V({ImmS(wOVeA|E>q7I-> zuaA-vB0=jrJFC8@$YS1zhdI_kt_I8Q@=_)2EIw!ggZz(e|D&=wjeSclcyK z0(~97!(H6oIj1M7nz{jl+4Riu;bjbNyE=x3fF{h=T>$?vf52i=vu z1Y|xjE1JB5NTkVq7R=z8SVA}t0sW~cC-S`uUIO}&umSuIV)7%#b7JFk+eV_%KncAx z(Xsa<&53O)(8)8D_c2_U5}ks54A3#<6X0c;qxDQB>lHx16}{*Vo)u=sHV7;Lzk!3G zA>_pR@D!&KHTfH5c#K<-jbzh-4tZYo(9w#O6YL|vxSXTF0AI)K|A5II1@!K_$a)_5 z(y}M5K3Ez-dT#1|=8g#RY)|s4d8EVBOBzYFiLF!iK)$7ab5DmMhu`I2>1n=bJcFoS zp9L}b7~^Hpz%Cex-RP38=t4;46b8Bu>~;g1syfz%+zz^2T5v~#!@%UR%4gTbNJgpy zPXc`(#H1DDo8WFRwp?0#+H=CvygbIw?4&V5B{l{hP26Je02o@3qXpkqum|X`;IBZ3 zz9K-uy=OiN-v)Y)B^1tPXqrcO1DtNy`X5^J}IH1 z0p(*-Dlz?r6!ia9o1CC8zQf=Puo|qQbo9flD%Cqsy#rPx#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91NT34%1ONa40RR91NB{r;0FW_8?*IS?Q%OWYRCodHn}3KERTRf})zUOb zMa$HpGBDTDei#&stgD5n1^r`GTTtjfMgM3-L{y7GMNzN@{gFi=1Q8Y~Nl_%4MCq22 zP-&W5x>}?}s9URUy*^)=$=UnPoj3D*^M2SI_%d_9_ndRjIs4|$ojbElO}XS1$SaUn zAg@4PfxH5F1*%_xLZPq-bc3V8agi^ItaN?j4dNNR4ZI3=fJ5LP5EZq>ZwD`f)jGv{!RJCDJbEbT~$n=t>JAo@p;*tsbFd7NoagBrayil*9k0f)%NN{4(q_9@Op^QE39kUdx1&hM)73`oXqt=b(c|VwWXNEY!ot zkA|O?us`k?6vr?x)P5yRR9lV6Qa?W6W250`eq3R~KJ0Y&vZSgjY2QMzHw-j#oE$k% zdb-b0ywu<<>MDzbvv`Y>xy4(YPuIJWu2g~cYh*_*aoWCSniX$Wx~U4}tGq8k@m7J7 z{(?F^jxFBeWNz^m=hGEmEL`{tjEjGJv1UAjkA;SxPvfml_hMVOcd_wCV!CCII30fJ zGxTQ|eo_~@^hnuhn3HsKbMqmFbSKzha5Gbea@^2Q^*myTQd#i;YgJ@P^u{U4{CbgA^@uhqf3_Z_hr0e&)Ue^H;$F3O`<7c1##OhxAesW%j^tSwS> z2n-%~je_KM1pQZ{DOuM zsCB7y`m#j-HQx1z6j*f54}ji!A?j$&uKHz!l9cdV5+V@DIDnL0hl0#}yegIzdviJPCLDazlT; z$L4GJ(LTF|nB!A3fr{c}^+18pj|LSo;k&GtgZ@^SX?BhAw-d&--3~D{;Ll-^)=lBMv z?;5Zd_~ZvV=F6UAGk6H}fin?pvuN4jjmsBr*}Mh=p94$Yg7jX#^o<27WSqQ9=f*gN zGWxb)b8*>8r!{1-N#Hk6pj~nPu+c|XFL`XUqi6B#sICurU%fnA#Sgo?xszko!B(VXD=jqKk!Kx9kG81 z`mY9CeGUR%lkZ9pTS)rP1J?n44ya8!pWKsuWg;UG#iPDR;58@3PLTBLl3Na}30aeR zdt|u8r`XK}e*#x_C3aFNMIv~?jUv+4r0iV+gfXBq8N3Pfm79Jw`ocf)M^~Yr=n?zd zfF-k{dYPXSfo{t$T9E{t)=4)f2?V{FU``U1xP$d3Pr}!i%eH`r*KhuRie2S_|{1Z zRyzZopy=_U($O%6<~CP;uk<*n{SlEClfD&q7;q0Kx-DC4snlay2KXKhTsdLsR-GfN zVL+>9-@FtCuII20Q1L?H)A|J+ta>rx1|-NfunUxueJDHyCdK(n(}%C6#-Ll$_^665 zLF%WjO*hRyrDOmFZS&p@%HG4qb{zN>xbkdOk}hWuB5eU{-H2n_x+87?S|Z#4&P_5d zdivtudLsi}`d_rFx)!k#BFG!zp8==#fGiykrwMik&<9!CP1HlIb{2)hKo7ACz;j>% zaODFYR?~hE=K82!n?kjM_keyWS&N?crdBVz3XVkJ6Ty?AxA%Dp+m%IXb1@a2y704^_KdQjLHHC6hace*;00000NkvXX Hu0mjfLj|}S literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/res/raw/info.json b/TMessagesProj/src/main/res/raw/info.json new file mode 100644 index 000000000..7ba33826b --- /dev/null +++ b/TMessagesProj/src/main/res/raw/info.json @@ -0,0 +1 @@ +{"v":"5.9.6","fr":60,"ip":0,"op":45,"w":64,"h":64,"nm":"s","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"luc12","parent":15,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[100]},{"t":20,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-43.5,75.344,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[2.5,0],[-2.5,0]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"stroke","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":-60,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"luc12","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[40]},{"t":20,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.697],"y":[0.848]},"o":{"x":[0.527],"y":[0.407]},"t":2,"s":[40]},{"t":5,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":45,"st":-15,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"luc11","parent":15,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[100]},{"t":20,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[43.5,75.344,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[2.5,0],[-2.5,0]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"stroke","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":60,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"luc11","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.697],"y":[0.848]},"o":{"x":[0.526],"y":[0.407]},"t":2,"s":[60]},{"t":5,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":2,"s":[60]},{"i":{"x":[0.201],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[60]},{"t":20,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":45,"st":-15,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"luc10","parent":15,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[100]},{"t":20,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,87,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[2.5,0],[-2.5,0]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"stroke","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":90,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"luc10","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.697],"y":[0.848]},"o":{"x":[0.526],"y":[0.407]},"t":2,"s":[60]},{"t":5,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":2,"s":[60]},{"i":{"x":[0.201],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[60]},{"t":20,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":45,"st":-15,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"luc9","parent":15,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[100]},{"t":20,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75.344,43.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[2.5,0],[-2.5,0]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"stroke","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":30,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"luc9","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.697],"y":[0.848]},"o":{"x":[0.526],"y":[0.407]},"t":2,"s":[60]},{"t":5,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":2,"s":[60]},{"i":{"x":[0.201],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[60]},{"t":20,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":45,"st":-15,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"luc8","parent":15,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[100]},{"t":20,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[87,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[2.5,0],[-2.5,0]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"stroke","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"luc8","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.697],"y":[0.848]},"o":{"x":[0.526],"y":[0.407]},"t":2,"s":[60]},{"t":5,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":2,"s":[60]},{"i":{"x":[0.201],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[60]},{"t":20,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":45,"st":-15,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"luc7","parent":15,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[100]},{"t":20,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75.344,-43.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[2.5,0],[-2.5,0]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"stroke","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":-30,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"luc7","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.697],"y":[0.848]},"o":{"x":[0.526],"y":[0.407]},"t":2,"s":[60]},{"t":5,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":2,"s":[60]},{"i":{"x":[0.201],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[60]},{"t":20,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":45,"st":-15,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"luc6","parent":15,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[100]},{"t":20,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[43.5,-75.344,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[2.5,0],[-2.5,0]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"stroke","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":-60,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"luc6","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.697],"y":[0.848]},"o":{"x":[0.526],"y":[0.407]},"t":2,"s":[60]},{"t":5,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":2,"s":[60]},{"i":{"x":[0.201],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[60]},{"t":20,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":45,"st":-15,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"luc5","parent":15,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[100]},{"t":20,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,-87,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[2.5,0],[-2.5,0]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"stroke","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":90,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"luc5","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[40]},{"t":20,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.697],"y":[0.848]},"o":{"x":[0.527],"y":[0.407]},"t":2,"s":[40]},{"t":5,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":45,"st":-15,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"luc4","parent":15,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[100]},{"t":20,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-43.5,-75.344,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[2.5,0],[-2.5,0]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"stroke","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":60,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"luc4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[40]},{"t":20,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.697],"y":[0.848]},"o":{"x":[0.527],"y":[0.407]},"t":2,"s":[40]},{"t":5,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":45,"st":-15,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"luc3","parent":15,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[100]},{"t":20,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-75.344,-43.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[2.5,0],[-2.5,0]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"stroke","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":30,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"luc3","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[40]},{"t":20,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.697],"y":[0.848]},"o":{"x":[0.527],"y":[0.407]},"t":2,"s":[40]},{"t":5,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":45,"st":-15,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"luc2","parent":15,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[100]},{"t":20,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-87,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[2.5,0],[-2.5,0]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"stroke","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"luc2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[40]},{"t":20,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.697],"y":[0.848]},"o":{"x":[0.527],"y":[0.407]},"t":2,"s":[40]},{"t":5,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":45,"st":-15,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"luc1","parent":15,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[100]},{"t":20,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-75.344,43.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[2.5,0],[-2.5,0]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"stroke","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":-30,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"luc1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[40]},{"t":20,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.697],"y":[0.848]},"o":{"x":[0.527],"y":[0.407]},"t":2,"s":[40]},{"t":5,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":45,"st":-15,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"info1","parent":15,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,14,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,3],[0,-3]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"stroke","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"info1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.799],"y":[0]},"t":5,"s":[0]},{"t":15,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"trim","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":45,"st":-15,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"info2","parent":15,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"t":15,"s":[0,-4,0],"to":[0,-2,0],"ti":[0,4.999,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":23,"s":[0,-39,0],"to":[0,-5.001,0],"ti":[0,2,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":31,"s":[0,-24,0],"to":[0,-4,0],"ti":[0,0,0]},{"t":39,"s":[0,-28,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0]},"t":15,"s":[67,67,100]},{"t":25,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.83,0],[0,0.83],[0.83,0],[0,-0.83]],"o":[[0.83,0],[0,-0.83],[-0.83,0],[0,0.83]],"v":[[0,1.5],[1.5,0],[0,-1.5],[-1.5,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"info2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":15,"op":45,"st":-15,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Oval","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":6,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[32,32,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.203,0.203,0.667],"y":[1,1,1]},"o":{"x":[0.17,0.17,0.333],"y":[0,0,0]},"t":2,"s":[20.741,20.741,100]},{"t":27,"s":[29.63,29.63,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[24,24],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"contour","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"fill","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":45,"st":-15,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values/strings.xml b/TMessagesProj/src/main/res/values/strings.xml index ee22dfcad..16f2113be 100644 --- a/TMessagesProj/src/main/res/values/strings.xml +++ b/TMessagesProj/src/main/res/values/strings.xml @@ -143,6 +143,7 @@ Email address will be passed to %1$s as billing info. Phone and email address will be passed to %1$s as billing info. You paid **%1$s** for **%2$s**. + No app found to handle this deep link. New conversation Auto-Night Mode is off @@ -1722,6 +1723,7 @@ No stickers found No GIFs found No emoji found + No reactions found No masks yet Emoji suggestions **Telegram** lets you find emoji by thousands of keywords, but there is always something missing. If you want to suggest a new emoji replacement, you can help us by visiting: @@ -5619,4 +5621,11 @@ Infinite Reactions Emoji Status Add any of thousands emojis next to your name to display current activity. + Microphone for voice messages + Built-In + Headset + Headset (if connected) + Using a headset microphone may reduce background noise but will slightly decrease audio quality. + %s Reaction + Search reactions diff --git a/TMessagesProj_App/build.gradle b/TMessagesProj_App/build.gradle index b1465beef..55e3189df 100644 --- a/TMessagesProj_App/build.gradle +++ b/TMessagesProj_App/build.gradle @@ -21,6 +21,17 @@ dependencies { implementation files('../TMessagesProj/libs/libgsaverification-client.aar') } +def getProps(String propName) { + def propsFile = rootProject.file('local.properties') + if (propsFile.exists()) { + def props = new Properties() + props.load(new FileInputStream(propsFile)) + return props[propName] + } else { + return "" + } +} + android { compileSdkVersion 31 buildToolsVersion '31.0.0' @@ -75,17 +86,6 @@ android { ndk.debugSymbolLevel = 'FULL' } - HA { - debuggable false - jniDebuggable false - signingConfig signingConfigs.debug - applicationIdSuffix ".beta" - minifyEnabled true - multiDexEnabled true - proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro' - ndk.debugSymbolLevel = 'FULL' - } - standalone { debuggable false jniDebuggable false @@ -113,10 +113,6 @@ android { manifest.srcFile '../TMessagesProj/config/debug/AndroidManifest.xml' } - sourceSets.HA { - manifest.srcFile '../TMessagesProj/config/debug/AndroidManifest.xml' - } - sourceSets.standalone { manifest.srcFile '../TMessagesProj/config/release/AndroidManifest.xml' } diff --git a/TMessagesProj_App/src/main/java/org/telegram/messenger/GoogleVoiceClientService.java b/TMessagesProj_App/src/main/java/org/telegram/messenger/GoogleVoiceClientService.java index 625a2aaef..25af0a81f 100644 --- a/TMessagesProj_App/src/main/java/org/telegram/messenger/GoogleVoiceClientService.java +++ b/TMessagesProj_App/src/main/java/org/telegram/messenger/GoogleVoiceClientService.java @@ -10,46 +10,13 @@ package org.telegram.messenger; import android.content.Intent; import android.os.Bundle; -import android.text.TextUtils; import com.google.android.search.verification.client.SearchActionVerificationClientService; -import org.telegram.tgnet.TLRPC; - public class GoogleVoiceClientService extends SearchActionVerificationClientService { @Override public void performAction(Intent intent, boolean isVerified, Bundle options) { - if (!isVerified) { - return; - } - AndroidUtilities.runOnUIThread(() -> { - try { - int currentAccount = UserConfig.selectedAccount; - ApplicationLoader.postInitApplication(); - if (AndroidUtilities.needShowPasscode() || SharedConfig.isWaitingForPasscodeEnter) { - return; - } - String text = intent.getStringExtra("android.intent.extra.TEXT"); - if (!TextUtils.isEmpty(text)) { - String contactUri = intent.getStringExtra("com.google.android.voicesearch.extra.RECIPIENT_CONTACT_URI"); - String id = intent.getStringExtra("com.google.android.voicesearch.extra.RECIPIENT_CONTACT_CHAT_ID"); - long uid = Long.parseLong(id); - TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(uid); - if (user == null) { - user = MessagesStorage.getInstance(currentAccount).getUserSync(uid); - if (user != null) { - MessagesController.getInstance(currentAccount).putUser(user, true); - } - } - if (user != null) { - ContactsController.getInstance(currentAccount).markAsContacted(contactUri); - SendMessagesHelper.getInstance(currentAccount).sendMessage(text, user.id, null, null, null, true, null, null, null, true, 0, null, false); - } - } - } catch (Exception e) { - FileLog.e(e); - } - }); + AndroidUtilities.googleVoiceClientService_performAction(intent, isVerified, options); } } diff --git a/TMessagesProj_AppHockeyApp/.gitignore b/TMessagesProj_AppHockeyApp/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/TMessagesProj_AppHockeyApp/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/TMessagesProj_AppHockeyApp/build.gradle b/TMessagesProj_AppHockeyApp/build.gradle new file mode 100644 index 000000000..1c213becd --- /dev/null +++ b/TMessagesProj_AppHockeyApp/build.gradle @@ -0,0 +1,171 @@ +apply plugin: 'com.android.application' + +repositories { + mavenCentral() + google() +} + +configurations { + compile.exclude module: 'support-v4' +} + +configurations.all { + exclude group: 'com.google.firebase', module: 'firebase-core' + exclude group: 'androidx.recyclerview', module: 'recyclerview' +} + +dependencies { + implementation project(':TMessagesProj') + implementation 'androidx.multidex:multidex:2.0.1' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' + implementation files('../TMessagesProj/libs/libgsaverification-client.aar') + + implementation "com.microsoft.appcenter:appcenter-distribute:3.3.1" + implementation "com.microsoft.appcenter:appcenter-crashes:3.3.1" +} + +android { + compileSdkVersion 31 + buildToolsVersion '31.0.0' + + defaultConfig.applicationId = APP_PACKAGE + + sourceSets.main.jniLibs.srcDirs = ['../TMessagesProj/jni/'] + + lintOptions { + disable 'MissingTranslation' + disable 'ExtraTranslation' + disable 'BlockedPrivateApi' + } + + dexOptions { + jumboMode = true + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + + coreLibraryDesugaringEnabled true + } + + signingConfigs { + debug { + storeFile file("../TMessagesProj/config/release.keystore") + storePassword RELEASE_STORE_PASSWORD + keyAlias RELEASE_KEY_ALIAS + keyPassword RELEASE_KEY_PASSWORD + } + + release { + storeFile file("../TMessagesProj/config/release.keystore") + storePassword RELEASE_STORE_PASSWORD + keyAlias RELEASE_KEY_ALIAS + keyPassword RELEASE_KEY_PASSWORD + } + } + + buildTypes { + HA_private { + debuggable false + jniDebuggable false + signingConfig signingConfigs.debug + applicationIdSuffix ".beta" + minifyEnabled true + multiDexEnabled true + proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro' + ndk.debugSymbolLevel = 'FULL' + } + HA_public { + debuggable false + jniDebuggable false + signingConfig signingConfigs.debug + applicationIdSuffix ".beta" + minifyEnabled true + multiDexEnabled true + proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro' + ndk.debugSymbolLevel = 'FULL' + } + } + + sourceSets.HA_private { + manifest.srcFile '../TMessagesProj/config/debug/AndroidManifest.xml' + } + sourceSets.HA_public { + manifest.srcFile '../TMessagesProj/config/debug/AndroidManifest.xml' + } + + flavorDimensions "minApi" + + productFlavors { + bundleAfat { + ndk { + abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64" + } + ext { + abiVersionCode = 1 + } + } + bundleAfat_SDK23 { + ndk { + abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64" + } + minSdkVersion 23 + ext { + abiVersionCode = 2 + } + } + afat { + ndk { + abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64" + } + ext { + abiVersionCode = 9 + } + } + } + + defaultConfig.versionCode = Integer.parseInt(APP_VERSION_CODE) + + applicationVariants.all { variant -> + variant.outputs.all { output -> + outputFileName = "app.apk" + output.versionCodeOverride = defaultConfig.versionCode * 10 + variant.productFlavors.get(0).abiVersionCode + } + } + + variantFilter { variant -> + def names = variant.flavors*.name + if (variant.buildType.name != "release" && !names.contains("afat")) { + setIgnore(true) + } + } + + defaultConfig { + minSdkVersion 16 + targetSdkVersion 30 + versionName APP_VERSION_NAME + ndkVersion "21.4.7075529" + + multiDexEnabled true + + vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi'] + + externalNativeBuild { + cmake { + version '3.10.2' + arguments '-DANDROID_STL=c++_static', '-DANDROID_PLATFORM=android-16', "-j=16" + } + } + } + + buildFeatures { + buildConfig = true + } + + lintOptions { + checkReleaseBuilds false + } +} + +apply plugin: 'com.google.gms.google-services' diff --git a/TMessagesProj_AppHockeyApp/google-services.json b/TMessagesProj_AppHockeyApp/google-services.json new file mode 100644 index 000000000..640e841b2 --- /dev/null +++ b/TMessagesProj_AppHockeyApp/google-services.json @@ -0,0 +1,98 @@ +{ + "project_info": { + "project_number": "760348033671", + "firebase_url": "https://tmessages2.firebaseio.com", + "project_id": "tmessages2", + "storage_bucket": "tmessages2.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:760348033671:android:f6afd7b67eae3860", + "android_client_info": { + "package_name": "org.telegram.messenger" + } + }, + "oauth_client": [ + { + "client_id": "760348033671-2hh8ebmuflsnjoc0kldkfells9rhtfni.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyA-t0jLPjUt2FxrA8VPK2EiYHcYcboIR6k" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "760348033671-2hh8ebmuflsnjoc0kldkfells9rhtfni.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:760348033671:android:dc022572c167a16c", + "android_client_info": { + "package_name": "org.telegram.messenger.beta" + } + }, + "oauth_client": [ + { + "client_id": "760348033671-2hh8ebmuflsnjoc0kldkfells9rhtfni.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyA-t0jLPjUt2FxrA8VPK2EiYHcYcboIR6k" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "760348033671-2hh8ebmuflsnjoc0kldkfells9rhtfni.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:760348033671:android:7396e651423888c3f66e22", + "android_client_info": { + "package_name": "org.telegram.messenger.web" + } + }, + "oauth_client": [ + { + "client_id": "760348033671-2hh8ebmuflsnjoc0kldkfells9rhtfni.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyA-t0jLPjUt2FxrA8VPK2EiYHcYcboIR6k" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "760348033671-2hh8ebmuflsnjoc0kldkfells9rhtfni.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/TMessagesProj_AppHockeyApp/src/main/AndroidManifest.xml b/TMessagesProj_AppHockeyApp/src/main/AndroidManifest.xml new file mode 100644 index 000000000..0e501a7e8 --- /dev/null +++ b/TMessagesProj_AppHockeyApp/src/main/AndroidManifest.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TMessagesProj_AppHockeyApp/src/main/java/org/telegram/messenger/ApplicationLoaderImpl.java b/TMessagesProj_AppHockeyApp/src/main/java/org/telegram/messenger/ApplicationLoaderImpl.java new file mode 100644 index 000000000..48ff7dc82 --- /dev/null +++ b/TMessagesProj_AppHockeyApp/src/main/java/org/telegram/messenger/ApplicationLoaderImpl.java @@ -0,0 +1,65 @@ +package org.telegram.messenger; + +import android.app.Activity; +import android.os.SystemClock; +import android.text.TextUtils; + +import com.microsoft.appcenter.AppCenter; +import com.microsoft.appcenter.crashes.Crashes; +import com.microsoft.appcenter.distribute.Distribute; + +import org.telegram.messenger.regular.BuildConfig; + +public class ApplicationLoaderImpl extends ApplicationLoader { + @Override + protected String onGetApplicationId() { + return BuildConfig.APPLICATION_ID; + } + + + @Override + protected void startAppCenterInternal(Activity context) { + if (org.telegram.messenger.BuildConfig.DEBUG) { + return; + } + try { + if (BuildVars.DEBUG_VERSION) { + Distribute.setEnabledForDebuggableBuild(true); + String appHash = org.telegram.messenger.BuildConfig.APP_CENTER_HASH; + if (TextUtils.isEmpty(appHash)) { + throw new RuntimeException("App Center hash is empty. add to local.properties field APP_CENTER_HASH_PRIVATE and APP_CENTER_HASH_PUBLIC"); + } + AppCenter.start(context.getApplication(), appHash, Distribute.class, Crashes.class); + AppCenter.setUserId("uid=" + UserConfig.getInstance(UserConfig.selectedAccount).clientUserId); + } + } catch (Throwable e) { + FileLog.e(e); + } + } + + private static long lastUpdateCheckTime; + @Override + protected void checkForUpdatesInternal() { + try { + if (BuildVars.DEBUG_VERSION) { + if (SystemClock.elapsedRealtime() - lastUpdateCheckTime < 60 * 60 * 1000) { + return; + } + lastUpdateCheckTime = SystemClock.elapsedRealtime(); + Distribute.checkForUpdate(); + } + } catch (Throwable e) { + FileLog.e(e); + } + } + + protected void appCenterLogInternal(Throwable e) { + try { + Crashes.trackError(e); + } catch (Throwable ignore) { + + } + } + + +} diff --git a/TMessagesProj_AppHockeyApp/src/main/java/org/telegram/messenger/GoogleVoiceClientActivity.java b/TMessagesProj_AppHockeyApp/src/main/java/org/telegram/messenger/GoogleVoiceClientActivity.java new file mode 100644 index 000000000..aa38318ed --- /dev/null +++ b/TMessagesProj_AppHockeyApp/src/main/java/org/telegram/messenger/GoogleVoiceClientActivity.java @@ -0,0 +1,19 @@ +/* + * This is the source code of Telegram for Android v. 5.x.x + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2018. + */ + +package org.telegram.messenger; + +import com.google.android.search.verification.client.SearchActionVerificationClientActivity; +import com.google.android.search.verification.client.SearchActionVerificationClientService; + +public class GoogleVoiceClientActivity extends SearchActionVerificationClientActivity { + + public Class getServiceClass() { + return GoogleVoiceClientService.class; + } +} diff --git a/TMessagesProj_AppHockeyApp/src/main/java/org/telegram/messenger/GoogleVoiceClientService.java b/TMessagesProj_AppHockeyApp/src/main/java/org/telegram/messenger/GoogleVoiceClientService.java new file mode 100644 index 000000000..25af0a81f --- /dev/null +++ b/TMessagesProj_AppHockeyApp/src/main/java/org/telegram/messenger/GoogleVoiceClientService.java @@ -0,0 +1,22 @@ +/* + * This is the source code of Telegram for Android v. 5.x.x + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2018. + */ + +package org.telegram.messenger; + +import android.content.Intent; +import android.os.Bundle; + +import com.google.android.search.verification.client.SearchActionVerificationClientService; + +public class GoogleVoiceClientService extends SearchActionVerificationClientService { + + @Override + public void performAction(Intent intent, boolean isVerified, Bundle options) { + AndroidUtilities.googleVoiceClientService_performAction(intent, isVerified, options); + } +} diff --git a/gradle.properties b/gradle.properties index 665539055..09e4ebed2 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.0.1 -APP_VERSION_CODE=2800 +APP_VERSION_NAME=9.0.2 +APP_VERSION_CODE=2808 APP_PACKAGE=org.telegram.messenger RELEASE_KEY_PASSWORD=TelegramAndroidPswd RELEASE_KEY_ALIAS=tmessages diff --git a/settings.gradle b/settings.gradle index 93d1f4b8e..9a0eef931 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,4 @@ include ':TMessagesProj' include ':TMessagesProj_App' include ':TMessagesProj_AppHuawei' +include ':TMessagesProj_AppHockeyApp'