diff --git a/TMessagesProj/jni/rlottie/src/lottie/lottiemodel.h b/TMessagesProj/jni/rlottie/src/lottie/lottiemodel.h index 9eabf1fac..b482b58e9 100755 --- a/TMessagesProj/jni/rlottie/src/lottie/lottiemodel.h +++ b/TMessagesProj/jni/rlottie/src/lottie/lottiemodel.h @@ -98,9 +98,9 @@ public: inline void getColorReplacement(std::map *colorMap, const LottieColor &c, float &r, float &g, float &b) { if (colorMap != nullptr && !colorMap->empty()) { - int32_t rr = (int32_t) (c.r * 255); - int32_t gg = (int32_t) (c.g * 255); - int32_t bb = (int32_t) (c.b * 255); + int32_t rr = (int32_t) round(c.r * 255); + int32_t gg = (int32_t) round(c.g * 255); + int32_t bb = (int32_t) round(c.b * 255); int32_t cc = (int32_t) (((bb & 0xff) << 16) | ((gg & 0xff) << 8) | (rr & 0xff)); std::map::iterator iter = colorMap->find(cc); if (iter != colorMap->end()) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java b/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java index b67377a16..549ad5711 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java @@ -1949,20 +1949,18 @@ public class AndroidUtilities { FileLog.d("external dir mounted"); try { File file; - if (Build.VERSION.SDK_INT >= 19) { - File[] dirs = ApplicationLoader.applicationContext.getExternalCacheDirs(); - file = dirs[0]; - if (!TextUtils.isEmpty(SharedConfig.storageCacheDir)) { - for (int a = 0; a < dirs.length; a++) { - if (dirs[a] != null && dirs[a].getAbsolutePath().startsWith(SharedConfig.storageCacheDir)) { - file = dirs[a]; - break; - } + + File[] dirs = ApplicationLoader.applicationContext.getExternalCacheDirs(); + file = dirs[0]; + if (!TextUtils.isEmpty(SharedConfig.storageCacheDir)) { + for (int a = 0; a < dirs.length; a++) { + if (dirs[a] != null && dirs[a].getAbsolutePath().startsWith(SharedConfig.storageCacheDir)) { + file = dirs[a]; + break; } } - } else { - file = ApplicationLoader.applicationContext.getExternalCacheDir(); } + FileLog.d("check dir " + (file == null ? null : file.getPath()) + " "); if (file != null && (file.exists() || file.mkdirs()) && file.canWrite()) { // boolean canWrite = true; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/AutoDeleteMediaTask.java b/TMessagesProj/src/main/java/org/telegram/messenger/AutoDeleteMediaTask.java index b8f5f58e9..52d1cb45e 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/AutoDeleteMediaTask.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/AutoDeleteMediaTask.java @@ -14,7 +14,7 @@ public class AutoDeleteMediaTask { public static void run() { int time = (int) (System.currentTimeMillis() / 1000); - if (!BuildVars.DEBUG_PRIVATE_VERSION && Math.abs(time - SharedConfig.lastKeepMediaCheckTime) < 24 * 60 * 60) { + if (Math.abs(time - SharedConfig.lastKeepMediaCheckTime) < 24 * 60 * 60) { return; } SharedConfig.lastKeepMediaCheckTime = time; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/BillingController.java b/TMessagesProj/src/main/java/org/telegram/messenger/BillingController.java index 1a568b401..a36f0b825 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/BillingController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/BillingController.java @@ -315,6 +315,7 @@ public class BillingController implements PurchasesUpdatedListener, BillingClien @Override public void onBillingSetupFinished(@NonNull BillingResult setupBillingResult) { + FileLog.d("Billing setup finished with result " + setupBillingResult); if (setupBillingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) { queryProductDetails(Collections.singletonList(PREMIUM_PRODUCT), (billingResult, list) -> { if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java index 8c15b27d1..23b0276ba 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java @@ -24,8 +24,8 @@ public class BuildVars { public static boolean USE_CLOUD_STRINGS = true; public static boolean CHECK_UPDATES = true; public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29; - public static int BUILD_VERSION = 3237; - public static String BUILD_VERSION_STRING = "9.5.6"; + public static int BUILD_VERSION = 3249; + public static String BUILD_VERSION_STRING = "9.5.7"; public static int APP_ID = 4; public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103"; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ContactsController.java b/TMessagesProj/src/main/java/org/telegram/messenger/ContactsController.java index ae006b92c..49a760064 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ContactsController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ContactsController.java @@ -23,13 +23,13 @@ import android.net.Uri; import android.os.Build; import android.provider.BaseColumns; import android.provider.ContactsContract; -import android.telephony.PhoneNumberUtils; import android.text.TextUtils; -import android.util.Log; import android.util.SparseArray; import androidx.collection.LongSparseArray; +import com.google.android.exoplayer2.util.Log; + import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.TLRPC; @@ -628,6 +628,7 @@ public class ContactsController extends BaseController { ArrayList idsArr = new ArrayList<>(); pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projectionPhones, null, null, null); + long time = System.currentTimeMillis(); int lastContactId = 1; if (pCur != null) { int count = pCur.getCount(); @@ -796,68 +797,96 @@ public class ContactsController extends BaseController { } pCur = null; } + FileLog.d("loading contacts 1 query time = " + (System.currentTimeMillis() - time) + " contactsSize = " + (contactsMap == null ? 0 : contactsMap.size())); + time = System.currentTimeMillis(); + + HashMap phoneBookContactHashMap = new HashMap<>(); + ArrayList phonebookContactsId = new ArrayList<>(); + + Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, new String[]{ + ContactsContract.Contacts._ID, + ContactsContract.Contacts.LOOKUP_KEY, + ContactsContract.Contacts.DISPLAY_NAME + }, ContactsContract.Contacts.HAS_PHONE_NUMBER + " = ?", new String[]{"0"}, null); - Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,ContactsContract.Contacts.HAS_PHONE_NUMBER + " = ?", new String[]{"0"}, null); if (cur != null) { - String[] metadata = new String[5]; - Pattern phonePattern = Pattern.compile(".*(\\+[0-9 \\-]+).*"); while (cur.moveToNext()) { - String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID)); - String lookup_key = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY)); - String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); - String phone = null; - if ((contactsMap != null && contactsMap.get(lookup_key) != null) || TextUtils.isEmpty(name)) { + PhoneBookContact phoneBookContact = new PhoneBookContact(); + phoneBookContact.id = cur.getString(0); + phoneBookContact.lookup_key = cur.getString(1); + phoneBookContact.name = cur.getString(2); + if ((contactsMap != null && contactsMap.get(phoneBookContact.lookup_key) != null) || TextUtils.isEmpty(phoneBookContact.name)) { continue; } - pCur = cr.query( - ContactsContract.Data.CONTENT_URI, - null, - ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", - new String[]{id}, null); - loop : while (pCur.moveToNext()) { - metadata[0] = pCur.getString(pCur.getColumnIndex(ContactsContract.Data.DATA1)); - metadata[1] = pCur.getString(pCur.getColumnIndex(ContactsContract.Data.DATA2)); - metadata[2] = pCur.getString(pCur.getColumnIndex(ContactsContract.Data.DATA3)); - metadata[3] = pCur.getString(pCur.getColumnIndex(ContactsContract.Data.DATA4)); - metadata[4] = pCur.getString(pCur.getColumnIndex(ContactsContract.Data.DATA5)); - for (int i = 0; i < metadata.length; i++) { - if (metadata[i] == null) { - continue; - } - Matcher matcher = phonePattern.matcher(metadata[i]); - if (matcher.matches()) { - phone = matcher.group(1).replace(" ", "").replace("-", ""); - break loop; - } - } - } - - pCur.close(); - - if (phone != null) { - - String shortNumber = phone; - if (phone.startsWith("+")) { - shortNumber = phone.substring(1); - } - - Contact contact = new Contact(); - contact.first_name = name; - contact.last_name = ""; - contact.contact_id = lastContactId++; - contact.key = lookup_key; - contact.phones.add(phone); - contact.shortPhones.add(shortNumber); - contact.phoneDeleted.add(0); - contact.phoneTypes.add(LocaleController.getString("PhoneOther", R.string.PhoneOther)); - -// contact.provider = accountType; -// contact.isGoodProvider = isGoodAccountType; - contactsMap.put(lookup_key, contact); - } + phoneBookContactHashMap.put(phoneBookContact.id, phoneBookContact); + phonebookContactsId.add(phoneBookContact.id); } cur.close(); } + FileLog.d("loading contacts 2 query time = " + (System.currentTimeMillis() - time) + " phoneBookConacts size = " + phonebookContactsId.size()); + time = System.currentTimeMillis(); + + if (!phonebookContactsId.isEmpty()) { + String[] metadata = new String[4]; + Pattern phonePattern = Pattern.compile(".*(\\+[0-9 \\-]+).*"); + pCur = cr.query( + ContactsContract.Data.CONTENT_URI, + new String[]{ + ContactsContract.CommonDataKinds.Phone.CONTACT_ID, + ContactsContract.Data.DATA1, + ContactsContract.Data.DATA2, + ContactsContract.Data.DATA3, + ContactsContract.Data.DATA4, + }, + ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " IN (" + TextUtils.join(", ", phonebookContactsId) + ")", + null, null); + if (pCur != null) { + while (pCur.moveToNext()) { + String id = pCur.getString(0); + PhoneBookContact phoneBookContact = phoneBookContactHashMap.get(id); + if (phoneBookContact != null) { + metadata[0] = pCur.getString(1); + metadata[1] = pCur.getString(2); + metadata[2] = pCur.getString(3); + metadata[3] = pCur.getString(4); + for (int i = 0; i < metadata.length; i++) { + if (metadata[i] == null) { + continue; + } + Matcher matcher = phonePattern.matcher(metadata[i]); + if (matcher.matches()) { + phoneBookContact.phone = matcher.group(1).replace(" ", "").replace("-", ""); + } + + if (phoneBookContact.phone != null) { + String shortNumber = phoneBookContact.phone; + if (phoneBookContact.phone.startsWith("+")) { + shortNumber = phoneBookContact.phone.substring(1); + } + + Contact contact = new Contact(); + contact.first_name = phoneBookContact.name; + contact.last_name = ""; + contact.contact_id = lastContactId++; + contact.key = phoneBookContact.lookup_key; + contact.phones.add(phoneBookContact.phone); + contact.shortPhones.add(shortNumber); + contact.phoneDeleted.add(0); + contact.phoneTypes.add(LocaleController.getString("PhoneOther", R.string.PhoneOther)); + if (contactsMap == null) { + contactsMap = new HashMap<>(); + } + contactsMap.put(phoneBookContact.lookup_key, contact); + break; + } + } + } + } + pCur.close(); + } + } + + FileLog.d("loading contacts 3 query time = " + (System.currentTimeMillis() - time)); } catch (Throwable e) { FileLog.e(e); @@ -1942,6 +1971,7 @@ public class ContactsController extends BaseController { private void performWriteContactsToPhoneBookInternal(ArrayList contactsArray) { Cursor cursor = null; + long time = System.currentTimeMillis(); try { Account account = systemAccount; if (!hasContactsPermission() || account == null) { @@ -1953,7 +1983,7 @@ public class ContactsController extends BaseController { settings.edit().putBoolean("contacts_updated_v7", true).commit(); } final ContentResolver contentResolver = ApplicationLoader.applicationContext.getContentResolver(); - Uri rawContactUri = ContactsContract.RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, systemAccount.name).appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, systemAccount.type).build(); + Uri rawContactUri = ContactsContract.RawContacts.CONTENT_URI; cursor = contentResolver.query(rawContactUri, new String[]{BaseColumns._ID, ContactsContract.RawContacts.SYNC2}, null, null, null); LongSparseArray bookContacts = new LongSparseArray<>(); if (cursor != null) { @@ -1963,12 +1993,26 @@ public class ContactsController extends BaseController { cursor.close(); cursor = null; + FileLog.d("performWriteContactsToPhoneBookInternal contacts array " + contactsArray.size() + " " + forceUpdate + " bookContactsSize=" + bookContacts.size() + " currentAccount=" + currentAccount); + ArrayList query = null; for (int a = 0; a < contactsArray.size(); a++) { TLRPC.TL_contact u = contactsArray.get(a); if (forceUpdate || bookContacts.indexOfKey(u.user_id) < 0) { - addContactToPhoneBook(getMessagesController().getUser(u.user_id), forceUpdate); + if (query == null) { + query = new ArrayList<>(); + } + applyContactToPhoneBook(query, getMessagesController().getUser(u.user_id)); + if (query.size() > 450) { + contentResolver.applyBatch(ContactsContract.AUTHORITY, query); + query.clear(); + } } } + if (query != null && !query.isEmpty()) { + contentResolver.applyBatch(ContactsContract.AUTHORITY, query); + query.clear(); + } + } } catch (Exception e) { FileLog.e(e); @@ -1977,6 +2021,8 @@ public class ContactsController extends BaseController { cursor.close(); } } + + FileLog.d("performWriteContactsToPhoneBookInternal " + (System.currentTimeMillis() - time)) ; } private void performWriteContactsToPhoneBook() { @@ -2167,56 +2213,7 @@ public class ContactsController extends BaseController { } ArrayList query = new ArrayList<>(); - - ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI); - builder.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, systemAccount.name); - builder.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, systemAccount.type); - builder.withValue(ContactsContract.RawContacts.SYNC1, TextUtils.isEmpty(user.phone) ? "" : user.phone); - builder.withValue(ContactsContract.RawContacts.SYNC2, user.id); - query.add(builder.build()); - - builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI); - builder.withValueBackReference(ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, 0); - builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE); - builder.withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, user.first_name); - builder.withValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, user.last_name); - query.add(builder.build()); - -// builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI); -// builder.withValueBackReference(ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, 0); -// builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE); -// builder.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, "+" + user.phone); -// builder.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE); -// query.add(builder.build()); - - final String phoneOrName = TextUtils.isEmpty(user.phone) ? ContactsController.formatName(user.first_name, user.last_name) : "+" + user.phone; - - builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI); - builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0); - builder.withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/vnd.org.telegram.messenger.android.profile"); - builder.withValue(ContactsContract.Data.DATA1, user.id); - builder.withValue(ContactsContract.Data.DATA2, "Telegram Profile"); - builder.withValue(ContactsContract.Data.DATA3, LocaleController.formatString("ContactShortcutMessage", R.string.ContactShortcutMessage, phoneOrName)); - builder.withValue(ContactsContract.Data.DATA4, user.id); - query.add(builder.build()); - - builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI); - builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0); - builder.withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/vnd.org.telegram.messenger.android.call"); - builder.withValue(ContactsContract.Data.DATA1, user.id); - builder.withValue(ContactsContract.Data.DATA2, "Telegram Voice Call"); - builder.withValue(ContactsContract.Data.DATA3, LocaleController.formatString("ContactShortcutVoiceCall", R.string.ContactShortcutVoiceCall, phoneOrName)); - builder.withValue(ContactsContract.Data.DATA4, user.id); - query.add(builder.build()); - - builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI); - builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0); - builder.withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/vnd.org.telegram.messenger.android.call.video"); - builder.withValue(ContactsContract.Data.DATA1, user.id); - builder.withValue(ContactsContract.Data.DATA2, "Telegram Video Call"); - builder.withValue(ContactsContract.Data.DATA3, LocaleController.formatString("ContactShortcutVideoCall", R.string.ContactShortcutVideoCall, phoneOrName)); - builder.withValue(ContactsContract.Data.DATA4, user.id); - query.add(builder.build()); + applyContactToPhoneBook(query, user); try { ContentProviderResult[] result = contentResolver.applyBatch(ContactsContract.AUTHORITY, query); @@ -2232,6 +2229,55 @@ public class ContactsController extends BaseController { return res; } + private void applyContactToPhoneBook(ArrayList query, TLRPC.User user) { + if (user == null) { + return; + } + int rawContactId = query.size(); + ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI); + builder.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, systemAccount.name); + builder.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, systemAccount.type); + builder.withValue(ContactsContract.RawContacts.SYNC1, TextUtils.isEmpty(user.phone) ? "" : user.phone); + builder.withValue(ContactsContract.RawContacts.SYNC2, user.id); + query.add(builder.build()); + + builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI); + builder.withValueBackReference(ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, rawContactId); + builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE); + builder.withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, user.first_name); + builder.withValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, user.last_name); + query.add(builder.build()); + + final String phoneOrName = TextUtils.isEmpty(user.phone) ? ContactsController.formatName(user.first_name, user.last_name) : "+" + user.phone; + + builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI); + builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); + builder.withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/vnd.org.telegram.messenger.android.profile"); + builder.withValue(ContactsContract.Data.DATA1, user.id); + builder.withValue(ContactsContract.Data.DATA2, "Telegram Profile"); + builder.withValue(ContactsContract.Data.DATA3, LocaleController.formatString("ContactShortcutMessage", R.string.ContactShortcutMessage, phoneOrName)); + builder.withValue(ContactsContract.Data.DATA4, user.id); + query.add(builder.build()); + + builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI); + builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); + builder.withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/vnd.org.telegram.messenger.android.call"); + builder.withValue(ContactsContract.Data.DATA1, user.id); + builder.withValue(ContactsContract.Data.DATA2, "Telegram Voice Call"); + builder.withValue(ContactsContract.Data.DATA3, LocaleController.formatString("ContactShortcutVoiceCall", R.string.ContactShortcutVoiceCall, phoneOrName)); + builder.withValue(ContactsContract.Data.DATA4, user.id); + query.add(builder.build()); + + builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI); + builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactId); + builder.withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/vnd.org.telegram.messenger.android.call.video"); + builder.withValue(ContactsContract.Data.DATA1, user.id); + builder.withValue(ContactsContract.Data.DATA2, "Telegram Video Call"); + builder.withValue(ContactsContract.Data.DATA3, LocaleController.formatString("ContactShortcutVideoCall", R.string.ContactShortcutVideoCall, phoneOrName)); + builder.withValue(ContactsContract.Data.DATA4, user.id); + query.add(builder.build()); + } + private void deleteContactFromPhoneBook(long uid) { if (!hasContactsPermission()) { return; @@ -2833,4 +2879,11 @@ public class ContactsController extends BaseController { } return result.toString(); } + + private class PhoneBookContact { + String id; + String lookup_key; + String name; + String phone; + } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/DatabaseMigrationHelper.java b/TMessagesProj/src/main/java/org/telegram/messenger/DatabaseMigrationHelper.java index 0a577a01a..88f48947b 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/DatabaseMigrationHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/DatabaseMigrationHelper.java @@ -1247,6 +1247,13 @@ public class DatabaseMigrationHelper { database.executeFast("PRAGMA user_version = 115").stepThis().dispose(); version = 115; } + if (version == 115) { + database.executeFast("CREATE INDEX IF NOT EXISTS idx_to_reply_messages_v2 ON messages_v2(reply_to_message_id, mid);").stepThis().dispose(); + database.executeFast("CREATE INDEX IF NOT EXISTS idx_to_reply_scheduled_messages_v2 ON scheduled_messages_v2(reply_to_message_id, mid);").stepThis().dispose(); + database.executeFast("CREATE INDEX IF NOT EXISTS idx_to_reply_messages_topics ON messages_topics(reply_to_message_id, mid);").stepThis().dispose(); + database.executeFast("PRAGMA user_version = 116").stepThis().dispose(); + version = 116; + } return version; } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java index 86a67a9b8..2ebf1bcd2 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java @@ -801,7 +801,7 @@ public class FileLoader extends BaseController { public void didPreFinishLoading(FileLoadOperation operation, File finalFile) { FileLoaderPriorityQueue queue = operation.getQueue(); fileLoaderQueue.postRunnable(() -> { - FileLoadOperation currentOperation = loadOperationPaths.remove(fileName); + FileLoadOperation currentOperation = loadOperationPaths.get(fileName); if (currentOperation != null) { currentOperation.preFinished = true; queue.checkLoadingOperations(); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoaderPriorityQueue.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoaderPriorityQueue.java index 426e9e035..5cacee6a2 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoaderPriorityQueue.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoaderPriorityQueue.java @@ -1,7 +1,5 @@ package org.telegram.messenger; -import org.telegram.tgnet.ConnectionsManager; - import java.util.ArrayList; public class FileLoaderPriorityQueue { @@ -85,10 +83,6 @@ public class FileLoaderPriorityQueue { if (operation == null) { return; } - ConnectionsManager connectionsManager = ConnectionsManager.getInstance(operation.currentAccount); - if (connectionsManager != null && connectionsManager.getConnectionState() == ConnectionsManager.ConnectionStateWaitingForNetwork) { - operation.cancel(); - } allOperations.remove(operation); } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java index 6644f9b48..235eb82b0 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java @@ -8,6 +8,8 @@ package org.telegram.messenger; +import android.content.Context; +import android.content.res.ColorStateList; import android.util.Log; import com.google.gson.ExclusionStrategy; @@ -116,7 +118,7 @@ public class FileLog { } public static void dumpUnparsedMessage(TLObject message, long messageId) { - if (!BuildVars.DEBUG_PRIVATE_VERSION || !BuildVars.LOGS_ENABLED || message == null) { + if (!BuildVars.DEBUG_PRIVATE_VERSION || !BuildVars.LOGS_ENABLED || message == null || SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_LOW) { return; } try { @@ -160,6 +162,7 @@ public class FileLog { privateFields.add("networkType"); privateFields.add("disableFree"); + privateFields.add("mContext"); //exclude file loading excludeRequests = new HashSet<>(); @@ -178,6 +181,9 @@ public class FileLog { @Override public boolean shouldSkipClass(Class clazz) { + if (clazz.isInstance(ColorStateList.class) || clazz.isInstance(Context.class)) { + return true; + } return false; } }).create(); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ImageLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/ImageLoader.java index e5b55df05..c0adf1938 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ImageLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ImageLoader.java @@ -582,7 +582,7 @@ public class ImageLoader { } } } catch (Exception e) { - FileLog.e(e); + FileLog.e(e, false); } if (imageSize == 0 && httpConnection != null) { try { @@ -2230,6 +2230,8 @@ public class ImageLoader { FileLog.d("cache path = " + cachePath); } + FileLog.d("selected SD card = " + SharedConfig.storageCacheDir); + try { if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { File path = Environment.getExternalStorageDirectory(); @@ -2238,14 +2240,28 @@ public class ImageLoader { if (dirs != null) { for (int a = 0, N = dirs.size(); a < N; a++) { File dir = dirs.get(a); + FileLog.d("root dir " + a + " " + dir); if (dir.getAbsolutePath().startsWith(SharedConfig.storageCacheDir)) { path = dir; break; } } } + if (!path.getAbsolutePath().startsWith(SharedConfig.storageCacheDir)) { + File[] dirsDebug = ApplicationLoader.applicationContext.getExternalFilesDirs(null); + if (dirsDebug != null) { + for (int a = 0; a < dirsDebug.length; a++) { + if (dirsDebug[a] == null) { + continue; + } + FileLog.d("dirsDebug " + a + " " + dirsDebug[a]); + } + } + } } + FileLog.d("external storage = " + path); + File publicMediaDir = null; if (Build.VERSION.SDK_INT >= 30) { File newPath; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/LinkifyPort.java b/TMessagesProj/src/main/java/org/telegram/messenger/LinkifyPort.java index 1646b7e68..a2e3bf157 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/LinkifyPort.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/LinkifyPort.java @@ -162,7 +162,7 @@ public class LinkifyPort { + "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@"; private static final String PORT_NUMBER = "\\:\\d{1,5}"; private static final String PATH_AND_QUERY = "[/\\?](?:(?:[" + LABEL_CHAR + ";/\\?:@&=#~" + "\\-\\.\\+!\\*'\\(\\),_\\$])|(?:%[a-fA-F0-9]{2}))*"; - private static final String RELAXED_DOMAIN_NAME = "(?:" + "(?:" + IRI_LABEL + "(?:\\.(?=\\S))" + "?)+" + "|" + IP_ADDRESS_STRING + ")"; + private static final String RELAXED_DOMAIN_NAME = "(?:" + "(?:" + IRI_LABEL + "(?:\\.(?=\\S))" + ")*" + "(?:" + IRI_LABEL + "(?:\\.(?=\\S))" + "?)" + "|" + IP_ADDRESS_STRING + ")"; private static final String WEB_URL_WITHOUT_PROTOCOL = "(" + WORD_BOUNDARY diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/LiteMode.java b/TMessagesProj/src/main/java/org/telegram/messenger/LiteMode.java index 43290e42c..3f17d5e9d 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/LiteMode.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/LiteMode.java @@ -5,9 +5,6 @@ import android.content.Context; import android.content.SharedPreferences; import android.os.BatteryManager; import android.os.Build; -import android.os.PowerManager; -import android.util.SparseArray; -import android.util.SparseIntArray; import androidx.annotation.RequiresApi; import androidx.core.math.MathUtils; @@ -20,9 +17,6 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; -import org.telegram.ui.ActionBar.Theme; -import org.telegram.ui.Components.AnimatedEmojiDrawable; - public class LiteMode { public static final int FLAG_ANIMATED_STICKERS_KEYBOARD = 1; @@ -138,6 +132,10 @@ public class LiteMode { } public static boolean isEnabled(int flag) { + if (flag == FLAG_CHAT_FORUM_TWOCOLUMN && AndroidUtilities.isTablet()) { + // always enabled for tablets + return true; + } return (getValue() & preprocessFlag(flag)) > 0; } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java b/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java index eef27a325..c8bd86c9b 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java @@ -34,6 +34,7 @@ import android.text.TextUtils; import android.text.style.CharacterStyle; import android.text.style.URLSpan; import android.text.util.Linkify; +import android.util.Log; import android.util.Pair; import android.util.SparseArray; @@ -4291,6 +4292,7 @@ public class MediaDataController extends BaseController { } } } + boolean recreateShortcuts = Build.VERSION.SDK_INT >= 30; Utilities.globalQueue.postRunnable(() -> { try { if (SharedConfig.directShareHash == null) { @@ -4298,19 +4300,58 @@ public class MediaDataController extends BaseController { ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).edit().putString("directShareHash2", SharedConfig.directShareHash).commit(); } - ShortcutManagerCompat.removeAllDynamicShortcuts(ApplicationLoader.applicationContext); + ArrayList shortcutsToUpdate = new ArrayList<>(); + ArrayList newShortcutsIds = new ArrayList<>(); + ArrayList shortcutsToDelete = new ArrayList<>(); + if (recreateShortcuts) { + ShortcutManagerCompat.removeAllDynamicShortcuts(ApplicationLoader.applicationContext); + } else { + List currentShortcuts = ShortcutManagerCompat.getDynamicShortcuts(ApplicationLoader.applicationContext); + if (currentShortcuts != null && !currentShortcuts.isEmpty()) { + newShortcutsIds.add("compose"); + for (int a = 0; a < hintsFinal.size(); a++) { + TLRPC.TL_topPeer hint = hintsFinal.get(a); + newShortcutsIds.add("did3_" + MessageObject.getPeerId(hint.peer)); + } + for (int a = 0; a < currentShortcuts.size(); a++) { + String id = currentShortcuts.get(a).getId(); + if (!newShortcutsIds.remove(id)) { + shortcutsToDelete.add(id); + } + shortcutsToUpdate.add(id); + } + if (newShortcutsIds.isEmpty() && shortcutsToDelete.isEmpty()) { + return; + } + } + + if (!shortcutsToDelete.isEmpty()) { + ShortcutManagerCompat.removeDynamicShortcuts(ApplicationLoader.applicationContext, shortcutsToDelete); + } + } Intent intent = new Intent(ApplicationLoader.applicationContext, LaunchActivity.class); intent.setAction("new_dialog"); ArrayList arrayList = new ArrayList<>(); - ShortcutManagerCompat.pushDynamicShortcut(ApplicationLoader.applicationContext, new ShortcutInfoCompat.Builder(ApplicationLoader.applicationContext, "compose") + ShortcutInfoCompat shortcut = new ShortcutInfoCompat.Builder(ApplicationLoader.applicationContext, "compose") .setShortLabel(LocaleController.getString("NewConversationShortcut", R.string.NewConversationShortcut)) .setLongLabel(LocaleController.getString("NewConversationShortcut", R.string.NewConversationShortcut)) .setIcon(IconCompat.createWithResource(ApplicationLoader.applicationContext, R.drawable.shortcut_compose)) .setRank(0) .setIntent(intent) - .build()); + .build(); + if (recreateShortcuts) { + ShortcutManagerCompat.pushDynamicShortcut(ApplicationLoader.applicationContext, shortcut); + } else { + arrayList.add(shortcut); + if (shortcutsToUpdate.contains("compose")) { + ShortcutManagerCompat.updateShortcuts(ApplicationLoader.applicationContext, arrayList); + } else { + ShortcutManagerCompat.addDynamicShortcuts(ApplicationLoader.applicationContext, arrayList); + } + arrayList.clear(); + } HashSet category = new HashSet<>(1); @@ -4405,7 +4446,18 @@ public class MediaDataController extends BaseController { } else { builder.setIcon(IconCompat.createWithResource(ApplicationLoader.applicationContext, R.drawable.shortcut_user)); } - ShortcutManagerCompat.pushDynamicShortcut(ApplicationLoader.applicationContext, builder.build()); + + if (recreateShortcuts) { + ShortcutManagerCompat.pushDynamicShortcut(ApplicationLoader.applicationContext, builder.build()); + } else { + arrayList.add(builder.build()); + if (shortcutsToUpdate.contains(id)) { + ShortcutManagerCompat.updateShortcuts(ApplicationLoader.applicationContext, arrayList); + } else { + ShortcutManagerCompat.addDynamicShortcuts(ApplicationLoader.applicationContext, arrayList); + } + arrayList.clear(); + } } } catch (Throwable ignore) { @@ -6211,7 +6263,7 @@ public class MediaDataController extends BaseController { return entities; } - private CharSequence parsePattern(CharSequence cs, Pattern pattern, List entities, GenericProvider entityProvider) { + private CharSequence parsePattern(CharSequence cs, Pattern pattern, ArrayList entities, GenericProvider entityProvider) { Matcher m = pattern.matcher(cs); int offset = 0; while (m.find()) { @@ -6231,6 +6283,8 @@ public class MediaDataController extends BaseController { TLRPC.MessageEntity entity = entityProvider.provide(null); entity.offset = m.start() - offset; entity.length = gr.length(); + + removeOffset4After(entity.offset, entity.offset + entity.length, entities); entities.add(entity); } @@ -6239,6 +6293,18 @@ public class MediaDataController extends BaseController { return cs; } + private static void removeOffset4After(int start, int end, ArrayList entities) { + int count = entities.size(); + for (int a = 0; a < count; a++) { + TLRPC.MessageEntity entity = entities.get(a); + if (entity.offset > end) { + entity.offset -= 4; + } else if (entity.offset > start) { + entity.offset -= 2; + } + } + } + //---------------- MESSAGES END ---------------- private LongSparseArray draftsFolderIds = new LongSparseArray<>(); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java index 4e33a6a14..61f70e63f 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java @@ -3329,7 +3329,11 @@ public class MessageObject { int i = messageText.toString().indexOf("un2"); if (i != -1) { SpannableStringBuilder sb = SpannableStringBuilder.valueOf(messageText); - messageText = sb.replace(i, i + 3, BillingController.getInstance().formatCurrency(messageOwner.action.amount, messageOwner.action.currency)); + CharSequence price = BillingController.getInstance().formatCurrency(messageOwner.action.amount, messageOwner.action.currency); + if ((messageOwner.action.flags & 1) != 0) { + price = String.format("%.2f", (messageOwner.action.cryptoAmount * Math.pow(10, -9))) + " " + messageOwner.action.cryptoCurrency + " (~ " + price + ")"; + } + messageText = sb.replace(i, i + 3, price); } } else if (messageOwner.action instanceof TLRPC.TL_messageActionSuggestProfilePhoto) { if (messageOwner.action.photo != null && messageOwner.action.photo.video_sizes != null && !messageOwner.action.photo.video_sizes.isEmpty()) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java index aa18b0fd0..e5e24cd05 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java @@ -284,6 +284,8 @@ public class MessagesController extends BaseController implements NotificationCe private String uploadingWallpaper; private Theme.OverrideWallpaperInfo uploadingWallpaperInfo; + private UserNameResolver userNameResolver; + private boolean loadingAppConfig; private Fetcher appConfigFetcher = new Fetcher() { @Override @@ -739,6 +741,13 @@ public class MessagesController extends BaseController implements NotificationCe return null; } + public UserNameResolver getUserNameResolver() { + if (userNameResolver == null) { + userNameResolver = new UserNameResolver(currentAccount); + } + return userNameResolver; + } + public class SponsoredMessagesInfo { public ArrayList messages; public Integer posts_between; @@ -4113,6 +4122,7 @@ public class MessagesController extends BaseController implements NotificationCe if (user.min) { if (oldUser != null) { if (!fromCache) { + getUserNameResolver().update(oldUser, user); if (user.bot) { if (user.username != null) { oldUser.username = user.username; @@ -4142,6 +4152,7 @@ public class MessagesController extends BaseController implements NotificationCe getUserConfig().setCurrentUser(user); getUserConfig().saveConfig(true); } + getUserNameResolver().update(oldUser, user); if (oldUser != null && user.status != null && oldUser.status != null && user.status.expires != oldUser.status.expires) { return true; } @@ -4222,6 +4233,7 @@ public class MessagesController extends BaseController implements NotificationCe if (chat.min) { if (oldChat != null) { if (!fromCache) { + getUserNameResolver().update(oldChat, chat); oldChat.title = chat.title; oldChat.photo = chat.photo; oldChat.broadcast = chat.broadcast; @@ -5501,6 +5513,10 @@ public class MessagesController extends BaseController implements NotificationCe } public void unblockPeer(long id) { + unblockPeer(id, null); + } + + public void unblockPeer(long id, Runnable callback) { TLRPC.TL_contacts_unblock req = new TLRPC.TL_contacts_unblock(); TLRPC.User user = null; TLRPC.Chat chat = null; @@ -5523,9 +5539,11 @@ public class MessagesController extends BaseController implements NotificationCe req.id = getInputPeer(chat); } getNotificationCenter().postNotificationName(NotificationCenter.blockedUsersDidLoad); - getConnectionsManager().sendRequest(req, (response, error) -> { - - }); + getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> { + if (callback != null) { + callback.run(); + } + })); } public void getBlockedPeers(boolean reset) { @@ -15467,13 +15485,18 @@ public class MessagesController extends BaseController implements NotificationCe } TelephonyManager tm = (TelephonyManager) ApplicationLoader.applicationContext.getSystemService(Context.TELEPHONY_SERVICE); boolean callStateIsIdle = true; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - //TODO check - if (ActivityCompat.checkSelfPermission(ApplicationLoader.applicationContext, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) { + try { + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + //TODO check + if (ActivityCompat.checkSelfPermission(ApplicationLoader.applicationContext, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) { + callStateIsIdle = tm.getCallStateForSubscription() == TelephonyManager.CALL_STATE_IDLE; + } + } else { callStateIsIdle = tm.getCallState() == TelephonyManager.CALL_STATE_IDLE; } - } else { - callStateIsIdle = tm.getCallState() == TelephonyManager.CALL_STATE_IDLE; + } catch (Throwable e) { + FileLog.e(e); } if (svc != null || VoIPService.callIShouldHavePutIntoIntent != null || !callStateIsIdle) { if (BuildVars.LOGS_ENABLED) { @@ -17132,10 +17155,8 @@ public class MessagesController extends BaseController implements NotificationCe AlertDialog[] progressDialog = new AlertDialog[] { new AlertDialog(fragment.getParentActivity(), AlertDialog.ALERT_TYPE_SPINNER) }; - - TLRPC.TL_contacts_resolveUsername req = new TLRPC.TL_contacts_resolveUsername(); - req.username = username; - int reqId = getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> { + boolean[] canceled = new boolean[]{false}; + getMessagesController().getUserNameResolver().resolve(username, (peerId) -> { try { if (progress != null) { progress.end(); @@ -17145,15 +17166,14 @@ public class MessagesController extends BaseController implements NotificationCe } catch (Exception ignored) {} progressDialog[0] = null; fragment.setVisibleDialog(null); - if (error == null) { - TLRPC.TL_contacts_resolvedPeer res = (TLRPC.TL_contacts_resolvedPeer) response; - putUsers(res.users, false); - putChats(res.chats, false); - getMessagesStorage().putUsersAndChats(res.users, res.chats, false, true); - if (!res.chats.isEmpty()) { - openChatOrProfileWith(null, res.chats.get(0), fragment, 1, false); - } else if (!res.users.isEmpty()) { - openChatOrProfileWith(res.users.get(0), null, fragment, type, false); + if (canceled[0]) { + return; + } + if (peerId != null) { + if (peerId < 0) { + openChatOrProfileWith(null, getChat(-peerId), fragment, 1, false); + } else { + openChatOrProfileWith(getUser(peerId), null, fragment, type, false); } } else { if (fragment.getParentActivity() != null) { @@ -17167,16 +17187,16 @@ public class MessagesController extends BaseController implements NotificationCe } } } - })); + }); if (progress != null) { - progress.onCancel(() -> getConnectionsManager().cancelRequest(reqId, true)); + progress.onCancel(() -> canceled[0] = true); progress.init(); } else { AndroidUtilities.runOnUIThread(() -> { if (progressDialog[0] == null) { return; } - progressDialog[0].setOnCancelListener(dialog -> getConnectionsManager().cancelRequest(reqId, true)); + progressDialog[0].setOnCancelListener(dialog -> canceled[0] = true); fragment.showDialog(progressDialog[0]); }, 500); } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java index 167e3f80c..1280c3add 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java @@ -15,7 +15,6 @@ import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextUtils; import android.text.style.ForegroundColorSpan; -import android.util.Log; import android.util.Pair; import android.util.SparseArray; import android.util.SparseIntArray; @@ -84,6 +83,7 @@ public class MessagesStorage extends BaseController { private int archiveUnreadCount; private volatile int pendingMainUnreadCount; private volatile int pendingArchiveUnreadCount; + private boolean databaseCreated; private CountDownLatch openSync = new CountDownLatch(1); @@ -95,7 +95,7 @@ public class MessagesStorage extends BaseController { } } - public final static int LAST_DB_VERSION = 115; + public final static int LAST_DB_VERSION = 116; private boolean databaseMigrationInProgress; public boolean showClearDatabaseAlert; private LongSparseIntArray dialogIsForum = new LongSparseIntArray(); @@ -287,6 +287,7 @@ public class MessagesStorage extends BaseController { boolean createTable = false; + databaseCreated = false; if (!cacheFile.exists()) { createTable = true; } @@ -353,6 +354,7 @@ public class MessagesStorage extends BaseController { } } } + databaseCreated = true; } catch (Exception e) { FileLog.e(e); if (openTries < 3 && e.getMessage() != null && e.getMessage().contains("malformed")) { @@ -363,6 +365,7 @@ public class MessagesStorage extends BaseController { cleanupInternal(false); } openDatabase(openTries == 1 ? 2 : 3); + return; } } @@ -399,6 +402,7 @@ public class MessagesStorage extends BaseController { private boolean recoverDatabase() { database.close(); boolean restored = DatabaseMigrationHelper.recoverDatabase(cacheFile, walCacheFile, shmCacheFile, currentAccount); + FileLog.e("Database restored = " + restored); if (restored) { try { database = new SQLiteDatabase(cacheFile.getPath()); @@ -412,9 +416,14 @@ public class MessagesStorage extends BaseController { } } if (!restored) { + cleanupInternal(true); openDatabase(1); + restored = databaseCreated; + FileLog.e("Try create new database = " + restored); + } + if (restored) { + reset(); } - reset(); return restored; } @@ -501,6 +510,7 @@ public class MessagesStorage extends BaseController { database.executeFast("CREATE INDEX IF NOT EXISTS send_state_idx_scheduled_messages_v2 ON scheduled_messages_v2(mid, send_state, date);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS uid_date_idx_scheduled_messages_v2 ON scheduled_messages_v2(uid, date);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS reply_to_idx_scheduled_messages_v2 ON scheduled_messages_v2(mid, reply_to_message_id);").stepThis().dispose(); + database.executeFast("CREATE INDEX IF NOT EXISTS idx_to_reply_scheduled_messages_v2 ON scheduled_messages_v2(reply_to_message_id, mid);").stepThis().dispose(); database.executeFast("CREATE TABLE messages_v2(mid INTEGER, uid INTEGER, read_state INTEGER, send_state INTEGER, date INTEGER, data BLOB, out INTEGER, ttl INTEGER, media INTEGER, replydata BLOB, imp INTEGER, mention INTEGER, forwards INTEGER, replies_data BLOB, thread_reply_id INTEGER, is_channel INTEGER, reply_to_message_id INTEGER, custom_params BLOB, group_id INTEGER, PRIMARY KEY(mid, uid))").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS uid_mid_read_out_idx_messages_v2 ON messages_v2(uid, mid, read_state, out);").stepThis().dispose(); @@ -511,6 +521,7 @@ public class MessagesStorage extends BaseController { database.executeFast("CREATE INDEX IF NOT EXISTS uid_mention_idx_messages_v2 ON messages_v2(uid, mention, read_state);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS is_channel_idx_messages_v2 ON messages_v2(mid, is_channel);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS reply_to_idx_messages_v2 ON messages_v2(mid, reply_to_message_id);").stepThis().dispose(); + database.executeFast("CREATE INDEX IF NOT EXISTS idx_to_reply_messages_v2 ON messages_v2(reply_to_message_id, mid);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS uid_mid_groupid_messages_v2 ON messages_v2(uid, mid, group_id);").stepThis().dispose(); database.executeFast("CREATE TABLE download_queue(uid INTEGER, type INTEGER, date INTEGER, data BLOB, parent TEXT, PRIMARY KEY (uid, type));").stepThis().dispose(); @@ -633,6 +644,7 @@ public class MessagesStorage extends BaseController { database.executeFast("CREATE INDEX IF NOT EXISTS send_state_idx_messages_topics ON messages_topics(mid, send_state, date);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS is_channel_idx_messages_topics ON messages_topics(mid, is_channel);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS reply_to_idx_messages_topics ON messages_topics(mid, reply_to_message_id);").stepThis().dispose(); + database.executeFast("CREATE INDEX IF NOT EXISTS idx_to_reply_messages_topics ON messages_topics(reply_to_message_id, mid);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS mid_uid_messages_topics ON messages_topics(mid, uid);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS uid_mid_read_out_idx_messages_topics ON messages_topics(uid, topic_id, mid, read_state, out);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS uid_mention_idx_messages_topics ON messages_topics(uid, topic_id, mention, read_state);").stepThis().dispose(); @@ -781,6 +793,7 @@ public class MessagesStorage extends BaseController { private void checkSQLException(Throwable e, boolean logToAppCenter) { if (e instanceof SQLiteException && e.getMessage() != null && e.getMessage().contains("is malformed") && !tryRecover) { tryRecover = true; + FileLog.e("disk image malformed detected, try recover"); if (recoverDatabase()) { tryRecover = false; clearLoadingDialogsOffsets(); @@ -1797,6 +1810,18 @@ public class MessagesStorage extends BaseController { }); } + public void removeTopics(long dialogId, ArrayList topicIds) { + storageQueue.postRunnable(() -> { + try { + String topics = TextUtils.join(", ", topicIds); + database.executeFast(String.format(Locale.US, "DELETE FROM topics WHERE did = %d AND topic_id IN (%s)", dialogId, topics)).stepThis().dispose(); + database.executeFast(String.format(Locale.US, "DELETE FROM messages_topics WHERE uid = %d AND topic_id = IN (%s)", dialogId, topics)).stepThis().dispose(); + } catch (SQLiteException e) { + e.printStackTrace(); + } + }); + } + public void updateTopicsWithReadMessages(HashMap topicsReadOutbox) { storageQueue.postRunnable(() -> { for (TopicKey topicKey : topicsReadOutbox.keySet()) { @@ -2790,6 +2815,293 @@ public class MessagesStorage extends BaseController { return array; } +// public void checkLoadedRemoteFilter(TLRPC.DialogFilter newFilter) { +// storageQueue.postRunnable(() -> { +// try { +// SparseArray filtersToDelete = new SparseArray<>(); +// for (int a = 0, N = dialogFilters.size(); a < N; a++) { +// MessagesController.DialogFilter filter = dialogFilters.get(a); +// filtersToDelete.put(filter.id, filter); +// } +// ArrayList filtersOrder = new ArrayList<>(); +// +// ArrayList usersToLoad = new ArrayList<>(); +// HashMap usersToLoadMap = new HashMap<>(); +// ArrayList chatsToLoad = new ArrayList<>(); +// HashMap chatsToLoadMap = new HashMap<>(); +// ArrayList dialogsToLoad = new ArrayList<>(); +// HashMap dialogsToLoadMap = new HashMap<>(); +// +// ArrayList filtersToSave = new ArrayList<>(); +// HashMap> filterDialogRemovals = new HashMap<>(); +// HashSet filtersUnreadCounterReset = new HashSet<>(); +// for (int a = 0, N = vector.objects.size(); a < N; a++) { +// TLRPC.DialogFilter newFilter = (TLRPC.DialogFilter) vector.objects.get(a); +// filtersOrder.add(newFilter.id); +// int newFlags = 0; +// if (newFilter.contacts) { +// newFlags |= MessagesController.DIALOG_FILTER_FLAG_CONTACTS; +// } +// if (newFilter.non_contacts) { +// newFlags |= MessagesController.DIALOG_FILTER_FLAG_NON_CONTACTS; +// } +// if (newFilter.groups) { +// newFlags |= MessagesController.DIALOG_FILTER_FLAG_GROUPS; +// } +// if (newFilter.broadcasts) { +// newFlags |= MessagesController.DIALOG_FILTER_FLAG_CHANNELS; +// } +// if (newFilter.bots) { +// newFlags |= MessagesController.DIALOG_FILTER_FLAG_BOTS; +// } +// if (newFilter.exclude_muted) { +// newFlags |= MessagesController.DIALOG_FILTER_FLAG_EXCLUDE_MUTED; +// } +// if (newFilter.exclude_read) { +// newFlags |= MessagesController.DIALOG_FILTER_FLAG_EXCLUDE_READ; +// } +// if (newFilter.exclude_archived) { +// newFlags |= MessagesController.DIALOG_FILTER_FLAG_EXCLUDE_ARCHIVED; +// } +// if (newFilter instanceof TLRPC.TL_dialogFilterCommunity) { +// newFlags |= MessagesController.DIALOG_FILTER_FLAG_COMMUNITY; +// if (newFilter.community_can_admin) { +// newFlags |= MessagesController.DIALOG_FILTER_FLAG_COMMUNITY_ADMIN; +// } +// } +// +// MessagesController.DialogFilter filter = dialogFiltersMap.get(newFilter.id); +// if (filter != null) { +// filtersToDelete.remove(newFilter.id); +// boolean changed = false; +// boolean unreadChanged = false; +// if (!TextUtils.equals(filter.name, newFilter.title)) { +// changed = true; +// filter.name = newFilter.title; +// } +// if (filter.flags != newFlags) { +// filter.flags = newFlags; +// changed = true; +// unreadChanged = true; +// } +// +// HashSet existingIds = new HashSet<>(filter.alwaysShow); +// existingIds.addAll(filter.neverShow); +// HashSet existingDialogsIds = new HashSet<>(); +// +// LinkedHashMap secretChatsMap = null; +// if (filter.pinnedDialogs.size() != 0) { +// ArrayList pinArray = new ArrayList<>(); +// boolean hasSecret = false; +// for (int c = 0, N2 = filter.pinnedDialogs.size(); c < N2; c++) { +// long did = filter.pinnedDialogs.keyAt(c); +// if (DialogObject.isEncryptedDialog(did)) { +// hasSecret = true; +// } +// pinArray.add(did); +// } +// if (hasSecret) { +// secretChatsMap = new LinkedHashMap<>(); +// LongSparseIntArray pinnedDialogs = filter.pinnedDialogs; +// Collections.sort(pinArray, (o1, o2) -> { +// int idx1 = pinnedDialogs.get(o1); +// int idx2 = pinnedDialogs.get(o2); +// if (idx1 > idx2) { +// return 1; +// } else if (idx1 < idx2) { +// return -1; +// } +// return 0; +// }); +// for (int c = 0, N2 = pinArray.size(); c < N2; c++) { +// long did = pinArray.get(c); +// if (!DialogObject.isEncryptedDialog(did)) { +// continue; +// } +// secretChatsMap.put(c, did); +// } +// } +// } +// for (int c = 0, N2 = filter.pinnedDialogs.size(); c < N2; c++) { +// long did = filter.pinnedDialogs.keyAt(c); +// if (DialogObject.isEncryptedDialog(did)) { +// continue; +// } +// existingDialogsIds.add(did); +// existingIds.remove(did); +// } +// +// filter.pinnedDialogs.clear(); +// for (int b = 0, N2 = newFilter.pinned_peers.size(); b < N2; b++) { +// TLRPC.InputPeer peer = newFilter.pinned_peers.get(b); +// Long id; +// if (peer.user_id != 0) { +// id = peer.user_id; +// } else { +// id = -(peer.chat_id != 0 ? peer.chat_id : peer.channel_id); +// } +// int index = filter.pinnedDialogs.size(); +// if (secretChatsMap != null) { +// Long did; +// while ((did = secretChatsMap.remove(index)) != null) { +// filter.pinnedDialogs.put(did, index); +// index++; +// } +// } +// filter.pinnedDialogs.put(id, index); +// existingIds.remove(id); +// if (!existingDialogsIds.remove(id)) { +// changed = true; +// if (!dialogsToLoadMap.containsKey(id)) { +// dialogsToLoad.add(id); +// dialogsToLoadMap.put(id, peer); +// } +// } +// } +// if (secretChatsMap != null) { +// for (LinkedHashMap.Entry entry : secretChatsMap.entrySet()) { +// filter.pinnedDialogs.put(entry.getValue(), filter.pinnedDialogs.size()); +// } +// } +// +// for (int c = 0; c < 2; c++) { +// ArrayList fromArray = toPeerIds(c == 0 ? newFilter.include_peers : newFilter.exclude_peers); +// ArrayList toArray = c == 0 ? filter.alwaysShow : filter.neverShow; +// +// if (c == 0) { +// // put pinned_peers into include_peers (alwaysShow) +// ArrayList pinnedArray = toPeerIds(newFilter.pinned_peers); +// for (int i = 0; i < pinnedArray.size(); ++i) { +// fromArray.remove(pinnedArray.get(i)); +// } +// fromArray.addAll(0, pinnedArray); +// } +// +// final int fromArrayCount = fromArray.size(); +// boolean isDifferent = fromArray.size() != toArray.size(); +// if (!isDifferent) { +// for (int i = 0; i < fromArrayCount; ++i) { +// if (!toArray.contains(fromArray.get(i))) { +// isDifferent = true; +// break; +// } +// } +// } +// +// if (isDifferent) { +// unreadChanged = true; +// changed = true; +// if (c == 0) { +// filter.alwaysShow = fromArray; +// } else { +// filter.neverShow = fromArray; +// } +// } +// } +// if (!existingDialogsIds.isEmpty()) { +// filterDialogRemovals.put(filter.id, existingDialogsIds); +// changed = true; +// } +// if (changed) { +// filtersToSave.add(filter); +// } +// if (unreadChanged) { +// filtersUnreadCounterReset.add(filter.id); +// } +// } else { +// filter = new MessagesController.DialogFilter(); +// filter.id = newFilter.id; +// filter.flags = newFlags; +// filter.name = newFilter.title; +// filter.pendingUnreadCount = -1; +// for (int c = 0; c < 2; c++) { +// if (c == 0) { +// for (int b = 0, N2 = newFilter.pinned_peers.size(); b < N2; b++) { +// TLRPC.InputPeer peer = newFilter.pinned_peers.get(b); +// Long id; +// if (peer.user_id != 0) { +// id = peer.user_id; +// } else { +// id = -(peer.chat_id != 0 ? peer.chat_id : peer.channel_id); +// } +// if (!filter.alwaysShow.contains(id)) { +// filter.alwaysShow.add(id); +// } +// filter.pinnedDialogs.put(id, filter.pinnedDialogs.size() + 1); +// if (!dialogsToLoadMap.containsKey(id)) { +// dialogsToLoad.add(id); +// dialogsToLoadMap.put(id, peer); +// } +// } +// } +// ArrayList fromArray = c == 0 ? newFilter.include_peers : newFilter.exclude_peers; +// ArrayList toArray = c == 0 ? filter.alwaysShow : filter.neverShow; +// for (int b = 0, N2 = fromArray.size(); b < N2; b++) { +// TLRPC.InputPeer peer = fromArray.get(b); +// if (peer.user_id != 0) { +// Long uid = peer.user_id; +// if (!toArray.contains(uid)) { +// toArray.add(uid); +// } +// if (!usersToLoadMap.containsKey(uid)) { +// usersToLoad.add(uid); +// usersToLoadMap.put(uid, peer); +// } +// } else { +// Long chatId = peer.chat_id != 0 ? peer.chat_id : peer.channel_id; +// Long dialogId = -chatId; +// if (!toArray.contains(dialogId)) { +// toArray.add(dialogId); +// } +// if (!chatsToLoadMap.containsKey(chatId)) { +// chatsToLoad.add(chatId); +// chatsToLoadMap.put(chatId, peer); +// } +// } +// } +// } +// filtersToSave.add(filter); +// } +// } +// +// TLRPC.messages_Dialogs dialogs; +// if (!dialogsToLoad.isEmpty()) { +// dialogs = loadDialogsByIds(TextUtils.join(",", dialogsToLoad), usersToLoad, chatsToLoad, new ArrayList<>()); +// for (int a = 0, N = dialogs.dialogs.size(); a < N; a++) { +// TLRPC.Dialog dialog = dialogs.dialogs.get(a); +// dialogsToLoadMap.remove(dialog.id); +// } +// } else { +// dialogs = new TLRPC.TL_messages_dialogs(); +// } +// ArrayList users = new ArrayList<>(); +// if (!usersToLoad.isEmpty()) { +// getUsersInternal(TextUtils.join(",", usersToLoad), users); +// for (int a = 0, N = users.size(); a < N; a++) { +// TLRPC.User user = users.get(a); +// usersToLoadMap.remove(user.id); +// } +// } +// ArrayList chats = new ArrayList<>(); +// if (!chatsToLoad.isEmpty()) { +// getChatsInternal(TextUtils.join(",", chatsToLoad), chats); +// for (int a = 0, N = chats.size(); a < N; a++) { +// TLRPC.Chat chat = chats.get(a); +// chatsToLoadMap.remove(chat.id); +// } +// } +// +// if (usersToLoadMap.isEmpty() && chatsToLoadMap.isEmpty() && dialogsToLoadMap.isEmpty()) { +// processLoadedFilterPeersInternal(dialogs, null, users, chats, filtersToSave, filtersToDelete, filtersOrder, filterDialogRemovals, filtersUnreadCounterReset); +// } else { +// getMessagesController().loadFilterPeers(dialogsToLoadMap, usersToLoadMap, chatsToLoadMap, dialogs, new TLRPC.TL_messages_dialogs(), users, chats, filtersToSave, filtersToDelete, filtersOrder, filterDialogRemovals, filtersUnreadCounterReset); +// } +// } catch (Exception e) { +// checkSQLException(e); +// } +// }); +// } + public void checkLoadedRemoteFilters(TLRPC.Vector vector) { storageQueue.postRunnable(() -> { try { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/SendMessagesHelper.java b/TMessagesProj/src/main/java/org/telegram/messenger/SendMessagesHelper.java index 70ce32712..595b6fa33 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/SendMessagesHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/SendMessagesHelper.java @@ -6649,7 +6649,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE); cursor.moveToFirst(); len = cursor.getLong(sizeIndex); - + cursor.close(); } catch (Exception e) { FileLog.e(e); } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java b/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java index bfe8a891b..22e3ac60e 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java @@ -12,7 +12,6 @@ import android.app.Activity; import android.app.ActivityManager; import android.app.Dialog; import android.content.Context; -import android.content.DialogInterface; import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.os.Build; @@ -31,7 +30,6 @@ import org.telegram.tgnet.SerializedData; import org.telegram.tgnet.TLRPC; import org.telegram.ui.ActionBar.AlertDialog; import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.CacheControlActivity; import org.telegram.ui.Components.SwipeGestureSettingsView; import org.telegram.ui.LaunchActivity; @@ -180,7 +178,7 @@ public class SharedConfig { public static boolean streamMkv = false; public static boolean saveStreamMedia = true; public static boolean pauseMusicOnRecord = false; - public static boolean pauseMusicOnMedia = true; + public static boolean pauseMusicOnMedia = false; public static boolean noiseSupression; public static final boolean noStatusBar = true; public static boolean debugWebView; @@ -511,7 +509,7 @@ public class SharedConfig { streamMedia = preferences.getBoolean("streamMedia", true); saveStreamMedia = preferences.getBoolean("saveStreamMedia", true); pauseMusicOnRecord = preferences.getBoolean("pauseMusicOnRecord", false); - pauseMusicOnMedia = preferences.getBoolean("pauseMusicOnMedia", true); + pauseMusicOnMedia = preferences.getBoolean("pauseMusicOnMedia", false); forceDisableTabletMode = preferences.getBoolean("forceDisableTabletMode", false); streamAllVideo = preferences.getBoolean("streamAllVideo", BuildVars.DEBUG_VERSION); streamMkv = preferences.getBoolean("streamMkv", false); @@ -1170,7 +1168,7 @@ public class SharedConfig { info.ping = data.readInt64(false); info.availableCheckTime = data.readInt64(false); - proxyList.add(info); + proxyList.add(0, info); if (currentProxy == null && !TextUtils.isEmpty(proxyAddress)) { if (proxyAddress.equals(info.address) && proxyPort == info.port && proxyUsername.equals(info.username) && proxyPassword.equals(info.password)) { currentProxy = info; @@ -1188,7 +1186,7 @@ public class SharedConfig { data.readString(false), data.readString(false), data.readString(false)); - proxyList.add(info); + proxyList.add(0, info); if (currentProxy == null && !TextUtils.isEmpty(proxyAddress)) { if (proxyAddress.equals(info.address) && proxyPort == info.port && proxyUsername.equals(info.username) && proxyPassword.equals(info.password)) { currentProxy = info; @@ -1222,7 +1220,7 @@ public class SharedConfig { serializedData.writeByte(PROXY_CURRENT_SCHEMA_VERSION); int count = infoToSerialize.size(); serializedData.writeInt32(count); - for (int a = 0; a < count; a++) { + for (int a = count - 1; a >= 0; a--) { ProxyInfo info = infoToSerialize.get(a); serializedData.writeString(info.address != null ? info.address : ""); serializedData.writeInt32(info.port); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/StatsController.java b/TMessagesProj/src/main/java/org/telegram/messenger/StatsController.java index 8e33394cb..3ad4a9f33 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/StatsController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/StatsController.java @@ -11,6 +11,8 @@ package org.telegram.messenger; import android.content.Context; import android.content.SharedPreferences; +import org.telegram.messenger.utils.ImmutableByteArrayOutputStream; + import java.io.File; import java.io.RandomAccessFile; @@ -78,6 +80,7 @@ public class StatsController extends BaseController { return ((long) bytes[0] & 0xFF) << 56 | ((long) bytes[1] & 0xFF) << 48 | ((long) bytes[2] & 0xFF) << 40 | ((long) bytes[3] & 0xFF) << 32 | ((long) bytes[4] & 0xFF) << 24 | ((long) bytes[5] & 0xFF) << 16 | ((long) bytes[6] & 0xFF) << 8 | ((long) bytes[7] & 0xFF); } + ImmutableByteArrayOutputStream byteArrayOutputStream = new ImmutableByteArrayOutputStream(); private Runnable saveRunnable = new Runnable() { @Override public void run() { @@ -87,25 +90,27 @@ public class StatsController extends BaseController { } lastInternalStatsSaveTime = newTime; try { - statsFile.seek(0); + byteArrayOutputStream.reset(); for (int a = 0; a < 3; a++) { for (int b = 0; b < OLD_TYPES_COUNT; b++) { - statsFile.write(longToBytes(sentBytes[a][b]), 0, 8); - statsFile.write(longToBytes(receivedBytes[a][b]), 0, 8); - statsFile.write(intToBytes(sentItems[a][b]), 0, 4); - statsFile.write(intToBytes(receivedItems[a][b]), 0, 4); + byteArrayOutputStream.write(longToBytes(sentBytes[a][b]), 0, 8); + byteArrayOutputStream.write(longToBytes(receivedBytes[a][b]), 0, 8); + byteArrayOutputStream.write(intToBytes(sentItems[a][b]), 0, 4); + byteArrayOutputStream.write(intToBytes(receivedItems[a][b]), 0, 4); } - statsFile.write(intToBytes(callsTotalTime[a]), 0, 4); - statsFile.write(longToBytes(resetStatsDate[a]), 0, 8); + byteArrayOutputStream.write(intToBytes(callsTotalTime[a]), 0, 4); + byteArrayOutputStream.write(longToBytes(resetStatsDate[a]), 0, 8); } for (int b = OLD_TYPES_COUNT; b < TYPES_COUNT; ++b) { for (int a = 0; a < 3; ++a) { - statsFile.write(longToBytes(sentBytes[a][b]), 0, 8); - statsFile.write(longToBytes(receivedBytes[a][b]), 0, 8); - statsFile.write(intToBytes(sentItems[a][b]), 0, 4); - statsFile.write(intToBytes(receivedItems[a][b]), 0, 4); + byteArrayOutputStream.write(longToBytes(sentBytes[a][b]), 0, 8); + byteArrayOutputStream.write(longToBytes(receivedBytes[a][b]), 0, 8); + byteArrayOutputStream.write(intToBytes(sentItems[a][b]), 0, 4); + byteArrayOutputStream.write(intToBytes(receivedItems[a][b]), 0, 4); } } + statsFile.seek(0); + statsFile.write(byteArrayOutputStream.buf, 0, byteArrayOutputStream.count()); statsFile.getFD().sync(); } catch (Exception ignore) { @@ -280,6 +285,7 @@ public class StatsController extends BaseController { long newTime = System.currentTimeMillis(); if (Math.abs(newTime - lastStatsSaveTime.get()) >= 2000) { lastStatsSaveTime.set(newTime); + statsSaveQueue.cancelRunnable(saveRunnable); statsSaveQueue.postRunnable(saveRunnable); } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/SvgHelper.java b/TMessagesProj/src/main/java/org/telegram/messenger/SvgHelper.java index c766b7421..419bd74e4 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/SvgHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/SvgHelper.java @@ -404,6 +404,26 @@ public class SvgHelper { public void copyCommandFromPosition(int position) { commands.add(commands.get(position)); } + + public SvgDrawable clone() { + SvgDrawable drawable = new SvgDrawable(); + for (int i = 0; i < commands.size(); i++) { + drawable.commands.add(commands.get(i)); + Paint fromPaint = paints.get(commands.get(i)); + if (fromPaint != null) { + Paint toPaint = new Paint(); + toPaint.setColor(fromPaint.getColor()); + toPaint.setStrokeCap(fromPaint.getStrokeCap()); + toPaint.setStrokeJoin(fromPaint.getStrokeJoin()); + toPaint.setStrokeWidth(fromPaint.getStrokeWidth()); + toPaint.setStyle(fromPaint.getStyle()); + drawable.paints.put(commands.get(i), toPaint); + } + } + drawable.width = width; + drawable.height = height; + return drawable; + } } public static Bitmap getBitmap(int res, int width, int height, int color) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/TopicsController.java b/TMessagesProj/src/main/java/org/telegram/messenger/TopicsController.java index 54a957356..5fee11154 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/TopicsController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/TopicsController.java @@ -147,6 +147,7 @@ public class TopicsController extends BaseController { } ArrayList topics = topicsByChatId.get(chatId); ArrayList topicsToReload = null; + ArrayList deletedTopics = null; LongSparseArray topicsMap = topicsMapByChatId.get(chatId); if (topics == null) { @@ -163,6 +164,10 @@ public class TopicsController extends BaseController { for (int i = 0; i < newTopics.size(); i++) { TLRPC.TL_forumTopic newTopic = newTopics.get(i); if (newTopic instanceof TLRPC.TL_forumTopicDeleted) { + if (deletedTopics == null) { + deletedTopics = new ArrayList<>(); + } + deletedTopics.add(newTopic.id); continue; } if (!topicsMap.containsKey(newTopic.id)) { @@ -204,6 +209,17 @@ public class TopicsController extends BaseController { } } + if (deletedTopics != null && loadType == LOAD_TYPE_LOAD_UNKNOWN) { + for (int i = 0; i < deletedTopics.size(); i++) { + for (int j = 0; j < topics.size(); j++) { + if (topics.get(j).id == deletedTopics.get(i)) { + topics.remove(j); + break; + } + } + } + getMessagesStorage().removeTopics(chatId, deletedTopics); + } if (topicsToReload != null && loadType != LOAD_TYPE_LOAD_UNKNOWN) { reloadTopics(chatId, topicsToReload, null); } else if (((loadType == LOAD_TYPE_PRELOAD && !fromCache) || loadType == LOAD_TYPE_LOAD_NEXT) && topics.size() >= totalCount && totalCount >= 0) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/UserNameResolver.java b/TMessagesProj/src/main/java/org/telegram/messenger/UserNameResolver.java new file mode 100644 index 000000000..190ca9f76 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/messenger/UserNameResolver.java @@ -0,0 +1,123 @@ +package org.telegram.messenger; + +import android.text.TextUtils; +import android.util.LruCache; + +import com.google.android.exoplayer2.util.Consumer; + +import org.telegram.tgnet.ConnectionsManager; +import org.telegram.tgnet.TLObject; +import org.telegram.tgnet.TLRPC; +import org.telegram.ui.ActionBar.BaseFragment; +import org.telegram.ui.Components.BulletinFactory; +import org.telegram.ui.LaunchActivity; + +import java.util.ArrayList; +import java.util.HashMap; + +public class UserNameResolver { + + private final int currentAccount; + private final static long CACHE_TIME = 1000 * 60 * 60; //1 hour + + UserNameResolver(int currentAccount) { + this.currentAccount = currentAccount; + } + + LruCache resolvedCache = new LruCache<>(100); + HashMap>> resolvingConsumers = new HashMap<>(); + + public void resolve(String username, Consumer resolveConsumer) { + CachedPeer cachedPeer = resolvedCache.get(username); + if (cachedPeer != null) { + if (System.currentTimeMillis() - cachedPeer.time < CACHE_TIME) { + resolveConsumer.accept(cachedPeer.peerId); + FileLog.d("resolve username from cache " + username + " " + cachedPeer.peerId); + return; + } else { + resolvedCache.remove(username); + } + } + + ArrayList> consumers = resolvingConsumers.get(username); + if (consumers != null) { + consumers.add(resolveConsumer); + return; + } + consumers = new ArrayList<>(); + consumers.add(resolveConsumer); + resolvingConsumers.put(username, consumers); + + + TLObject req; + if (AndroidUtilities.isNumeric(username)) { + TLRPC.TL_contacts_resolvePhone resolvePhone = new TLRPC.TL_contacts_resolvePhone(); + resolvePhone.phone = username; + req = resolvePhone; + } else { + TLRPC.TL_contacts_resolveUsername resolveUsername = new TLRPC.TL_contacts_resolveUsername(); + resolveUsername.username = username; + req = resolveUsername; + } + ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> { + ArrayList> finalConsumers = resolvingConsumers.remove(username); + if (finalConsumers == null) { + return; + } + if (error != null) { + for (int i = 0; i < finalConsumers.size(); i++) { + finalConsumers.get(i).accept(null); + } + + if (error != null && error.text != null && error.text.contains("FLOOD_WAIT")) { + BaseFragment fragment = LaunchActivity.getLastFragment(); + if (fragment != null) { + BulletinFactory.of(fragment).createErrorBulletin(LocaleController.getString("FloodWait", R.string.FloodWait)).show(); + } + } + return; + } + TLRPC.TL_contacts_resolvedPeer res = (TLRPC.TL_contacts_resolvedPeer) response; + + MessagesController.getInstance(currentAccount).putUsers(res.users, false); + MessagesController.getInstance(currentAccount).putChats(res.chats, false); + MessagesStorage.getInstance(currentAccount).putUsersAndChats(res.users, res.chats, false, true); + + long peerId = MessageObject.getPeerId(res.peer); + resolvedCache.put(username, new CachedPeer(peerId)); + for (int i = 0; i < finalConsumers.size(); i++) { + finalConsumers.get(i).accept(peerId); + } + }, ConnectionsManager.RequestFlagFailOnServerErrors)); + }; + + public void update(TLRPC.User oldUser, TLRPC.User user) { + if (oldUser == null || user == null || oldUser.username == null || TextUtils.equals(oldUser.username, user.username)) { + return; + } + resolvedCache.remove(oldUser.username); + if (user.username != null) { + resolvedCache.put(user.username, new CachedPeer(user.id)); + } + } + + public void update(TLRPC.Chat oldChat, TLRPC.Chat chat) { + if (oldChat == null || chat == null || oldChat.username == null || TextUtils.equals(oldChat.username, chat.username)) { + return; + } + resolvedCache.remove(oldChat.username); + if (chat.username != null) { + resolvedCache.put(chat.username, new CachedPeer(-chat.id)); + } + } + + private class CachedPeer { + final long peerId; + final long time; + + public CachedPeer(long peerId) { + this.peerId = peerId; + time = System.currentTimeMillis(); + } + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/utils/ImmutableByteArrayOutputStream.java b/TMessagesProj/src/main/java/org/telegram/messenger/utils/ImmutableByteArrayOutputStream.java index 38b6b98a3..6e5bed68c 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/utils/ImmutableByteArrayOutputStream.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/utils/ImmutableByteArrayOutputStream.java @@ -90,4 +90,7 @@ public class ImmutableByteArrayOutputStream extends OutputStream { count = 0; } + public int count() { + return count; + } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/video/MediaCodecVideoConvertor.java b/TMessagesProj/src/main/java/org/telegram/messenger/video/MediaCodecVideoConvertor.java index ce3fd3478..21f2ee03f 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/video/MediaCodecVideoConvertor.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/video/MediaCodecVideoConvertor.java @@ -83,7 +83,9 @@ public class MediaCodecVideoConvertor { long time = System.currentTimeMillis(); boolean error = false; boolean repeatWithIncreasedTimeout = false; + boolean isAvatar = avatarStartTime >= 0; int videoTrackIndex = -5; + String selectedEncoderName = null; try { MediaCodec.BufferInfo info = new MediaCodec.BufferInfo(); @@ -108,7 +110,7 @@ public class MediaCodecVideoConvertor { boolean decoderDone = false; int framesCount = 0; - if (avatarStartTime >= 0) { + if (isAvatar) { if (durationS <= 2000) { bitrate = 2600000; } else if (durationS <= 5000) { @@ -144,6 +146,10 @@ public class MediaCodecVideoConvertor { outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1); encoder = MediaCodec.createEncoderByType(MediaController.VIDEO_MIME_TYPE); + + selectedEncoderName = encoder.getName(); + FileLog.d("selected encoder " + selectedEncoderName); + encoder.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); inputSurface = new InputSurface(encoder.createInputSurface()); inputSurface.makeCurrent(); @@ -345,7 +351,7 @@ public class MediaCodecVideoConvertor { extractor.selectTrack(videoIndex); MediaFormat videoFormat = extractor.getTrackFormat(videoIndex); String encoderName = null; - if (avatarStartTime >= 0) { + if (isAvatar) { if (durationS <= 2000) { bitrate = 2600000; } else if (durationS <= 5000) { @@ -392,21 +398,6 @@ public class MediaCodecVideoConvertor { w = resultWidth; h = resultHeight; } - if (BuildVars.LOGS_ENABLED) { - FileLog.d("create encoder with w = " + w + " h = " + h + " bitrate = " + bitrate); - } - MediaFormat outputFormat = MediaFormat.createVideoFormat(MediaController.VIDEO_MIME_TYPE, w, h); - outputFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface); - outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate); - outputFormat.setInteger(MediaFormat.KEY_FRAME_RATE, framerate); - outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 2); - - if (Build.VERSION.SDK_INT < 23 && Math.min(h, w) <= 480) { - if (bitrate > 921600) { - bitrate = 921600; - } - outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate); - } if (encoderName != null) { try { @@ -418,6 +409,30 @@ public class MediaCodecVideoConvertor { if (encoder == null) { encoder = MediaCodec.createEncoderByType(MediaController.VIDEO_MIME_TYPE); } + + if (BuildVars.LOGS_ENABLED) { + FileLog.d("create encoder with w = " + w + " h = " + h + " bitrate = " + bitrate); + } + MediaFormat outputFormat = MediaFormat.createVideoFormat(MediaController.VIDEO_MIME_TYPE, w, h); + outputFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface); + outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate); + if (isAvatar && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + // prevent case when result video max 2MB + outputFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR); + } + outputFormat.setInteger( "max-bitrate", bitrate); + outputFormat.setInteger(MediaFormat.KEY_FRAME_RATE, framerate); + outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1); + + if (Build.VERSION.SDK_INT < 23 && Math.min(h, w) <= 480 && !isAvatar) { + if (bitrate > 921600) { + bitrate = 921600; + } + outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate); + } + + selectedEncoderName = encoder.getName(); + FileLog.d("selected encoder " + selectedEncoderName); encoder.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); inputSurface = new InputSurface(encoder.createInputSurface()); inputSurface.makeCurrent(); @@ -825,12 +840,16 @@ public class MediaCodecVideoConvertor { long timeLeft = System.currentTimeMillis() - time; if (BuildVars.LOGS_ENABLED) { - FileLog.d("compression completed time=" + timeLeft + " needCompress=" + needCompress + " w=" + resultWidth + " h=" + resultHeight + " bitrate=" + bitrate + " file size=" + cacheFile.length()); + FileLog.d("compression completed time=" + timeLeft + " needCompress=" + needCompress + " w=" + resultWidth + " h=" + resultHeight + " bitrate=" + bitrate + " file size=" + AndroidUtilities.formatFileSize(cacheFile.length()) + " encoder_name=" + selectedEncoderName); } return error; } + private boolean isMediatekAvcEncoder(MediaCodec encoder) { + return encoder.getName().equals("c2.mtk.avc.encoder"); + } + private long readAndWriteTracks(MediaExtractor extractor, MP4Builder mediaMuxer, MediaCodec.BufferInfo info, long start, long end, long duration, File file, boolean needAudio) throws Exception { int videoTrackIndex = MediaController.findTrack(extractor, false); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/voip/VoIPService.java b/TMessagesProj/src/main/java/org/telegram/messenger/voip/VoIPService.java index 82baade21..09f338665 100755 --- a/TMessagesProj/src/main/java/org/telegram/messenger/voip/VoIPService.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/voip/VoIPService.java @@ -3103,7 +3103,11 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa if (hasAudioFocus) { am.abandonAudioFocus(this); } - Utilities.globalQueue.postRunnable(() -> soundPool.release()); + Utilities.globalQueue.postRunnable(() -> { + if (soundPool != null) { + soundPool.release(); + } + }); } if (USE_CONNECTION_SERVICE) { @@ -3553,6 +3557,7 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa if (!USE_CONNECTION_SERVICE && btAdapter != null && btAdapter.isEnabled()) { try { MediaRouter mr = (MediaRouter) getSystemService(Context.MEDIA_ROUTER_SERVICE); + AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE); if (Build.VERSION.SDK_INT < 24) { int headsetState = btAdapter.getProfileConnectionState(BluetoothProfile.HEADSET); updateBluetoothHeadsetState(headsetState == BluetoothProfile.STATE_CONNECTED); @@ -3568,7 +3573,7 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa l.onAudioSettingsChanged(); } } else { - updateBluetoothHeadsetState(false); + updateBluetoothHeadsetState(am.isBluetoothA2dpOn()); } } } catch (Throwable e) { diff --git a/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java b/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java index d0ce4099d..9f1d47038 100644 --- a/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java +++ b/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java @@ -70,7 +70,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 = 156; + public static final int LAYER = 157; public static class TL_stats_megagroupStats extends TLObject { public static int constructor = 0xef7ff916; @@ -24362,6 +24362,8 @@ public class TLRPC { public int score; public boolean video; public int months; + public String cryptoCurrency; + public long cryptoAmount; public static MessageAction TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) { MessageAction result = null; @@ -24528,7 +24530,7 @@ public class TLRPC { case 0x8f31b327: result = new TL_messageActionPaymentSentMe(); break; - case 0xaba0f5c6: + case 0xc83d6aec: result = new TL_messageActionGiftPremium(); break; case 0xfe77345d: @@ -25504,19 +25506,29 @@ public class TLRPC { } public static class TL_messageActionGiftPremium extends MessageAction { - public static int constructor = 0xaba0f5c6; + public static int constructor = 0xc83d6aec; public void readParams(AbstractSerializedData stream, boolean exception) { + flags = stream.readInt32(exception); currency = stream.readString(exception); amount = stream.readInt64(exception); months = stream.readInt32(exception); + if ((flags & 1) != 0) { + cryptoCurrency = stream.readString(exception); + cryptoAmount = stream.readInt64(exception); + } } public void serializeToStream(AbstractSerializedData stream) { stream.writeInt32(constructor); + stream.writeInt32(flags); stream.writeString(currency); stream.writeInt64(amount); stream.writeInt32(months); + if ((flags & 1) != 0) { + stream.writeString(cryptoCurrency); + stream.writeInt64(cryptoAmount); + } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java index 8530e8f20..caad346af 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java @@ -6277,6 +6277,7 @@ public class Theme { public static Drawable rect(String backgroundColorKey) { return rect(Theme.getColor(backgroundColorKey)); } + public static Drawable rect(String backgroundColorKey, float ...radii) { return rect(Theme.getColor(backgroundColorKey), radii); } @@ -10878,13 +10879,27 @@ public class Theme { return false; } - public static void turnOffAutoNight(BaseFragment fragment) { - turnOffAutoNight(fragment != null ? fragment.getLayoutContainer() : null, () -> { - INavigationLayout nav = fragment != null ? fragment.getParentLayout() : null; - if (nav != null) { - nav.presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_NIGHT)); + public static void turnOffAutoNight(@NonNull BaseFragment fragment) { + if (selectedAutoNightType != AUTO_NIGHT_TYPE_NONE) { + if (fragment != null) { + try { + BulletinFactory.of(fragment).createSimpleBulletin( + R.raw.auto_night_off, + selectedAutoNightType == AUTO_NIGHT_TYPE_SYSTEM ? + LocaleController.getString("AutoNightSystemModeOff", R.string.AutoNightSystemModeOff) : + LocaleController.getString("AutoNightModeOff", R.string.AutoNightModeOff), + LocaleController.getString("Settings", R.string.Settings), + Bulletin.DURATION_PROLONG, + () -> fragment.presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_NIGHT)) + ).show(); + } catch (Exception e) { + FileLog.e(e); + } } - }); + selectedAutoNightType = AUTO_NIGHT_TYPE_NONE; + saveAutoNightThemeConfig(); + cancelAutoNightThemeCallbacks(); + } } public static void turnOffAutoNight(FrameLayout container, Runnable openSettings) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsSearchAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsSearchAdapter.java index 6f76667e9..7722ff043 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsSearchAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsSearchAdapter.java @@ -22,6 +22,8 @@ import androidx.recyclerview.widget.DefaultItemAnimator; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import com.google.android.exoplayer2.util.Log; + import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.SQLite.SQLiteCursor; import org.telegram.SQLite.SQLitePreparedStatement; @@ -285,6 +287,9 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter { if (reqForumId != 0 && reqId != 0) { return; } + if (lastMessagesSearchId != lastSearchId) { + return; + } if (delegate != null && delegate.getSearchForumDialogId() != 0 && !localMessagesSearchEndReached) { searchForumMessagesInternal(lastMessagesSearchString, lastMessagesSearchId); } else { @@ -457,7 +462,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter { req.filter = new TLRPC.TL_inputMessagesFilterEmpty(); req.flags |= 1; req.folder_id = folderId; - if (query.equals(lastMessagesSearchString) && !searchResultMessages.isEmpty()) { + if (query.equals(lastMessagesSearchString) && !searchResultMessages.isEmpty() && lastMessagesSearchId == lastSearchId) { MessageObject lastMessage = searchResultMessages.get(searchResultMessages.size() - 1); req.offset_id = lastMessage.getId(); req.offset_rate = nextSearchRate; @@ -469,7 +474,8 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter { req.offset_peer = new TLRPC.TL_inputPeerEmpty(); } lastMessagesSearchString = query; - final int currentReqId = ++lastReqId; + lastReqId++; + final int currentReqId = lastReqId; reqId = ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> { final ArrayList messageObjects = new ArrayList<>(); if (error == null) { @@ -1034,7 +1040,8 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter { searchResultHashtags.clear(); } - final int searchId = ++lastSearchId; + lastSearchId++; + final int searchId = lastSearchId; waitingResponseCount = 3; globalSearchCollapsed = true; phoneCollapsed = true; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java index 106bb7417..3538eecaa 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java @@ -82,6 +82,7 @@ import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.messenger.AccountInstance; import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.ApplicationLoader; +import org.telegram.messenger.BuildVars; import org.telegram.messenger.ChatObject; import org.telegram.messenger.ContactsController; import org.telegram.messenger.DialogObject; @@ -3889,9 +3890,6 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.userInfoDidLoad); cancelShakeAnimation(); - if (animationRunning) { - return; - } if (checkBox != null) { checkBox.onDetachedFromWindow(); } @@ -3948,9 +3946,6 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiLoaded); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.userInfoDidLoad); -// if (currentMessageObject != null) { -// currentMessageObject.onAttachedWindow(this); -// } if (currentMessageObject != null) { currentMessageObject.animateComments = false; } @@ -4103,7 +4098,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate } private void cancelLoading(MessageObject messageObject) { - if (messageObject != null && !messageObject.mediaExists && !messageObject.putInDownloadsStore && !DownloadController.getInstance(currentAccount).isDownloading(messageObject.messageOwner.id)) { + if (messageObject != null && !messageObject.mediaExists && !messageObject.putInDownloadsStore && !DownloadController.getInstance(currentAccount).isDownloading(messageObject.messageOwner.id) && !PhotoViewer.getInstance().isVisible()) { TLRPC.Document document = messageObject.getDocument(); boolean loadDocumentFromImageReceiver = MessageObject.isStickerDocument(document) || MessageObject.isAnimatedStickerDocument(document, true) || MessageObject.isGifDocument(document) || MessageObject.isRoundVideoDocument(document); if (!loadDocumentFromImageReceiver) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index 3cb2eece1..9a5962db1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -713,6 +713,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private int loadsCount; private int last_message_id = 0; private long mergeDialogId; + private boolean sentBotStart; private long startMessageAppearTransitionMs; private List messageSkeletons = new ArrayList<>(); @@ -3311,6 +3312,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (themeDelegate.isThemeChangeAvailable()) { headerItem.lazilyAddSubItem(change_colors, R.drawable.msg_colors, LocaleController.getString("ChangeColors", R.string.ChangeColors)); } + boolean addedSettings = false; if (!isTopic) { if (ChatObject.isChannel(currentChat) && !currentChat.creator) { if (!ChatObject.isNotInChat(currentChat)) { @@ -3323,6 +3325,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } else if (!ChatObject.isChannel(currentChat)) { if (currentChat != null) { headerItem.lazilyAddSubItem(delete_chat, R.drawable.msg_leave, LocaleController.getString("DeleteAndExit", R.string.DeleteAndExit)); + } else if (currentUser != null && currentUser.bot) { + headerItem.lazilyAddSubItem(bot_settings, R.drawable.msg_settings_old, LocaleController.getString("BotSettings", R.string.BotSettings)); + addedSettings = true; + headerItem.lazilyAddSubItem(delete_chat, R.drawable.msg_block2, LocaleController.getString(R.string.DeleteAndBlock)).setColors(getThemedColor(Theme.key_dialogTextRed), getThemedColor(Theme.key_dialogTextRed)); } else { headerItem.lazilyAddSubItem(delete_chat, R.drawable.msg_delete, LocaleController.getString("DeleteChatUser", R.string.DeleteChatUser)); } @@ -3332,7 +3338,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not headerItem.lazilyAddSubItem(add_shortcut, R.drawable.msg_home, LocaleController.getString("AddShortcut", R.string.AddShortcut)); } if (currentUser != null && currentEncryptedChat == null && currentUser.bot) { - headerItem.lazilyAddSubItem(bot_settings, R.drawable.msg_settings_old, LocaleController.getString("BotSettings", R.string.BotSettings)); + if (!addedSettings) { + headerItem.lazilyAddSubItem(bot_settings, R.drawable.msg_settings_old, LocaleController.getString("BotSettings", R.string.BotSettings)); + } headerItem.lazilyAddSubItem(bot_help, R.drawable.msg_help, LocaleController.getString("BotHelp", R.string.BotHelp)); updateBotButtons(); } @@ -6681,7 +6689,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not }; bottomOverlayStartButton.setBackground(Theme.AdaptiveRipple.filledRect(getThemedColor(Theme.key_featuredStickers_addButton), 8)); bottomOverlayStartButton.setTextColor(getThemedColor(Theme.key_featuredStickers_buttonText)); - bottomOverlayStartButton.setText(LocaleController.getString(R.string.BotStartButton)); + bottomOverlayStartButton.setText(LocaleController.getString(R.string.BotStart)); bottomOverlayStartButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); bottomOverlayStartButton.setGravity(Gravity.CENTER); bottomOverlayStartButton.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)); @@ -6743,12 +6751,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (currentUser.bot) { String botUserLast = botUser; botUser = null; - getMessagesController().unblockPeer(currentUser.id); - if (botUserLast != null && botUserLast.length() != 0) { - getMessagesController().sendBotStart(currentUser, botUserLast); - } else { - getSendMessagesHelper().sendMessage("/start", dialog_id, null, null, null, false, null, null, null, true, 0, null, false); - } + getMessagesController().unblockPeer(currentUser.id, () -> { + if (botUserLast != null && botUserLast.length() != 0) { + getMessagesController().sendBotStart(currentUser, botUserLast); + } else { + getSendMessagesHelper().sendMessage("/start", dialog_id, null, null, null, false, null, null, null, true, 0, null, false); + } + }); } else { AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity(), themeDelegate); builder.setMessage(LocaleController.getString("AreYouSureUnblockContact", R.string.AreYouSureUnblockContact)); @@ -13408,6 +13417,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (keyboardSize > AndroidUtilities.dp(20) && getLayoutParams().height < 0) { h += keyboardSize; } + if (bottomOverlay != null && bottomOverlay.getVisibility() == View.VISIBLE && bottomOverlayStartButton != null && bottomOverlayStartButton.getVisibility() != View.GONE) { + h -= AndroidUtilities.dp(16); + } int contentHeightSpec = View.MeasureSpec.makeMeasureSpec(Math.max(AndroidUtilities.dp(10), h), View.MeasureSpec.EXACTLY); child.measure(contentWidthSpec, contentHeightSpec); } else if (child == progressView) { @@ -15228,15 +15240,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not int loaded_max_id = (Integer) args[12]; int loaded_mentions_count = chatWasReset ? 0 : (Integer) args[13]; - if (did == dialog_id && count > 0 && currentUser != null && (bottomOverlayStartButton != null && bottomOverlayStartButton.getVisibility() == View.VISIBLE)) { - if (!TextUtils.isEmpty(botUser)) { - getMessagesController().sendBotStart(currentUser, botUser); - - bottomOverlayChat.setVisibility(View.GONE); - chatActivityEnterView.setVisibility(View.VISIBLE); - } - } - if (loaded_mentions_count < 0) { loaded_mentions_count *= -1; hasAllMentionsLocal = false; @@ -16170,6 +16173,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not getNotificationCenter().runDelayedNotifications(); }); } + + if (did == dialog_id && !messages.isEmpty() && currentUser != null && (bottomOverlayStartButton != null && bottomOverlayStartButton.getVisibility() == View.VISIBLE)) { + if (!TextUtils.isEmpty(botUser) && !sentBotStart) { + sentBotStart = true; + getMessagesController().sendBotStart(currentUser, botUser); + + bottomOverlayChat.setVisibility(View.GONE); + chatActivityEnterView.setVisibility(View.VISIBLE); + } + } } else if (id == NotificationCenter.invalidateMotionBackground) { if (chatListView != null) { chatListView.invalidateViews(); @@ -20528,6 +20541,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (getParentActivity() != null) { AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); } + + if (dialog_id == dialog_id && !messages.isEmpty() && currentUser != null) { + if (botUser.length() != 0 && !sentBotStart) { + sentBotStart = true; + } + } } else { bottomOverlayChatText.setText(LocaleController.getString("DeleteThisChat", R.string.DeleteThisChat)); } @@ -20697,6 +20716,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not topViewWasVisible = 0; } } + if (sentBotStart) { + getMessagesController().sendBotStart(currentUser, botUser); + + bottomOverlayChat.setVisibility(View.GONE); + chatActivityEnterView.setVisibility(View.VISIBLE); + } checkRaiseSensors(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java index 5c5b9c943..19e7d308b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java @@ -1508,7 +1508,19 @@ public class AlertsCreator { lastMessageIsJoined = true; } - if (!second && (secret && !clear || canDeleteInbox) && !UserObject.isDeleted(user) && !lastMessageIsJoined || (deleteChatForAll = checkDeleteForAll && !clear && chat != null && chat.creator)) { + if (user != null && user.bot) { + cell[0] = new CheckBoxCell(context, 1, resourcesProvider); + cell[0].setBackgroundDrawable(Theme.getSelectorDrawable(false)); + cell[0].setText(LocaleController.getString(R.string.BlockBot), "", false, false); + cell[0].setPadding(LocaleController.isRTL ? AndroidUtilities.dp(16) : AndroidUtilities.dp(8), 0, LocaleController.isRTL ? AndroidUtilities.dp(8) : AndroidUtilities.dp(16), 0); + cell[0].setChecked(deleteForAll[0] = true, false); + frameLayout.addView(cell[0], LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.BOTTOM | Gravity.LEFT, 0, 0, 0, 0)); + cell[0].setOnClickListener(v -> { + CheckBoxCell cell1 = (CheckBoxCell) v; + deleteForAll[0] = !deleteForAll[0]; + cell1.setChecked(deleteForAll[0], true); + }); + } else if (!second && (secret && !clear || canDeleteInbox) && !UserObject.isDeleted(user) && !lastMessageIsJoined || (deleteChatForAll = checkDeleteForAll && !clear && chat != null && chat.creator)) { cell[0] = new CheckBoxCell(context, 1, resourcesProvider); cell[0].setBackgroundDrawable(Theme.getSelectorDrawable(false)); if (deleteChatForAll) { @@ -1601,7 +1613,7 @@ public class AlertsCreator { messageTextView.setText(AndroidUtilities.replaceTags(LocaleController.getString("AreYouSureDeleteThisChatSavedMessages", R.string.AreYouSureDeleteThisChatSavedMessages))); } else { if (user.bot && !user.support) { - messageTextView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("AreYouSureDeleteThisChatWithBot", R.string.AreYouSureDeleteThisChatWithBot, UserObject.getUserName(user)))); + messageTextView.setText(AndroidUtilities.replaceTags(LocaleController.formatString(R.string.AreYouSureDeleteThisChatWithBotWithCheckmark, UserObject.getUserName(user)))); } else { messageTextView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("AreYouSureDeleteThisChatWithUser", R.string.AreYouSureDeleteThisChatWithUser, UserObject.getUserName(user)))); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/AnimatedEmojiDrawable.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/AnimatedEmojiDrawable.java index c91221cbf..49023dfdd 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/AnimatedEmojiDrawable.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/AnimatedEmojiDrawable.java @@ -462,6 +462,7 @@ public class AnimatedEmojiDrawable extends Drawable { return super.setImageBitmapByKey(drawable, key, type, memCache, guid); } }; + imageReceiver.setAllowLoadingOnAttachedOnly(true); }; if (cacheType == CACHE_TYPE_RENDERING_VIDEO) { imageReceiver.ignoreNotifications = true; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Bulletin.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Bulletin.java index 647eaed27..43ab4a0a1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Bulletin.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Bulletin.java @@ -93,7 +93,7 @@ public class Bulletin { @SuppressLint("RtlHardcoded") public static Bulletin make(@NonNull BaseFragment fragment, @NonNull Layout contentLayout, int duration) { if (fragment instanceof ChatActivity) { - contentLayout.setWideScreenParams(ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.RIGHT); + contentLayout.setWideScreenParams(ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL); } else if (fragment instanceof DialogsActivity) { contentLayout.setWideScreenParams(ViewGroup.LayoutParams.MATCH_PARENT, Gravity.NO_GRAVITY); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/CanvasButton.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/CanvasButton.java index 344056a31..2cf5bda65 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/CanvasButton.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/CanvasButton.java @@ -29,7 +29,7 @@ public class CanvasButton { ArrayList drawingRects = new ArrayList<>(); int usingRectCount; boolean buttonPressed; - RippleDrawable selectorDrawable; + Drawable selectorDrawable; private final static int[] pressedState = new int[]{android.R.attr.state_enabled, android.R.attr.state_pressed}; private final View parent; @@ -256,7 +256,9 @@ public class CanvasButton { public void setRoundRadius(int radius) { roundRadius = radius; pathEffect = new CornerPathEffect(radius); - maskPaint.setPathEffect(new CornerPathEffect(radius)); + if (maskPaint != null) { + maskPaint.setPathEffect(new CornerPathEffect(radius)); + } } public void cancelRipple() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java index b60a9792b..a1e4ce9c7 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java @@ -2019,55 +2019,84 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific sendButtonContainer.setClipToPadding(false); textFieldContainer.addView(sendButtonContainer, LayoutHelper.createFrame(48, 48, Gravity.BOTTOM | Gravity.RIGHT)); - audioVideoButtonContainer = new FrameLayout(context); - audioVideoButtonContainer.setSoundEffectsEnabled(false); - sendButtonContainer.addView(audioVideoButtonContainer, LayoutHelper.createFrame(48, 48)); - audioVideoButtonContainer.setFocusable(true); - audioVideoButtonContainer.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); - audioVideoButtonContainer.setOnTouchListener((view, motionEvent) -> { - createRecordCircle(); - if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { - if (recordCircle.isSendButtonVisible()) { - if (!hasRecordVideo || calledRecordRunnable) { - startedDraggingX = -1; - if (hasRecordVideo && isInVideoMode()) { - delegate.needStartRecordVideo(1, true, 0); - } else { - if (recordingAudioVideo && isInScheduleMode()) { - AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), (notify, scheduleDate) -> MediaController.getInstance().stopRecording(1, notify, scheduleDate), () -> MediaController.getInstance().stopRecording(0, false, 0), resourcesProvider); + audioVideoButtonContainer = new FrameLayout(context) { + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + return true; + } + + @Override + public boolean onTouchEvent(MotionEvent motionEvent) { + createRecordCircle(); + if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { + if (recordCircle.isSendButtonVisible()) { + if (!hasRecordVideo || calledRecordRunnable) { + startedDraggingX = -1; + if (hasRecordVideo && isInVideoMode()) { + delegate.needStartRecordVideo(1, true, 0); + } else { + if (recordingAudioVideo && isInScheduleMode()) { + AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), (notify, scheduleDate) -> MediaController.getInstance().stopRecording(1, notify, scheduleDate), () -> MediaController.getInstance().stopRecording(0, false, 0), resourcesProvider); + } + MediaController.getInstance().stopRecording(isInScheduleMode() ? 3 : 1, true, 0); + delegate.needStartRecordAudio(0); } - MediaController.getInstance().stopRecording(isInScheduleMode() ? 3 : 1, true, 0); - delegate.needStartRecordAudio(0); + recordingAudioVideo = false; + messageTransitionIsRunning = false; + AndroidUtilities.runOnUIThread(moveToSendStateRunnable = () -> { + moveToSendStateRunnable = null; + updateRecordInterface(RECORD_STATE_SENDING); + }, 200); } - recordingAudioVideo = false; - messageTransitionIsRunning = false; - AndroidUtilities.runOnUIThread(moveToSendStateRunnable = () -> { - moveToSendStateRunnable = null; - updateRecordInterface(RECORD_STATE_SENDING); - }, 200); - } - getParent().requestDisallowInterceptTouchEvent(true); - return true; - } - if (parentFragment != null) { - TLRPC.Chat chat = parentFragment.getCurrentChat(); - TLRPC.UserFull userFull = parentFragment.getCurrentUserInfo(); - if (chat != null && !(ChatObject.canSendVoice(chat) || (ChatObject.canSendRoundVideo(chat) && hasRecordVideo)) || userFull != null && userFull.voice_messages_forbidden) { - delegate.needShowMediaBanHint(); + getParent().requestDisallowInterceptTouchEvent(true); return true; } - } - if (hasRecordVideo) { - calledRecordRunnable = false; - recordAudioVideoRunnableStarted = true; - AndroidUtilities.runOnUIThread(recordAudioVideoRunnable, 150); - } else { - recordAudioVideoRunnable.run(); - } - return true; - } else if (motionEvent.getAction() == MotionEvent.ACTION_UP || motionEvent.getAction() == MotionEvent.ACTION_CANCEL) { - if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL && recordingAudioVideo) { - if (recordCircle.slideToCancelProgress < 0.7f) { + if (parentFragment != null) { + TLRPC.Chat chat = parentFragment.getCurrentChat(); + TLRPC.UserFull userFull = parentFragment.getCurrentUserInfo(); + if (chat != null && !(ChatObject.canSendVoice(chat) || (ChatObject.canSendRoundVideo(chat) && hasRecordVideo)) || userFull != null && userFull.voice_messages_forbidden) { + delegate.needShowMediaBanHint(); + return true; + } + } + if (hasRecordVideo) { + calledRecordRunnable = false; + recordAudioVideoRunnableStarted = true; + AndroidUtilities.runOnUIThread(recordAudioVideoRunnable, 150); + } else { + recordAudioVideoRunnable.run(); + } + return true; + } else if (motionEvent.getAction() == MotionEvent.ACTION_UP || motionEvent.getAction() == MotionEvent.ACTION_CANCEL) { + if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL && recordingAudioVideo) { + if (recordCircle.slideToCancelProgress < 0.7f) { + if (hasRecordVideo && isInVideoMode()) { + CameraController.getInstance().cancelOnInitRunnable(onFinishInitCameraRunnable); + delegate.needStartRecordVideo(2, true, 0); + } else { + delegate.needStartRecordAudio(0); + MediaController.getInstance().stopRecording(0, false, 0); + } + recordingAudioVideo = false; + updateRecordInterface(RECORD_STATE_CANCEL_BY_GESTURE); + } else { + recordCircle.sendButtonVisible = true; + startLockTransition(); + } + return false; + } + if (recordCircle != null && recordCircle.isSendButtonVisible() || recordedAudioPanel != null && recordedAudioPanel.getVisibility() == VISIBLE) { + if (recordAudioVideoRunnableStarted) { + AndroidUtilities.cancelRunOnUIThread(recordAudioVideoRunnable); + } + return false; + } + + float x = motionEvent.getX() + audioVideoButtonContainer.getX(); + float dist = (x - startedDraggingX); + float alpha = 1.0f + dist / distCanMove; + if (alpha < 0.45) { if (hasRecordVideo && isInVideoMode()) { CameraController.getInstance().cancelOnInitRunnable(onFinishInitCameraRunnable); delegate.needStartRecordVideo(2, true, 0); @@ -2078,119 +2107,264 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific recordingAudioVideo = false; updateRecordInterface(RECORD_STATE_CANCEL_BY_GESTURE); } else { - recordCircle.sendButtonVisible = true; - startLockTransition(); - } - return false; - } - if (recordCircle != null && recordCircle.isSendButtonVisible() || recordedAudioPanel != null && recordedAudioPanel.getVisibility() == VISIBLE) { - if (recordAudioVideoRunnableStarted) { - AndroidUtilities.cancelRunOnUIThread(recordAudioVideoRunnable); - } - return false; - } - - float x = motionEvent.getX() + audioVideoButtonContainer.getX(); - float dist = (x - startedDraggingX); - float alpha = 1.0f + dist / distCanMove; - if (alpha < 0.45) { - if (hasRecordVideo && isInVideoMode()) { - CameraController.getInstance().cancelOnInitRunnable(onFinishInitCameraRunnable); - delegate.needStartRecordVideo(2, true, 0); - } else { - delegate.needStartRecordAudio(0); - MediaController.getInstance().stopRecording(0, false, 0); - } - recordingAudioVideo = false; - updateRecordInterface(RECORD_STATE_CANCEL_BY_GESTURE); - } else { - if (recordAudioVideoRunnableStarted) { - AndroidUtilities.cancelRunOnUIThread(recordAudioVideoRunnable); - if (sendVoiceEnabled && sendRoundEnabled) { - delegate.onSwitchRecordMode(!isInVideoMode()); - setRecordVideoButtonVisible(!isInVideoMode(), true); - } else { - delegate.needShowMediaBanHint(); + if (recordAudioVideoRunnableStarted) { + AndroidUtilities.cancelRunOnUIThread(recordAudioVideoRunnable); + if (sendVoiceEnabled && sendRoundEnabled) { + delegate.onSwitchRecordMode(!isInVideoMode()); + setRecordVideoButtonVisible(!isInVideoMode(), true); + } else { + delegate.needShowMediaBanHint(); + } + performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP); + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); + } else if (!hasRecordVideo || calledRecordRunnable) { + startedDraggingX = -1; + if (hasRecordVideo && isInVideoMode()) { + CameraController.getInstance().cancelOnInitRunnable(onFinishInitCameraRunnable); + delegate.needStartRecordVideo(1, true, 0); + } else if (!sendVoiceEnabled) { + delegate.needShowMediaBanHint(); + } else { + if (recordingAudioVideo && isInScheduleMode()) { + AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), (notify, scheduleDate) -> MediaController.getInstance().stopRecording(1, notify, scheduleDate), () -> MediaController.getInstance().stopRecording(0, false, 0), resourcesProvider); + } + delegate.needStartRecordAudio(0); + MediaController.getInstance().stopRecording(isInScheduleMode() ? 3 : 1, true, 0); + } + recordingAudioVideo = false; + messageTransitionIsRunning = false; + AndroidUtilities.runOnUIThread(moveToSendStateRunnable = () -> { + moveToSendStateRunnable = null; + updateRecordInterface(RECORD_STATE_SENDING); + }, 500); } - performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP); - sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); - } else if (!hasRecordVideo || calledRecordRunnable) { - startedDraggingX = -1; + } + return true; + } else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE && recordingAudioVideo) { + float x = motionEvent.getX(); + float y = motionEvent.getY(); + if (recordCircle.isSendButtonVisible()) { + return false; + } + if (recordCircle.setLockTranslation(y) == 2) { + startLockTransition(); + return false; + } else { + recordCircle.setMovingCords(x, y); + } + + if (startedDraggingX == -1) { + startedDraggingX = x; + distCanMove = (float) (sizeNotifierLayout.getMeasuredWidth() * 0.35); + if (distCanMove > AndroidUtilities.dp(140)) { + distCanMove = AndroidUtilities.dp(140); + } + } + + x = x + audioVideoButtonContainer.getX(); + float dist = (x - startedDraggingX); + float alpha = 1.0f + dist / distCanMove; + if (startedDraggingX != -1) { + if (alpha > 1) { + alpha = 1; + } else if (alpha < 0) { + alpha = 0; + } + if (slideText != null) { + slideText.setSlideX(alpha); + } + if (recordCircle != null) { + recordCircle.setSlideToCancelProgress(alpha); + } + } + + if (alpha == 0) { if (hasRecordVideo && isInVideoMode()) { CameraController.getInstance().cancelOnInitRunnable(onFinishInitCameraRunnable); - delegate.needStartRecordVideo(1, true, 0); - } else if (!sendVoiceEnabled) { - delegate.needShowMediaBanHint(); + delegate.needStartRecordVideo(2, true, 0); } else { - if (recordingAudioVideo && isInScheduleMode()) { - AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), (notify, scheduleDate) -> MediaController.getInstance().stopRecording(1, notify, scheduleDate), () -> MediaController.getInstance().stopRecording(0, false, 0), resourcesProvider); - } delegate.needStartRecordAudio(0); - MediaController.getInstance().stopRecording(isInScheduleMode() ? 3 : 1, true, 0); + MediaController.getInstance().stopRecording(0, false, 0); } recordingAudioVideo = false; - messageTransitionIsRunning = false; - AndroidUtilities.runOnUIThread(moveToSendStateRunnable = () -> { - moveToSendStateRunnable = null; - updateRecordInterface(RECORD_STATE_SENDING); - }, 500); + updateRecordInterface(RECORD_STATE_CANCEL_BY_GESTURE); } - } - return true; - } else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE && recordingAudioVideo) { - float x = motionEvent.getX(); - float y = motionEvent.getY(); - if (recordCircle.isSendButtonVisible()) { - return false; - } - if (recordCircle.setLockTranslation(y) == 2) { - startLockTransition(); - return false; - } else { - recordCircle.setMovingCords(x, y); - } - - if (startedDraggingX == -1) { - startedDraggingX = x; - distCanMove = (float) (sizeNotifierLayout.getMeasuredWidth() * 0.35); - if (distCanMove > AndroidUtilities.dp(140)) { - distCanMove = AndroidUtilities.dp(140); - } - } - - x = x + audioVideoButtonContainer.getX(); - float dist = (x - startedDraggingX); - float alpha = 1.0f + dist / distCanMove; - if (startedDraggingX != -1) { - if (alpha > 1) { - alpha = 1; - } else if (alpha < 0) { - alpha = 0; - } - if (slideText != null) { - slideText.setSlideX(alpha); - } - if (recordCircle != null) { - recordCircle.setSlideToCancelProgress(alpha); - } - } - - if (alpha == 0) { - if (hasRecordVideo && isInVideoMode()) { - CameraController.getInstance().cancelOnInitRunnable(onFinishInitCameraRunnable); - delegate.needStartRecordVideo(2, true, 0); - } else { - delegate.needStartRecordAudio(0); - MediaController.getInstance().stopRecording(0, false, 0); - } - recordingAudioVideo = false; - updateRecordInterface(RECORD_STATE_CANCEL_BY_GESTURE); + return true; } return true; } - view.onTouchEvent(motionEvent); - return true; - }); + }; + audioVideoButtonContainer.setSoundEffectsEnabled(false); + sendButtonContainer.addView(audioVideoButtonContainer, LayoutHelper.createFrame(48, 48)); + audioVideoButtonContainer.setFocusable(true); + audioVideoButtonContainer.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); +// audioVideoButtonContainer.setOnTouchListener((view, motionEvent) -> { +// createRecordCircle(); +// if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { +// if (recordCircle.isSendButtonVisible()) { +// if (!hasRecordVideo || calledRecordRunnable) { +// startedDraggingX = -1; +// if (hasRecordVideo && isInVideoMode()) { +// delegate.needStartRecordVideo(1, true, 0); +// } else { +// if (recordingAudioVideo && isInScheduleMode()) { +// AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), (notify, scheduleDate) -> MediaController.getInstance().stopRecording(1, notify, scheduleDate), () -> MediaController.getInstance().stopRecording(0, false, 0), resourcesProvider); +// } +// MediaController.getInstance().stopRecording(isInScheduleMode() ? 3 : 1, true, 0); +// delegate.needStartRecordAudio(0); +// } +// recordingAudioVideo = false; +// messageTransitionIsRunning = false; +// AndroidUtilities.runOnUIThread(moveToSendStateRunnable = () -> { +// moveToSendStateRunnable = null; +// updateRecordInterface(RECORD_STATE_SENDING); +// }, 200); +// } +// getParent().requestDisallowInterceptTouchEvent(true); +// return true; +// } +// if (parentFragment != null) { +// TLRPC.Chat chat = parentFragment.getCurrentChat(); +// TLRPC.UserFull userFull = parentFragment.getCurrentUserInfo(); +// if (chat != null && !(ChatObject.canSendVoice(chat) || (ChatObject.canSendRoundVideo(chat) && hasRecordVideo)) || userFull != null && userFull.voice_messages_forbidden) { +// delegate.needShowMediaBanHint(); +// return true; +// } +// } +// if (hasRecordVideo) { +// calledRecordRunnable = false; +// recordAudioVideoRunnableStarted = true; +// AndroidUtilities.runOnUIThread(recordAudioVideoRunnable, 150); +// } else { +// recordAudioVideoRunnable.run(); +// } +// return true; +// } else if (motionEvent.getAction() == MotionEvent.ACTION_UP || motionEvent.getAction() == MotionEvent.ACTION_CANCEL) { +// if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL && recordingAudioVideo) { +// if (recordCircle.slideToCancelProgress < 0.7f) { +// if (hasRecordVideo && isInVideoMode()) { +// CameraController.getInstance().cancelOnInitRunnable(onFinishInitCameraRunnable); +// delegate.needStartRecordVideo(2, true, 0); +// } else { +// delegate.needStartRecordAudio(0); +// MediaController.getInstance().stopRecording(0, false, 0); +// } +// recordingAudioVideo = false; +// updateRecordInterface(RECORD_STATE_CANCEL_BY_GESTURE); +// } else { +// recordCircle.sendButtonVisible = true; +// startLockTransition(); +// } +// return false; +// } +// if (recordCircle != null && recordCircle.isSendButtonVisible() || recordedAudioPanel != null && recordedAudioPanel.getVisibility() == VISIBLE) { +// if (recordAudioVideoRunnableStarted) { +// AndroidUtilities.cancelRunOnUIThread(recordAudioVideoRunnable); +// } +// return false; +// } +// +// float x = motionEvent.getX() + audioVideoButtonContainer.getX(); +// float dist = (x - startedDraggingX); +// float alpha = 1.0f + dist / distCanMove; +// if (alpha < 0.45) { +// if (hasRecordVideo && isInVideoMode()) { +// CameraController.getInstance().cancelOnInitRunnable(onFinishInitCameraRunnable); +// delegate.needStartRecordVideo(2, true, 0); +// } else { +// delegate.needStartRecordAudio(0); +// MediaController.getInstance().stopRecording(0, false, 0); +// } +// recordingAudioVideo = false; +// updateRecordInterface(RECORD_STATE_CANCEL_BY_GESTURE); +// } else { +// if (recordAudioVideoRunnableStarted) { +// AndroidUtilities.cancelRunOnUIThread(recordAudioVideoRunnable); +// if (sendVoiceEnabled && sendRoundEnabled) { +// delegate.onSwitchRecordMode(!isInVideoMode()); +// setRecordVideoButtonVisible(!isInVideoMode(), true); +// } else { +// delegate.needShowMediaBanHint(); +// } +// performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP); +// sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); +// } else if (!hasRecordVideo || calledRecordRunnable) { +// startedDraggingX = -1; +// if (hasRecordVideo && isInVideoMode()) { +// CameraController.getInstance().cancelOnInitRunnable(onFinishInitCameraRunnable); +// delegate.needStartRecordVideo(1, true, 0); +// } else if (!sendVoiceEnabled) { +// delegate.needShowMediaBanHint(); +// } else { +// if (recordingAudioVideo && isInScheduleMode()) { +// AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), (notify, scheduleDate) -> MediaController.getInstance().stopRecording(1, notify, scheduleDate), () -> MediaController.getInstance().stopRecording(0, false, 0), resourcesProvider); +// } +// delegate.needStartRecordAudio(0); +// MediaController.getInstance().stopRecording(isInScheduleMode() ? 3 : 1, true, 0); +// } +// recordingAudioVideo = false; +// messageTransitionIsRunning = false; +// AndroidUtilities.runOnUIThread(moveToSendStateRunnable = () -> { +// moveToSendStateRunnable = null; +// updateRecordInterface(RECORD_STATE_SENDING); +// }, 500); +// } +// } +// return true; +// } else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE && recordingAudioVideo) { +// float x = motionEvent.getX(); +// float y = motionEvent.getY(); +// if (recordCircle.isSendButtonVisible()) { +// return false; +// } +// if (recordCircle.setLockTranslation(y) == 2) { +// startLockTransition(); +// return false; +// } else { +// recordCircle.setMovingCords(x, y); +// } +// +// if (startedDraggingX == -1) { +// startedDraggingX = x; +// distCanMove = (float) (sizeNotifierLayout.getMeasuredWidth() * 0.35); +// if (distCanMove > AndroidUtilities.dp(140)) { +// distCanMove = AndroidUtilities.dp(140); +// } +// } +// +// x = x + audioVideoButtonContainer.getX(); +// float dist = (x - startedDraggingX); +// float alpha = 1.0f + dist / distCanMove; +// if (startedDraggingX != -1) { +// if (alpha > 1) { +// alpha = 1; +// } else if (alpha < 0) { +// alpha = 0; +// } +// if (slideText != null) { +// slideText.setSlideX(alpha); +// } +// if (recordCircle != null) { +// recordCircle.setSlideToCancelProgress(alpha); +// } +// } +// +// if (alpha == 0) { +// if (hasRecordVideo && isInVideoMode()) { +// CameraController.getInstance().cancelOnInitRunnable(onFinishInitCameraRunnable); +// delegate.needStartRecordVideo(2, true, 0); +// } else { +// delegate.needStartRecordAudio(0); +// MediaController.getInstance().stopRecording(0, false, 0); +// } +// recordingAudioVideo = false; +// updateRecordInterface(RECORD_STATE_CANCEL_BY_GESTURE); +// } +// return true; +// } +// view.onTouchEvent(motionEvent); +// return true; +// }); audioVideoSendButton = new ChatActivityEnterViewAnimatedIconView(context); audioVideoSendButton.setFocusable(true); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAvatarContainer.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAvatarContainer.java index cbaeaec6b..a3ca79bbd 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAvatarContainer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAvatarContainer.java @@ -1080,7 +1080,6 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent sb.append("\n"); sb.append(subtitleTextView.getText()); info.setContentDescription(sb); - setContentDescription(sb); if (info.isClickable() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { info.addAction(new AccessibilityNodeInfo.AccessibilityAction(AccessibilityNodeInfo.ACTION_CLICK, LocaleController.getString("OpenProfile", R.string.OpenProfile))); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/FloatingDebug/FloatingDebugView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/FloatingDebug/FloatingDebugView.java index 1bf4067bc..33d8a6cd7 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/FloatingDebug/FloatingDebugView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/FloatingDebug/FloatingDebugView.java @@ -57,6 +57,7 @@ import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.SeekBarView; import org.telegram.ui.LaunchActivity; +import org.telegram.ui.ProfileActivity; import java.util.ArrayList; import java.util.List; @@ -520,6 +521,7 @@ public class FloatingDebugView extends FrameLayout implements NotificationCenter NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.needSetDayNightTheme, finalThemeInfo, true, null, -1); }, 200); })); + items.add(new FloatingDebugController.DebugItem(LocaleController.getString(R.string.DebugSendLogs), () -> ProfileActivity.sendLogs((Activity) getContext(), false))); return items; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Forum/ForumBubbleDrawable.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Forum/ForumBubbleDrawable.java index b2ac09801..49adb4254 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Forum/ForumBubbleDrawable.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Forum/ForumBubbleDrawable.java @@ -35,6 +35,7 @@ public class ForumBubbleDrawable extends Drawable { private final Paint strokePaint; private final Paint topPaint; + private static SvgHelper.SvgDrawable mainDrawable; private int currentColors[]; @@ -60,7 +61,10 @@ public class ForumBubbleDrawable extends Drawable { public ForumBubbleDrawable(int color) { - svgDrawable = SvgHelper.getDrawable(R.raw.topic_bubble, Color.WHITE); + if (mainDrawable == null) { + mainDrawable = SvgHelper.getDrawable(R.raw.topic_bubble, Color.WHITE); + } + svgDrawable = mainDrawable.clone(); svgDrawable.copyCommandFromPosition(0); topPaint = new Paint(Paint.ANTI_ALIAS_FLAG); strokePaint = new Paint(Paint.ANTI_ALIAS_FLAG); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumPreviewBottomSheet.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumPreviewBottomSheet.java index 1d101ea10..67d907fee 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumPreviewBottomSheet.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/PremiumPreviewBottomSheet.java @@ -357,6 +357,9 @@ public class PremiumPreviewBottomSheet extends BottomSheetWithRecyclerListView i if (isOutboundGift) { titleView[0].setText(AndroidUtilities.replaceSingleTag(LocaleController.formatString(R.string.TelegramPremiumUserGiftedPremiumOutboundDialogTitleWithPlural, user != null ? user.first_name : "", LocaleController.formatPluralString("GiftMonths", giftTier.getMonths())), Theme.key_windowBackgroundWhiteBlueButton, AndroidUtilities.REPLACING_TAG_TYPE_LINK, null)); subtitleView.setText(AndroidUtilities.replaceSingleTag(LocaleController.formatString(R.string.TelegramPremiumUserGiftedPremiumOutboundDialogSubtitle, user != null ? user.first_name : ""), Theme.key_windowBackgroundWhiteBlueButton, AndroidUtilities.REPLACING_TAG_TYPE_LINK, null)); + } else if (user != null && user.id == 777000) { + titleView[0].setText(AndroidUtilities.replaceSingleTag(LocaleController.formatString(R.string.TelegramPremiumUserGiftedPremiumDialogTitleWithPluralSomeone, LocaleController.formatPluralString("GiftMonths", giftTier.getMonths())), Theme.key_windowBackgroundWhiteBlueButton, AndroidUtilities.REPLACING_TAG_TYPE_LINK, null)); + subtitleView.setText(AndroidUtilities.replaceTags(LocaleController.getString(R.string.TelegramPremiumUserGiftedPremiumDialogSubtitle))); } else { titleView[0].setText(AndroidUtilities.replaceSingleTag(LocaleController.formatString(R.string.TelegramPremiumUserGiftedPremiumDialogTitleWithPlural, user != null ? user.first_name : "", LocaleController.formatPluralString("GiftMonths", giftTier.getMonths())), Theme.key_windowBackgroundWhiteBlueButton, AndroidUtilities.REPLACING_TAG_TYPE_LINK, null)); subtitleView.setText(AndroidUtilities.replaceTags(LocaleController.getString(R.string.TelegramPremiumUserGiftedPremiumDialogSubtitle))); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java index 4fd9a7182..76363620a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/DialogsActivity.java @@ -6665,6 +6665,11 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. chatActivity.setPreloadedSticker(sticker, true); } } + if (AndroidUtilities.isTablet()) { + if (rightSlidingDialogContainer.currentFragment != null) { + rightSlidingDialogContainer.finishPreview(); + } + } presentFragment(chatActivity); } } @@ -8797,7 +8802,16 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. long dialogId = (Long) args[0]; TLRPC.User user = (TLRPC.User) args[1]; TLRPC.Chat chat = (TLRPC.Chat) args[2]; - boolean revoke = (Boolean) args[3]; + boolean revoke; + boolean botBlock; + if (user != null && user.bot) { + revoke = false; + botBlock = (Boolean) args[3]; + } else { + revoke = (Boolean) args[3]; + botBlock = false; + } + Runnable deleteRunnable = () -> { if (chat != null) { if (ChatObject.isNotInChat(chat)) { @@ -8807,7 +8821,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter. } } else { getMessagesController().deleteDialog(dialogId, 0, revoke); - if (user != null && user.bot) { + if (user != null && user.bot && botBlock) { getMessagesController().blockPeer(user.id); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/DownloadProgressIcon.java b/TMessagesProj/src/main/java/org/telegram/ui/DownloadProgressIcon.java index 79d334f82..e7ac9b0d8 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/DownloadProgressIcon.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/DownloadProgressIcon.java @@ -161,8 +161,13 @@ public class DownloadProgressIcon extends View implements NotificationCenter.Not } } if (currentListeners.size() == 0 && (getVisibility() != View.VISIBLE || getAlpha() != 1f)) { - progress = 0; - currentProgress = 0; + if (DownloadController.getInstance(currentAccount).hasUnviewedDownloads()) { + progress = 1f; + currentProgress = 1f; + } else { + progress = 0; + currentProgress = 0; + } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java index e9f8df0f5..9c4f23af5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java @@ -3514,27 +3514,12 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati } })); } else if (username != null) { - TLObject req; - if (AndroidUtilities.isNumeric(username)) { - TLRPC.TL_contacts_resolvePhone resolvePhone = new TLRPC.TL_contacts_resolvePhone(); - resolvePhone.phone = username; - req = resolvePhone; - } else { - TLRPC.TL_contacts_resolveUsername resolveUsername = new TLRPC.TL_contacts_resolveUsername(); - resolveUsername.username = username; - req = resolveUsername; - } - requestId[0] = ConnectionsManager.getInstance(intentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> { + MessagesController.getInstance(intentAccount).getUserNameResolver().resolve(username, (peerId) -> { if (!LaunchActivity.this.isFinishing()) { boolean hideProgressDialog = true; - TLRPC.TL_contacts_resolvedPeer res = (TLRPC.TL_contacts_resolvedPeer) response; - if (error == null && actionBarLayout != null && (game == null && voicechat == null || game != null && !res.users.isEmpty() || voicechat != null && !res.chats.isEmpty() || livestream != null && !res.chats.isEmpty())) { - MessagesController.getInstance(intentAccount).putUsers(res.users, false); - MessagesController.getInstance(intentAccount).putChats(res.chats, false); - MessagesStorage.getInstance(intentAccount).putUsersAndChats(res.users, res.chats, false, true); - + if (peerId != null && actionBarLayout != null && (game == null && voicechat == null || game != null && peerId > 0 || voicechat != null && peerId > 0 || livestream != null && peerId < 0)) { if (!TextUtils.isEmpty(botAppMaybe)) { - TLRPC.User user = MessagesController.getInstance(intentAccount).getUser(res.peer.user_id); + TLRPC.User user = MessagesController.getInstance(intentAccount).getUser(peerId); if (user != null && user.bot) { TLRPC.TL_messages_getBotApp getBotApp = new TLRPC.TL_messages_getBotApp(); TLRPC.TL_inputBotAppShortName app = new TLRPC.TL_inputBotAppShortName(); @@ -3593,11 +3578,11 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati } if (setAsAttachBot != null && attachMenuBotToOpen == null) { - TLRPC.User user = MessagesController.getInstance(intentAccount).getUser(res.peer.user_id); + TLRPC.User user = MessagesController.getInstance(intentAccount).getUser(peerId); if (user != null && user.bot) { if (user.bot_attach_menu) { TLRPC.TL_messages_getAttachMenuBot getAttachMenuBot = new TLRPC.TL_messages_getAttachMenuBot(); - getAttachMenuBot.bot = MessagesController.getInstance(intentAccount).getInputUser(res.peer.user_id); + getAttachMenuBot.bot = MessagesController.getInstance(intentAccount).getInputUser(peerId); ConnectionsManager.getInstance(intentAccount).sendRequest(getAttachMenuBot, (response1, error1) -> AndroidUtilities.runOnUIThread(() -> { if (response1 instanceof TLRPC.TL_attachMenuBotsBot) { TLRPC.TL_attachMenuBotsBot attachMenuBotsBot = (TLRPC.TL_attachMenuBotsBot) response1; @@ -3677,7 +3662,7 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati .setMessage(AndroidUtilities.replaceTags(LocaleController.formatString("BotRequestAttachPermission", R.string.BotRequestAttachPermission, UserObject.getUserName(user)))) .setPositiveButton(LocaleController.getString(R.string.BotAddToMenu), (dialog, which) -> { TLRPC.TL_messages_toggleBotInAttachMenu botRequest = new TLRPC.TL_messages_toggleBotInAttachMenu(); - botRequest.bot = MessagesController.getInstance(intentAccount).getInputUser(res.peer.user_id); + botRequest.bot = MessagesController.getInstance(intentAccount).getInputUser(peerId); botRequest.enabled = true; botRequest.write_allowed = allowWrite.get(); @@ -3723,8 +3708,9 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati } else { BulletinFactory.of(mainFragmentsStack.get(mainFragmentsStack.size() - 1)).createErrorBulletin(LocaleController.getString(R.string.BotSetAttachLinkNotBot)).show(); } - } else if (messageId != null && (commentId != null || threadId != null) && !res.chats.isEmpty()) { - requestId[0] = runCommentRequest(intentAccount, dismissLoading, messageId, commentId, threadId, res.chats.get(0)); + } else if (messageId != null && (commentId != null || threadId != null) && peerId < 0) { + TLRPC.Chat chat = MessagesController.getInstance(intentAccount).getChat(-peerId); + requestId[0] = runCommentRequest(intentAccount, dismissLoading, messageId, commentId, threadId, chat); if (requestId[0] != 0) { hideProgressDialog = false; } @@ -3736,12 +3722,13 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati args.putString("selectAlertString", LocaleController.getString("SendGameToText", R.string.SendGameToText)); args.putString("selectAlertStringGroup", LocaleController.getString("SendGameToGroupText", R.string.SendGameToGroupText)); DialogsActivity fragment = new DialogsActivity(args); + TLRPC.User user = MessagesController.getInstance(intentAccount).getUser(peerId); fragment.setDelegate((fragment1, dids, message1, param, topicsFragment) -> { long did = dids.get(0).dialogId; TLRPC.TL_inputMediaGame inputMediaGame = new TLRPC.TL_inputMediaGame(); inputMediaGame.id = new TLRPC.TL_inputGameShortName(); inputMediaGame.id.short_name = game; - inputMediaGame.id.bot_id = MessagesController.getInstance(intentAccount).getInputUser(res.users.get(0)); + inputMediaGame.id.bot_id = MessagesController.getInstance(intentAccount).getInputUser(user); SendMessagesHelper.getInstance(intentAccount).sendGame(MessagesController.getInstance(intentAccount).getInputPeer(did), inputMediaGame, 0, 0); Bundle args1 = new Bundle(); @@ -3784,7 +3771,7 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati drawerLayoutContainer.setAllowOpenDrawer(true, false); } } else if (botChat != null || botChannel != null) { - final TLRPC.User user = !res.users.isEmpty() ? res.users.get(0) : null; + final TLRPC.User user = MessagesController.getInstance(intentAccount).getUser(peerId); if (user == null || user.bot && user.bot_nochats) { try { if (!mainFragmentsStack.isEmpty()) { @@ -3936,14 +3923,15 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati long dialog_id; boolean isBot = false; Bundle args = new Bundle(); - if (!res.chats.isEmpty()) { - args.putLong("chat_id", res.chats.get(0).id); - dialog_id = -res.chats.get(0).id; + TLRPC.User user = MessagesController.getInstance(intentAccount).getUser(peerId); + if (peerId < 0) { + args.putLong("chat_id", -peerId); + dialog_id = peerId; } else { - args.putLong("user_id", res.users.get(0).id); - dialog_id = res.users.get(0).id; + args.putLong("user_id", peerId); + dialog_id = peerId; } - if (botUser != null && res.users.size() > 0 && res.users.get(0).bot) { + if (botUser != null && user != null && user.bot) { args.putString("botUser", botUser); isBot = true; } @@ -4080,17 +4068,15 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati } } else { try { - if (!mainFragmentsStack.isEmpty()) { - BaseFragment fragment = mainFragmentsStack.get(mainFragmentsStack.size() - 1); - if (fragment instanceof ChatActivity) { - ((ChatActivity) fragment).shakeContent(); + BaseFragment lastFragment = LaunchActivity.getLastFragment(); + if (lastFragment != null) { + if (lastFragment instanceof ChatActivity) { + ((ChatActivity) lastFragment).shakeContent(); } - if (error != null && error.text != null && error.text.startsWith("FLOOD_WAIT")) { - BulletinFactory.of(fragment).createErrorBulletin(LocaleController.getString("FloodWait", R.string.FloodWait)).show(); - } else if (AndroidUtilities.isNumeric(username)) { - BulletinFactory.of(fragment).createErrorBulletin(LocaleController.getString("NoPhoneFound", R.string.NoPhoneFound)).show(); + if (AndroidUtilities.isNumeric(username)) { + BulletinFactory.of(lastFragment).createErrorBulletin(LocaleController.getString("NoPhoneFound", R.string.NoPhoneFound)).show(); } else { - BulletinFactory.of(fragment).createErrorBulletin(LocaleController.getString("NoUsernameFound", R.string.NoUsernameFound)).show(); + BulletinFactory.of(lastFragment).createErrorBulletin(LocaleController.getString("NoUsernameFound", R.string.NoUsernameFound)).show(); } } } catch (Exception e) { @@ -4106,7 +4092,7 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati } } } - }, ConnectionsManager.RequestFlagFailOnServerErrors)); + }); } else if (group != null) { if (state == 0) { final TLRPC.TL_messages_checkChatInvite req = new TLRPC.TL_messages_checkChatInvite(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LiteModeSettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LiteModeSettingsActivity.java index c7812f962..0285ce26e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LiteModeSettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LiteModeSettingsActivity.java @@ -78,6 +78,8 @@ public class LiteModeSettingsActivity extends BaseFragment { Bulletin restrictBulletin; + private int FLAGS_CHAT; + @Override public View createView(Context context) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); @@ -142,6 +144,7 @@ public class LiteModeSettingsActivity extends BaseFragment { }); fragmentView = contentView; + FLAGS_CHAT = AndroidUtilities.isTablet() ? (LiteMode.FLAGS_CHAT & ~LiteMode.FLAG_CHAT_FORUM_TWOCOLUMN) : LiteMode.FLAGS_CHAT; updateItems(); @@ -168,7 +171,7 @@ public class LiteModeSettingsActivity extends BaseFragment { return 0; } else if (flags == LiteMode.FLAGS_ANIMATED_EMOJI) { return 1; - } else if (flags == LiteMode.FLAGS_CHAT) { + } else if (flags == FLAGS_CHAT) { return 2; } return -1; @@ -206,10 +209,12 @@ public class LiteModeSettingsActivity extends BaseFragment { items.add(Item.asCheckbox(LocaleController.getString("LiteOptionsAutoplayReactions"), LiteMode.FLAG_ANIMATED_EMOJI_REACTIONS)); items.add(Item.asCheckbox(LocaleController.getString("LiteOptionsAutoplayChat"), LiteMode.FLAG_ANIMATED_EMOJI_CHAT)); } - items.add(Item.asSwitch(R.drawable.msg2_ask_question, LocaleController.getString("LiteOptionsChat"), LiteMode.FLAGS_CHAT)); + items.add(Item.asSwitch(R.drawable.msg2_ask_question, LocaleController.getString("LiteOptionsChat"), FLAGS_CHAT)); if (expanded[2]) { items.add(Item.asCheckbox(LocaleController.getString("LiteOptionsBackground"), LiteMode.FLAG_CHAT_BACKGROUND)); - items.add(Item.asCheckbox(LocaleController.getString("LiteOptionsTopics"), LiteMode.FLAG_CHAT_FORUM_TWOCOLUMN)); + if (!AndroidUtilities.isTablet()) { + items.add(Item.asCheckbox(LocaleController.getString("LiteOptionsTopics"), LiteMode.FLAG_CHAT_FORUM_TWOCOLUMN)); + } items.add(Item.asCheckbox(LocaleController.getString("LiteOptionsSpoiler"), LiteMode.FLAG_CHAT_SPOILER)); if (SharedConfig.getDevicePerformanceClass() >= SharedConfig.PERFORMANCE_CLASS_AVERAGE) { items.add(Item.asCheckbox(LocaleController.getString("LiteOptionsBlur"), LiteMode.FLAG_CHAT_BLUR)); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java index 09b8176e4..0b99c778a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java @@ -3658,6 +3658,8 @@ public class LoginActivity extends BaseFragment { if (currentType == AUTH_TYPE_MESSAGE) { if (nextType == AUTH_TYPE_FLASH_CALL || nextType == AUTH_TYPE_CALL || nextType == AUTH_TYPE_MISSED_CALL) { problemText.setText(LocaleController.getString("DidNotGetTheCodePhone", R.string.DidNotGetTheCodePhone)); + } else if (nextType == 0) { + problemText.setText(LocaleController.getString("DidNotGetTheCode", R.string.DidNotGetTheCode)); } else { problemText.setText(LocaleController.getString("DidNotGetTheCodeSms", R.string.DidNotGetTheCodeSms)); } @@ -3907,9 +3909,11 @@ public class LoginActivity extends BaseFragment { } else if (currentType == AUTH_TYPE_FLASH_CALL) { AndroidUtilities.setWaitingForCall(true); NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.didReceiveCall); - AndroidUtilities.runOnUIThread(() -> { - CallReceiver.checkLastReceivedCall(); - }); + if (restore) { + AndroidUtilities.runOnUIThread(() -> { + CallReceiver.checkLastReceivedCall(); + }); + } } currentParams = params; @@ -4238,7 +4242,6 @@ public class LoginActivity extends BaseFragment { AndroidUtilities.setWaitingForSms(false); NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.didReceiveSmsCode); } else if (currentType == AUTH_TYPE_FLASH_CALL) { - AndroidUtilities.setWaitingForCall(false); NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.didReceiveCall); } waitingForEvent = false; @@ -4469,6 +4472,9 @@ public class LoginActivity extends BaseFragment { } else if (currentType == AUTH_TYPE_FLASH_CALL) { AndroidUtilities.setWaitingForCall(true); NotificationCenter.getGlobalInstance().addObserver(LoginActivitySmsView.this, NotificationCenter.didReceiveCall); + AndroidUtilities.runOnUIThread(() -> { + CallReceiver.checkLastReceivedCall(); + }); } waitingForEvent = true; if (currentType != AUTH_TYPE_FLASH_CALL) { @@ -4502,6 +4508,7 @@ public class LoginActivity extends BaseFragment { if (ok) { if (currentType == AUTH_TYPE_FLASH_CALL) { AndroidUtilities.endIncomingCall(); + AndroidUtilities.setWaitingForCall(false); } } }), ConnectionsManager.RequestFlagFailOnServerErrors | ConnectionsManager.RequestFlagWithoutLogin); @@ -4513,6 +4520,10 @@ public class LoginActivity extends BaseFragment { } private void animateSuccess(Runnable callback) { + if (currentType == AUTH_TYPE_FLASH_CALL) { + callback.run(); + return; + } for (int i = 0; i < codeFieldContainer.codeField.length; i++) { int finalI = i; codeFieldContainer.postDelayed(()-> codeFieldContainer.codeField[finalI].animateSuccessProgress(1f), i * 75L); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PremiumPreviewFragment.java b/TMessagesProj/src/main/java/org/telegram/ui/PremiumPreviewFragment.java index e7b884003..edb0e7404 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PremiumPreviewFragment.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PremiumPreviewFragment.java @@ -664,10 +664,13 @@ public class PremiumPreviewFragment extends BaseFragment implements Notification if (tier == null) { forcePremium = true; - for (TLRPC.TL_premiumSubscriptionOption option : fragment.getAccountInstance().getMediaDataController().getPremiumPromo().period_options) { - if (option.months == 1) { - tier = new SubscriptionTier(option); - break; + TLRPC.TL_help_premiumPromo promo = fragment.getAccountInstance().getMediaDataController().getPremiumPromo(); + if (promo != null) { + for (TLRPC.TL_premiumSubscriptionOption option : promo.period_options) { + if (option.months == 1) { + tier = new SubscriptionTier(option); + break; + } } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java index 618765557..c5e10957a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java @@ -1806,10 +1806,15 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } } else { if (!userBlocked) { - getMessagesController().blockPeer(userId); + AlertsCreator.createClearOrDeleteDialogAlert(ProfileActivity.this, false, currentChat, user, currentEncryptedChat != null, true, true, (param) -> { + if (getParentLayout().getFragmentStack().get(getParentLayout().getFragmentStack().size() - 2) instanceof ChatActivity) { + getParentLayout().removeFragmentFromStack(getParentLayout().getFragmentStack().size() - 2); + } + finishFragment(); + getNotificationCenter().postNotificationName(NotificationCenter.needDeleteDialog, dialogId, user, currentChat, param); + }, getResourceProvider()); } else { - getMessagesController().unblockPeer(userId); - getSendMessagesHelper().sendMessage("/start", userId, null, null, null, false, null, null, null, true, 0, null, false); + getMessagesController().unblockPeer(userId, ()-> getSendMessagesHelper().sendMessage("/start", userId, null, null, null, false, null, null, null, true, 0, null, false)); finishFragment(); } } @@ -7944,10 +7949,12 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. if (userBlocked) { otherItem.addSubItem(block_contact, R.drawable.msg_block, LocaleController.getString("Unblock", R.string.Unblock)); } + otherItem.addSubItem(add_shortcut, R.drawable.msg_home, LocaleController.getString("AddShortcut", R.string.AddShortcut)); } else { if (currentEncryptedChat == null) { createAutoDeleteItem(context); } + otherItem.addSubItem(add_shortcut, R.drawable.msg_home, LocaleController.getString("AddShortcut", R.string.AddShortcut)); if (isBot) { otherItem.addSubItem(share, R.drawable.msg_share, LocaleController.getString("BotShare", R.string.BotShare)); } else { @@ -7957,7 +7964,11 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. otherItem.addSubItem(share_contact, R.drawable.msg_share, LocaleController.getString("ShareContact", R.string.ShareContact)); } if (isBot) { - otherItem.addSubItem(block_contact, !userBlocked ? R.drawable.msg_block : R.drawable.msg_retry, !userBlocked ? LocaleController.getString("BotStop", R.string.BotStop) : LocaleController.getString("BotRestart", R.string.BotRestart)); + if (!userBlocked) { + otherItem.addSubItem(block_contact, R.drawable.msg_block2, LocaleController.getString(R.string.DeleteAndBlock)).setColors(getThemedColor(Theme.key_dialogTextRed), getThemedColor(Theme.key_dialogTextRed)); + } else { + otherItem.addSubItem(block_contact, R.drawable.msg_retry, LocaleController.getString("BotRestart", R.string.BotRestart)); + } } else { otherItem.addSubItem(block_contact, !userBlocked ? R.drawable.msg_block : R.drawable.msg_block, !userBlocked ? LocaleController.getString("BlockContact", R.string.BlockContact) : LocaleController.getString("Unblock", R.string.Unblock)); } @@ -7980,7 +7991,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } otherItem.addSubItem(start_secret_chat, R.drawable.msg_secret, LocaleController.getString("StartEncryptedChat", R.string.StartEncryptedChat)); } - otherItem.addSubItem(add_shortcut, R.drawable.msg_home, LocaleController.getString("AddShortcut", R.string.AddShortcut)); + if (!isBot && getContactsController().contactsDict.get(userId) != null) { + otherItem.addSubItem(add_shortcut, R.drawable.msg_home, LocaleController.getString("AddShortcut", R.string.AddShortcut)); + } } } else if (chatId != 0) { TLRPC.Chat chat = getMessagesController().getChat(chatId); @@ -8662,6 +8675,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. try { File dir = AndroidUtilities.getLogsDir(); if (dir == null) { + AndroidUtilities.runOnUIThread(progressDialog::dismiss); return; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ThemePreviewActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ThemePreviewActivity.java index a36a46b81..4ec9a5683 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ThemePreviewActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ThemePreviewActivity.java @@ -2070,10 +2070,12 @@ public class ThemePreviewActivity extends BaseFragment implements DownloadContro editor.putString("lastDayTheme", applyingTheme.getKey()); editor.commit(); } + BaseFragment lastFragment = getParentLayout().getFragmentStack().get(Math.max(0, getParentLayout().getFragmentStack().size() - 2)); finishFragment(); if (screenType == SCREEN_TYPE_PREVIEW) { NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.didApplyNewTheme, previousTheme, previousAccent, deleteOnCancel); } + Theme.turnOffAutoNight(lastFragment); }); } diff --git a/TMessagesProj/src/main/res/values/strings.xml b/TMessagesProj/src/main/res/values/strings.xml index b0300e866..28968e2cc 100644 --- a/TMessagesProj/src/main/res/values/strings.xml +++ b/TMessagesProj/src/main/res/values/strings.xml @@ -3492,7 +3492,6 @@ has no access to messages What can this bot do? START - Start bot RESTART Stop bot Restart bot @@ -5842,6 +5841,7 @@ Emoji status is a premium feature. Other features included in **Telegram Premium**: This is %1$s\'s current status. **%1$s** has gifted you a %2$s subscription for Telegram Premium. + Someone has gifted you a %1$s subscription for Telegram Premium. You now have access to additional features. You gifted **%1$s** a %2$s subscription for Telegram Premium. **%1$s** now have access to additional features. @@ -6375,6 +6375,9 @@ Telegram Premium Required Due to the high cost of SMS in your country, you need a **Telegram Premium** account to immediately reset this email via an SMS code.\n\nYou can ask a friend to gift a Premium subscription for your account **%1$s** Resetting email, please wait... + Delete and Block + Block bot + Are you sure you want to delete the chat with **%1$s**? Decrease speed Storing on SD card will make Telegram slow. Proceed anyway? Proceed diff --git a/gradle.properties b/gradle.properties index 80a5d5731..8d19ce835 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,8 +13,8 @@ # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true #Sat Mar 12 05:53:50 MSK 2016 -APP_VERSION_CODE=3237 -APP_VERSION_NAME=9.5.6 +APP_VERSION_CODE=3249 +APP_VERSION_NAME=9.5.7 APP_PACKAGE=org.telegram.messenger RELEASE_KEY_PASSWORD=android RELEASE_KEY_ALIAS=androidkey