diff --git a/TMessagesProj/build.gradle b/TMessagesProj/build.gradle index b0578408d..2ce1c3eec 100644 --- a/TMessagesProj/build.gradle +++ b/TMessagesProj/build.gradle @@ -3,15 +3,15 @@ import cn.hutool.core.util.RuntimeUtil apply plugin: "com.android.application" apply plugin: "kotlin-android" -def verName = "8.8.3-preview01" +def verName = "8.8.5-preview01" def verCode = 640 if (System.getenv("DEBUG_BUILD") == "true") { verName += "-" + RuntimeUtil.execForStr("git log --pretty=format:'%h' -n 1").trim() } -def officialVer = "8.8.3" -def officialCode = 2705 +def officialVer = "8.8.5" +def officialCode = 2721 def serviceAccountCredentialsFile = rootProject.file("service_account_credentials.json") diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java b/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java index c88ac6ff2..884342f5b 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java @@ -2519,7 +2519,7 @@ public class AndroidUtilities { } public static void appCenterLog(Throwable e) { - + } public static boolean shouldShowClipboardToast() { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/AnimatedFileDrawableStream.java b/TMessagesProj/src/main/java/org/telegram/messenger/AnimatedFileDrawableStream.java index 1e0841698..1e7173924 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/AnimatedFileDrawableStream.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/AnimatedFileDrawableStream.java @@ -6,7 +6,7 @@ import java.util.concurrent.CountDownLatch; public class AnimatedFileDrawableStream implements FileLoadOperationStream { - private FileLoadOperation loadOperation; + private final FileLoadOperation loadOperation; private CountDownLatch countDownLatch; private TLRPC.Document document; private ImageLocation location; @@ -20,8 +20,6 @@ public class AnimatedFileDrawableStream implements FileLoadOperationStream { private boolean finishedLoadingFile; private String finishedFilePath; - private boolean ignored; - public AnimatedFileDrawableStream(TLRPC.Document d, ImageLocation l, Object p, int a, boolean prev) { document = d; location = l; @@ -63,6 +61,7 @@ public class AnimatedFileDrawableStream implements FileLoadOperationStream { } synchronized (sync) { if (canceled) { + FileLoader.getInstance(currentAccount).cancelLoadFile(document); return 0; } countDownLatch = new CountDownLatch(1); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java index 505cffa04..e87736887 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java @@ -351,6 +351,7 @@ public class ApplicationLoader extends Application { if (BuildVars.LOGS_ENABLED) { FileLog.d("app start time = " + (startTime = SystemClock.elapsedRealtime())); + FileLog.d("buildVersion = " + BuildVars.BUILD_VERSION); } if (applicationContext == null) { applicationContext = getApplicationContext(); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java index f798eae2e..f9cc44b8b 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java @@ -70,9 +70,13 @@ public class FileLoadOperation { private int cdnChunkCheckSize = 1024 * 128; private int maxDownloadRequests = 4; private int maxDownloadRequestsBig = 4; - private int bigFileSizeFrom = 1024 * 1024; + private int bigFileSizeFrom = 10 * 1024 * 1024; private int maxCdnParts = (int) (FileLoader.DEFAULT_MAX_FILE_SIZE / downloadChunkSizeBig); + //load small parts for stream + private int downloadChunkSizeAnimation = 1024 * 128; + private int maxDownloadRequestsAnimation = 4; + private final static int preloadMaxBytes = 2 * 1024 * 1024; private String fileName; @@ -136,7 +140,7 @@ public class FileLoadOperation { private HashMap cdnHashes; - private boolean forceBig; + private boolean isStream; private byte[] encryptKey; private byte[] encryptIv; @@ -174,17 +178,19 @@ public class FileLoadOperation { private int currentType; public FilePathDatabase.PathData pathSaveData; + private long startTime; public interface FileLoadOperationDelegate { void didFinishLoadingFile(FileLoadOperation operation, File finalFile); void didFailedLoadingFile(FileLoadOperation operation, int state); void didChangedLoadProgress(FileLoadOperation operation, long uploadedSize, long totalSize); void saveFilePath(FilePathDatabase.PathData pathSaveData, File cacheFileFinal); + boolean hasAnotherRefOnFile(String path); } private void updateParams() { if (MessagesController.getInstance(currentAccount).getfileExperimentalParams) { - downloadChunkSizeBig = 1024 * 128; + downloadChunkSizeBig = 1024 * 512; maxDownloadRequests = 8; maxDownloadRequestsBig = 8; } else { @@ -198,7 +204,7 @@ public class FileLoadOperation { public FileLoadOperation(ImageLocation imageLocation, Object parent, String extension, long size) { updateParams(); parentObject = parent; - forceBig = imageLocation.imageType == FileLoader.IMAGE_TYPE_ANIMATION; + isStream = imageLocation.imageType == FileLoader.IMAGE_TYPE_ANIMATION; if (imageLocation.isEncrypted()) { location = new TLRPC.TL_inputEncryptedFileLocation(); location.id = imageLocation.location.volume_id; @@ -632,10 +638,15 @@ public class FileLoadOperation { } public boolean start(final FileLoadOperationStream stream, final long streamOffset, final boolean steamPriority) { + startTime = System.currentTimeMillis(); updateParams(); if (currentDownloadChunkSize == 0) { - currentDownloadChunkSize = totalBytesCount >= bigFileSizeFrom || forceBig ? downloadChunkSizeBig : downloadChunkSize; - currentMaxDownloadRequests = totalBytesCount >= bigFileSizeFrom || forceBig ? maxDownloadRequestsBig : maxDownloadRequests; + if (isStream) { + currentDownloadChunkSize = downloadChunkSizeAnimation; + currentMaxDownloadRequests = maxDownloadRequestsAnimation; + } + currentDownloadChunkSize = totalBytesCount >= bigFileSizeFrom || isStream ? downloadChunkSizeBig : downloadChunkSize; + currentMaxDownloadRequests = totalBytesCount >= bigFileSizeFrom || isStream ? maxDownloadRequestsBig : maxDownloadRequests; } final boolean alreadyStarted = state != stateIdle; final boolean wasPaused = paused; @@ -782,7 +793,9 @@ public class FileLoadOperation { } boolean finalFileExist = cacheFileFinal.exists(); if (finalFileExist && (parentObject instanceof TLRPC.TL_theme || totalBytesCount != 0 && totalBytesCount != cacheFileFinal.length())) { - cacheFileFinal.delete(); + if (!delegate.hasAnotherRefOnFile(cacheFileFinal.toString())) { + cacheFileFinal.delete(); + } finalFileExist = false; } @@ -1311,7 +1324,7 @@ public class FileLoadOperation { } } if (BuildVars.LOGS_ENABLED) { - FileLog.d("finished downloading file to " + cacheFileFinal); + FileLog.d("finished downloading file to " + cacheFileFinal + " time = " + (System.currentTimeMillis() - startTime)); } if (increment) { if (currentType == ConnectionsManager.FileTypeAudio) { @@ -1435,7 +1448,7 @@ public class FileLoadOperation { protected boolean processRequestResult(RequestInfo requestInfo, TLRPC.TL_error error) { if (state != stateDownloading) { if (BuildVars.DEBUG_VERSION) { - FileLog.d("trying to write to finished file " + cacheFileFinal + " offset " + requestInfo.offset); + FileLog.e(new Exception("trying to write to finished file " + cacheFileFinal + " offset " + requestInfo.offset)); } return false; } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java index 02e19765e..67c003067 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java @@ -89,7 +89,7 @@ public class FileLoader extends BaseController { private ConcurrentHashMap loadOperationPaths = new ConcurrentHashMap<>(); private ArrayList activeFileLoadOperation = new ArrayList<>(); - private ConcurrentHashMap loadOperationPathsUI = new ConcurrentHashMap<>(10, 1, 2); + private ConcurrentHashMap loadOperationPathsUI = new ConcurrentHashMap<>(10, 1, 2); private HashMap uploadSizes = new HashMap<>(); private HashMap loadingVideos = new HashMap<>(); @@ -524,7 +524,12 @@ public class FileLoader extends BaseController { } else { fileName = name; } - boolean removed = loadOperationPathsUI.remove(fileName) != null; + LoadOperationUIObject uiObject = loadOperationPathsUI.remove(fileName); + Runnable runnable = uiObject != null ? uiObject.loadInternalRunnable : null; + boolean removed = uiObject != null; + if (runnable != null) { + fileLoaderQueue.cancelRunnable(runnable); + } fileLoaderQueue.postRunnable(() -> { FileLoadOperation operation = loadOperationPaths.remove(fileName); if (operation != null) { @@ -632,7 +637,7 @@ public class FileLoader extends BaseController { return null; } if (cacheType != 10 && !TextUtils.isEmpty(fileName) && !fileName.contains("" + Integer.MIN_VALUE)) { - loadOperationPathsUI.put(fileName, true); + loadOperationPathsUI.put(fileName, new LoadOperationUIObject()); } if (document != null && parentObject instanceof MessageObject && ((MessageObject) parentObject).putInDownloadsStore && !((MessageObject) parentObject).isAnyKindOfSticker()) { @@ -845,6 +850,11 @@ public class FileLoader extends BaseController { public void saveFilePath(FilePathDatabase.PathData pathSaveData, File cacheFileFinal) { getFileDatabase().putPath(pathSaveData.id, pathSaveData.dc, pathSaveData.type, cacheFileFinal != null ? cacheFileFinal.toString() : null); } + + @Override + public boolean hasAnotherRefOnFile(String path) { + return getFileDatabase().hasAnotherRefOnFile(path); + } }; operation.setDelegate(fileLoadOperationDelegate); @@ -970,10 +980,13 @@ public class FileLoader extends BaseController { } else { fileName = null; } + Runnable runnable = () -> loadFileInternal(document, secureDocument, webDocument, location, imageLocation, parentObject, locationExt, locationSize, priority, null, 0, false, cacheType); if (cacheType != 10 && !TextUtils.isEmpty(fileName) && !fileName.contains("" + Integer.MIN_VALUE)) { - loadOperationPathsUI.put(fileName, true); + LoadOperationUIObject uiObject = new FileLoader.LoadOperationUIObject(); + uiObject.loadInternalRunnable = runnable; + loadOperationPathsUI.put(fileName, uiObject); } - fileLoaderQueue.postRunnable(() -> loadFileInternal(document, secureDocument, webDocument, location, imageLocation, parentObject, locationExt, locationSize, priority, null, 0, false, cacheType)); + fileLoaderQueue.postRunnable(runnable); } protected FileLoadOperation loadStreamFile(final FileLoadOperationStream stream, final TLRPC.Document document, final ImageLocation location, final Object parentObject, final int offset, final boolean priority) { @@ -1664,4 +1677,8 @@ public class FileLoader extends BaseController { } return false; } + + private static class LoadOperationUIObject { + Runnable loadInternalRunnable; + } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FilePathDatabase.java b/TMessagesProj/src/main/java/org/telegram/messenger/FilePathDatabase.java index cf1b49ee1..96fa112c9 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FilePathDatabase.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FilePathDatabase.java @@ -21,7 +21,7 @@ public class FilePathDatabase { private File cacheFile; private File shmCacheFile; - private final static int LAST_DB_VERSION = 1; + private final static int LAST_DB_VERSION = 2; private final static String DATABASE_NAME = "file_to_path"; private final static String DATABASE_BACKUP_NAME = "file_to_path_backup"; @@ -57,6 +57,7 @@ public class FilePathDatabase { if (createTable) { database.executeFast("CREATE TABLE paths(document_id INTEGER, dc_id INTEGER, type INTEGER, path TEXT, PRIMARY KEY(document_id, dc_id, type));").stepThis().dispose(); + database.executeFast("CREATE INDEX IF NOT EXISTS path_in_paths ON paths(path);").stepThis().dispose(); database.executeFast("PRAGMA user_version = " + LAST_DB_VERSION).stepThis().dispose(); } else { int version = database.executeInt("PRAGMA user_version"); @@ -66,6 +67,7 @@ public class FilePathDatabase { if (version == 0) { throw new Exception("malformed"); } + migrateDatabase(version); //migration } if (!fromBackup) { @@ -89,6 +91,14 @@ public class FilePathDatabase { } } + private void migrateDatabase(int version) throws SQLiteException { + if (version == 1) { + database.executeFast("CREATE INDEX IF NOT EXISTS path_in_paths ON paths(path);").stepThis().dispose(); + database.executeFast("PRAGMA user_version = " + 2).stepThis().dispose(); + version = 2; + } + } + private void createBackup() { File filesDir = ApplicationLoader.getFilesDirFixed(); if (currentAccount != 0) { @@ -117,7 +127,7 @@ public class FilePathDatabase { try { return AndroidUtilities.copyFile(backupCacheFile, cacheFile); } catch (IOException e) { - FileLog.e(e); + FileLog.e(e); } return false; } @@ -182,6 +192,7 @@ public class FilePathDatabase { SQLitePreparedStatement state = null; try { if (path != null) { + database.executeFast("DELETE FROM paths WHERE path = '" + path + "'"); state = database.executeFast("REPLACE INTO paths VALUES(?, ?, ?, ?)"); state.requery(); state.bindLong(1, id); @@ -243,6 +254,29 @@ public class FilePathDatabase { }); } + public boolean hasAnotherRefOnFile(String path) { + CountDownLatch syncLatch = new CountDownLatch(1); + boolean[] res = new boolean[]{false}; + dispatchQueue.postRunnable(() -> { + try { + SQLiteCursor cursor = database.queryFinalized("SELECT document_id FROM paths WHERE path = '" + path + "'"); + if (cursor.next()) { + res[0] = true; + } + } catch (Exception e) { + FileLog.e(e); + } + syncLatch.countDown(); + }); + + try { + syncLatch.await(); + } catch (InterruptedException e) { + FileLog.e(e); + } + return res[0]; + } + public static class PathData { public final long id; public final int dc; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ImageLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/ImageLoader.java index 8c42aeedd..9720bee2d 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ImageLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ImageLoader.java @@ -1742,12 +1742,12 @@ public class ImageLoader { final ArrayList finalImageReceiverArray = new ArrayList<>(imageReceiverArray); final ArrayList finalImageReceiverGuidsArray = new ArrayList<>(imageReceiverGuidsArray); AndroidUtilities.runOnUIThread(() -> { - if (image instanceof AnimatedFileDrawable) { + if (image instanceof AnimatedFileDrawable && !((AnimatedFileDrawable) image).isWebmSticker) { boolean imageSet = false; AnimatedFileDrawable fileDrawable = (AnimatedFileDrawable) image; for (int a = 0; a < finalImageReceiverArray.size(); a++) { ImageReceiver imgView = finalImageReceiverArray.get(a); - AnimatedFileDrawable toSet = fileDrawable; + AnimatedFileDrawable toSet = (a == 0 ? fileDrawable : fileDrawable.makeCopy()); if (imgView.setImageBitmapByKey(toSet, key, type, false, finalImageReceiverGuidsArray.get(a))) { if (toSet == fileDrawable) { imageSet = true; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ImageReceiver.java b/TMessagesProj/src/main/java/org/telegram/messenger/ImageReceiver.java index cf9126207..808daaa2b 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ImageReceiver.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ImageReceiver.java @@ -280,6 +280,8 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg private ArrayList loadingOperations = new ArrayList<>(); private boolean attachedToWindow; private boolean videoThumbIsSame; + private boolean allowLoadingOnAttachedOnly; + private boolean shouldLoadOnAttach; public int animatedFileDrawableRepeatMaxCount; @@ -410,6 +412,23 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg } public void setImage(ImageLocation mediaLocation, String mediaFilter, ImageLocation imageLocation, String imageFilter, ImageLocation thumbLocation, String thumbFilter, Drawable thumb, long size, String ext, Object parentObject, int cacheType) { + if (allowLoadingOnAttachedOnly && !attachedToWindow) { + if (setImageBackup == null) { + setImageBackup = new SetImageBackup(); + } + setImageBackup.mediaLocation = mediaLocation; + setImageBackup.mediaFilter = mediaFilter; + setImageBackup.imageLocation = imageLocation; + setImageBackup.imageFilter = imageFilter; + setImageBackup.thumbLocation = thumbLocation; + setImageBackup.thumbFilter = thumbFilter; + setImageBackup.thumb = thumb; + setImageBackup.size = size; + setImageBackup.ext = ext; + setImageBackup.cacheType = cacheType; + setImageBackup.parentObject = parentObject; + return; + } if (ignoreImageSet) { return; } @@ -625,7 +644,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg if (delegate != null) { delegate.didSetImage(this, currentImageDrawable != null || currentThumbDrawable != null || staticThumbDrawable != null || currentMediaDrawable != null, currentImageDrawable == null && currentMediaDrawable == null, false); } + loadImage(); + isRoundVideo = parentObject instanceof MessageObject && ((MessageObject) parentObject).isRoundVideo(); + } + private void loadImage() { ImageLoader.getInstance().loadImageForImageReceiver(this); if (parentView != null) { if (invalidateAll) { @@ -634,8 +657,6 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg parentView.invalidate((int) imageX, (int) imageY, (int) (imageX + imageW), (int) (imageY + imageH)); } } - - isRoundVideo = parentObject instanceof MessageObject && ((MessageObject) parentObject).isRoundVideo(); } public boolean canInvertBitmap() { @@ -2518,4 +2539,8 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg videoThumbIsSame = b; } + public void setAllowLoadingOnAttachedOnly(boolean b) { + allowLoadingOnAttachedOnly = b; + } + } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java index d9c2f5277..3aaa5081d 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java @@ -28,6 +28,8 @@ import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.SparseIntArray; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.collection.LongSparseArray; import androidx.core.app.NotificationManagerCompat; import androidx.core.util.Consumer; @@ -9037,6 +9039,15 @@ public class MessagesController extends BaseController implements NotificationCe for (int a = 0; a < dialogsToUpdate.size(); a++) { long dialogId = dialogsToUpdate.keyAt(a); TLRPC.Dialog currentDialog = dialogs_dict.get(dialogId); + if (currentDialog == null) { + for (int i = 0; i < allDialogs.size(); i++) { + if (allDialogs.get(i).id == dialogId) { + dialogs_dict.put(dialogId, allDialogs.get(i)); + currentDialog = allDialogs.get(i); + break; + } + } + } if (currentDialog != null) { int prevCount = currentDialog.unread_count; currentDialog.unread_count = dialogsToUpdate.valueAt(a); @@ -9274,6 +9285,12 @@ public class MessagesController extends BaseController implements NotificationCe if (value == null) { value = 0; } + if (d.read_inbox_max_id > d.top_message) { + d.read_inbox_max_id = d.top_message; + } + if (value > d.top_message) { + value = d.top_message; + } dialogs_read_inbox_max.put(d.id, Math.max(value, d.read_inbox_max_id)); value = dialogs_read_outbox_max.get(d.id); @@ -12310,6 +12327,7 @@ public class MessagesController extends BaseController implements NotificationCe TLRPC.User user3 = null; TLRPC.Chat channel = null; + FileLog.d("update message short userId = " + userId); if (user == null || user.min) { user = getMessagesStorage().getUserSync(userId); if (user != null && user.min) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java index ed5bae77b..4c220fe3f 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java @@ -28,7 +28,6 @@ import org.telegram.SQLite.SQLiteCursor; import org.telegram.SQLite.SQLiteDatabase; import org.telegram.SQLite.SQLiteException; import org.telegram.SQLite.SQLitePreparedStatement; -import org.telegram.messenger.ringtone.RingtoneDataStore; import org.telegram.messenger.support.LongSparseIntArray; import org.telegram.tgnet.NativeByteBuffer; import org.telegram.tgnet.RequestDelegate; @@ -2376,6 +2375,11 @@ public class MessagesStorage extends BaseController { data.reuse(); } } + if (!DialogObject.isEncryptedDialog(dialogId)) { + if (dialog.read_inbox_max_id > dialog.top_message) { + dialog.read_inbox_max_id = 0; + } + } if (DialogObject.isEncryptedDialog(dialogId)) { int encryptedChatId = DialogObject.getEncryptedChatId(dialogId); if (!encryptedToLoad.contains(encryptedChatId)) { @@ -9324,15 +9328,22 @@ public class MessagesStorage extends BaseController { if (!(message.action instanceof TLRPC.TL_messageActionHistoryClear) && (!MessageObject.isOut(message) || message.from_scheduled) && (message.id > 0 || MessageObject.isUnread(message))) { int currentMaxId = dialogsReadMax.get(message.dialog_id, -1); if (currentMaxId == -1) { - SQLiteCursor cursor = database.queryFinalized("SELECT inbox_max FROM dialogs WHERE did = " + message.dialog_id); + SQLiteCursor cursor = database.queryFinalized("SELECT last_mid, inbox_max FROM dialogs WHERE did = " + message.dialog_id); if (cursor.next()) { - currentMaxId = cursor.intValue(0); + int lastMessageId = cursor.intValue(0); + int inboxMax = cursor.intValue(1); + if (inboxMax > lastMessageId) { + currentMaxId = 0; + } else { + currentMaxId = inboxMax; + } } else { currentMaxId = 0; } cursor.dispose(); dialogsReadMax.put(message.dialog_id, currentMaxId); } + FileLog.d("update messageRead currentMaxId = " + currentMaxId); if (message.id < 0 || currentMaxId < message.id) { StringBuilder messageIds = messageIdsMap.get(message.dialog_id); if (messageIds == null) { @@ -9350,6 +9361,7 @@ public class MessagesStorage extends BaseController { dialogMessagesIdsMap.put(message.dialog_id, ids); } ids.add(messageId); + FileLog.d("addMessage = " + messageId); } } if (MediaDataController.canAddMessageToMedia(message)) { @@ -10698,6 +10710,11 @@ public class MessagesStorage extends BaseController { addUsersAndChatsFromMessage(message, usersToLoad, chatsToLoad); } + if (!DialogObject.isEncryptedDialog(dialogId)) { + if (dialog.read_inbox_max_id > dialog.top_message) { + dialog.read_inbox_max_id = 0; + } + } if (DialogObject.isEncryptedDialog(dialogId)) { int encryptedChatId = DialogObject.getEncryptedChatId(dialogId); if (!encryptedToLoad.contains(encryptedChatId)) { @@ -11833,6 +11850,12 @@ public class MessagesStorage extends BaseController { } } + if (!DialogObject.isEncryptedDialog(dialogId)) { + if (dialog.read_inbox_max_id > dialog.top_message) { + dialog.read_inbox_max_id = 0; + } + } + if (DialogObject.isEncryptedDialog(dialogId)) { int encryptedChatId = DialogObject.getEncryptedChatId(dialogId); if (!encryptedToLoad.contains(encryptedChatId)) { @@ -12414,11 +12437,20 @@ public class MessagesStorage extends BaseController { try { if (outbox) { cursor = database.queryFinalized("SELECT outbox_max FROM dialogs WHERE did = " + dialog_id); + if (cursor.next()) { + max[0] = cursor.intValue(0); + } } else { - cursor = database.queryFinalized("SELECT inbox_max FROM dialogs WHERE did = " + dialog_id); - } - if (cursor.next()) { - max[0] = cursor.intValue(0); + cursor = database.queryFinalized("SELECT last_mid, inbox_max FROM dialogs WHERE did = " + dialog_id); + if (cursor.next()) { + int lastMid = cursor.intValue(0); + int inboxMax = cursor.intValue(1); + if (inboxMax > lastMid) { + max[0] = 0; + } else { + max[0] = inboxMax; + } + } } } catch (Exception e) { FileLog.e(e); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/AboutLinkCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/AboutLinkCell.java index 8cd94c6d9..232a594ba 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/AboutLinkCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/AboutLinkCell.java @@ -87,6 +87,13 @@ public class AboutLinkCell extends FrameLayout { private FrameLayout container; private Drawable rippleBackground; + private StaticLayout firstThreeLinesLayout; + private StaticLayout[] nextLinesLayouts = null; + private int lastInlineLine = -1; + private Point[] nextLinesLayoutsPositions; + private boolean needSpace = false; + private boolean moreButtonDisabled; + public AboutLinkCell(Context context, BaseFragment fragment) { this(context, fragment, null); } @@ -627,12 +634,10 @@ public class AboutLinkCell extends FrameLayout { } } - private StaticLayout firstThreeLinesLayout; - private StaticLayout[] nextLinesLayouts = null; - private int lastInlineLine = -1; - private Point[] nextLinesLayoutsPositions; - private boolean needSpace = false; private void checkTextLayout(int maxWidth, boolean force) { + if (moreButtonDisabled) { + shouldExpand = false; + } if (stringBuilder != null && (maxWidth != lastMaxWidth || force)) { textLayout = makeTextLayout(stringBuilder, maxWidth); shouldExpand = textLayout.getLineCount() >= 4; // && valueTextView.getVisibility() != View.VISIBLE; @@ -732,4 +737,8 @@ public class AboutLinkCell extends FrameLayout { } } } + + public void setMoreButtonDisabled(boolean moreButtonDisabled) { + this.moreButtonDisabled = moreButtonDisabled; + } } 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 56621f166..403213510 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java @@ -167,6 +167,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate public boolean clipToGroupBounds; private boolean flipImage; + private boolean visibleOnScreen; + public boolean shouldCheckVisibleOnScreen; public RadialProgress2 getRadialProgress() { return radialProgress; @@ -336,6 +338,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate currentMessageObject.markReactionsAsRead(); } + public void setVisibleOnScreen(boolean visibleOnScreen) { + if (this.visibleOnScreen != visibleOnScreen) { + this.visibleOnScreen = visibleOnScreen; + checkImageReceiversAttachState(); + } + } + public interface ChatMessageCellDelegate { default void didPressUserAvatar(ChatMessageCell cell, TLRPC.User user, float touchX, float touchY) { } @@ -1078,16 +1087,20 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate backgroundDrawable = new MessageBackgroundDrawable(this); avatarImage = new ImageReceiver(); + avatarImage.setAllowLoadingOnAttachedOnly(true); avatarImage.setRoundRadius(AndroidUtilities.dp(21)); avatarDrawable = new AvatarDrawable(); replyImageReceiver = new ImageReceiver(this); + replyImageReceiver.setAllowLoadingOnAttachedOnly(true); replyImageReceiver.setRoundRadius(AndroidUtilities.dp(2)); locationImageReceiver = new ImageReceiver(this); + locationImageReceiver.setAllowLoadingOnAttachedOnly(true); locationImageReceiver.setRoundRadius(AndroidUtilities.dp(26.1f)); TAG = DownloadController.getInstance(currentAccount).generateObserverTag(); contactAvatarDrawable = new AvatarDrawable(); photoImage = new ImageReceiver(this); + photoImage.setAllowLoadingOnAttachedOnly(true); photoImage.setUseRoundForThumbDrawable(true); photoImage.setDelegate(this); radialProgress = new RadialProgress2(this, resourcesProvider); @@ -3423,22 +3436,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate } } attachedToWindow = false; - radialProgress.onDetachedFromWindow(); - videoRadialProgress.onDetachedFromWindow(); avatarImage.onDetachedFromWindow(); - if (pollAvatarImages != null) { - for (int a = 0; a < pollAvatarImages.length; a++) { - pollAvatarImages[a].onDetachedFromWindow(); - } - } - if (commentAvatarImages != null) { - for (int a = 0; a < commentAvatarImages.length; a++) { - commentAvatarImages[a].onDetachedFromWindow(); - } - } - replyImageReceiver.onDetachedFromWindow(); - locationImageReceiver.onDetachedFromWindow(); - photoImage.onDetachedFromWindow(); + checkImageReceiversAttachState(); if (addedForTest && currentUrl != null && currentWebFile != null) { ImageLoader.getInstance().removeTestWebFile(currentUrl); addedForTest = false; @@ -3503,35 +3502,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate checkBoxTranslation = 0; updateTranslation(); - radialProgress.onAttachedToWindow(); - videoRadialProgress.onAttachedToWindow(); avatarImage.setParentView((View) getParent()); avatarImage.onAttachedToWindow(); + checkImageReceiversAttachState(); if (currentMessageObject != null) { setAvatar(currentMessageObject); } - if (pollAvatarImages != null) { - for (int a = 0; a < pollAvatarImages.length; a++) { - pollAvatarImages[a].onAttachedToWindow(); - } - } - if (commentAvatarImages != null) { - for (int a = 0; a < commentAvatarImages.length; a++) { - commentAvatarImages[a].onAttachedToWindow(); - } - } - replyImageReceiver.onAttachedToWindow(); - locationImageReceiver.onAttachedToWindow(); - if (photoImage.onAttachedToWindow()) { - if (drawPhotoImage) { - updateButtonState(false, false, false); - } - } else { - updateButtonState(false, false, false); - } - if (currentMessageObject != null && (isRoundVideo || currentMessageObject.isVideo())) { - checkVideoPlayback(true, null); - } if (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO && autoPlayingMedia) { animatingNoSoundPlaying = MediaController.getInstance().isPlayingMessage(currentMessageObject); animatingNoSoundProgress = animatingNoSoundPlaying ? 0.0f : 1.0f; @@ -3555,6 +3531,92 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate updateFlagSecure(); } + boolean imageReceiversAttachState; + private void checkImageReceiversAttachState() { + boolean newAttachState = attachedToWindow && (visibleOnScreen || !shouldCheckVisibleOnScreen); + if (newAttachState == imageReceiversAttachState) { + return; + } + imageReceiversAttachState = newAttachState; + if (newAttachState) { + radialProgress.onAttachedToWindow(); + videoRadialProgress.onAttachedToWindow(); + if (pollAvatarImages != null) { + for (int a = 0; a < pollAvatarImages.length; a++) { + pollAvatarImages[a].onAttachedToWindow(); + } + } + if (commentAvatarImages != null) { + for (int a = 0; a < commentAvatarImages.length; a++) { + commentAvatarImages[a].onAttachedToWindow(); + } + } + replyImageReceiver.onAttachedToWindow(); + locationImageReceiver.onAttachedToWindow(); + if (photoImage.onAttachedToWindow()) { + if (drawPhotoImage) { + updateButtonState(false, false, false); + } + } else { + updateButtonState(false, false, false); + } + if (currentMessageObject != null && (isRoundVideo || currentMessageObject.isVideo())) { + checkVideoPlayback(true, null); + } + if (currentMessageObject != null && !currentMessageObject.mediaExists) { + int canDownload = DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject.messageOwner); + TLRPC.Document document = currentMessageObject.getDocument(); + boolean loadDocumentFromImageReceiver = MessageObject.isStickerDocument(document) || MessageObject.isAnimatedStickerDocument(document, true) || MessageObject.isGifDocument(document) || MessageObject.isRoundVideoDocument(document); + if (!loadDocumentFromImageReceiver) { + TLRPC.PhotoSize photo = document == null ? FileLoader.getClosestPhotoSizeWithSize(currentMessageObject.photoThumbs, AndroidUtilities.getPhotoSize()) : null; + if (canDownload == 2 || canDownload == 1 && currentMessageObject.isVideo()) { + if (document != null && !currentMessageObject.shouldEncryptPhotoOrVideo() && currentMessageObject.canStreamVideo()) { + FileLoader.getInstance(currentAccount).loadFile(document, currentMessageObject, 0, 10); + } + } else if (canDownload != 0){ + if (document != null) { + FileLoader.getInstance(currentAccount).loadFile(document, currentMessageObject, 0, MessageObject.isVideoDocument(document) && currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0); + } else if (photo != null) { + FileLoader.getInstance(currentAccount).loadFile(ImageLocation.getForObject(photo, currentMessageObject.photoThumbsObject), currentMessageObject, null, 0, currentMessageObject.shouldEncryptPhotoOrVideo() ? 2 : 0); + } + } + updateButtonState(false, false, false); + } + } + } else { + radialProgress.onDetachedFromWindow(); + videoRadialProgress.onDetachedFromWindow(); + if (pollAvatarImages != null) { + for (int a = 0; a < pollAvatarImages.length; a++) { + pollAvatarImages[a].onDetachedFromWindow(); + } + } + if (commentAvatarImages != null) { + for (int a = 0; a < commentAvatarImages.length; a++) { + commentAvatarImages[a].onDetachedFromWindow(); + } + } + replyImageReceiver.onDetachedFromWindow(); + locationImageReceiver.onDetachedFromWindow(); + photoImage.onDetachedFromWindow(); + + if (currentMessageObject != null && !currentMessageObject.mediaExists && !currentMessageObject.putInDownloadsStore) { + TLRPC.Document document = currentMessageObject.getDocument(); + boolean loadDocumentFromImageReceiver = MessageObject.isStickerDocument(document) || MessageObject.isAnimatedStickerDocument(document, true) || MessageObject.isGifDocument(document) || MessageObject.isRoundVideoDocument(document); + if (!loadDocumentFromImageReceiver) { + if (document != null) { + FileLoader.getInstance(currentAccount).cancelLoadFile(document); + } else { + TLRPC.PhotoSize photo = FileLoader.getClosestPhotoSizeWithSize(currentMessageObject.photoThumbs, AndroidUtilities.getPhotoSize()); + if (photo != null) { + FileLoader.getInstance(currentAccount).cancelLoadFile(photo); + } + } + } + } + } + } + private boolean lastTranslated; private void setMessageContent(MessageObject messageObject, MessageObject.GroupedMessages groupedMessages, boolean bottomNear, boolean topNear) { @@ -11373,10 +11435,6 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate if (currentMessageObject == null) { return; } - if (!wasLayout && !animationRunning) { - forceLayout(); - return; - } if (!wasLayout) { onLayout(false, getLeft(), getTop(), getRight(), getBottom()); } 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 e328d513e..911b7a506 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java @@ -2076,9 +2076,10 @@ public class DialogCell extends BaseCell { if (isDialogCell) { TLRPC.Dialog dialog = MessagesController.getInstance(currentAccount).dialogs_dict.get(currentDialogId); if (dialog != null) { - clearingDialog = MessagesController.getInstance(currentAccount).isClearingDialog(dialog.id); - message = MessagesController.getInstance(currentAccount).dialogMessage.get(dialog.id); - if (message != null && NekoConfig.ignoreBlocked.Bool() && MessagesController.getInstance(currentAccount).blockePeers.indexOfKey(message.getSenderId()) >= 0) { + if (mask == 0) { + clearingDialog = MessagesController.getInstance(currentAccount).isClearingDialog(dialog.id); + message = MessagesController.getInstance(currentAccount).dialogMessage.get(dialog.id); + if (message != null && NekoConfig.ignoreBlocked.Bool() && MessagesController.getInstance(currentAccount).blockePeers.indexOfKey(message.getSenderId()) >= 0) { if (MessagesController.getInstance(currentAccount).dialogMessageFromUnblocked.get(dialog.id) != null) message = MessagesController.getInstance(currentAccount).dialogMessageFromUnblocked.get(dialog.id); else { @@ -2108,7 +2109,7 @@ public class DialogCell extends BaseCell { } if (message != null) { lastSendState = message.messageOwner.send_state; - +} } } else { unreadCount = 0; @@ -2170,7 +2171,7 @@ public class DialogCell extends BaseCell { continueUpdate = true; } } - if (!continueUpdate && (mask & MessagesController.UPDATE_MASK_READ_DIALOG_MESSAGE) != 0) { + if (!continueUpdate) { if (message != null && lastUnreadState != message.isUnread()) { lastUnreadState = message.isUnread(); continueUpdate = true; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index 9c8794a1f..cd7e6ea96 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -10980,76 +10980,6 @@ ChatActivity extends BaseFragment implements NotificationCenter.NotificationCent if (chatListView == null) { return; } - int count = chatListView.getChildCount(); - int firstMessagePosition = -1; - int lastMessagePosition = -1; - for (int a = 0; a < count; a++) { - View child = chatListView.getChildAt(a); - if (!(child instanceof ChatMessageCell)) { - continue; - } - RecyclerListView.ViewHolder holder = chatListView.findContainingViewHolder(child); - if (holder != null) { - int p = holder.getAdapterPosition(); - if (firstMessagePosition == -1) { - firstMessagePosition = p; - } - lastMessagePosition = p; - } - - ChatMessageCell cell = (ChatMessageCell) child; - MessageObject object = cell.getMessageObject(); - if (object == null || object.mediaExists || !object.isSent() || object.loadingCancelled) { - continue; - } - TLRPC.Document document = object.getDocument(); - if (document == null) { - continue; - } - int canDownload; - if (!MessageObject.isStickerDocument(document) && !MessageObject.isAnimatedStickerDocument(document, true) && !MessageObject.isGifDocument(document) && !MessageObject.isRoundVideoDocument(document) - && (canDownload = getDownloadController().canDownloadMedia(object.messageOwner)) != 0) { - if (canDownload == 2) { - if (currentEncryptedChat == null && !object.shouldEncryptPhotoOrVideo() && object.canStreamVideo()) { - getFileLoader().loadFile(document, object, 0, 10); - } - } else { - int cacheType; - if (object.isWallpaper() || object.isTheme()) { - cacheType = 1; - } else if (MessageObject.isVideoDocument(document) && object.shouldEncryptPhotoOrVideo()) { - cacheType = 2; - } else { - cacheType = 0; - } - getFileLoader().loadFile(document, object, 0, cacheType); - cell.updateButtonState(false, true, false); - } - } - } - if (firstMessagePosition != -1) { - int lastPosition; - if (scrollUp) { - firstMessagePosition = lastPosition = lastMessagePosition; - firstMessagePosition = Math.min(firstMessagePosition + 10, chatAdapter.messagesEndRow); - for (int a = lastPosition, N = messages.size(); a < firstMessagePosition; a++) { - int n = a - chatAdapter.messagesStartRow; - if (n < 0 || n >= N) { - continue; - } - checkAutoDownloadMessage(messages.get(n)); - } - } else { - lastPosition = Math.max(firstMessagePosition - 20, chatAdapter.messagesStartRow); - for (int a = firstMessagePosition - 1, N = messages.size(); a >= lastPosition; a--) { - int n = a - chatAdapter.messagesStartRow; - if (n < 0 || n >= N) { - continue; - } - checkAutoDownloadMessage(messages.get(n)); - } - } - } showNoSoundHint(); } @@ -12435,9 +12365,15 @@ ChatActivity extends BaseFragment implements NotificationCenter.NotificationCent messageCell.isBlurred = (view.getY() < clipTop && view.getY() + view.getMeasuredHeight() > clipTop) || (view.getY() + view.getMeasuredHeight() > chatListView.getMeasuredHeight() - blurredViewBottomOffset && view.getY() < chatListView.getMeasuredHeight() - blurredViewBottomOffset); } - if (bottom <= clipTop - chatListViewPaddingVisibleOffset || top > chatListView.getMeasuredHeight()) { + if (bottom <= clipTop - chatListViewPaddingVisibleOffset || top > chatListView.getMeasuredHeight() - blurredViewBottomOffset) { + if (messageCell != null) { + messageCell.setVisibleOnScreen(false); + } continue; } + if (messageCell != null) { + messageCell.setVisibleOnScreen(true); + } int viewTop = top >= 0 ? 0 : -top; int viewBottom = view.getMeasuredHeight(); @@ -25895,6 +25831,7 @@ ChatActivity extends BaseFragment implements NotificationCenter.NotificationCent view = new ChatMessageCell(mContext, true, themeDelegate); } ChatMessageCell chatMessageCell = (ChatMessageCell) view; + chatMessageCell.shouldCheckVisibleOnScreen = true; chatMessageCell.setDelegate(new ChatMessageCell.ChatMessageCellDelegate() { @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/InstantCameraView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/InstantCameraView.java index ec63e6227..1caf36601 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/InstantCameraView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/InstantCameraView.java @@ -983,7 +983,11 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter } } if (sortedSizes.isEmpty() || SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_LOW || SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_AVERAGE) { - return CameraController.chooseOptimalSize(previewSizes, 480, 270, aspectRatio); + if (!sortedSizes.isEmpty()) { + return CameraController.chooseOptimalSize(sortedSizes, 480, 270, aspectRatio); + } else { + return CameraController.chooseOptimalSize(previewSizes, 480, 270, aspectRatio); + } } Collections.sort(sortedSizes, (o1, o2) -> { float a1 = Math.abs(1f - Math.min(o1.mHeight, o1.mWidth) / (float) Math.max(o1.mHeight, o1.mWidth)); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/GLIcon/Star3DIcon.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/GLIcon/Star3DIcon.java index 6d5457b0d..882dfe53f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/GLIcon/Star3DIcon.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/GLIcon/Star3DIcon.java @@ -48,8 +48,8 @@ public class Star3DIcon { int trianglesCount; float enterAlpha = 0f; - public float spec1 = 0f; - public float spec2 = 0f; + public float spec1 = 2f; + public float spec2 = 0.13f; public float diffuse = 1f; public int gradientColor1; public int gradientColor2; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java index 415d1a205..2901319f1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java @@ -8029,7 +8029,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. aboutLinkCell.setTextAndValue(LocaleController.getString("UserBioDetail", R.string.UserBioDetail), LocaleController.getString("UserBio", R.string.UserBio), false); currentBio = null; } -// aboutLinkCell.setMoreButtonDisabled(true); +// aboutLinkCell.setMoreButtonDisabled(true); } if (position == bioRow) { aboutLinkCell.setOnClickListener(e -> {