update to 9.0.2

This commit is contained in:
xaxtix 2022-09-21 18:20:30 +04:00
parent 11edd5ee0d
commit e9a35cea54
82 changed files with 3160 additions and 738 deletions

View File

@ -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'

View File

@ -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() {

View File

@ -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) {
}
}

View File

@ -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";

View File

@ -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);

View File

@ -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) {

View File

@ -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<ArrayList<Long>> onResult) {
if (query == null) {
if (onResult != null) {
onResult.run(new ArrayList<>());
}
return;
}
final ArrayList<TLRPC.TL_messages_stickerSet> stickerSets = getStickerSets(TYPE_EMOJIPACKS);
final ArrayList<TLRPC.StickerSetCovered> featuredStickerSets = getFeaturedEmojiSets();
Utilities.searchQueue.postRunnable(() -> {
ArrayList<Long> fullMatch = new ArrayList<>();
ArrayList<Long> halfMatch = new ArrayList<>();
String queryLowercased = query.toLowerCase();
for (int i = 0; i < stickerSets.size(); ++i) {
if (stickerSets.get(i).keywords != null) {
ArrayList<TLRPC.TL_stickerKeyword> 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<TLRPC.TL_stickerKeyword> 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<KeywordResult> animatedResult = new ArrayList<>();
ArrayList<TLRPC.Document> 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;
}
}
}
}

View File

@ -358,6 +358,12 @@ public class MessageObject {
}
}
}
isSpoilersRevealed = old.isSpoilersRevealed;
if (isSpoilersRevealed && textLayoutBlocks != null) {
for (TextLayoutBlock block : textLayoutBlocks) {
block.spoilers.clear();
}
}
}
public ArrayList<ReactionsLayoutInBubble.VisibleReaction> getChoosenReactions() {

View File

@ -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++) {

View File

@ -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()) {

View File

@ -418,7 +418,7 @@ public class NotificationsController extends BaseController {
});
}
public void removeDeletedMessagesFromNotifications(LongSparseArray<ArrayList<Integer>> deletedMessages) {
public void removeDeletedMessagesFromNotifications(LongSparseArray<ArrayList<Integer>> deletedMessages, boolean isReactions) {
ArrayList<MessageObject> 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) {

View File

@ -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<ArrayList<Integer>> deletedMessages = new LongSparseArray<>();
ArrayList<Integer> 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")) {

View File

@ -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 + ")");
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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<TL_stickerPack> packs = new ArrayList<>();
public ArrayList<TL_stickerKeyword> keywords = new ArrayList<>();
public ArrayList<Document> 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<TL_stickerPack> packs = new ArrayList<>();
public ArrayList<Document> documents = new ArrayList<>();
public long document_id;
public ArrayList<String> 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<TL_stickerPack> packs = new ArrayList<>();
public ArrayList<TL_stickerKeyword> keywords = new ArrayList<>();
public ArrayList<Document> 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;

View File

@ -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();

View File

@ -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);
}

View File

@ -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) {

View File

@ -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;
}

View File

@ -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 -> {

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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("$")) {

View File

@ -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() {

View File

@ -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) {

View File

@ -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);

View File

@ -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) {

View File

@ -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));

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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];

View File

@ -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 {

View File

@ -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(() -> {

View File

@ -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);

View File

@ -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

View File

@ -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<Size> 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) -> {

View File

@ -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<MotionBackgroundDrawable, Float> 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<MotionBackgroundDrawable, Float> 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) {

View File

@ -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<Runnable> backgroundSpringQueue = new LinkedList<>();
private LinkedList<Boolean> 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<Runnable> remove = new ArrayList<>();
List<Integer> 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<Runnable> remove = new ArrayList<>();
List<Integer> 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;
}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -35,14 +35,6 @@ import java.util.ArrayList;
public class DoubledLimitsBottomSheet extends BottomSheetWithRecyclerListView implements NotificationCenter.NotificationCenterDelegate {
final ArrayList<Limit> 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<Limit> 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;
}
}
}

View File

@ -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<PremiumPreviewFragment.PremiumFeatureData> 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;
}
}

View File

@ -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));
}
// }
}
});

View File

@ -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<TLRPC.InputStickerSet> sets = new ArrayList<>();
HashSet<Long> 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;

View File

@ -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<ReactionsLayoutInBubble.VisibleReaction> reactions, HashSet<ReactionsLayoutInBubble.VisibleReaction> 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();

View File

@ -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) {

View File

@ -427,10 +427,18 @@ public class SearchDownloadsContainer extends FrameLayout implements Notificatio
private void updateRows(ArrayList<MessageObject> currentLoadingFilesTmp, ArrayList<MessageObject> 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;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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];

View File

@ -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

View File

@ -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) {

View File

@ -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<String> WEBVIEW_PROTOCOLS = Arrays.asList(
"http",
"https"
);
private final static List<String> 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) {
}

View File

@ -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();
}

View File

@ -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);

View File

@ -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++;

View File

@ -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<CharSequence> items = new ArrayList<>();
final ArrayList<Integer> actions = new ArrayList<>();
ArrayList<Integer> actions = new ArrayList<>();
List<Integer> 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);

View File

@ -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<Dialog> 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;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 757 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

File diff suppressed because one or more lines are too long

View File

@ -143,6 +143,7 @@
<string name="PaymentEmailToProvider">Email address will be passed to %1$s as billing info.</string>
<string name="PaymentPhoneEmailToProvider">Phone and email address will be passed to %1$s as billing info.</string>
<string name="PaymentInfoHint">You paid **%1$s** for **%2$s**.</string>
<string name="PaymentAppNotFoundForDeeplink">No app found to handle this deep link.</string>
<!--chats view-->
<string name="NewConversationShortcut">New conversation</string>
<string name="AutoNightModeOff">Auto-Night Mode is off</string>
@ -1722,6 +1723,7 @@
<string name="NoStickersFound">No stickers found</string>
<string name="NoGIFsFound">No GIFs found</string>
<string name="NoEmojiFound">No emoji found</string>
<string name="NoReactionsFound">No reactions found</string>
<string name="NoMasks">No masks yet</string>
<string name="EmojiSuggestions">Emoji suggestions</string>
<string name="EmojiSuggestionsInfo">**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:</string>
@ -5619,4 +5621,11 @@
<string name="PremiumPreviewReactions2">Infinite Reactions</string>
<string name="PremiumPreviewEmojiStatus">Emoji Status</string>
<string name="PremiumPreviewEmojiStatusDescription">Add any of thousands emojis next to your name to display current activity.</string>
<string name="MicrophoneForVoiceMessages">Microphone for voice messages</string>
<string name="MicrophoneForVoiceMessagesBuiltIn">Built-In</string>
<string name="MicrophoneForVoiceMessagesSco">Headset</string>
<string name="MicrophoneForVoiceMessagesScoIfConnected">Headset (if connected)</string>
<string name="MicrophoneForVoiceMessagesScoHint">Using a headset microphone may reduce background noise but will slightly decrease audio quality.</string>
<string name="ReactionInDialog">%s Reaction</string>
<string name="SearchReactionsHint">Search reactions</string>
</resources>

View File

@ -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'
}

View File

@ -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);
}
}

1
TMessagesProj_AppHockeyApp/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

View File

@ -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'

View File

@ -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"
}

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.telegram.messenger.regular"
android:installLocation="auto">
<application android:name="org.telegram.messenger.ApplicationLoaderImpl" tools:replace="name">
<service android:name="org.telegram.messenger.GoogleVoiceClientService"/>
<activity
android:name="org.telegram.messenger.GoogleVoiceClientActivity"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.voicesearch.SEND_MESSAGE_TO_CONTACTS" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -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) {
}
}
}

View File

@ -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<? extends SearchActionVerificationClientService> getServiceClass() {
return GoogleVoiceClientService.class;
}
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -1,3 +1,4 @@
include ':TMessagesProj'
include ':TMessagesProj_App'
include ':TMessagesProj_AppHuawei'
include ':TMessagesProj_AppHockeyApp'