merge official 8.8.5

This commit is contained in:
luvletter2333 2022-07-06 20:35:15 +08:00
commit a0f3ad497d
No known key found for this signature in database
GPG Key ID: A26A8880836E1978
18 changed files with 310 additions and 162 deletions

View File

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

View File

@ -2519,7 +2519,7 @@ public class AndroidUtilities {
}
public static void appCenterLog(Throwable e) {
}
public static boolean shouldShowClipboardToast() {

View File

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

View File

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

View File

@ -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<Long, TLRPC.TL_fileHash> 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;
}

View File

@ -89,7 +89,7 @@ public class FileLoader extends BaseController {
private ConcurrentHashMap<String, FileLoadOperation> loadOperationPaths = new ConcurrentHashMap<>();
private ArrayList<FileLoadOperation> activeFileLoadOperation = new ArrayList<>();
private ConcurrentHashMap<String, Boolean> loadOperationPathsUI = new ConcurrentHashMap<>(10, 1, 2);
private ConcurrentHashMap<String, LoadOperationUIObject> loadOperationPathsUI = new ConcurrentHashMap<>(10, 1, 2);
private HashMap<String, Long> uploadSizes = new HashMap<>();
private HashMap<String, Boolean> 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;
}
}

View File

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

View File

@ -1742,12 +1742,12 @@ public class ImageLoader {
final ArrayList<ImageReceiver> finalImageReceiverArray = new ArrayList<>(imageReceiverArray);
final ArrayList<Integer> 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;

View File

@ -280,6 +280,8 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
private ArrayList<Runnable> 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;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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