diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java index 01de5ae21..194a65e38 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 = 3023; - public static String BUILD_VERSION_STRING = "9.3.2"; + public static int BUILD_VERSION = 3026; + public static String BUILD_VERSION_STRING = "9.3.3"; public static int APP_ID = 4; public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103"; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/DatabaseMigrationHelper.java b/TMessagesProj/src/main/java/org/telegram/messenger/DatabaseMigrationHelper.java index a26eaa99a..1ecc488f4 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/DatabaseMigrationHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/DatabaseMigrationHelper.java @@ -1212,6 +1212,12 @@ public class DatabaseMigrationHelper { version = 110; } + if (version == 110) { + database.executeFast("CREATE TABLE stickersets(id INTEGER PRIMATE KEY, data BLOB, hash INTEGER);").stepThis().dispose(); + database.executeFast("PRAGMA user_version = 111").stepThis().dispose(); + version = 111; + } + return version; } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java index ead765882..757cd1521 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java @@ -71,7 +71,7 @@ public class FileLog { private static HashSet excludeRequests; public static void dumpResponseAndRequest(TLObject request, TLObject response, TLRPC.TL_error error, long requestMsgId, long startRequestTimeInMillis, int requestToken) { - if (!BuildVars.DEBUG_PRIVATE_VERSION || !BuildVars.LOGS_ENABLED || request == null || SharedConfig.getDevicePerformanceClass() != SharedConfig.PERFORMANCE_CLASS_LOW) { + if (!BuildVars.DEBUG_PRIVATE_VERSION || !BuildVars.LOGS_ENABLED || request == null || SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_LOW) { return; } String requestSimpleName = request.getClass().getSimpleName(); @@ -119,6 +119,7 @@ public class FileLog { return; } try { + checkGson(); getInstance().dateFormat.format(System.currentTimeMillis()); String messageStr = "receive message -> " + message.getClass().getSimpleName() + " : " + gson.toJson(message); String res = "null"; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ImageReceiver.java b/TMessagesProj/src/main/java/org/telegram/messenger/ImageReceiver.java index 3ca9ae14e..0ef7415bc 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ImageReceiver.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ImageReceiver.java @@ -2775,15 +2775,19 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg if (type == TYPE_MEDIA) { currentMediaKey = null; currentMediaDrawable = null; + mediaShader = null; } else if (type == TYPE_CROSSFDADE) { crossfadeKey = null; crossfadeImage = null; + crossfadeShader = null; } else if (type == TYPE_THUMB) { currentThumbDrawable = null; currentThumbKey = null; + thumbShader = null; } else { currentImageDrawable = null; currentImageKey = null; + imageShader = null; } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java b/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java index 5ae8c1f1f..4c8c27238 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java @@ -701,6 +701,7 @@ public class MediaDataController extends BaseController { return; } imageReceiver.setUniqKeyPrefix("preload"); + imageReceiver.setFileLoadingPriority(FileLoader.PRIORITY_LOW); imageReceiver.setImage(location, filter, null, null, 0, FileLoader.PRELOAD_CACHE_TYPE); } @@ -1083,10 +1084,14 @@ public class MediaDataController extends BaseController { } public TLRPC.TL_messages_stickerSet getStickerSet(TLRPC.InputStickerSet inputStickerSet, boolean cacheOnly) { - return getStickerSet(inputStickerSet, cacheOnly, null); + return getStickerSet(inputStickerSet, null, cacheOnly, null); } - public TLRPC.TL_messages_stickerSet getStickerSet(TLRPC.InputStickerSet inputStickerSet, boolean cacheOnly, Utilities.Callback onResponse) { + public TLRPC.TL_messages_stickerSet getStickerSet(TLRPC.InputStickerSet inputStickerSet, Integer hash, boolean cacheOnly) { + return getStickerSet(inputStickerSet, hash, cacheOnly, null); + } + + public TLRPC.TL_messages_stickerSet getStickerSet(TLRPC.InputStickerSet inputStickerSet, Integer hash, boolean cacheOnly, Utilities.Callback onResponse) { if (inputStickerSet == null) { return null; } @@ -1104,37 +1109,149 @@ public class MediaDataController extends BaseController { } return cacheSet; } - if (cacheOnly) { - return null; + if (inputStickerSet instanceof TLRPC.TL_inputStickerSetID && hash != null) { + getMessagesStorage().getStorageQueue().postRunnable(() -> { + TLRPC.TL_messages_stickerSet cachedSet = getCachedStickerSetInternal(inputStickerSet.id, hash); + AndroidUtilities.runOnUIThread(() -> { + if (cachedSet != null) { + if (onResponse != null) { + onResponse.run(cachedSet); + } + if (cachedSet.set != null) { + stickerSetsById.put(cachedSet.set.id, cachedSet); + stickerSetsByName.put(cachedSet.set.short_name.toLowerCase(), cachedSet); + } + getNotificationCenter().postNotificationName(NotificationCenter.groupStickersDidLoad, cachedSet.set.id, cachedSet); + } else { + fetchStickerSetInternal(inputStickerSet, (ok, set) -> { + if (onResponse != null) { + onResponse.run(set); + } + if (set != null && set.set != null) { + stickerSetsById.put(set.set.id, set); + stickerSetsByName.put(set.set.short_name.toLowerCase(), set); + saveStickerSetIntoCache(set); + getNotificationCenter().postNotificationName(NotificationCenter.groupStickersDidLoad, set.set.id, set); + } + }); + } + }); + }); + } else if (!cacheOnly) { + fetchStickerSetInternal(inputStickerSet, (ok, set) -> { + if (onResponse != null) { + onResponse.run(set); + } + if (set != null) { + if (set.set != null) { + stickerSetsById.put(set.set.id, set); + stickerSetsByName.put(set.set.short_name.toLowerCase(), set); + if (inputStickerSet instanceof TLRPC.TL_inputStickerSetEmojiDefaultStatuses) { + stickerSetDefaultStatuses = set; + } + } + saveStickerSetIntoCache(set); + getNotificationCenter().postNotificationName(NotificationCenter.groupStickersDidLoad, set.set.id, set); + } + }); + } + return null; + } + + private void saveStickerSetIntoCache(TLRPC.TL_messages_stickerSet set) { + if (set == null || set.set == null) { + return; + } + getMessagesStorage().getStorageQueue().postRunnable(() -> { + try { + SQLitePreparedStatement state = getMessagesStorage().getDatabase().executeFast("REPLACE INTO stickersets VALUES(?, ?, ?)"); + state.requery(); + NativeByteBuffer data = new NativeByteBuffer(set.getObjectSize()); + set.serializeToStream(data); + state.bindLong(1, set.set.id); + state.bindByteBuffer(2, data); + state.bindInteger(3, set.set.hash); + state.step(); + data.reuse(); + state.dispose(); + } catch (Exception e) { + FileLog.e(e); + } + }); + } + + private TLRPC.TL_messages_stickerSet getCachedStickerSetInternal(long id, Integer hash) { + TLRPC.TL_messages_stickerSet set = null; + SQLiteCursor cursor = null; + NativeByteBuffer data = null; + try { + cursor = getMessagesStorage().getDatabase().queryFinalized("SELECT data, hash FROM stickersets WHERE id = " + id + " LIMIT 1"); + if (cursor.next() && !cursor.isNull(0)) { + data = cursor.byteBufferValue(0); + if (data != null) { + set = TLRPC.TL_messages_stickerSet.TLdeserialize(data, data.readInt32(false), false); + int cachedHash = cursor.intValue(1); + if (hash != null && hash != cachedHash) { + return null; + } + } + } + } catch (Throwable e) { + FileLog.e(e); + } finally { + if (data != null) { + data.reuse(); + } + if (cursor != null) { + cursor.dispose(); + } + } + return set; + } + + private void fetchStickerSetInternal(long id, Integer hash, Utilities.Callback2 onDone) { + if (onDone == null) { + return; + } + TLRPC.TL_messages_getStickerSet req = new TLRPC.TL_messages_getStickerSet(); + TLRPC.TL_inputStickerSetID inputStickerSetID = new TLRPC.TL_inputStickerSetID(); + inputStickerSetID.id = id; + req.stickerset = inputStickerSetID; + if (hash != null) { + req.hash = hash; + } + getConnectionsManager().sendRequest(req, (response, error) -> { + AndroidUtilities.runOnUIThread(() -> { +// if (error != null && "".equals(error.text)) { +// onDone.run(true, null); +// } else + if (response != null) { + onDone.run(true, (TLRPC.TL_messages_stickerSet) response); + } else { + onDone.run(false, null); + } + }); + }); + } + + private void fetchStickerSetInternal(TLRPC.InputStickerSet inputStickerSet, Utilities.Callback2 onDone) { + if (onDone == null) { + return; } TLRPC.TL_messages_getStickerSet req = new TLRPC.TL_messages_getStickerSet(); req.stickerset = inputStickerSet; getConnectionsManager().sendRequest(req, (response, error) -> { - if (response != null) { - TLRPC.TL_messages_stickerSet set = (TLRPC.TL_messages_stickerSet) response; - AndroidUtilities.runOnUIThread(() -> { - if (set == null || set.set == null) { - return; - } - stickerSetsById.put(set.set.id, set); - stickerSetsByName.put(set.set.short_name.toLowerCase(), set); - if (inputStickerSet instanceof TLRPC.TL_inputStickerSetEmojiDefaultStatuses) { - stickerSetDefaultStatuses = set; - } - getNotificationCenter().postNotificationName(NotificationCenter.groupStickersDidLoad, set.set.id, set); - if (onResponse != null) { - onResponse.run(set); - } - }); - } else { - AndroidUtilities.runOnUIThread(() -> { - if (onResponse != null) { - onResponse.run(null); - } - }); - } + AndroidUtilities.runOnUIThread(() -> { +// if (error != null && "".equals(error.text)) { +// onDone.run(true, null); +// } else + if (response != null) { + onDone.run(true, (TLRPC.TL_messages_stickerSet) response); + } else { + onDone.run(false, null); + } + }); }); - return null; } private void loadGroupStickerSet(TLRPC.StickerSet stickerSet, boolean cache) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java index a7e0c8cf3..c6a523a91 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; @@ -94,7 +93,7 @@ public class MessagesStorage extends BaseController { } } - private final static int LAST_DB_VERSION = 110; + private final static int LAST_DB_VERSION = 111; private boolean databaseMigrationInProgress; public boolean showClearDatabaseAlert; private LongSparseIntArray dialogIsForum = new LongSparseIntArray(); @@ -374,6 +373,7 @@ public class MessagesStorage extends BaseController { database.executeFast("CREATE TABLE stickers_v2(id INTEGER PRIMARY KEY, data BLOB, date INTEGER, hash INTEGER);").stepThis().dispose(); database.executeFast("CREATE TABLE stickers_featured(id INTEGER PRIMARY KEY, data BLOB, unread BLOB, date INTEGER, hash INTEGER, premium INTEGER, emoji INTEGER);").stepThis().dispose(); database.executeFast("CREATE TABLE stickers_dice(emoji TEXT PRIMARY KEY, data BLOB, date INTEGER);").stepThis().dispose(); + database.executeFast("CREATE TABLE stickersets(id INTEGER PRIMATE KEY, data BLOB, hash INTEGER);").stepThis().dispose(); database.executeFast("CREATE TABLE hashtag_recent_v2(id TEXT PRIMARY KEY, date INTEGER);").stepThis().dispose(); database.executeFast("CREATE TABLE webpage_pending_v2(id INTEGER, mid INTEGER, uid INTEGER, PRIMARY KEY (id, mid, uid));").stepThis().dispose(); database.executeFast("CREATE TABLE sent_files_v2(uid TEXT, type INTEGER, data BLOB, parent TEXT, PRIMARY KEY (uid, type))").stepThis().dispose(); @@ -1083,6 +1083,7 @@ public class MessagesStorage extends BaseController { database.executeFast("DELETE FROM attach_menu_bots").stepThis().dispose(); database.executeFast("DELETE FROM animated_emoji").stepThis().dispose(); database.executeFast("DELETE FROM stickers_v2").stepThis().dispose(); + database.executeFast("DELETE FROM stickersets").stepThis().dispose(); database.executeFast("DELETE FROM messages_holes_topics").stepThis().dispose(); database.executeFast("DELETE FROM messages_topics").stepThis().dispose(); database.executeFast("DELETE FROM topics").stepThis().dispose(); @@ -9722,14 +9723,14 @@ public class MessagesStorage extends BaseController { cursor.dispose(); cursor = null; - database.executeFast(String.format(Locale.US, "UPDATE messages_topics SET read_state = read_state | 1 WHERE uid = %d AND topic_id = %d AND mid <= %d AND read_state IN(0,2) AND out = 0", -chatId, mid, readMaxId)).stepThis().dispose(); + database.executeFast(String.format(Locale.US, "UPDATE messages_topics SET read_state = read_state | 1 WHERE uid = %d AND topic_id = %d AND mid <= %d AND read_state IN(0, 2) AND out = 0", -chatId, mid, readMaxId)).stepThis().dispose(); //mark mentions as read - database.executeFast(String.format(Locale.US, "UPDATE messages_topics SET read_state = read_state | 2 WHERE uid = %d AND topic_id = %d AND mid <= %d AND read_state IN(0,1) AND out = 0", -chatId, mid, readMaxId)).stepThis().dispose(); + database.executeFast(String.format(Locale.US, "UPDATE messages_topics SET read_state = read_state | 2 WHERE uid = %d AND topic_id = %d AND mid <= %d AND read_state IN(0, 1) AND out = 0", -chatId, mid, readMaxId)).stepThis().dispose(); int unreadMentionsCount = -1; if (unreadCount < 0) { unreadCount = 0; - cursor = database.queryFinalized(String.format(Locale.US, "SELECT count(mid) FROM messages_topics WHERE uid = %d AND topic_id = %d AND mid > %d AND read_state IN(0,2) AND out = 0", -chatId, mid, readMaxId)); + cursor = database.queryFinalized(String.format(Locale.US, "SELECT count(mid) FROM messages_topics WHERE uid = %d AND topic_id = %d AND mid > %d AND read_state IN(0, 2) AND out = 0", -chatId, mid, readMaxId)); if (cursor.next()) { unreadCount = cursor.intValue(0); } @@ -9738,12 +9739,23 @@ public class MessagesStorage extends BaseController { if (unreadCount == 0) { unreadMentionsCount = 0; } else { - cursor = database.queryFinalized(String.format(Locale.US, "SELECT count(mid) FROM messages_topics WHERE uid = %d AND topic_id = %d AND mid > %d AND read_state < 2 AND out = 0", -chatId, mid, readMaxId)); + cursor = database.queryFinalized(String.format(Locale.US, "SELECT count(mid) FROM messages_topics WHERE uid = %d AND topic_id = %d AND mid > %d AND read_state IN(0, 1) AND out = 0", -chatId, mid, readMaxId)); if (cursor.next()) { unreadMentionsCount = cursor.intValue(0); } cursor.dispose(); cursor = null; + + int currentUnreadMentions = 0; + cursor = database.queryFinalized(String.format(Locale.US, "SELECT unread_mentions FROM topics WHERE did = %d AND topic_id = %d", -chatId, mid)); + if (cursor.next()) { + currentUnreadMentions = cursor.intValue(0); + } + cursor.dispose(); + cursor = null; + if (unreadMentionsCount > currentUnreadMentions) { + unreadMentionsCount = currentUnreadMentions; + } } } else if (unreadCount == 0) { unreadMentionsCount = 0; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/NotificationCenter.java b/TMessagesProj/src/main/java/org/telegram/messenger/NotificationCenter.java index c79e99067..944693535 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/NotificationCenter.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/NotificationCenter.java @@ -12,9 +12,12 @@ import android.os.SystemClock; import android.util.SparseArray; import android.view.View; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.UiThread; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -572,7 +575,7 @@ public class NotificationCenter { } ArrayList objects = observers.get(id); if (objects == null) { - observers.put(id, (objects = new ArrayList<>())); + observers.put(id, (objects = createArrayForId(id))); } if (objects.contains(observer)) { return; @@ -580,6 +583,15 @@ public class NotificationCenter { objects.add(observer); } + private ArrayList createArrayForId(int id) { + // this notifications often add/remove + // UniqArrayList for fast contains method check + if (id == didReplacedPhotoInMemCache || id == stopAllHeavyOperations || id == startAllHeavyOperations) { + return new UniqArrayList<>(); + } + return new ArrayList<>(); + } + public void removeObserver(NotificationCenterDelegate observer, int id) { if (BuildVars.DEBUG_VERSION) { if (Thread.currentThread() != ApplicationLoader.applicationHandler.getLooper().getThread()) { @@ -677,4 +689,72 @@ public class NotificationCenter { } }); } + + private class UniqArrayList extends ArrayList { + HashSet set = new HashSet<>(); + + @Override + public boolean add(T t) { + if (set.add(t)) { + return super.add(t); + } + return false; + } + + @Override + public void add(int index, T element) { + if (set.add(element)) { + super.add(index, element); + } + } + + @Override + public boolean addAll(@NonNull Collection c) { + boolean modified = false; + for (T t : c) { + if (add(t)) { + modified = true; + } + } + return modified; + } + + @Override + public boolean addAll(int index, @NonNull Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public T remove(int index) { + T t = super.remove(index); + if (t != null) { + set.remove(t); + } + return t; + } + + @Override + public boolean remove(@Nullable Object o) { + if (set.remove(0)) { + return super.remove(o); + } + return false; + } + + @Override + public boolean removeAll(@NonNull Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean contains(@Nullable Object o) { + return set.contains(o); + } + + @Override + public void clear() { + set.clear(); + super.clear(); + } + } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/SendMessagesHelper.java b/TMessagesProj/src/main/java/org/telegram/messenger/SendMessagesHelper.java index c70ee541c..21ce755ec 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/SendMessagesHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/SendMessagesHelper.java @@ -7130,13 +7130,25 @@ public class SendMessagesHelper extends BaseController implements NotificationCe @UiThread public static void prepareSendingText(AccountInstance accountInstance, String text, long dialogId, boolean notify, int scheduleDate) { + prepareSendingText(accountInstance, text, dialogId, 0, notify, scheduleDate); + } + + @UiThread + public static void prepareSendingText(AccountInstance accountInstance, String text, long dialogId, int topicId, boolean notify, int scheduleDate) { accountInstance.getMessagesStorage().getStorageQueue().postRunnable(() -> Utilities.stageQueue.postRunnable(() -> AndroidUtilities.runOnUIThread(() -> { String textFinal = getTrimmedString(text); if (textFinal.length() != 0) { int count = (int) Math.ceil(textFinal.length() / 4096.0f); + MessageObject replyToMsg = null; + if (topicId != 0) { + TLRPC.TL_forumTopic topic = accountInstance.getMessagesController().getTopicsController().findTopic(-dialogId, topicId); + if (topic != null && topic.topicStartMessage != null) { + replyToMsg = new MessageObject(accountInstance.getCurrentAccount(), topic.topicStartMessage, false, false); + } + } for (int a = 0; a < count; a++) { String mess = textFinal.substring(a * 4096, Math.min((a + 1) * 4096, textFinal.length())); - accountInstance.getSendMessagesHelper().sendMessage(mess, dialogId, null, null, null, true, null, null, null, notify, scheduleDate, null, false); + accountInstance.getSendMessagesHelper().sendMessage(mess, dialogId, replyToMsg, replyToMsg, null, true, null, null, null, notify, scheduleDate, null, false); } } }))); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/VideoEditedInfo.java b/TMessagesProj/src/main/java/org/telegram/messenger/VideoEditedInfo.java index d44203a04..aef8d17c4 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/VideoEditedInfo.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/VideoEditedInfo.java @@ -11,7 +11,6 @@ package org.telegram.messenger; import android.graphics.Bitmap; import android.graphics.Canvas; import android.text.TextUtils; -import android.util.Log; import android.view.View; import org.telegram.tgnet.AbstractSerializedData; @@ -149,6 +148,7 @@ public class VideoEditedInfo { viewWidth = data.readInt32(false); viewHeight = data.readInt32(false); textAlign = data.readInt32(false); + textTypeface = PaintTypeface.find(data.readString(false)); } private void serializeTo(SerializedData data) { @@ -169,6 +169,7 @@ public class VideoEditedInfo { data.writeInt32(viewWidth); data.writeInt32(viewHeight); data.writeInt32(textAlign); + data.writeString(textTypeface == null ? "" : textTypeface.getKey()); } public MediaEntity copy() { @@ -192,6 +193,7 @@ public class VideoEditedInfo { entity.textViewX = textViewX; entity.textViewY = textViewY; entity.textAlign = textAlign; + entity.textTypeface = textTypeface; return entity; } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/utils/BitmapsCache.java b/TMessagesProj/src/main/java/org/telegram/messenger/utils/BitmapsCache.java index 1078cb10e..cb6a39eb5 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/utils/BitmapsCache.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/utils/BitmapsCache.java @@ -48,7 +48,7 @@ public class BitmapsCache { static volatile boolean cleanupScheduled; byte[] bufferTmp; - private final static int N = Utilities.clamp(Runtime.getRuntime().availableProcessors() - 2, 8, 1); + private final static int N = Utilities.clamp(Runtime.getRuntime().availableProcessors() - 2, 6, 1); private static ThreadPoolExecutor bitmapCompressExecutor; private final Object mutex = new Object(); private int frameIndex; diff --git a/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java b/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java index 59e61c453..d405d420b 100644 --- a/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java +++ b/TMessagesProj/src/main/java/org/telegram/tgnet/TLRPC.java @@ -14,6 +14,7 @@ import android.text.TextUtils; import androidx.annotation.Nullable; +import org.telegram.messenger.BuildVars; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; import org.telegram.messenger.ImageLoader; @@ -25466,7 +25467,7 @@ public class TLRPC { ttl = stream.readInt32(exception); message = stream.readString(exception); if ((flags & 512) != 0) { - media = DecryptedMessageMedia.TLdeserialize(stream, stream.readInt32(exception), exception); + media = DecryptedMessageMedia.TLdeserialize(stream, stream.readInt32(exception), exception || BuildVars.DEBUG_PRIVATE_VERSION); } if ((flags & 128) != 0) { int magic = stream.readInt32(exception); @@ -25478,7 +25479,7 @@ public class TLRPC { } int count = stream.readInt32(exception); for (int a = 0; a < count; a++) { - MessageEntity object = MessageEntity.TLdeserialize(stream, stream.readInt32(exception), exception); + MessageEntity object = MessageEntity.TLdeserialize(stream, stream.readInt32(exception), exception || BuildVars.DEBUG_PRIVATE_VERSION); if (object == null) { return; } @@ -40018,9 +40019,12 @@ public class TLRPC { case 0x89f5c4a: result = new TL_decryptedMessageMediaEmpty(); break; - case 0x7afe8ae2: + case 0x6abd9782: result = new TL_decryptedMessageMediaDocument(); break; + case 0x7afe8ae2: + result = new TL_decryptedMessageMediaDocument_layer101(); + break; case 0xe50511d8: result = new TL_decryptedMessageMediaWebPage(); break; @@ -40130,6 +40134,56 @@ public class TLRPC { } public static class TL_decryptedMessageMediaDocument extends DecryptedMessageMedia { + public static int constructor = 0x6abd9782; + + public byte[] thumb; + + public void readParams(AbstractSerializedData stream, boolean exception) { + thumb = stream.readByteArray(exception); + thumb_w = stream.readInt32(exception); + thumb_h = stream.readInt32(exception); + mime_type = stream.readString(exception); + size = stream.readInt64(exception); + key = stream.readByteArray(exception); + iv = stream.readByteArray(exception); + int magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + int count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + DocumentAttribute object = DocumentAttribute.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + attributes.add(object); + } + caption = stream.readString(exception); + } + + public void serializeToStream(AbstractSerializedData stream) { + stream.writeInt32(constructor); + stream.writeByteArray(thumb); + stream.writeInt32(thumb_w); + stream.writeInt32(thumb_h); + stream.writeString(mime_type); + stream.writeInt64(size); + stream.writeByteArray(key); + stream.writeByteArray(iv); + stream.writeInt32(0x1cb5c415); + int count = attributes.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + attributes.get(a).serializeToStream(stream); + } + stream.writeString(caption); + } + } + + public static class TL_decryptedMessageMediaDocument_layer101 extends TL_decryptedMessageMediaDocument { public static int constructor = 0x7afe8ae2; public byte[] thumb; @@ -53517,9 +53571,10 @@ public class TLRPC { } public static class TL_messages_getStickerSet extends TLObject { - public static int constructor = 0x2619a90e; + public static int constructor = 0xc8a0ec74; public InputStickerSet stickerset; + public int hash; public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) { return TL_messages_stickerSet.TLdeserialize(stream, constructor, exception); @@ -53528,6 +53583,7 @@ public class TLRPC { public void serializeToStream(AbstractSerializedData stream) { stream.writeInt32(constructor); stickerset.serializeToStream(stream); + stream.writeInt32(hash); } } 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 43a7a8d57..d47e462d5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java @@ -5893,7 +5893,7 @@ public class Theme { if (monthOfYear == 0 && dayOfMonth == 1 && hour <= 23) { canStartHolidayAnimation = true; } else { - canStartHolidayAnimation = BuildVars.DEBUG_VERSION;//false; + canStartHolidayAnimation = false; } if (dialogs_holidayDrawable == null) { if (monthOfYear == 11 && dayOfMonth >= (BuildVars.DEBUG_PRIVATE_VERSION ? 29 : 31) && dayOfMonth <= 31 || monthOfYear == 0 && dayOfMonth == 1) { 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 2f195edb2..8f745cc92 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java @@ -9854,7 +9854,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate canvas.save(); canvas.translate(linkX + AndroidUtilities.dp(10) + descriptionX, descriptionY); descriptionLayout.draw(canvas); - AnimatedEmojiSpan.drawAnimatedEmojis(canvas, descriptionLayout, animatedEmojiDescriptionStack, 0, null, 0, 0, 0, 1f); + AnimatedEmojiSpan.drawAnimatedEmojis(canvas, descriptionLayout, animatedEmojiDescriptionStack, 0, null, 0, 0, 0, 1f, Theme.chat_animatedEmojiTextColorFilter); canvas.restore(); } drawTime = true; @@ -10348,7 +10348,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate delegate.getTextSelectionHelper().drawDescription(currentMessageObject.isOutOwner(), descriptionLayout, canvas); } descriptionLayout.draw(canvas); - AnimatedEmojiSpan.drawAnimatedEmojis(canvas, descriptionLayout, animatedEmojiDescriptionStack, 0, null, 0, 0, 0, 1f); + AnimatedEmojiSpan.drawAnimatedEmojis(canvas, descriptionLayout, animatedEmojiDescriptionStack, 0, null, 0, 0, 0, 1f, Theme.chat_animatedEmojiTextColorFilter); canvas.restore(); linkPreviewY += descriptionLayout.getLineBottom(descriptionLayout.getLineCount() - 1); } @@ -13767,7 +13767,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate if (transitionParams.messageEntering) { top = bottom = 0; } - AnimatedEmojiSpan.drawAnimatedEmojis(canvas, block.textLayout, stack, 0, block.spoilers, top, bottom, drawingYOffset, alpha); + AnimatedEmojiSpan.drawAnimatedEmojis(canvas, block.textLayout, stack, 0, block.spoilers, top, bottom, drawingYOffset, alpha, Theme.chat_animatedEmojiTextColorFilter); canvas.restore(); } } @@ -13811,7 +13811,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate canvas.translate(captionX, captionY); try { - AnimatedEmojiSpan.drawAnimatedEmojis(canvas, layout, stack, 0, captionSpoilers, 0, 0, captionY, renderingAlpha); + AnimatedEmojiSpan.drawAnimatedEmojis(canvas, layout, stack, 0, captionSpoilers, 0, 0, captionY, renderingAlpha, Theme.chat_animatedEmojiTextColorFilter); } catch (Exception e) { FileLog.e(e); } @@ -14692,7 +14692,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate canvas.translate(forwardNameX, replyStartY + Theme.chat_replyNamePaint.getTextSize() + AndroidUtilities.dp(5)); int spoilersColor = currentMessageObject.isOut() && !ChatObject.isChannelAndNotMegaGroup(currentMessageObject.getChatId(), currentAccount) ? getThemedColor(Theme.key_chat_outTimeText) : replyTextLayout.getPaint().getColor(); SpoilerEffect.renderWithRipple(this, invalidateSpoilersParent, spoilersColor, -AndroidUtilities.dp(2), spoilersPatchedReplyTextLayout, replyTextLayout, replySpoilers, canvas, false); - AnimatedEmojiSpan.drawAnimatedEmojis(canvas, replyTextLayout, animatedEmojiReplyStack, 0, replySpoilers, 0, 0, 0, alpha); + AnimatedEmojiSpan.drawAnimatedEmojis(canvas, replyTextLayout, animatedEmojiReplyStack, 0, replySpoilers, 0, 0, 0, alpha, Theme.chat_animatedEmojiTextColorFilter); canvas.restore(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java index da9391532..d6a968ce9 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java @@ -855,7 +855,7 @@ public class DialogCell extends BaseCell { } if (isDialogCell) { boolean needUpdate = updateHelper.update(); - if (!needUpdate && currentDialogFolderId == 0) { + if (!needUpdate && currentDialogFolderId == 0 && encryptedChat == null) { return; } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/FeaturedStickerSetCell2.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/FeaturedStickerSetCell2.java index 1e1647169..87acfc9e4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/FeaturedStickerSetCell2.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/FeaturedStickerSetCell2.java @@ -33,6 +33,7 @@ import org.telegram.messenger.ImageLocation; import org.telegram.messenger.LocaleController; import org.telegram.messenger.MediaDataController; import org.telegram.messenger.MessageObject; +import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.SvgHelper; import org.telegram.messenger.UserConfig; @@ -49,7 +50,7 @@ import org.telegram.ui.Components.RecyclerListView; import java.util.ArrayList; import java.util.List; -public class FeaturedStickerSetCell2 extends FrameLayout { +public class FeaturedStickerSetCell2 extends FrameLayout implements NotificationCenter.NotificationCenterDelegate { private final int currentAccount = UserConfig.selectedAccount; @@ -67,6 +68,11 @@ public class FeaturedStickerSetCell2 extends FrameLayout { private boolean needDivider; private final Theme.ResourcesProvider resourcesProvider; + private boolean bindedObserver; + private Long waitingForStickerSetId; + private boolean unread; + private boolean forceInstalled; + public FeaturedStickerSetCell2(Context context, Theme.ResourcesProvider resourcesProvider) { super(context); this.resourcesProvider = resourcesProvider; @@ -162,7 +168,7 @@ public class FeaturedStickerSetCell2 extends FrameLayout { setWillNotDraw(!needDivider); textView.setText(stickersSet.set.title); - if (unread) { + if (this.unread = unread) { Drawable drawable = new Drawable() { Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); @@ -206,14 +212,33 @@ public class FeaturedStickerSetCell2 extends FrameLayout { valueTextView.setText(LocaleController.formatPluralString(set.set.emojis ? "EmojiCount" : "Stickers", set.set.count)); TLRPC.Document sticker; - if (set.cover != null) { + if (set instanceof TLRPC.TL_stickerSetNoCovered && set.set != null) { + sticker = null; + waitingForStickerSetId = set.set.id; + if (!bindedObserver) { + NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.groupStickersDidLoad); + bindedObserver = true; + } + TLRPC.TL_messages_stickerSet fullSet = MediaDataController.getInstance(currentAccount).getStickerSet(MediaDataController.getInputStickerSet(set.set), set.set.hash, false); + if (fullSet != null && fullSet.documents != null && !fullSet.documents.isEmpty()) { + sticker = fullSet.documents.get(0); + for (int i = 0; i < fullSet.documents.size(); ++i) { + if (fullSet.documents.get(i).id == set.set.thumb_document_id) { + sticker = fullSet.documents.get(i); + break; + } + } + } + } else if (set.cover != null) { sticker = set.cover; } else if (!set.covers.isEmpty()) { sticker = set.covers.get(0); - for (int i = 0; i < set.covers.size(); ++i) { - if (set.covers.get(i).id == set.set.thumb_document_id) { - sticker = set.covers.get(i); - break; + if (set.set != null) { + for (int i = 0; i < set.covers.size(); ++i) { + if (set.covers.get(i).id == set.set.thumb_document_id) { + sticker = set.covers.get(i); + break; + } } } } else if ((set instanceof TLRPC.TL_stickerSetFullCovered && !((TLRPC.TL_stickerSetFullCovered) set).documents.isEmpty())) { @@ -269,6 +294,7 @@ public class FeaturedStickerSetCell2 extends FrameLayout { } addButton.setVisibility(VISIBLE); + this.forceInstalled = forceInstalled; isInstalled = forceInstalled || MediaDataController.getInstance(currentAccount).isStickerPackInstalled(set.set.id); isLocked = !UserConfig.getInstance(currentAccount).isPremium() && MessageObject.isPremiumEmojiPack(set); if (animated) { @@ -403,4 +429,26 @@ public class FeaturedStickerSetCell2 extends FrameLayout { Integer color = resourcesProvider != null ? resourcesProvider.getColor(key) : null; return color != null ? color : Theme.getColor(key); } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + if (bindedObserver) { + NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.groupStickersDidLoad); + bindedObserver = false; + } + } + + @Override + public void didReceivedNotification(int id, int account, Object... args) { + if (id == NotificationCenter.groupStickersDidLoad) { + long setId = (long) args[0]; + if (waitingForStickerSetId != null && waitingForStickerSetId == setId) { + waitingForStickerSetId = null; + TLRPC.TL_stickerSetNoCovered setNoCovered = new TLRPC.TL_stickerSetNoCovered(); + setNoCovered.set = ((TLRPC.TL_messages_stickerSet) args[1]).set; + setStickersSet(setNoCovered, needDivider, unread, forceInstalled, true); + } + } + } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index 9f5e28a38..6258fdeb3 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -23643,7 +23643,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not didPressMessageUrl(link, false, selectedObject, v instanceof ChatMessageCell ? (ChatMessageCell) v : null); return true; }; - TLRPC.InputPeer inputPeer = selectedObject != null && (selectedObject.isPoll() || selectedObject.isVoiceTranscriptionOpen()) ? null : getMessagesController().getInputPeer(dialog_id); + TLRPC.InputPeer inputPeer = selectedObject != null && (selectedObject.isPoll() || selectedObject.isVoiceTranscriptionOpen() || selectedObject.isSponsored()) ? null : getMessagesController().getInputPeer(dialog_id); if (LanguageDetector.hasSupport()) { final String[] fromLang = {null}; cell.setVisibility(View.GONE); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/BulletinFactory.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/BulletinFactory.java index 107db8807..b18cd5970 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/BulletinFactory.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/BulletinFactory.java @@ -351,7 +351,7 @@ public final class BulletinFactory { if (loadingSpan != null && bulletin.getLayout() instanceof Bulletin.LoadingLottieLayout) { loadingSpan.setView(((Bulletin.LoadingLottieLayout) bulletin.getLayout()).textLoadingView); } - MediaDataController.getInstance(UserConfig.selectedAccount).getStickerSet(inputStickerSet, false, set -> { + MediaDataController.getInstance(UserConfig.selectedAccount).getStickerSet(inputStickerSet, null, false, set -> { CharSequence message; if (set != null && set.set != null) { if (inTopic) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/DrawingInBackgroundThreadDrawable.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/DrawingInBackgroundThreadDrawable.java index 8331822ef..b6b686484 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/DrawingInBackgroundThreadDrawable.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/DrawingInBackgroundThreadDrawable.java @@ -183,6 +183,9 @@ public class DrawingInBackgroundThreadDrawable implements NotificationCenter.Not } public void onAttachToWindow() { + if (attachedToWindow) { + return; + } attachedToWindow = true; error = false; currentOpenedLayerFlags = NotificationCenter.getGlobalInstance().getCurrentHeavyOperationFlags(); @@ -199,6 +202,9 @@ public class DrawingInBackgroundThreadDrawable implements NotificationCenter.Not } public void onDetachFromWindow() { + if (!attachedToWindow) { + return; + } if (!bitmapUpdating) { recycleBitmaps(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiPacksAlert.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiPacksAlert.java index 1b8add9e5..d572c2db5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiPacksAlert.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiPacksAlert.java @@ -1571,7 +1571,7 @@ public class EmojiPacksAlert extends BottomSheet implements NotificationCenter.N NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.groupStickersDidLoad); final boolean[] failed = new boolean[1]; for (int i = 0; i < data.length; ++i) { - TLRPC.TL_messages_stickerSet stickerSet = MediaDataController.getInstance(currentAccount).getStickerSet(inputStickerSets.get(i), false, (set) -> { + TLRPC.TL_messages_stickerSet stickerSet = MediaDataController.getInstance(currentAccount).getStickerSet(inputStickerSets.get(i), null, false, (set) -> { if (set == null && !failed[0]) { failed[0] = true; AndroidUtilities.runOnUIThread(() -> { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiView.java index ce2b19057..cb5efca0f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiView.java @@ -5626,6 +5626,12 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific return stickersGridAdapter != null && stickersGridAdapter.getItemCount() > 0; } + private Runnable updateStickersLoadedDelayed = () -> { + if (emojiAdapter != null) { + emojiAdapter.notifyDataSetChanged(true); + } + }; + @SuppressWarnings("unchecked") @Override public void didReceivedNotification(int id, int account, Object... args) { @@ -5674,9 +5680,8 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific } } } - if (emojiAdapter != null) { - emojiAdapter.notifyDataSetChanged(true); - } + AndroidUtilities.cancelRunOnUIThread(updateStickersLoadedDelayed); + AndroidUtilities.runOnUIThread(updateStickersLoadedDelayed, 100); } else if (id == NotificationCenter.emojiLoaded) { if (stickersGridView != null) { int count = stickersGridView.getChildCount(); @@ -6662,7 +6667,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific if (set instanceof TLRPC.TL_stickerSetFullCovered) { pack.documents = ((TLRPC.TL_stickerSetFullCovered) set).documents; } else if (set instanceof TLRPC.TL_stickerSetNoCovered) { - TLRPC.TL_messages_stickerSet stickerSet = mediaDataController.getStickerSet(MediaDataController.getInputStickerSet(set.set), false); + TLRPC.TL_messages_stickerSet stickerSet = mediaDataController.getStickerSet(MediaDataController.getInputStickerSet(set.set), set.set.hash, false); if (stickerSet != null) { pack.documents = stickerSet.documents; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Paint/PaintTypeface.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Paint/PaintTypeface.java index f97041e3d..666190d5c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Paint/PaintTypeface.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Paint/PaintTypeface.java @@ -146,6 +146,25 @@ public class PaintTypeface { return typefaces; } + public static PaintTypeface find(String key) { + if (key == null || TextUtils.isEmpty(key)) { + return null; + } + if (typefaces == null) { + get(); + } + if (typefaces == null) { + return null; + } + for (int i = 0; i < typefaces.size(); ++i) { + PaintTypeface typeface = typefaces.get(i); + if (typeface != null && TextUtils.equals(key, typeface.key)) { + return typeface; + } + } + return null; + } + public static boolean fetched(Runnable runnable) { if (typefaces != null || runnable == null) { return true; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Reactions/ReactionsEffectOverlay.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Reactions/ReactionsEffectOverlay.java index 67d1bdedb..338ac6f21 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Reactions/ReactionsEffectOverlay.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Reactions/ReactionsEffectOverlay.java @@ -13,6 +13,7 @@ import android.view.WindowManager; import android.widget.FrameLayout; import org.telegram.messenger.AndroidUtilities; +import org.telegram.messenger.FileLoader; import org.telegram.messenger.ImageLocation; import org.telegram.messenger.ImageReceiver; import org.telegram.messenger.MediaDataController; @@ -743,6 +744,7 @@ public class ReactionsEffectOverlay { public AnimationView(Context context) { super(context); + getImageReceiver().setFileLoadingPriority(FileLoader.PRIORITY_HIGH); } boolean wasPlaying; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java index 0894a9d4a..842e2bcf9 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java @@ -4937,7 +4937,6 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati final ChatActivity fragment; if (dids.size() <= 1) { final long did = dids.get(0).dialogId; - final int topicId = dids.get(0).topicId; Bundle args = new Bundle(); args.putBoolean("scrollToTopOnResume", true); @@ -5007,8 +5006,16 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati String captionToSend = null; for (int i = 0; i < dids.size(); i++) { final long did = dids.get(i).dialogId; + final int topicId = dids.get(i).topicId; AccountInstance accountInstance = AccountInstance.getInstance(UserConfig.selectedAccount); + MessageObject replyToMsg = null; + if (topicId != 0) { + TLRPC.TL_forumTopic topic = accountInstance.getMessagesController().getTopicsController().findTopic(-did, topicId); + if (topic != null && topic.topicStartMessage != null) { + replyToMsg = new MessageObject(accountInstance.getCurrentAccount(), topic.topicStartMessage, false, false); + } + } boolean photosEditorOpened = false, videoEditorOpened = false; if (fragment != null) { boolean withoutAnimation = dialogsFragment == null || (videoPath != null || (photoPathsArray != null && photoPathsArray.size() > 0)); @@ -5031,7 +5038,7 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati } ArrayList arrayList = new ArrayList<>(); arrayList.add(videoPath); - SendMessagesHelper.prepareSendingDocuments(accountInstance, arrayList, arrayList, null, captionToSend, null, did, null, null, null, null, notify, 0); + SendMessagesHelper.prepareSendingDocuments(accountInstance, arrayList, arrayList, null, captionToSend, null, did, replyToMsg, replyToMsg, null, null, notify, 0); } } if (photoPathsArray != null && !photosEditorOpened) { @@ -5039,7 +5046,7 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati photoPathsArray.get(0).caption = sendingText; sendingText = null; } - SendMessagesHelper.prepareSendingMedia(accountInstance, photoPathsArray, did, null, null, null, false, false, null, notify, 0, false); + SendMessagesHelper.prepareSendingMedia(accountInstance, photoPathsArray, did, replyToMsg, replyToMsg, null, false, false, null, notify, 0, false); } if (documentsPathsArray != null || documentsUrisArray != null) { if (sendingText != null && sendingText.length() <= 1024 && ((documentsPathsArray != null ? documentsPathsArray.size() : 0) + (documentsUrisArray != null ? documentsUrisArray.size() : 0)) == 1) { @@ -5049,16 +5056,16 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati SendMessagesHelper.prepareSendingDocuments(accountInstance, documentsPathsArray, documentsOriginalPathsArray, documentsUrisArray, captionToSend, documentsMimeType, did, null, null, null, null, notify, 0); } if (sendingText != null) { - SendMessagesHelper.prepareSendingText(accountInstance, sendingText, did, true, 0); + SendMessagesHelper.prepareSendingText(accountInstance, sendingText, did, topicId, notify, 0); } if (contactsToSend != null && !contactsToSend.isEmpty()) { for (int a = 0; a < contactsToSend.size(); a++) { TLRPC.User user = contactsToSend.get(a); - SendMessagesHelper.getInstance(account).sendMessage(user, did, null, null, null, null, notify, 0); + SendMessagesHelper.getInstance(account).sendMessage(user, did, replyToMsg, replyToMsg, null, null, notify, 0); } } if (!TextUtils.isEmpty(message) && !videoEditorOpened && !photosEditorOpened) { - SendMessagesHelper.prepareSendingText(accountInstance, message.toString(), did, notify, 0); + SendMessagesHelper.prepareSendingText(accountInstance, message.toString(), did, topicId, notify, 0); } } } @@ -6618,8 +6625,12 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati if (actionBarLayout != null) { actionBarLayout.onLowMemory(); if (AndroidUtilities.isTablet()) { - rightActionBarLayout.onLowMemory(); - layersActionBarLayout.onLowMemory(); + if (rightActionBarLayout != null) { + rightActionBarLayout.onLowMemory(); + } + if (layersActionBarLayout != null) { + layersActionBarLayout.onLowMemory(); + } } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/NewContactBottomSheet.java b/TMessagesProj/src/main/java/org/telegram/ui/NewContactBottomSheet.java index 38b9ea9cd..6bcf59d8b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/NewContactBottomSheet.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/NewContactBottomSheet.java @@ -633,7 +633,7 @@ public class NewContactBottomSheet extends BottomSheet implements AdapterView.On } private void doOnDone() { - if (donePressed) { + if (donePressed || parentFragment == null || parentFragment.getParentActivity() == null) { return; } if (firstNameField.getEditText().length() == 0) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PremiumPreviewFragment.java b/TMessagesProj/src/main/java/org/telegram/ui/PremiumPreviewFragment.java index be2a8828a..63b1511c0 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PremiumPreviewFragment.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PremiumPreviewFragment.java @@ -731,7 +731,7 @@ public class PremiumPreviewFragment extends BaseFragment implements Notification BillingController.getInstance().addResultListener(BillingController.PREMIUM_PRODUCT_ID, billingResult -> { if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) { - onSuccess.run(); + AndroidUtilities.runOnUIThread(onSuccess); } }); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java index 4cb241177..4d22c1461 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java @@ -611,6 +611,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. private float customAvatarProgress; private float customPhotoOffset; private boolean hasFallbackPhoto; + private boolean hasCustomPhoto; private ImageReceiver fallbackImage; public int getTopicId() { @@ -6519,14 +6520,16 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. boolean onlineTextCrosafade = false; - ChatAvatarContainer avatarContainer = ((ChatActivityInterface) previousTransitionFragment).getAvatarContainer(); - if (avatarContainer.getSubtitleTextView().getLeftDrawable() != null || avatarContainer.statusMadeShorter[0]) { - transitionOnlineText = avatarContainer.getSubtitleTextView(); - avatarContainer2.invalidate(); - onlineTextCrosafade = true; - onlineTextView[0].setAlpha(0f); - onlineTextView[1].setAlpha(0f); - animators.add(ObjectAnimator.ofFloat(onlineTextView[1], View.ALPHA, 1.0f)); + if (previousTransitionFragment != null) { + ChatAvatarContainer avatarContainer = previousTransitionFragment.getAvatarContainer(); + if (avatarContainer != null && avatarContainer.getSubtitleTextView().getLeftDrawable() != null || avatarContainer.statusMadeShorter[0]) { + transitionOnlineText = avatarContainer.getSubtitleTextView(); + avatarContainer2.invalidate(); + onlineTextCrosafade = true; + onlineTextView[0].setAlpha(0f); + onlineTextView[1].setAlpha(0f); + animators.add(ObjectAnimator.ofFloat(onlineTextView[1], View.ALPHA, 1.0f)); + } } if (!onlineTextCrosafade) { @@ -7223,6 +7226,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. boolean shortStatus; hasFallbackPhoto = false; + hasCustomPhoto = false; if (userId != 0) { TLRPC.User user = getMessagesController().getUser(userId); if (user == null) { @@ -7288,6 +7292,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } } } + hasCustomPhoto = user.photo != null && user.photo.personal; try { newString = Emoji.replaceEmoji(newString, nameTextView[1].getPaint().getFontMetricsInt(), AndroidUtilities.dp(24), false); } catch (Exception ignore) { @@ -10461,9 +10466,16 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } } else { - if (onlineTextView[2] != null) { - onlineTextView[2].setAlpha(photoDescriptionProgress); + if (hasCustomPhoto) { + if (onlineTextView[2] != null) { + onlineTextView[2].setAlpha(photoDescriptionProgress); + } + } else { + if (onlineTextView[2] != null) { + onlineTextView[2].setAlpha(0); + } } + } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SelectAnimatedEmojiDialog.java b/TMessagesProj/src/main/java/org/telegram/ui/SelectAnimatedEmojiDialog.java index 0f4f594ba..d0cb2350f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SelectAnimatedEmojiDialog.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SelectAnimatedEmojiDialog.java @@ -2754,31 +2754,43 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati final int maxlen = layoutManager.getSpanCount() * EXPAND_MAX_LINES; for (int i = 0; i < featuredEmojiPacks.size(); ++i) { TLRPC.StickerSetCovered set1 = featuredEmojiPacks.get(i); - if (set1 instanceof TLRPC.TL_stickerSetFullCovered) { - TLRPC.TL_stickerSetFullCovered set = (TLRPC.TL_stickerSetFullCovered) set1; - boolean foundDuplicate = false; - for (int j = 0; j < packs.size(); ++j) { - if (packs.get(j).set.id == set.set.id) { - foundDuplicate = true; - break; - } + TLRPC.StickerSet set = set1.set; + boolean isPremiumPack = false; + boolean foundDuplicate = false; + for (int j = 0; j < packs.size(); ++j) { + if (packs.get(j).set.id == set.id) { + foundDuplicate = true; + break; } + } + if (foundDuplicate) { + continue; + } - if (foundDuplicate) { - continue; + ArrayList documents = null; + if (set1 instanceof TLRPC.TL_stickerSetNoCovered) { + TLRPC.TL_messages_stickerSet fullSet = mediaDataController.getStickerSet(MediaDataController.getInputStickerSet(set1.set), set1.set.hash, true); + if (fullSet != null) { + documents = fullSet.documents; + isPremiumPack = MessageObject.isPremiumEmojiPack(fullSet); } + } else if (set1 instanceof TLRPC.TL_stickerSetFullCovered) { + documents = ((TLRPC.TL_stickerSetFullCovered) set1).documents; + isPremiumPack = MessageObject.isPremiumEmojiPack(set1); + } + if (documents != null) { positionToSection.put(totalCount, packs.size()); sectionToPosition.put(packs.size(), totalCount); totalCount++; - rowHashCodes.add(Objects.hash(9211, set.set.id)); + rowHashCodes.add(Objects.hash(9211, set.id)); EmojiView.EmojiPack pack = new EmojiView.EmojiPack(); - pack.installed = installedEmojiSets.contains(set.set.id); + pack.installed = installedEmojiSets.contains(set.id); pack.featured = true; - pack.free = !MessageObject.isPremiumEmojiPack(set); - pack.set = set.set; - pack.documents = set.documents; + pack.free = !isPremiumPack; + pack.set = set; + pack.documents = documents; pack.index = packs.size(); pack.expanded = expandedEmojiSets.contains(pack.set.id); @@ -2787,7 +2799,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati for (int k = 0; k < maxlen - 1; ++k) { rowHashCodes.add(Objects.hash(3212, pack.documents.get(k).id)); } - rowHashCodes.add(Objects.hash(-5531, set.set.id, (pack.documents.size() - maxlen + 1))); + rowHashCodes.add(Objects.hash(-5531, set.id, (pack.documents.size() - maxlen + 1))); positionToExpand.put(totalCount - 1, packs.size()); } else { totalCount += pack.documents.size(); @@ -2799,7 +2811,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati if (!pack.installed) { positionToButton.put(totalCount, packs.size()); totalCount++; - rowHashCodes.add(Objects.hash(3321, set.set.id)); + rowHashCodes.add(Objects.hash(3321, set.id)); } packs.add(pack); @@ -3522,6 +3534,8 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } } + private Runnable updateRowsDelayed = () -> updateRows(true, true); + @Override public void didReceivedNotification(int id, int account, Object... args) { if (id == NotificationCenter.stickersDidLoad) { @@ -3533,10 +3547,8 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati } else if (id == NotificationCenter.recentEmojiStatusesUpdate) { updateRows(false, true); } else if (id == NotificationCenter.groupStickersDidLoad) { - if (defaultSetLoading) { - updateRows(true, true); - defaultSetLoading = false; - } + AndroidUtilities.cancelRunOnUIThread(updateRowsDelayed); + AndroidUtilities.runOnUIThread(updateRowsDelayed, 100); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/TopicsFragment.java b/TMessagesProj/src/main/java/org/telegram/ui/TopicsFragment.java index 3a2d7ac1a..4edde87cd 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/TopicsFragment.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/TopicsFragment.java @@ -1889,7 +1889,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N private void checkLoading() { loadingTopics = topicsController.isLoading(chatId); - if (topicsEmptyView != null/* && forumTopics.size() == 0*/) { + if (topicsEmptyView != null && (forumTopics.size() == 0 || (forumTopics.size() == 1 && forumTopics.get(0).topic.id == 1))) { topicsEmptyView.showProgress(loadingTopics, fragmentBeginToShow); } if (recyclerListView != null) { @@ -2547,8 +2547,8 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N adapter.setItems(oldItems, forumTopics); } - if (scrollToTop && layoutManager != null) { - layoutManager.scrollToPosition(0); + if ((scrollToTop || oldCount == 0) && layoutManager != null) { + layoutManager.scrollToPositionWithOffset(0, 0); scrollToTop = false; } } diff --git a/gradle.properties b/gradle.properties index 9d41a702e..6039e9515 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,8 +13,8 @@ # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true #Sat Mar 12 05:53:50 MSK 2016 -APP_VERSION_NAME=9.3.2 -APP_VERSION_CODE=3023 +APP_VERSION_NAME=9.3.3 +APP_VERSION_CODE=3026 APP_PACKAGE=org.telegram.messenger RELEASE_KEY_PASSWORD=TelegramAndroidPswd RELEASE_KEY_ALIAS=tmessages