update to 9.1.3

This commit is contained in:
xaxtix 2022-11-12 12:41:35 +04:00
parent 23118a4a6c
commit 4951061dde
98 changed files with 4578 additions and 1393 deletions

View file

@ -1200,11 +1200,11 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
bool ignoreResult = false; bool ignoreResult = false;
if (hasResult) { if (hasResult) {
TLObject *object = response->result.get(); TLObject *object = response->result.get();
if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) received rpc_result with %s", connection, instanceNum, datacenter->getDatacenterId(), connection->getConnectionType(), typeid(*object).name()); if (LOGS_ENABLED) DEBUG_D("message_id %lld connection(%p, account%u, dc%u, type %d) received rpc_result with %s", messageId, connection, instanceNum, datacenter->getDatacenterId(), connection->getConnectionType(), typeid(*object).name());
} }
RpcError *error = hasResult ? dynamic_cast<RpcError *>(response->result.get()) : nullptr; RpcError *error = hasResult ? dynamic_cast<RpcError *>(response->result.get()) : nullptr;
if (error != nullptr) { if (error != nullptr) {
if (LOGS_ENABLED) DEBUG_E("connection(%p, account%u, dc%u, type %d) rpc error %d: %s", connection, instanceNum, datacenter->getDatacenterId(), connection->getConnectionType(), error->error_code, error->error_message.c_str()); if (LOGS_ENABLED) DEBUG_E("message_id %lld connection(%p, account%u, dc%u, type %d) rpc error %d: %s", messageId, connection, instanceNum, datacenter->getDatacenterId(), connection->getConnectionType(), error->error_code, error->error_message.c_str());
if (error->error_code == 303) { if (error->error_code == 303) {
uint32_t migrateToDatacenterId = DEFAULT_DATACENTER_ID; uint32_t migrateToDatacenterId = DEFAULT_DATACENTER_ID;

View file

@ -127,6 +127,7 @@ listSelector=771751936
chat_outPreviewInstantText=-1 chat_outPreviewInstantText=-1
chat_inMenuSelected=-1517440301 chat_inMenuSelected=-1517440301
avatar_backgroundOrange=-869276 avatar_backgroundOrange=-869276
avatar_background2Orange=-1734333
avatar_actionBarSelectorGreen=-12758164 avatar_actionBarSelectorGreen=-12758164
chat_outLocationIcon=-1 chat_outLocationIcon=-1
chat_inLoaderSelected=-11297295 chat_inLoaderSelected=-11297295
@ -155,6 +156,7 @@ chat_messageTextOut=-328966
chat_inInstant=-8796932 chat_inInstant=-8796932
groupcreate_cursor=-10177041 groupcreate_cursor=-10177041
avatar_backgroundSaved=-11558424 avatar_backgroundSaved=-11558424
avatar_background2Saved=-15038233
returnToCallBackground=-10639897 returnToCallBackground=-10639897
checkboxSquareUnchecked=-11245959 checkboxSquareUnchecked=-11245959
dialogCheckboxSquareDisabled=-12040120 dialogCheckboxSquareDisabled=-12040120
@ -201,6 +203,7 @@ calls_callReceivedGreenIcon=-12001930
chats_pinnedOverlay=201326591 chats_pinnedOverlay=201326591
windowBackgroundWhiteInputField=-11513776 windowBackgroundWhiteInputField=-11513776
avatar_backgroundRed=-2326437 avatar_backgroundRed=-2326437
avatar_background2Red=-2863816
statisticChartLine_green=-12729793 statisticChartLine_green=-12729793
chat_emojiPanelIconSelector=-10177041 chat_emojiPanelIconSelector=-10177041
chat_emojiPanelBadgeBackground=-11291403 chat_emojiPanelBadgeBackground=-11291403

View file

@ -24,8 +24,8 @@ public class BuildVars {
public static boolean USE_CLOUD_STRINGS = true; public static boolean USE_CLOUD_STRINGS = true;
public static boolean CHECK_UPDATES = true; public static boolean CHECK_UPDATES = true;
public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29; public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29;
public static int BUILD_VERSION = 2902; public static int BUILD_VERSION = 2917;
public static String BUILD_VERSION_STRING = "9.1.2"; public static String BUILD_VERSION_STRING = "9.1.3";
public static int APP_ID = 4; public static int APP_ID = 4;
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103"; public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";

View file

@ -18,6 +18,7 @@ public class DispatchQueuePoolBackground {
private int totalTasksCount; private int totalTasksCount;
private boolean cleanupScheduled; private boolean cleanupScheduled;
public static final String THREAD_PREFIX = "DispatchQueuePoolThreadSafety_";
static ArrayList<Runnable> updateTaskCollection; static ArrayList<Runnable> updateTaskCollection;
private static DispatchQueuePoolBackground backgroundQueue; private static DispatchQueuePoolBackground backgroundQueue;
@ -62,7 +63,7 @@ public class DispatchQueuePoolBackground {
if (!busyQueues.isEmpty() && (totalTasksCount / 2 <= busyQueues.size() || queues.isEmpty() && createdCount >= maxCount)) { if (!busyQueues.isEmpty() && (totalTasksCount / 2 <= busyQueues.size() || queues.isEmpty() && createdCount >= maxCount)) {
queue = busyQueues.remove(0); queue = busyQueues.remove(0);
} else if (queues.isEmpty()) { } else if (queues.isEmpty()) {
queue = new DispatchQueue("DispatchQueuePoolThreadSafety" + guid + "_" + Utilities.random.nextInt()); queue = new DispatchQueue(THREAD_PREFIX + guid + "_" + Utilities.random.nextInt());
queue.setPriority(Thread.MAX_PRIORITY); queue.setPriority(Thread.MAX_PRIORITY);
createdCount++; createdCount++;
} else { } else {
@ -104,6 +105,10 @@ public class DispatchQueuePoolBackground {
@UiThread @UiThread
public static void execute(Runnable runnable) { public static void execute(Runnable runnable) {
execute(runnable, false);
}
@UiThread
public static void execute(Runnable runnable, boolean now) {
if (BuildVars.DEBUG_PRIVATE_VERSION && Thread.currentThread() != ApplicationLoader.applicationHandler.getLooper().getThread()) { if (BuildVars.DEBUG_PRIVATE_VERSION && Thread.currentThread() != ApplicationLoader.applicationHandler.getLooper().getThread()) {
throw new RuntimeException("wrong thread"); throw new RuntimeException("wrong thread");
} }
@ -113,10 +118,16 @@ public class DispatchQueuePoolBackground {
} else { } else {
updateTaskCollection = new ArrayList<>(100); updateTaskCollection = new ArrayList<>(100);
} }
AndroidUtilities.runOnUIThread(finishCollectUpdateRunnable); if (!now) {
AndroidUtilities.runOnUIThread(finishCollectUpdateRunnable);
}
} }
updateTaskCollection.add(runnable); updateTaskCollection.add(runnable);
if (now) {
AndroidUtilities.cancelRunOnUIThread(finishCollectUpdateRunnable);
finishCollectUpdateRunnable.run();
}
} }
private static void finishCollectUpdateRunnables() { private static void finishCollectUpdateRunnables() {
@ -127,7 +138,7 @@ public class DispatchQueuePoolBackground {
ArrayList<Runnable> arrayList = updateTaskCollection; ArrayList<Runnable> arrayList = updateTaskCollection;
updateTaskCollection = null; updateTaskCollection = null;
if (backgroundQueue == null) { if (backgroundQueue == null) {
backgroundQueue = new DispatchQueuePoolBackground(Math.max(1, Runtime.getRuntime().availableProcessors() - 2)); backgroundQueue = new DispatchQueuePoolBackground(Math.max(1, Runtime.getRuntime().availableProcessors()));
} }
Utilities.globalQueue.postRunnable(() -> { Utilities.globalQueue.postRunnable(() -> {
backgroundQueue.execute(arrayList); backgroundQueue.execute(arrayList);

View file

@ -1281,114 +1281,127 @@ public class FileLoadOperation {
if (BuildVars.DEBUG_VERSION) { if (BuildVars.DEBUG_VERSION) {
FileLog.d("finished preloading file to " + cacheFileTemp + " loaded " + totalPreloadedBytes + " of " + totalBytesCount); FileLog.d("finished preloading file to " + cacheFileTemp + " loaded " + totalPreloadedBytes + " of " + totalBytesCount);
} }
delegate.didFinishLoadingFile(FileLoadOperation.this, cacheFileFinal);
} else { } else {
if (cacheIvTemp != null) { final File cacheIvTempFinal = cacheIvTemp;
cacheIvTemp.delete(); final File cacheFilePartsFinal = cacheFileParts;
cacheIvTemp = null; final File cacheFilePreloadFinal = cacheFilePreload;
} final File cacheFileTempFinal = cacheFileTemp;
if (cacheFileParts != null) { Utilities.globalQueue.postRunnable(() -> {
cacheFileParts.delete(); if (cacheIvTempFinal != null) {
cacheFileParts = null; cacheIvTempFinal.delete();
} }
if (cacheFilePreload != null) { if (cacheFilePartsFinal != null) {
cacheFilePreload.delete(); cacheFilePartsFinal.delete();
cacheFilePreload = null; }
} if (cacheFilePreloadFinal != null) {
if (cacheFileTemp != null) { cacheFilePreloadFinal.delete();
if (ungzip) { }
try { File cacheFileTempLocal = cacheFileTempFinal;
GZIPInputStream gzipInputStream = new GZIPInputStream(new FileInputStream(cacheFileTemp)); if (cacheFileTempLocal != null) {
FileLoader.copyFile(gzipInputStream, cacheFileGzipTemp, 1024 * 1024 * 2); if (ungzip) {
gzipInputStream.close(); try {
cacheFileTemp.delete(); GZIPInputStream gzipInputStream = new GZIPInputStream(new FileInputStream(cacheFileTempLocal));
cacheFileTemp = cacheFileGzipTemp; FileLoader.copyFile(gzipInputStream, cacheFileGzipTemp, 1024 * 1024 * 2);
ungzip = false; gzipInputStream.close();
} catch (ZipException zipException) { cacheFileTempLocal.delete();
ungzip = false; cacheFileTempLocal = cacheFileGzipTemp;
} catch (Throwable e) { ungzip = false;
FileLog.e(e); } catch (ZipException zipException) {
if (BuildVars.LOGS_ENABLED) { ungzip = false;
FileLog.e("unable to ungzip temp = " + cacheFileTemp + " to final = " + cacheFileFinal); } catch (Throwable e) {
FileLog.e(e);
if (BuildVars.LOGS_ENABLED) {
FileLog.e("unable to ungzip temp = " + cacheFileTempFinal + " to final = " + cacheFileFinal);
}
} }
} }
} if (!ungzip) {
if (!ungzip) { boolean renameResult;
boolean renameResult; if (parentObject instanceof TLRPC.TL_theme) {
if (parentObject instanceof TLRPC.TL_theme) { try {
try { renameResult = AndroidUtilities.copyFile(cacheFileTempLocal, cacheFileFinal);
renameResult = AndroidUtilities.copyFile(cacheFileTemp, cacheFileFinal); } catch (Exception e) {
} catch (Exception e) { renameResult = false;
renameResult = false; FileLog.e(e);
FileLog.e(e); }
} } else {
} else { try {
try { if (pathSaveData != null) {
if (pathSaveData != null) { synchronized (lockObject) {
synchronized (lockObject) { cacheFileFinal = new File(storePath, storeFileName);
cacheFileFinal = new File(storePath, storeFileName); int count = 1;
int count = 1; while (cacheFileFinal.exists()) {
while (cacheFileFinal.exists()) { int lastDotIndex = storeFileName.lastIndexOf('.');
int lastDotIndex = storeFileName.lastIndexOf('.'); String newFileName;
String newFileName; if (lastDotIndex > 0) {
if (lastDotIndex > 0) { newFileName = storeFileName.substring(0, lastDotIndex) + " (" + count + ")" + storeFileName.substring(lastDotIndex);
newFileName = storeFileName.substring(0, lastDotIndex) + " (" + count + ")" + storeFileName.substring(lastDotIndex); } else {
} else { newFileName = storeFileName + " (" + count + ")";
newFileName = storeFileName + " (" + count + ")"; }
cacheFileFinal = new File(storePath, newFileName);
count++;
} }
cacheFileFinal = new File(storePath, newFileName);
count++;
} }
} }
renameResult = cacheFileTempLocal.renameTo(cacheFileFinal);
} catch (Exception e) {
renameResult = false;
FileLog.e(e);
} }
renameResult = cacheFileTemp.renameTo(cacheFileFinal);
} catch (Exception e) {
renameResult = false;
FileLog.e(e);
} }
} if (!renameResult) {
if (!renameResult) { if (BuildVars.LOGS_ENABLED) {
if (BuildVars.LOGS_ENABLED) { FileLog.e("unable to rename temp = " + cacheFileTempLocal + " to final = " + cacheFileFinal + " retry = " + renameRetryCount);
FileLog.e("unable to rename temp = " + cacheFileTemp + " to final = " + cacheFileFinal + " retry = " + renameRetryCount); }
renameRetryCount++;
if (renameRetryCount < 3) {
state = stateDownloading;
Utilities.stageQueue.postRunnable(() -> {
try {
onFinishLoadingFile(increment);
} catch (Exception e) {
onFail(false, 0);
}
}, 200);
return;
}
cacheFileFinal = cacheFileTempLocal;
} else {
if (pathSaveData != null && cacheFileFinal.exists()) {
delegate.saveFilePath(pathSaveData, cacheFileFinal);
}
} }
renameRetryCount++;
if (renameRetryCount < 3) {
state = stateDownloading;
Utilities.stageQueue.postRunnable(() -> {
try {
onFinishLoadingFile(increment);
} catch (Exception e) {
onFail(false, 0);
}
}, 200);
return;
}
cacheFileFinal = cacheFileTemp;
} else { } else {
if (pathSaveData != null && cacheFileFinal.exists()) { Utilities.stageQueue.postRunnable(() -> {
delegate.saveFilePath(pathSaveData, cacheFileFinal); onFail(false, 0);
});
return;
}
}
Utilities.stageQueue.postRunnable(() -> {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("finished downloading file to " + cacheFileFinal + " time = " + (System.currentTimeMillis() - startTime));
}
if (increment) {
if (currentType == ConnectionsManager.FileTypeAudio) {
StatsController.getInstance(currentAccount).incrementReceivedItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_AUDIOS, 1);
} else if (currentType == ConnectionsManager.FileTypeVideo) {
StatsController.getInstance(currentAccount).incrementReceivedItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_VIDEOS, 1);
} else if (currentType == ConnectionsManager.FileTypePhoto) {
StatsController.getInstance(currentAccount).incrementReceivedItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_PHOTOS, 1);
} else if (currentType == ConnectionsManager.FileTypeFile) {
StatsController.getInstance(currentAccount).incrementReceivedItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_FILES, 1);
} }
} }
} else { delegate.didFinishLoadingFile(FileLoadOperation.this, cacheFileFinal);
onFail(false, 0); });
return; });
} cacheIvTemp = null;
} cacheFileParts = null;
if (BuildVars.LOGS_ENABLED) { cacheFilePreload = null;
FileLog.d("finished downloading file to " + cacheFileFinal + " time = " + (System.currentTimeMillis() - startTime));
}
if (increment) {
if (currentType == ConnectionsManager.FileTypeAudio) {
StatsController.getInstance(currentAccount).incrementReceivedItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_AUDIOS, 1);
} else if (currentType == ConnectionsManager.FileTypeVideo) {
StatsController.getInstance(currentAccount).incrementReceivedItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_VIDEOS, 1);
} else if (currentType == ConnectionsManager.FileTypePhoto) {
StatsController.getInstance(currentAccount).incrementReceivedItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_PHOTOS, 1);
} else if (currentType == ConnectionsManager.FileTypeFile) {
StatsController.getInstance(currentAccount).incrementReceivedItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_FILES, 1);
}
}
} }
delegate.didFinishLoadingFile(FileLoadOperation.this, cacheFileFinal);
} }
private void delayRequestInfo(RequestInfo requestInfo) { private void delayRequestInfo(RequestInfo requestInfo) {

View file

@ -92,6 +92,7 @@ public class FileLog {
try { try {
String metadata = "requestMsgId=" + requestMsgId + " requestingTime=" + (System.currentTimeMillis() - startRequestTimeInMillis) + " request_token=" + requestToken; String metadata = "requestMsgId=" + requestMsgId + " requestingTime=" + (System.currentTimeMillis() - startRequestTimeInMillis) + " request_token=" + requestToken;
FileLog.getInstance().tlStreamWriter.write(getInstance().dateFormat.format(time) + " " + metadata); FileLog.getInstance().tlStreamWriter.write(getInstance().dateFormat.format(time) + " " + metadata);
FileLog.getInstance().tlStreamWriter.write("\n");
FileLog.getInstance().tlStreamWriter.write(req); FileLog.getInstance().tlStreamWriter.write(req);
FileLog.getInstance().tlStreamWriter.write("\n"); FileLog.getInstance().tlStreamWriter.write("\n");
FileLog.getInstance().tlStreamWriter.write(finalRes); FileLog.getInstance().tlStreamWriter.write(finalRes);
@ -125,6 +126,7 @@ public class FileLog {
String metadata = getInstance().dateFormat.format(time);// + " msgId=" + messageId; String metadata = getInstance().dateFormat.format(time);// + " msgId=" + messageId;
FileLog.getInstance().tlStreamWriter.write(metadata); FileLog.getInstance().tlStreamWriter.write(metadata);
FileLog.getInstance().tlStreamWriter.write("\n");
FileLog.getInstance().tlStreamWriter.write(messageStr); FileLog.getInstance().tlStreamWriter.write(messageStr);
FileLog.getInstance().tlStreamWriter.write("\n\n"); FileLog.getInstance().tlStreamWriter.write("\n\n");
FileLog.getInstance().tlStreamWriter.flush(); FileLog.getInstance().tlStreamWriter.flush();

View file

@ -69,7 +69,9 @@ public class FileRefController extends BaseController {
} }
public static String getKeyForParentObject(Object parentObject) { public static String getKeyForParentObject(Object parentObject) {
if (parentObject instanceof TLRPC.TL_availableReaction) { if (parentObject instanceof TLRPC.TL_help_premiumPromo) {
return "premium_promo";
} else if (parentObject instanceof TLRPC.TL_availableReaction) {
return "available_reaction_" + ((TLRPC.TL_availableReaction) parentObject).reaction; return "available_reaction_" + ((TLRPC.TL_availableReaction) parentObject).reaction;
} else if (parentObject instanceof TLRPC.BotInfo) { } else if (parentObject instanceof TLRPC.BotInfo) {
TLRPC.BotInfo botInfo = (TLRPC.BotInfo) parentObject; TLRPC.BotInfo botInfo = (TLRPC.BotInfo) parentObject;
@ -317,7 +319,18 @@ public class FileRefController extends BaseController {
} }
private void requestReferenceFromServer(Object parentObject, String locationKey, String parentKey, Object[] args) { private void requestReferenceFromServer(Object parentObject, String locationKey, String parentKey, Object[] args) {
if (parentObject instanceof TLRPC.TL_availableReaction) { if (parentObject instanceof TLRPC.TL_help_premiumPromo) {
TLRPC.TL_help_getPremiumPromo req = new TLRPC.TL_help_getPremiumPromo();
getConnectionsManager().sendRequest(req, (response, error) -> {
int date = (int) (System.currentTimeMillis() / 1000);
if (response instanceof TLRPC.TL_help_premiumPromo) {
TLRPC.TL_help_premiumPromo r = (TLRPC.TL_help_premiumPromo) response;
getMediaDataController().processLoadedPremiumPromo(r, date, false);
}
onRequestComplete(locationKey, parentKey, response, true, false);
});
} else if (parentObject instanceof TLRPC.TL_availableReaction) {
TLRPC.TL_messages_getAvailableReactions req = new TLRPC.TL_messages_getAvailableReactions(); TLRPC.TL_messages_getAvailableReactions req = new TLRPC.TL_messages_getAvailableReactions();
req.hash = 0; req.hash = 0;
getConnectionsManager().sendRequest(req, (response, error) -> onRequestComplete(locationKey, parentKey, response, true, false)); getConnectionsManager().sendRequest(req, (response, error) -> onRequestComplete(locationKey, parentKey, response, true, false));
@ -674,7 +687,9 @@ public class FileRefController extends BaseController {
private boolean onRequestComplete(String locationKey, String parentKey, TLObject response, boolean cache, boolean fromCache) { private boolean onRequestComplete(String locationKey, String parentKey, TLObject response, boolean cache, boolean fromCache) {
boolean found = false; boolean found = false;
String cacheKey = parentKey; String cacheKey = parentKey;
if (response instanceof TLRPC.TL_account_wallPapers) { if (response instanceof TLRPC.TL_help_premiumPromo) {
cacheKey = "premium_promo";
} else if (response instanceof TLRPC.TL_account_wallPapers) {
cacheKey = "wallpaper"; cacheKey = "wallpaper";
} else if (response instanceof TLRPC.TL_messages_savedGifs) { } else if (response instanceof TLRPC.TL_messages_savedGifs) {
cacheKey = "gif"; cacheKey = "gif";
@ -754,6 +769,14 @@ public class FileRefController extends BaseController {
} }
} }
} }
} else if (response instanceof TLRPC.TL_help_premiumPromo) {
TLRPC.TL_help_premiumPromo premiumPromo = (TLRPC.TL_help_premiumPromo) response;
for (TLRPC.Document document : premiumPromo.videos) {
result = getFileReference(document, requester.location, needReplacement, locationReplacement);
if (result != null) {
break;
}
}
} else if (response instanceof TLRPC.TL_messages_availableReactions) { } else if (response instanceof TLRPC.TL_messages_availableReactions) {
TLRPC.TL_messages_availableReactions availableReactions = (TLRPC.TL_messages_availableReactions) response; TLRPC.TL_messages_availableReactions availableReactions = (TLRPC.TL_messages_availableReactions) response;
getMediaDataController().processLoadedReactions(availableReactions.reactions, availableReactions.hash, (int) (System.currentTimeMillis() / 1000), false); getMediaDataController().processLoadedReactions(availableReactions.reactions, availableReactions.hash, (int) (System.currentTimeMillis() / 1000), false);

View file

@ -378,15 +378,18 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (userFull == null) { if (userFull == null) {
MessagesController.getInstance(currentAccount).loadFullUser(user, currentGuid, false); MessagesController.getInstance(currentAccount).loadFullUser(user, currentGuid, false);
} else { } else {
if (userFull.profile_photo != null && userFull.profile_photo.video_sizes != null && !userFull.profile_photo.video_sizes.isEmpty()) { if (userFull.profile_photo != null) {
TLRPC.VideoSize videoSize = userFull.profile_photo.video_sizes.get(0); TLRPC.Photo photo = userFull.profile_photo;
for (int i = 0; i < userFull.profile_photo.video_sizes.size(); i++) { if (photo != null && photo.video_sizes != null && !photo.video_sizes.isEmpty()) {
if ("p".equals(userFull.profile_photo.video_sizes.get(i).type)) { TLRPC.VideoSize videoSize = photo.video_sizes.get(0);
videoSize = userFull.profile_photo.video_sizes.get(i); for (int i = 0; i < photo.video_sizes.size(); i++) {
break; if ("p".equals(photo.video_sizes.get(i).type)) {
videoSize = photo.video_sizes.get(i);
break;
}
} }
videoLocation = ImageLocation.getForPhoto(videoSize, photo);
} }
videoLocation = ImageLocation.getForPhoto(videoSize, userFull.profile_photo);
} }
} }
} }
@ -1470,7 +1473,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (time == 0) { if (time == 0) {
time = System.currentTimeMillis(); time = System.currentTimeMillis();
} }
((SvgHelper.SvgDrawable) drawable).drawInternal(canvas, true, time, backgroundThreadDrawHolder.imageX, backgroundThreadDrawHolder.imageY, backgroundThreadDrawHolder.imageW, backgroundThreadDrawHolder.imageH); ((SvgHelper.SvgDrawable) drawable).drawInternal(canvas, true, backgroundThreadDrawHolder.threadIndex, time, backgroundThreadDrawHolder.imageX, backgroundThreadDrawHolder.imageY, backgroundThreadDrawHolder.imageW, backgroundThreadDrawHolder.imageH);
} else { } else {
drawable.draw(canvas); drawable.draw(canvas);
} }
@ -1487,9 +1490,9 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
private void drawBitmapDrawable(Canvas canvas, BitmapDrawable bitmapDrawable, BackgroundThreadDrawHolder backgroundThreadDrawHolder, int alpha) { private void drawBitmapDrawable(Canvas canvas, BitmapDrawable bitmapDrawable, BackgroundThreadDrawHolder backgroundThreadDrawHolder, int alpha) {
if (backgroundThreadDrawHolder != null) { if (backgroundThreadDrawHolder != null) {
if (bitmapDrawable instanceof RLottieDrawable) { if (bitmapDrawable instanceof RLottieDrawable) {
((RLottieDrawable) bitmapDrawable).drawInBackground(canvas, backgroundThreadDrawHolder.imageX, backgroundThreadDrawHolder.imageY, backgroundThreadDrawHolder.imageW, backgroundThreadDrawHolder.imageH, alpha, backgroundThreadDrawHolder.colorFilter); ((RLottieDrawable) bitmapDrawable).drawInBackground(canvas, backgroundThreadDrawHolder.imageX, backgroundThreadDrawHolder.imageY, backgroundThreadDrawHolder.imageW, backgroundThreadDrawHolder.imageH, alpha, backgroundThreadDrawHolder.colorFilter, backgroundThreadDrawHolder.threadIndex);
} else if (bitmapDrawable instanceof AnimatedFileDrawable) { } else if (bitmapDrawable instanceof AnimatedFileDrawable) {
((AnimatedFileDrawable) bitmapDrawable).drawInBackground(canvas, backgroundThreadDrawHolder.imageX, backgroundThreadDrawHolder.imageY, backgroundThreadDrawHolder.imageW, backgroundThreadDrawHolder.imageH, alpha, backgroundThreadDrawHolder.colorFilter); ((AnimatedFileDrawable) bitmapDrawable).drawInBackground(canvas, backgroundThreadDrawHolder.imageX, backgroundThreadDrawHolder.imageY, backgroundThreadDrawHolder.imageW, backgroundThreadDrawHolder.imageH, alpha, backgroundThreadDrawHolder.colorFilter, backgroundThreadDrawHolder.threadIndex);
} else { } else {
Bitmap bitmap = bitmapDrawable.getBitmap(); Bitmap bitmap = bitmapDrawable.getBitmap();
if (bitmap != null) { if (bitmap != null) {
@ -1508,9 +1511,9 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
} else { } else {
bitmapDrawable.setAlpha(alpha); bitmapDrawable.setAlpha(alpha);
if (bitmapDrawable instanceof RLottieDrawable) { if (bitmapDrawable instanceof RLottieDrawable) {
((RLottieDrawable) bitmapDrawable).drawInternal(canvas, false, currentTime); ((RLottieDrawable) bitmapDrawable).drawInternal(canvas, false, currentTime, 0);
} else if (bitmapDrawable instanceof AnimatedFileDrawable) { } else if (bitmapDrawable instanceof AnimatedFileDrawable) {
((AnimatedFileDrawable) bitmapDrawable).drawInternal(canvas, false, currentTime); ((AnimatedFileDrawable) bitmapDrawable).drawInternal(canvas, false, currentTime, 0);
} else { } else {
bitmapDrawable.draw(canvas); bitmapDrawable.draw(canvas);
} }
@ -2895,10 +2898,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
return fileLoadingPriority; return fileLoadingPriority;
} }
public BackgroundThreadDrawHolder setDrawInBackgroundThread(BackgroundThreadDrawHolder holder) { public BackgroundThreadDrawHolder setDrawInBackgroundThread(BackgroundThreadDrawHolder holder, int threadIndex) {
if (holder == null) { if (holder == null) {
holder = new BackgroundThreadDrawHolder(); holder = new BackgroundThreadDrawHolder();
} }
holder.threadIndex = threadIndex;
holder.animation = getAnimation(); holder.animation = getAnimation();
holder.lottieDrawable = getLottieAnimation(); holder.lottieDrawable = getLottieAnimation();
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
@ -2931,6 +2935,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
public boolean animationNotReady; public boolean animationNotReady;
public float overrideAlpha; public float overrideAlpha;
public long time; public long time;
public int threadIndex;
private AnimatedFileDrawable animation; private AnimatedFileDrawable animation;
private RLottieDrawable lottieDrawable; private RLottieDrawable lottieDrawable;
private int[] roundRadius = new int[4]; private int[] roundRadius = new int[4];

View file

@ -34,6 +34,7 @@ import android.text.TextUtils;
import android.text.style.CharacterStyle; import android.text.style.CharacterStyle;
import android.text.style.URLSpan; import android.text.style.URLSpan;
import android.text.util.Linkify; import android.text.util.Linkify;
import android.util.Pair;
import android.util.SparseArray; import android.util.SparseArray;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -65,7 +66,6 @@ import org.telegram.ui.Components.Bulletin;
import org.telegram.ui.Components.ChatThemeBottomSheet; import org.telegram.ui.Components.ChatThemeBottomSheet;
import org.telegram.ui.Components.RLottieDrawable; import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.Reactions.ReactionsEffectOverlay; import org.telegram.ui.Components.Reactions.ReactionsEffectOverlay;
import org.telegram.ui.Components.Reactions.ReactionsUtils;
import org.telegram.ui.Components.StickerSetBulletinLayout; import org.telegram.ui.Components.StickerSetBulletinLayout;
import org.telegram.ui.Components.StickersArchiveAlert; import org.telegram.ui.Components.StickersArchiveAlert;
import org.telegram.ui.Components.TextStyleSpan; import org.telegram.ui.Components.TextStyleSpan;
@ -523,7 +523,7 @@ public class MediaDataController extends BaseController {
} }
} }
private void processLoadedPremiumPromo(TLRPC.TL_help_premiumPromo premiumPromo, int date, boolean cache) { public void processLoadedPremiumPromo(TLRPC.TL_help_premiumPromo premiumPromo, int date, boolean cache) {
this.premiumPromo = premiumPromo; this.premiumPromo = premiumPromo;
premiumPromoUpdateDate = date; premiumPromoUpdateDate = date;
getMessagesController().putUsers(premiumPromo.users, cache); getMessagesController().putUsers(premiumPromo.users, cache);
@ -638,7 +638,7 @@ public class MediaDataController extends BaseController {
reactionsUpdateDate = date; reactionsUpdateDate = date;
if (reactions != null) { if (reactions != null) {
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
preloadReactions(); preloadDefaultReactions();
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.reactionsDidLoad); NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.reactionsDidLoad);
}); });
} }
@ -651,21 +651,23 @@ public class MediaDataController extends BaseController {
} }
} }
public void preloadReactions() { public void preloadDefaultReactions() {
if (reactionsList == null || reactionsCacheGenerated) { if (reactionsList == null || reactionsCacheGenerated) {
return; return;
} }
reactionsCacheGenerated = true; reactionsCacheGenerated = true;
ArrayList<TLRPC.TL_availableReaction> arrayList = new ArrayList<>(reactionsList); ArrayList<TLRPC.TL_availableReaction> arrayList = new ArrayList<>(reactionsList);
for (int i = 0; i < arrayList.size(); i++) {
TLRPC.TL_availableReaction reaction = arrayList.get(i);
preloadImage(ImageLocation.getForDocument(reaction.activate_animation), null);
preloadImage(ImageLocation.getForDocument(reaction.appear_animation), null);
}
for (int i = 0; i < arrayList.size(); i++) { for (int i = 0; i < arrayList.size(); i++) {
TLRPC.TL_availableReaction reaction = arrayList.get(i); TLRPC.TL_availableReaction reaction = arrayList.get(i);
int size = ReactionsEffectOverlay.sizeForBigReaction(); int size = ReactionsEffectOverlay.sizeForBigReaction();
preloadImage(ImageLocation.getForDocument(reaction.around_animation), ReactionsEffectOverlay.getFilterForAroundAnimation(), true); preloadImage(ImageLocation.getForDocument(reaction.around_animation), ReactionsEffectOverlay.getFilterForAroundAnimation(), true);
preloadImage(ImageLocation.getForDocument(reaction.effect_animation), size + "_" + size); preloadImage(ImageLocation.getForDocument(reaction.effect_animation), null);
preloadImage(ImageLocation.getForDocument(reaction.activate_animation), null);
preloadImage(ImageLocation.getForDocument(reaction.appear_animation), ReactionsUtils.APPEAR_ANIMATION_FILTER);
preloadImage(ImageLocation.getForDocument(reaction.center_icon), null);
} }
} }
@ -675,6 +677,9 @@ public class MediaDataController extends BaseController {
private void preloadImage(ImageLocation location, String filter, boolean log) { private void preloadImage(ImageLocation location, String filter, boolean log) {
ImageReceiver imageReceiver = new ImageReceiver(); ImageReceiver imageReceiver = new ImageReceiver();
imageReceiver.setAllowStartAnimation(false);
imageReceiver.setAllowStartLottieAnimation(false);
imageReceiver.setAllowDecodeSingleFrame(false);
imageReceiver.setDelegate((imageReceiver1, set, thumb, memCache) -> { imageReceiver.setDelegate((imageReceiver1, set, thumb, memCache) -> {
if (set) { if (set) {
RLottieDrawable rLottieDrawable = imageReceiver.getLottieAnimation(); RLottieDrawable rLottieDrawable = imageReceiver.getLottieAnimation();
@ -6061,6 +6066,19 @@ public class MediaDataController extends BaseController {
return threads.get(threadId); return threads.get(threadId);
} }
public Pair<Integer, TLRPC.DraftMessage> getOneThreadDraft(long dialogId) {
SparseArray<TLRPC.DraftMessage> threads = drafts.get(dialogId);
if (threads == null || threads.size() <= 0) {
return null;
}
for (int i = 0; i < threads.size(); ++i) {
if (threads.keyAt(i) != 0) {
return new Pair(threads.keyAt(i), threads.valueAt(i));
}
}
return null;
}
public TLRPC.Message getDraftMessage(long dialogId, int threadId) { public TLRPC.Message getDraftMessage(long dialogId, int threadId) {
SparseArray<TLRPC.Message> threads = draftMessages.get(dialogId); SparseArray<TLRPC.Message> threads = draftMessages.get(dialogId);
if (threads == null) { if (threads == null) {

View file

@ -175,6 +175,8 @@ public class MessageObject {
public boolean sponsoredShowPeerPhoto; public boolean sponsoredShowPeerPhoto;
public boolean sponsoredRecommended; public boolean sponsoredRecommended;
public TLRPC.TL_forumTopic replyToForumTopic; // used only for reply message in view all messages
public String botStartParam; public String botStartParam;
public boolean animateComments; public boolean animateComments;
@ -2547,7 +2549,7 @@ public class MessageObject {
} }
public boolean hasValidReplyMessageObject() { public boolean hasValidReplyMessageObject() {
return !(replyMessageObject == null || replyMessageObject.messageOwner instanceof TLRPC.TL_messageEmpty || replyMessageObject.messageOwner.action instanceof TLRPC.TL_messageActionHistoryClear); return !(replyMessageObject == null || replyMessageObject.messageOwner instanceof TLRPC.TL_messageEmpty || replyMessageObject.messageOwner.action instanceof TLRPC.TL_messageActionHistoryClear || replyMessageObject.messageOwner.action instanceof TLRPC.TL_messageActionTopicCreate);
} }
public void generatePaymentSentMessageText(TLRPC.User fromUser) { public void generatePaymentSentMessageText(TLRPC.User fromUser) {
@ -3442,10 +3444,13 @@ public class MessageObject {
TLRPC.TL_messageActionTopicEdit editAction = (TLRPC.TL_messageActionTopicEdit) messageOwner.action; TLRPC.TL_messageActionTopicEdit editAction = (TLRPC.TL_messageActionTopicEdit) messageOwner.action;
String name = null; String name = null;
TLObject object = null;
if (fromUser != null) { if (fromUser != null) {
name = ContactsController.formatName(fromUser.first_name, fromUser.last_name); name = ContactsController.formatName(fromUser.first_name, fromUser.last_name);
object = fromUser;
} else if (fromChat != null) { } else if (fromChat != null) {
name = fromChat.title; name = fromChat.title;
object = fromChat;
} }
if (name != null) { if (name != null) {
name = name.trim(); name = name.trim();
@ -3455,10 +3460,10 @@ public class MessageObject {
if ((messageOwner.action.flags & 4) > 0) { if ((messageOwner.action.flags & 4) > 0) {
if (((TLRPC.TL_messageActionTopicEdit) messageOwner.action).closed) { if (((TLRPC.TL_messageActionTopicEdit) messageOwner.action).closed) {
messageText = LocaleController.formatString("TopicClosed2", R.string.TopicClosed2, name); messageText = replaceWithLink(LocaleController.getString("TopicClosed2", R.string.TopicClosed2), "%s", object);
messageTextShort = LocaleController.getString("TopicClosed", R.string.TopicClosed); messageTextShort = LocaleController.getString("TopicClosed", R.string.TopicClosed);
} else { } else {
messageText = LocaleController.formatString("TopicRestarted2", R.string.TopicRestarted2, name); messageText = replaceWithLink(LocaleController.getString("TopicRestarted2", R.string.TopicRestarted2), "%s", object);
messageTextShort = LocaleController.getString("TopicRestarted", R.string.TopicRestarted); messageTextShort = LocaleController.getString("TopicRestarted", R.string.TopicRestarted);
} }
} else { } else {
@ -4776,6 +4781,10 @@ public class MessageObject {
} }
public static Spannable replaceAnimatedEmoji(CharSequence text, ArrayList<TLRPC.MessageEntity> entities, Paint.FontMetricsInt fontMetricsInt) { public static Spannable replaceAnimatedEmoji(CharSequence text, ArrayList<TLRPC.MessageEntity> entities, Paint.FontMetricsInt fontMetricsInt) {
return replaceAnimatedEmoji(text, entities, fontMetricsInt, false);
}
public static Spannable replaceAnimatedEmoji(CharSequence text, ArrayList<TLRPC.MessageEntity> entities, Paint.FontMetricsInt fontMetricsInt, boolean top) {
Spannable spannable = text instanceof Spannable ? (Spannable) text : new SpannableString(text); Spannable spannable = text instanceof Spannable ? (Spannable) text : new SpannableString(text);
if (entities == null) { if (entities == null) {
return spannable; return spannable;
@ -4812,6 +4821,7 @@ public class MessageObject {
} else { } else {
span = new AnimatedEmojiSpan(entity.document_id, fontMetricsInt); span = new AnimatedEmojiSpan(entity.document_id, fontMetricsInt);
} }
span.top = top;
spannable.setSpan(span, messageEntity.offset, messageEntity.offset + messageEntity.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); spannable.setSpan(span, messageEntity.offset, messageEntity.offset + messageEntity.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} }
} }
@ -5524,6 +5534,22 @@ public class MessageObject {
return false; return false;
} }
public static boolean peersEqual(TLRPC.Chat a, TLRPC.Peer b) {
if (a == null && b == null) {
return true;
}
if (a == null || b == null) {
return false;
}
if (ChatObject.isChannel(a) && b instanceof TLRPC.TL_peerChannel) {
return a.id == b.channel_id;
}
if (!ChatObject.isChannel(a) && b instanceof TLRPC.TL_peerChat) {
return a.id == b.chat_id;
}
return false;
}
public long getFromChatId() { public long getFromChatId() {
return getFromChatId(messageOwner); return getFromChatId(messageOwner);
} }

View file

@ -85,6 +85,7 @@ public class MessagesController extends BaseController implements NotificationCe
private ConcurrentHashMap<Integer, TLRPC.EncryptedChat> encryptedChats = new ConcurrentHashMap<>(10, 1.0f, 2); private ConcurrentHashMap<Integer, TLRPC.EncryptedChat> encryptedChats = new ConcurrentHashMap<>(10, 1.0f, 2);
private ConcurrentHashMap<Long, TLRPC.User> users = new ConcurrentHashMap<>(100, 1.0f, 2); private ConcurrentHashMap<Long, TLRPC.User> users = new ConcurrentHashMap<>(100, 1.0f, 2);
private ConcurrentHashMap<String, TLObject> objectsByUsernames = new ConcurrentHashMap<>(100, 1.0f, 2); private ConcurrentHashMap<String, TLObject> objectsByUsernames = new ConcurrentHashMap<>(100, 1.0f, 2);
public static int stableIdPointer = 100;
private HashMap<Long, TLRPC.Chat> activeVoiceChatsMap = new HashMap<>(); private HashMap<Long, TLRPC.Chat> activeVoiceChatsMap = new HashMap<>();
@ -365,6 +366,7 @@ public class MessagesController extends BaseController implements NotificationCe
public int reactionsUserMaxPremium; public int reactionsUserMaxPremium;
public int reactionsInChatMax; public int reactionsInChatMax;
public int forumUpgradeParticipantsMin; public int forumUpgradeParticipantsMin;
public int topicsPinnedLimit;
public int uploadMaxFileParts; public int uploadMaxFileParts;
public int uploadMaxFilePartsPremium; public int uploadMaxFilePartsPremium;
@ -592,6 +594,13 @@ public class MessagesController extends BaseController implements NotificationCe
getMessagesStorage().updateRepliesMaxReadId(-did, topic.id, topic.top_message, 0, true); getMessagesStorage().updateRepliesMaxReadId(-did, topic.id, topic.top_message, 0, true);
} }
} }
getMessagesStorage().getStorageQueue().postRunnable(() -> {
getMessagesStorage().resetAllUnreadCounters(false);
AndroidUtilities.runOnUIThread(() -> {
getMessagesController().sortDialogs(null);
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload, true);
});
});
}); });
}); });
} }
@ -1103,6 +1112,7 @@ public class MessagesController extends BaseController implements NotificationCe
premiumLocked = mainPreferences.getBoolean("premiumLocked", false); premiumLocked = mainPreferences.getBoolean("premiumLocked", false);
transcribeButtonPressed = mainPreferences.getInt("transcribeButtonPressed", 0); transcribeButtonPressed = mainPreferences.getInt("transcribeButtonPressed", 0);
forumUpgradeParticipantsMin = mainPreferences.getInt("forumUpgradeParticipantsMin", 200); forumUpgradeParticipantsMin = mainPreferences.getInt("forumUpgradeParticipantsMin", 200);
topicsPinnedLimit = mainPreferences.getInt("topicsPinnedLimit", 3);
BuildVars.GOOGLE_AUTH_CLIENT_ID = mainPreferences.getString("googleAuthClientId", BuildVars.GOOGLE_AUTH_CLIENT_ID); BuildVars.GOOGLE_AUTH_CLIENT_ID = mainPreferences.getString("googleAuthClientId", BuildVars.GOOGLE_AUTH_CLIENT_ID);
Set<String> currencySet = mainPreferences.getStringSet("directPaymentsCurrency", null); Set<String> currencySet = mainPreferences.getStringSet("directPaymentsCurrency", null);
@ -2619,6 +2629,16 @@ public class MessagesController extends BaseController implements NotificationCe
} }
break; break;
} }
case "topics_pinned_limit": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber number = (TLRPC.TL_jsonNumber) value.value;
if (number.value != topicsPinnedLimit) {
topicsPinnedLimit = (int) number.value;
editor.putInt("topicsPinnedLimit", topicsPinnedLimit);
changed = true;
}
}
}
} }
} }
if (changed) { if (changed) {
@ -3361,7 +3381,7 @@ public class MessagesController extends BaseController implements NotificationCe
editor = emojiPreferences.edit(); editor = emojiPreferences.edit();
editor.putLong("lastGifLoadTime", 0).putLong("lastStickersLoadTime", 0).putLong("lastStickersLoadTimeMask", 0).putLong("lastStickersLoadTimeFavs", 0).commit(); editor.putLong("lastGifLoadTime", 0).putLong("lastStickersLoadTime", 0).putLong("lastStickersLoadTimeMask", 0).putLong("lastStickersLoadTimeFavs", 0).commit();
editor = mainPreferences.edit(); editor = mainPreferences.edit();
editor.remove("archivehint").remove("proximityhint").remove("archivehint_l").remove("gifhint").remove("reminderhint").remove("soundHint").remove("dcDomainName2").remove("webFileDatacenterId").remove("themehint").remove("showFiltersTooltip").commit(); editor.remove("archivehint").remove("proximityhint").remove("archivehint_l").remove("gifhint").remove("reminderhint").remove("soundHint").remove("dcDomainName2").remove("webFileDatacenterId").remove("themehint").remove("showFiltersTooltip").remove("transcribeButtonPressed").commit();
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("shortcut_widget", Activity.MODE_PRIVATE); SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("shortcut_widget", Activity.MODE_PRIVATE);
SharedPreferences.Editor widgetEditor = null; SharedPreferences.Editor widgetEditor = null;
@ -12546,6 +12566,8 @@ public class MessagesController extends BaseController implements NotificationCe
return ((TLRPC.TL_updateReadChannelInbox) update).channel_id; return ((TLRPC.TL_updateReadChannelInbox) update).channel_id;
} else if (update instanceof TLRPC.TL_updateChannelPinnedTopic) { } else if (update instanceof TLRPC.TL_updateChannelPinnedTopic) {
return ((TLRPC.TL_updateChannelPinnedTopic) update).channel_id; return ((TLRPC.TL_updateChannelPinnedTopic) update).channel_id;
} else if (update instanceof TLRPC.TL_updateChannelPinnedTopics) {
return ((TLRPC.TL_updateChannelPinnedTopics) update).channel_id;
} else if (update instanceof TLRPC.TL_updateReadChannelDiscussionInbox) { } else if (update instanceof TLRPC.TL_updateReadChannelDiscussionInbox) {
return ((TLRPC.TL_updateReadChannelDiscussionInbox) update).channel_id; return ((TLRPC.TL_updateReadChannelDiscussionInbox) update).channel_id;
} else if (update instanceof TLRPC.TL_updateReadChannelDiscussionOutbox) { } else if (update instanceof TLRPC.TL_updateReadChannelDiscussionOutbox) {
@ -13898,7 +13920,10 @@ public class MessagesController extends BaseController implements NotificationCe
stillUnreadMessagesCount.put(dialogId, update.still_unread_count); stillUnreadMessagesCount.put(dialogId, update.still_unread_count);
dialogs_read_inbox_max.put(dialogId, Math.max(value, update.max_id)); dialogs_read_inbox_max.put(dialogId, Math.max(value, update.max_id));
FileLog.d("TL_updateReadChannelInbox " + dialogId + " new unread = " + update.still_unread_count + " max id = " + update.max_id + " from get diff " + fromGetDifference); FileLog.d("TL_updateReadChannelInbox " + dialogId + " new unread = " + update.still_unread_count + " max id = " + update.max_id + " from get diff " + fromGetDifference);
} else if (baseUpdate instanceof TLRPC.TL_updateChannelPinnedTopic) { } else if (
baseUpdate instanceof TLRPC.TL_updateChannelPinnedTopic ||
baseUpdate instanceof TLRPC.TL_updateChannelPinnedTopics
) {
if (updatesOnMainThread == null) { if (updatesOnMainThread == null) {
updatesOnMainThread = new ArrayList<>(); updatesOnMainThread = new ArrayList<>();
} }
@ -14791,14 +14816,21 @@ public class MessagesController extends BaseController implements NotificationCe
} else if (baseUpdate instanceof TLRPC.TL_updateChannelPinnedTopic) { } else if (baseUpdate instanceof TLRPC.TL_updateChannelPinnedTopic) {
TLRPC.TL_updateChannelPinnedTopic update = (TLRPC.TL_updateChannelPinnedTopic) baseUpdate; TLRPC.TL_updateChannelPinnedTopic update = (TLRPC.TL_updateChannelPinnedTopic) baseUpdate;
ArrayList<TLRPC.TL_forumTopic> topics = getTopicsController().getTopics(update.channel_id); ArrayList<Integer> newOrder = getTopicsController().getCurrentPinnedOrder(update.channel_id);
if (topics != null) { newOrder.remove((Integer) update.topic_id);
for (int i = 0; i < topics.size(); ++i) { if (update.pinned) {
topics.get(i).pinned = update.topic_id == topics.get(i).id; newOrder.add(0, update.topic_id);
}
} }
getTopicsController().applyPinnedOrder(update.channel_id, newOrder);
updateMask |= UPDATE_MASK_SELECT_DIALOG; } else if (baseUpdate instanceof TLRPC.TL_updateChannelPinnedTopics) {
TLRPC.TL_updateChannelPinnedTopics update = (TLRPC.TL_updateChannelPinnedTopics) baseUpdate;
if ((update.flags & 1) > 0) {
getTopicsController().applyPinnedOrder(update.channel_id, update.order);
} else {
getTopicsController().reloadTopics(update.channel_id, false);
}
} else if (baseUpdate instanceof TLRPC.TL_updatePhoneCallSignalingData) { } else if (baseUpdate instanceof TLRPC.TL_updatePhoneCallSignalingData) {
TLRPC.TL_updatePhoneCallSignalingData data = (TLRPC.TL_updatePhoneCallSignalingData) baseUpdate; TLRPC.TL_updatePhoneCallSignalingData data = (TLRPC.TL_updatePhoneCallSignalingData) baseUpdate;
VoIPService svc = VoIPService.getSharedInstance(); VoIPService svc = VoIPService.getSharedInstance();

View file

@ -2383,10 +2383,14 @@ public class MessagesStorage extends BaseController {
SQLitePreparedStatement state = null; SQLitePreparedStatement state = null;
try { try {
HashSet<Integer> existingTopics = new HashSet<>(); HashSet<Integer> existingTopics = new HashSet<>();
HashMap<Integer, Integer> pinnedValues = new HashMap<>();
for (int i = 0; i < topics.size(); i++) { for (int i = 0; i < topics.size(); i++) {
TLRPC.TL_forumTopic topic = topics.get(i); TLRPC.TL_forumTopic topic = topics.get(i);
SQLiteCursor cursor = database.queryFinalized("SELECT did FROM topics WHERE did = " + dialogId + " AND topic_id = " + topic.id); SQLiteCursor cursor = database.queryFinalized("SELECT did, pinned FROM topics WHERE did = " + dialogId + " AND topic_id = " + topic.id);
boolean exist = cursor.next(); boolean exist = cursor.next();
if (exist) {
pinnedValues.put(i, cursor.intValue(2));
}
cursor.dispose(); cursor.dispose();
cursor = null; cursor = null;
if (exist) { if (exist) {
@ -2422,7 +2426,11 @@ public class MessagesStorage extends BaseController {
state.bindInteger(8, topic.unread_mentions_count); state.bindInteger(8, topic.unread_mentions_count);
state.bindInteger(9, topic.unread_reactions_count); state.bindInteger(9, topic.unread_reactions_count);
state.bindInteger(10, topic.read_outbox_max_id); state.bindInteger(10, topic.read_outbox_max_id);
state.bindInteger(11, topic.pinned ? 1 : 0); if (topic.isShort && pinnedValues.containsKey(i)) {
state.bindInteger(11, pinnedValues.get(i));
} else {
state.bindInteger(11, topic.pinned ? 1 + topic.pinnedOrder : 0);
}
state.step(); state.step();
messageData.reuse(); messageData.reuse();
@ -2487,8 +2495,9 @@ public class MessagesStorage extends BaseController {
} }
if ((flags & TopicsController.TOPIC_FLAG_PIN) != 0) { if ((flags & TopicsController.TOPIC_FLAG_PIN) != 0) {
topicToUpdate.pinned = fromTopic.pinned; topicToUpdate.pinned = fromTopic.pinned;
topicToUpdate.pinnedOrder = fromTopic.pinnedOrder;
} }
boolean pinned = topicToUpdate.pinned; int pinnedOrder = topicToUpdate.pinned ? 1 + topicToUpdate.pinnedOrder : 0;
if ((flags & TopicsController.TOPIC_FLAG_CLOSE) != 0) { if ((flags & TopicsController.TOPIC_FLAG_CLOSE) != 0) {
topicToUpdate.closed = fromTopic.closed; topicToUpdate.closed = fromTopic.closed;
} }
@ -2497,7 +2506,7 @@ public class MessagesStorage extends BaseController {
NativeByteBuffer data = new NativeByteBuffer(topicToUpdate.getObjectSize()); NativeByteBuffer data = new NativeByteBuffer(topicToUpdate.getObjectSize());
topicToUpdate.serializeToStream(data); topicToUpdate.serializeToStream(data);
state.bindByteBuffer(1, data); state.bindByteBuffer(1, data);
state.bindInteger(2, pinned ? 1 : 0); state.bindInteger(2, pinnedOrder);
state.bindLong(3, dialogId); state.bindLong(3, dialogId);
state.bindInteger(4, topicToUpdate.id); state.bindInteger(4, topicToUpdate.id);
state.step(); state.step();
@ -2522,7 +2531,7 @@ public class MessagesStorage extends BaseController {
ArrayList<TLRPC.TL_forumTopic> topics = null; ArrayList<TLRPC.TL_forumTopic> topics = null;
SQLiteCursor cursor = null; SQLiteCursor cursor = null;
try { try {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT top_message, data, topic_message, unread_count, max_read_id, unread_mentions, unread_reactions, read_outbox FROM topics WHERE did = %d ORDER BY pinned DESC", dialogId)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT top_message, data, topic_message, unread_count, max_read_id, unread_mentions, unread_reactions, read_outbox, pinned FROM topics WHERE did = %d ORDER BY pinned ASC", dialogId));
SparseArray<ArrayList<TLRPC.TL_forumTopic>> topicsByTopMessageId = null; SparseArray<ArrayList<TLRPC.TL_forumTopic>> topicsByTopMessageId = null;
HashSet<Integer> topMessageIds = null; HashSet<Integer> topMessageIds = null;
@ -2559,6 +2568,8 @@ public class MessagesStorage extends BaseController {
topic.unread_mentions_count = cursor.intValue(5); topic.unread_mentions_count = cursor.intValue(5);
topic.unread_reactions_count = cursor.intValue(6); topic.unread_reactions_count = cursor.intValue(6);
topic.read_outbox_max_id = cursor.intValue(7); topic.read_outbox_max_id = cursor.intValue(7);
topic.pinnedOrder = cursor.intValue(8) - 1;
topic.pinned = topic.pinnedOrder >= 0;
} }
data.reuse(); data.reuse();
@ -10759,31 +10770,34 @@ public class MessagesStorage extends BaseController {
SQLiteCursor cursor = null; SQLiteCursor cursor = null;
try { try {
long dialogId = -chatId; long dialogId = -chatId;
state = database.executeFast("UPDATE messages_v2 SET replies_data = ? WHERE mid = ? AND uid = ?"); if (!isForum(-chatId)) {
TLRPC.MessageReplies currentReplies = null; state = database.executeFast("UPDATE messages_v2 SET replies_data = ? WHERE mid = ? AND uid = ?");
cursor = database.queryFinalized(String.format(Locale.US, "SELECT replies_data FROM messages_v2 WHERE mid = %d AND uid = %d", mid, dialogId)); TLRPC.MessageReplies currentReplies = null;
if (cursor.next()) { cursor = database.queryFinalized(String.format(Locale.US, "SELECT replies_data FROM messages_v2 WHERE mid = %d AND uid = %d", mid, dialogId));
NativeByteBuffer data = cursor.byteBufferValue(0); if (cursor.next()) {
if (data != null) { NativeByteBuffer data = cursor.byteBufferValue(0);
currentReplies = TLRPC.MessageReplies.TLdeserialize(data, data.readInt32(false), false); if (data != null) {
currentReplies = TLRPC.MessageReplies.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
}
}
cursor.dispose();
cursor = null;
if (currentReplies != null) {
currentReplies.read_max_id = readMaxId;
state.requery();
NativeByteBuffer data = new NativeByteBuffer(currentReplies.getObjectSize());
currentReplies.serializeToStream(data);
state.bindByteBuffer(1, data);
state.bindInteger(2, mid);
state.bindLong(3, dialogId);
state.step();
data.reuse(); data.reuse();
} }
state.dispose();
state = null;
} }
cursor.dispose();
cursor = null;
if (currentReplies != null) {
currentReplies.read_max_id = readMaxId;
state.requery();
NativeByteBuffer data = new NativeByteBuffer(currentReplies.getObjectSize());
currentReplies.serializeToStream(data);
state.bindByteBuffer(1, data);
state.bindInteger(2, mid);
state.bindLong(3, dialogId);
state.step();
data.reuse();
}
state.dispose();
state = null;
cursor = database.queryFinalized(String.format(Locale.US, "SELECT max_read_id FROM topics WHERE did = %d AND topic_id = %d", -chatId, mid)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT max_read_id FROM topics WHERE did = %d AND topic_id = %d", -chatId, mid));
@ -11908,7 +11922,7 @@ public class MessagesStorage extends BaseController {
topicUpdate.topicId = topicKey.topicId; topicUpdate.topicId = topicKey.topicId;
topicUpdate.reloadTopic = true; topicUpdate.reloadTopic = true;
topicUpdatesInUi.add(topicUpdate); topicUpdatesInUi.add(topicUpdate);
FileLog.d("unknown topic need reload" + topicKey.dialogId + " " + topicKey.topicId); FileLog.d("unknown topic need reload " + topicKey.dialogId + " " + topicKey.topicId);
continue; continue;
} }
Integer newMessagesInteger = topicsNewUnreadMessages.get(topicKey); Integer newMessagesInteger = topicsNewUnreadMessages.get(topicKey);
@ -12097,7 +12111,6 @@ public class MessagesStorage extends BaseController {
private void createOrEditTopic(long dialogId, TLRPC.Message message) { private void createOrEditTopic(long dialogId, TLRPC.Message message) {
TLRPC.TL_forumTopic forumTopic = new TLRPC.TL_forumTopic(); TLRPC.TL_forumTopic forumTopic = new TLRPC.TL_forumTopic();
forumTopic.topicStartMessage = message; forumTopic.topicStartMessage = message;
forumTopic.top_message = message.id; forumTopic.top_message = message.id;
forumTopic.topMessage = message; forumTopic.topMessage = message;

View file

@ -130,6 +130,7 @@ public class NotificationCenter {
public static final int voiceTranscriptionUpdate = totalEvents++; public static final int voiceTranscriptionUpdate = totalEvents++;
public static final int animatedEmojiDocumentLoaded = totalEvents++; public static final int animatedEmojiDocumentLoaded = totalEvents++;
public static final int recentEmojiStatusesUpdate = totalEvents++; public static final int recentEmojiStatusesUpdate = totalEvents++;
public static final int updateSearchSettings = totalEvents++;
public static final int didGenerateFingerprintKeyPair = totalEvents++; public static final int didGenerateFingerprintKeyPair = totalEvents++;

View file

@ -356,7 +356,7 @@ public class SharedConfig {
if (updateVersionString == null) { if (updateVersionString == null) {
updateVersionString = BuildVars.BUILD_VERSION_STRING; updateVersionString = BuildVars.BUILD_VERSION_STRING;
} }
if (pendingAppUpdateBuildVersion != updateVersion || pendingAppUpdate.version == null || updateVersionString.compareTo(pendingAppUpdate.version) >= 0) { if (pendingAppUpdateBuildVersion != updateVersion || pendingAppUpdate.version == null || updateVersionString.compareTo(pendingAppUpdate.version) >= 0 || BuildVars.DEBUG_PRIVATE_VERSION) {
pendingAppUpdate = null; pendingAppUpdate = null;
AndroidUtilities.runOnUIThread(SharedConfig::saveConfig); AndroidUtilities.runOnUIThread(SharedConfig::saveConfig);
} }

View file

@ -42,6 +42,7 @@ import android.os.Build;
import android.util.SparseArray; import android.util.SparseArray;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.DrawingInBackgroundThreadDrawable;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.XMLReader; import org.xml.sax.XMLReader;
@ -108,10 +109,10 @@ public class SvgHelper {
protected int height; protected int height;
private static int[] parentPosition = new int[2]; private static int[] parentPosition = new int[2];
private Bitmap[] backgroundBitmap = new Bitmap[2]; private Bitmap[] backgroundBitmap = new Bitmap[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private Canvas[] backgroundCanvas = new Canvas[2]; private Canvas[] backgroundCanvas = new Canvas[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private LinearGradient[] placeholderGradient = new LinearGradient[2]; private LinearGradient[] placeholderGradient = new LinearGradient[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private Matrix[] placeholderMatrix = new Matrix[2]; private Matrix[] placeholderMatrix = new Matrix[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private static float totalTranslation; private static float totalTranslation;
private static float gradientWidth; private static float gradientWidth;
private static long lastUpdateTime; private static long lastUpdateTime;
@ -154,10 +155,10 @@ public class SvgHelper {
@Override @Override
public void draw(Canvas canvas) { public void draw(Canvas canvas) {
drawInternal(canvas, false, System.currentTimeMillis(), getBounds().left, getBounds().top, getBounds().width(), getBounds().height()); drawInternal(canvas, false, 0, System.currentTimeMillis(), getBounds().left, getBounds().top, getBounds().width(), getBounds().height());
} }
public void drawInternal(Canvas canvas, boolean drawInBackground, long time, float x, float y, float w, float h) { public void drawInternal(Canvas canvas, boolean drawInBackground, int threadIndex, long time, float x, float y, float w, float h) {
if (currentColorKey != null) { if (currentColorKey != null) {
setupGradient(currentColorKey, currentResourcesProvider, colorAlpha, drawInBackground); setupGradient(currentColorKey, currentResourcesProvider, colorAlpha, drawInBackground);
} }
@ -205,7 +206,7 @@ public class SvgHelper {
offset = 0; offset = 0;
} }
int index = drawInBackground ? 1 : 0; int index = drawInBackground ? 1 + threadIndex : 0;
if (placeholderMatrix[index] != null) { if (placeholderMatrix[index] != null) {
placeholderMatrix[index].reset(); placeholderMatrix[index].reset();
if (drawInBackground) { if (drawInBackground) {
@ -365,6 +366,11 @@ public class SvgHelper {
currentColorKey = colorKey; currentColorKey = colorKey;
} }
public void setColorKey(String colorKey, Theme.ResourcesProvider resourcesProvider) {
currentColorKey = colorKey;
currentResourcesProvider = resourcesProvider;
}
public void setColor(int color) { public void setColor(int color) {
overrideColor = color; overrideColor = color;
} }

View file

@ -14,6 +14,8 @@ import org.telegram.tgnet.NativeByteBuffer;
import org.telegram.tgnet.RequestDelegate; import org.telegram.tgnet.RequestDelegate;
import org.telegram.tgnet.TLObject; import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.Components.Forum.ForumUtilities; import org.telegram.ui.Components.Forum.ForumUtilities;
import java.util.ArrayList; import java.util.ArrayList;
@ -56,12 +58,11 @@ public class TopicsController extends BaseController {
loadTopics(chatId, true, LOAD_TYPE_PRELOAD); loadTopics(chatId, true, LOAD_TYPE_PRELOAD);
} }
public void loadTopics(long chatId) { public void loadTopics(long chatId) {
loadTopics(chatId, false, LOAD_TYPE_LOAD_NEXT); loadTopics(chatId, false, LOAD_TYPE_LOAD_NEXT);
} }
private void loadTopics(long chatId, boolean fromCache, int loadType) { public void loadTopics(long chatId, boolean fromCache, int loadType) {
if (topicsIsLoading.get(chatId, 0) != 0) { if (topicsIsLoading.get(chatId, 0) != 0) {
return; return;
} }
@ -78,6 +79,10 @@ public class TopicsController extends BaseController {
topicsIsLoading.put(chatId, 0); topicsIsLoading.put(chatId, 0);
processTopics(chatId, topics, null, fromCache, loadType, -1); processTopics(chatId, topics, null, fromCache, loadType, -1);
if (!endIsReached(chatId)) {
endIsReached.put(chatId, getUserConfig().getPreferences().getBoolean("topics_end_reached_" + chatId, false) ? 1 : 0);
}
}); });
}); });
return; return;
@ -120,7 +125,7 @@ public class TopicsController extends BaseController {
if (!topics.topics.isEmpty() && loadType == LOAD_TYPE_LOAD_NEXT) { if (!topics.topics.isEmpty() && loadType == LOAD_TYPE_LOAD_NEXT) {
TLRPC.TL_forumTopic lastTopic = topics.topics.get(topics.topics.size() - 1); TLRPC.TL_forumTopic lastTopic = topics.topics.get(topics.topics.size() - 1);
TLRPC.Message lastTopicMessage = messagesMap.get(lastTopic.top_message); TLRPC.Message lastTopicMessage = messagesMap.get(lastTopic.top_message);
saveLoadOffset(chatId, lastTopic.top_message, lastTopicMessage.date, lastTopic.id); saveLoadOffset(chatId, lastTopic.top_message, lastTopicMessage == null ? 0 : lastTopicMessage.date, lastTopic.id);
} else if (getTopics(chatId) == null || getTopics(chatId).size() < topics.count) { } else if (getTopics(chatId) == null || getTopics(chatId).size() < topics.count) {
clearLoadingOffset(chatId); clearLoadingOffset(chatId);
loadTopics(chatId); loadTopics(chatId);
@ -144,22 +149,25 @@ public class TopicsController extends BaseController {
if (topics == null) { if (topics == null) {
topics = new ArrayList<>(); topics = new ArrayList<>();
topicsByChatId.put(chatId, topics); topicsByChatId.put(chatId, topics);
} }
if (topicsMap == null) { if (topicsMap == null) {
topicsMap = new LongSparseArray<>(); topicsMap = new LongSparseArray<>();
topicsMapByChatId.put(chatId, topicsMap); topicsMapByChatId.put(chatId, topicsMap);
} }
boolean changed = false; boolean changed = false;
if (newTopics != null) { if (newTopics != null) {
for (int i = 0; i < newTopics.size(); i++) { for (int i = 0; i < newTopics.size(); i++) {
TLRPC.TL_forumTopic newTopic = newTopics.get(i); TLRPC.TL_forumTopic newTopic = newTopics.get(i);
if (newTopic instanceof TLRPC.TL_forumTopicDeleted) {
continue;
}
if (!topicsMap.containsKey(newTopic.id)) { if (!topicsMap.containsKey(newTopic.id)) {
if (messagesMap != null) { if (messagesMap != null) {
newTopic.topMessage = messagesMap.get(newTopic.top_message); newTopic.topMessage = messagesMap.get(newTopic.top_message);
newTopic.topicStartMessage = messagesMap.get(newTopic.id); newTopic.topicStartMessage = messagesMap.get(newTopic.id);
} }
if (newTopic.topMessage == null) { if (newTopic.topMessage == null && !newTopic.isShort) {
if (topicsToReload == null) { if (topicsToReload == null) {
topicsToReload = new ArrayList<>(); topicsToReload = new ArrayList<>();
} }
@ -182,20 +190,35 @@ public class TopicsController extends BaseController {
} }
} }
int pinnedTopics = 0;
for (int i = 0; i < topics.size(); ++i) {
TLRPC.TL_forumTopic topic = topics.get(i);
if (topic != null && topic.pinned) {
int newPinnedOrder = pinnedTopics++;
if (topic.pinnedOrder != newPinnedOrder) {
topic.pinnedOrder = newPinnedOrder;
changed = true;
}
}
}
if (changed) { if (changed) {
sortTopics(chatId); sortTopics(chatId);
} }
if (topicsToReload != null) { if (topicsToReload != null && loadType != LOAD_TYPE_LOAD_UNKNOWN) {
reloadTopics(chatId, topicsToReload); reloadTopics(chatId, topicsToReload);
} else if (loadType == LOAD_TYPE_LOAD_NEXT && topics.size() >= totalCount && totalCount >= 0) { } else if (loadType == LOAD_TYPE_LOAD_NEXT && topics.size() >= totalCount && totalCount >= 0) {
endIsReached.put(chatId, 1); endIsReached.put(chatId, 1);
getUserConfig().getPreferences().edit().putBoolean("topics_end_reached_" + chatId, true).apply();
} }
getNotificationCenter().postNotificationName(NotificationCenter.topicsDidLoaded, chatId, true); getNotificationCenter().postNotificationName(NotificationCenter.topicsDidLoaded, chatId, true);
if ((loadType == LOAD_TYPE_PRELOAD || (loadType == LOAD_TYPE_PRELOAD && !fromCache)) && fromCache && topicsByChatId.get(chatId).isEmpty()) { if ((loadType == LOAD_TYPE_PRELOAD || (loadType == LOAD_TYPE_PRELOAD && !fromCache)) && fromCache && topicsByChatId.get(chatId).isEmpty()) {
loadTopics(chatId, false, LOAD_TYPE_PRELOAD); AndroidUtilities.runOnUIThread(() -> {
loadTopics(chatId, false, LOAD_TYPE_PRELOAD);
});
} }
} }
@ -212,11 +235,11 @@ public class TopicsController extends BaseController {
sortTopics(chatId, true); sortTopics(chatId, true);
} }
private void sortTopics(long chatId, boolean notify) { public void sortTopics(long chatId, boolean notify) {
ArrayList<TLRPC.TL_forumTopic> topics = topicsByChatId.get(chatId); ArrayList<TLRPC.TL_forumTopic> topics = topicsByChatId.get(chatId);
if (topics != null) { if (topics != null) {
if (openedTopicsBuChatId.get(chatId, 0) > 0) { if (openedTopicsBuChatId.get(chatId, 0) > 0) {
Collections.sort(topics, Comparator.comparingInt(o -> o.pinned ? -1 : -o.topMessage.date)); Collections.sort(topics, Comparator.comparingInt(o -> o.topMessage == null ? Integer.MAX_VALUE : -(o.pinned ? Integer.MAX_VALUE - o.pinnedOrder : o.topMessage.date)));
} }
if (notify) { if (notify) {
getNotificationCenter().postNotificationName(NotificationCenter.topicsDidLoaded, chatId, true); getNotificationCenter().postNotificationName(NotificationCenter.topicsDidLoaded, chatId, true);
@ -510,33 +533,106 @@ public class TopicsController extends BaseController {
}); });
} }
public void pinTopic(long chatId, int topicId, boolean pin) { public ArrayList<Integer> getCurrentPinnedOrder(long chatId) {
ArrayList<TLRPC.TL_forumTopic> topics = getTopics(chatId);
ArrayList<Integer> newOrder = new ArrayList<>();
if (topics != null) {
for (int i = 0; i < topics.size(); ++i) {
TLRPC.TL_forumTopic topic = topics.get(i);
if (topic == null) {
continue;
}
if (topic.pinned) {
newOrder.add(topic.id);
}
}
}
return newOrder;
}
public void applyPinnedOrder(long chatId, ArrayList<Integer> order) {
applyPinnedOrder(chatId, order, true);
}
public void applyPinnedOrder(long chatId, ArrayList<Integer> order, boolean notify) {
if (order == null) {
return;
}
ArrayList<TLRPC.TL_forumTopic> topics = getTopics(chatId);
boolean updated = false;
if (topics != null) {
for (int i = 0; i < topics.size(); ++i) {
TLRPC.TL_forumTopic topic = topics.get(i);
if (topic == null) {
continue;
}
int newPinnedOrder = order.indexOf(topic.id);
boolean newPinned = newPinnedOrder >= 0;
if (topic.pinned != newPinned || newPinned && topic.pinnedOrder != newPinnedOrder) {
updated = true;
topic.pinned = newPinned;
topic.pinnedOrder = newPinnedOrder;
getMessagesStorage().updateTopicData(chatId, topic, TopicsController.TOPIC_FLAG_PIN);
}
}
} else {
updated = true;
}
if (notify && updated) {
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.updateInterfaces, MessagesController.UPDATE_MASK_SELECT_DIALOG);
});
}
}
public void pinTopic(long chatId, int topicId, boolean pin, BaseFragment fragment) {
TLRPC.TL_channels_updatePinnedForumTopic req = new TLRPC.TL_channels_updatePinnedForumTopic(); TLRPC.TL_channels_updatePinnedForumTopic req = new TLRPC.TL_channels_updatePinnedForumTopic();
req.channel = getMessagesController().getInputChannel(chatId); req.channel = getMessagesController().getInputChannel(chatId);
req.topic_id = topicId; req.topic_id = topicId;
req.pinned = pin; req.pinned = pin;
ArrayList<TLRPC.TL_forumTopic> topics = topicsByChatId.get(chatId); ArrayList<Integer> prevOrder = getCurrentPinnedOrder(chatId);
if (topics != null) { ArrayList<Integer> newOrder = new ArrayList<>(prevOrder);
for (int i = 0; i < topics.size(); ++i) { newOrder.remove((Integer) topicId);
TLRPC.TL_forumTopic topic = topics.get(i); if (pin) {
if (topic != null && (topicId == topic.id && pin) != topic.pinned) { newOrder.add(0, topicId);
topic.pinned = topicId == topic.id && pin;
// topic.flags = topic.pinned ? (topic.flags | 8) : (topic.flags &~ 8);
getMessagesStorage().updateTopicData(-chatId, topic, TOPIC_FLAG_PIN);
}
}
} }
applyPinnedOrder(chatId, newOrder);
sortTopics(chatId);
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> { ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
if (response instanceof TLRPC.Updates) { if (error != null) {
// getMessagesController().processUpdates((TLRPC.Updates) response, false); if ("PINNED_TOO_MUCH".equals(error.text)) {
if (fragment == null) {
return;
}
applyPinnedOrder(chatId, prevOrder);
fragment.showDialog(
new AlertDialog.Builder(fragment.getContext())
.setTitle(LocaleController.getString("LimitReached", R.string.LimitReached))
.setMessage(LocaleController.formatString("LimitReachedPinnedTopics", R.string.LimitReachedPinnedTopics, MessagesController.getInstance(currentAccount).topicsPinnedLimit))
.setPositiveButton(LocaleController.getString("OK", R.string.OK), null)
.create()
);
} else if ("PINNED_TOPIC_NOT_MODIFIED".equals(error.text)) {
reloadTopics(chatId, false);
}
} }
}); });
} }
public void reorderPinnedTopics(long chatId, ArrayList<Integer> topics) {
TLRPC.TL_channels_reorderPinnedForumTopics req = new TLRPC.TL_channels_reorderPinnedForumTopics();
req.channel = getMessagesController().getInputChannel(chatId);
if (topics != null) {
req.order.addAll(topics);
}
req.force = true;
applyPinnedOrder(chatId, topics, false);
ConnectionsManager.getInstance(currentAccount).sendRequest(req, null);
}
public void updateMentionsUnread(long dialogId, int topicId, int topicMentionsCount) { public void updateMentionsUnread(long dialogId, int topicId, int topicMentionsCount) {
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
TLRPC.TL_forumTopic topic = findTopic(-dialogId, topicId); TLRPC.TL_forumTopic topic = findTopic(-dialogId, topicId);
@ -713,7 +809,12 @@ public class TopicsController extends BaseController {
} }
public void reloadTopics(long chatId) { public void reloadTopics(long chatId) {
reloadTopics(chatId, true);
}
public void reloadTopics(long chatId, boolean fromCache) {
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
getUserConfig().getPreferences().edit().remove("topics_end_reached_" + chatId).apply();
topicsByChatId.remove(chatId); topicsByChatId.remove(chatId);
topicsMapByChatId.remove(chatId); topicsMapByChatId.remove(chatId);
endIsReached.delete(chatId); endIsReached.delete(chatId);
@ -722,7 +823,11 @@ public class TopicsController extends BaseController {
TLRPC.Chat chat = getMessagesController().getChat(chatId); TLRPC.Chat chat = getMessagesController().getChat(chatId);
if (chat != null && chat.forum) { if (chat != null && chat.forum) {
preloadTopics(chatId); if (fromCache) {
preloadTopics(chatId);
} else {
loadTopics(chatId, false, LOAD_TYPE_PRELOAD);
}
} }
sortTopics(chatId); sortTopics(chatId);
}); });
@ -745,13 +850,15 @@ public class TopicsController extends BaseController {
if (key.startsWith("topics_load_offset_topic_id_")) { if (key.startsWith("topics_load_offset_topic_id_")) {
editor.remove(key); editor.remove(key);
} }
if (key.startsWith("topics_end_reached_")) {
editor.remove(key);
}
} }
editor.apply(); editor.apply();
}); });
} }
public void updateReadOutbox(HashMap<MessagesStorage.TopicKey, Integer> topicsReadOutbox) { public void updateReadOutbox(HashMap<MessagesStorage.TopicKey, Integer> topicsReadOutbox) {
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
HashSet<Long> updatedChats = new HashSet<>(); HashSet<Long> updatedChats = new HashSet<>();
for (MessagesStorage.TopicKey topicKey : topicsReadOutbox.keySet()) { for (MessagesStorage.TopicKey topicKey : topicsReadOutbox.keySet()) {
@ -760,7 +867,7 @@ public class TopicsController extends BaseController {
if (topic != null) { if (topic != null) {
topic.read_outbox_max_id = Math.max(topic.read_outbox_max_id, value); topic.read_outbox_max_id = Math.max(topic.read_outbox_max_id, value);
updatedChats.add(-topicKey.dialogId); updatedChats.add(-topicKey.dialogId);
if ( topic.read_outbox_max_id >= topic.topMessage.id) { if (topic.read_outbox_max_id >= topic.topMessage.id) {
topic.topMessage.unread = false; topic.topMessage.unread = false;
} }
} }

View file

@ -6,19 +6,23 @@ import android.os.Build;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.BuildVars; import org.telegram.messenger.BuildVars;
import org.telegram.messenger.DispatchQueuePoolBackground;
import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import org.telegram.ui.Components.RLottieDrawable;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
@ -37,18 +41,40 @@ public class BitmapsCache {
ArrayList<FrameOffset> frameOffsets = new ArrayList<>(); ArrayList<FrameOffset> frameOffsets = new ArrayList<>();
final boolean useSharedBuffers;
static ConcurrentHashMap<Thread, byte[]> sharedBuffers = new ConcurrentHashMap();
static volatile boolean cleanupScheduled;
byte[] bufferTmp; 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(), 8, 1);
private static ThreadPoolExecutor bitmapCompressExecutor; private static ThreadPoolExecutor bitmapCompressExecutor;
private final Object mutex = new Object(); private final Object mutex = new Object();
private int frameIndex; private int frameIndex;
boolean error; boolean error;
boolean fileExist;
int compressQuality; int compressQuality;
final File file; final File file;
private int tryCount;
public AtomicBoolean cancelled = new AtomicBoolean(false); public AtomicBoolean cancelled = new AtomicBoolean(false);
private Runnable cleanupSharedBuffers = new Runnable() {
@Override
public void run() {
for (Thread thread : sharedBuffers.keySet()) {
if (!thread.isAlive()) {
sharedBuffers.remove(thread);
}
}
if (!sharedBuffers.isEmpty()) {
AndroidUtilities.runOnUIThread(cleanupSharedBuffers, 5000);
} else {
cleanupScheduled = false;
}
}
};
public BitmapsCache(File sourceFile, Cacheable source, CacheOptions options, int w, int h, boolean noLimit) { public BitmapsCache(File sourceFile, Cacheable source, CacheOptions options, int w, int h, boolean noLimit) {
this.source = source; this.source = source;
@ -62,6 +88,38 @@ public class BitmapsCache {
File fileTmo = new File(FileLoader.checkDirectory(FileLoader.MEDIA_DIR_CACHE), "acache"); File fileTmo = new File(FileLoader.checkDirectory(FileLoader.MEDIA_DIR_CACHE), "acache");
file = new File(fileTmo, fileName + "_" + w + "_" + h + (noLimit ? "_nolimit" : " ") + ".pcache2"); file = new File(fileTmo, fileName + "_" + w + "_" + h + (noLimit ? "_nolimit" : " ") + ".pcache2");
useSharedBuffers = w < AndroidUtilities.dp(60) && h < AndroidUtilities.dp(60);
fileExist = file.exists();
if (fileExist) {
RandomAccessFile randomAccessFile = null;
try {
randomAccessFile = new RandomAccessFile(file, "r");
cacheCreated = randomAccessFile.readBoolean();
if (cacheCreated && frameOffsets.isEmpty()) {
randomAccessFile.seek(randomAccessFile.readInt());
int count = randomAccessFile.readInt();
fillFrames(randomAccessFile, count);
if (count == 0) {
file.delete();
cacheCreated = false;
fileExist = false;
}
}
} catch (Throwable e) {
e.printStackTrace();
file.delete();
fileExist = false;
} finally {
try {
if (randomAccessFile != null) {
randomAccessFile.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
} }
volatile boolean checkCache; volatile boolean checkCache;
@ -71,6 +129,27 @@ public class BitmapsCache {
RandomAccessFile cachedFile; RandomAccessFile cachedFile;
BitmapFactory.Options options; BitmapFactory.Options options;
private static int taskCounter;
private static CacheGeneratorSharedTools sharedTools;
public static void incrementTaskCounter() {
taskCounter++;
}
public static void decrementTaskCounter() {
taskCounter--;
if (taskCounter <= 0) {
taskCounter = 0;
RLottieDrawable.lottieCacheGenerateQueue.postRunnable(() -> {
if (sharedTools != null) {
sharedTools.release();
sharedTools = null;
}
});
}
}
public void createCache() { public void createCache() {
try { try {
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
@ -84,7 +163,12 @@ public class BitmapsCache {
cacheCreated = false; cacheCreated = false;
} }
if (cacheCreated) { if (cacheCreated) {
frameOffsets.clear();
randomAccessFile.seek(randomAccessFile.readInt());
int count = randomAccessFile.readInt();
fillFrames(randomAccessFile, count);
randomAccessFile.close(); randomAccessFile.close();
fileExist = true;
return; return;
} else { } else {
file.delete(); file.delete();
@ -108,18 +192,17 @@ public class BitmapsCache {
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw"); RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
if (sharedTools == null) {
Bitmap[] bitmap = new Bitmap[N]; sharedTools = new CacheGeneratorSharedTools();
ByteArrayOutputStream[] byteArrayOutputStream = new ByteArrayOutputStream[N];
CountDownLatch[] countDownLatch = new CountDownLatch[N];
for (int i = 0; i < N; i++) {
bitmap[i] = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
byteArrayOutputStream[i] = new ByteArrayOutputStream(w * h * 2);
} }
sharedTools.allocate(h, w);
Bitmap[] bitmap = sharedTools.bitmap;
ByteArrayOutputStream[] byteArrayOutputStream = sharedTools.byteArrayOutputStream;
CountDownLatch[] countDownLatch = new CountDownLatch[N];
ArrayList<FrameOffset> frameOffsets = new ArrayList<>(); ArrayList<FrameOffset> frameOffsets = new ArrayList<>();
RandomAccessFile finalRandomAccessFile = randomAccessFile; RandomAccessFile finalRandomAccessFile = randomAccessFile;
finalRandomAccessFile.writeBoolean(false); finalRandomAccessFile.writeBoolean(false);
finalRandomAccessFile.writeInt(0); finalRandomAccessFile.writeInt(0);
@ -131,6 +214,7 @@ public class BitmapsCache {
AtomicBoolean closed = new AtomicBoolean(false); AtomicBoolean closed = new AtomicBoolean(false);
source.prepareForGenerateCache(); source.prepareForGenerateCache();
while (true) { while (true) {
if (countDownLatch[index] != null) { if (countDownLatch[index] != null) {
try { try {
@ -204,7 +288,8 @@ public class BitmapsCache {
e.printStackTrace(); e.printStackTrace();
try { try {
finalRandomAccessFile1.close(); finalRandomAccessFile1.close();
} catch (Exception e2) {} finally { } catch (Exception e2) {
} finally {
closed.set(true); closed.set(true);
} }
} }
@ -226,35 +311,33 @@ public class BitmapsCache {
e.printStackTrace(); e.printStackTrace();
} }
} }
if (bitmap[i] != null) {
try {
bitmap[i].recycle();
} catch (Exception e) {
}
}
if (byteArrayOutputStream[i] != null) {
byteArrayOutputStream[i].buf = null;
}
} }
int arrayOffset = (int) randomAccessFile.length(); int arrayOffset = (int) randomAccessFile.length();
Collections.sort(frameOffsets, Comparator.comparingInt(o -> o.index)); Collections.sort(frameOffsets, Comparator.comparingInt(o -> o.index));
randomAccessFile.writeInt(frameOffsets.size()); byteArrayOutputStream[0].reset();
int count = frameOffsets.size();
byteArrayOutputStream[0].writeInt(count);
for (int i = 0; i < frameOffsets.size(); i++) { for (int i = 0; i < frameOffsets.size(); i++) {
randomAccessFile.writeInt(frameOffsets.get(i).frameOffset); byteArrayOutputStream[0].writeInt(frameOffsets.get(i).frameOffset);
randomAccessFile.writeInt(frameOffsets.get(i).frameSize); byteArrayOutputStream[0].writeInt(frameOffsets.get(i).frameSize);
} }
randomAccessFile.write(byteArrayOutputStream[0].buf, 0, 4 + 4 * 2 * count);
byteArrayOutputStream[0].reset();
randomAccessFile.seek(0); randomAccessFile.seek(0);
randomAccessFile.writeBoolean(true); randomAccessFile.writeBoolean(true);
randomAccessFile.writeInt(arrayOffset); randomAccessFile.writeInt(arrayOffset);
closed.set(true); closed.set(true);
randomAccessFile.close(); randomAccessFile.close();
if (BuildVars.DEBUG_VERSION) { this.frameOffsets.clear();
FileLog.d("generate cache for time = " + (System.currentTimeMillis() - time) + " drawFrameTime = " + bitmapFrameTime + " comressQuality = " + compressQuality + " fileSize = " + AndroidUtilities.formatFileSize(file.length()) + " " + fileName); // this.frameOffsets.addAll(frameOffsets);
} fileExist = true;
// if (BuildVars.DEBUG_VERSION) {
// FileLog.d("generate cache for time = " + (System.currentTimeMillis() - time) + " drawFrameTime = " + bitmapFrameTime + " comressQuality = " + compressQuality + " fileSize = " + AndroidUtilities.formatFileSize(file.length()) + " " + fileName);
// }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
@ -264,6 +347,18 @@ public class BitmapsCache {
} }
} }
private void fillFrames(RandomAccessFile randomAccessFile, int count) throws Throwable {
byte[] bytes = new byte[4 * 2 * count];
randomAccessFile.read(bytes);
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
for (int i = 0; i < count; i++) {
FrameOffset frameOffset = new FrameOffset(i);
frameOffset.frameOffset = byteBuffer.getInt();
frameOffset.frameSize = byteBuffer.getInt();
frameOffsets.add(frameOffset);
}
}
public void cancelCreate() { public void cancelCreate() {
// cancelled.set(true); // cancelled.set(true);
} }
@ -317,49 +412,43 @@ public class BitmapsCache {
RandomAccessFile randomAccessFile = null; RandomAccessFile randomAccessFile = null;
try { try {
FrameOffset selectedFrame; FrameOffset selectedFrame;
synchronized (mutex) { if (!cacheCreated && !fileExist) {
if (!cacheCreated || cachedFile == null) { return FRAME_RESULT_NO_FRAME;
randomAccessFile = new RandomAccessFile(file, "r");
cacheCreated = randomAccessFile.readBoolean();
if (cacheCreated && frameOffsets.isEmpty()) {
randomAccessFile.seek(randomAccessFile.readInt());
int count = randomAccessFile.readInt();
for (int i = 0; i < count; i++) {
FrameOffset frameOffset = new FrameOffset(i);
frameOffset.frameOffset = randomAccessFile.readInt();
frameOffset.frameSize = randomAccessFile.readInt();
frameOffsets.add(frameOffset);
}
}
if (!cacheCreated) {
randomAccessFile.close();
randomAccessFile = null;
source.getFirstFrame(bitmap);
return FRAME_RESULT_OK;
} else if (frameOffsets.isEmpty()) {
randomAccessFile.close();
randomAccessFile = null;
return FRAME_RESULT_NO_FRAME;
}
} else {
randomAccessFile = cachedFile;
}
index = Utilities.clamp(index, frameOffsets.size() - 1, 0);
selectedFrame = frameOffsets.get(index);
randomAccessFile.seek(selectedFrame.frameOffset);
if (bufferTmp == null || bufferTmp.length < selectedFrame.frameSize) {
bufferTmp = new byte[(int) (selectedFrame.frameSize * 1.3f)];
}
randomAccessFile.readFully(bufferTmp, 0, selectedFrame.frameSize);
if (!recycled) {
cachedFile = randomAccessFile;
} else {
cachedFile = null;
randomAccessFile.close();
}
} }
byte[] bufferTmp;
if (!cacheCreated || cachedFile == null) {
randomAccessFile = new RandomAccessFile(file, "r");
cacheCreated = randomAccessFile.readBoolean();
if (cacheCreated && frameOffsets.isEmpty()) {
randomAccessFile.seek(randomAccessFile.readInt());
int count = randomAccessFile.readInt();
fillFrames(randomAccessFile, count);
}
if (frameOffsets.size() == 0) {
cacheCreated = false;
}
if (!cacheCreated) {
randomAccessFile.close();
randomAccessFile = null;
return FRAME_RESULT_NO_FRAME;
}
} else {
randomAccessFile = cachedFile;
}
index = Utilities.clamp(index, frameOffsets.size() - 1, 0);
selectedFrame = frameOffsets.get(index);
randomAccessFile.seek(selectedFrame.frameOffset);
bufferTmp = getBuffer(selectedFrame);
randomAccessFile.readFully(bufferTmp, 0, selectedFrame.frameSize);
if (!recycled) {
cachedFile = randomAccessFile;
} else {
cachedFile = null;
randomAccessFile.close();
}
if (options == null) { if (options == null) {
options = new BitmapFactory.Options(); options = new BitmapFactory.Options();
} }
@ -370,9 +459,13 @@ public class BitmapsCache {
} catch (Throwable e) { } catch (Throwable e) {
FileLog.e(e, false); FileLog.e(e, false);
tryCount++;
if (tryCount > 10) {
error = true;
}
} }
if (randomAccessFile != null) { if (error && randomAccessFile != null) {
try { try {
randomAccessFile.close(); randomAccessFile.close();
} catch (IOException e) { } catch (IOException e) {
@ -380,12 +473,36 @@ public class BitmapsCache {
} }
} }
// source.getFirstFrame(bitmap); // source.getFirstFrame(bitmap);
return FRAME_RESULT_NO_FRAME; return FRAME_RESULT_NO_FRAME;
} }
private byte[] getBuffer(FrameOffset selectedFrame) {
boolean useSharedBuffers = this.useSharedBuffers && Thread.currentThread().getName().startsWith(DispatchQueuePoolBackground.THREAD_PREFIX);
byte[] bufferTmp;
if (useSharedBuffers) {
bufferTmp = sharedBuffers.get(Thread.currentThread());
} else {
bufferTmp = this.bufferTmp;
}
if (bufferTmp == null || bufferTmp.length < selectedFrame.frameSize) {
bufferTmp = new byte[(int) (selectedFrame.frameSize * 1.3f)];
if (useSharedBuffers) {
sharedBuffers.put(Thread.currentThread(), bufferTmp);
if (!cleanupScheduled) {
cleanupScheduled = true;
AndroidUtilities.runOnUIThread(cleanupSharedBuffers, 5000);
}
} else {
this.bufferTmp = bufferTmp;
}
}
return bufferTmp;
}
public boolean needGenCache() { public boolean needGenCache() {
return !cacheCreated; return !cacheCreated || !fileExist;
} }
public void recycle() { public void recycle() {
@ -416,7 +533,9 @@ public class BitmapsCache {
public interface Cacheable { public interface Cacheable {
void prepareForGenerateCache(); void prepareForGenerateCache();
int getNextFrame(Bitmap bitmap); int getNextFrame(Bitmap bitmap);
void releaseForGenerateCache(); void releaseForGenerateCache();
Bitmap getFirstFrame(Bitmap bitmap); Bitmap getFirstFrame(Bitmap bitmap);
@ -437,8 +556,9 @@ public class BitmapsCache {
} }
private void ensureCapacity(int minCapacity) { private void ensureCapacity(int minCapacity) {
if (minCapacity - buf.length > 0) if (minCapacity - buf.length > 0) {
grow(minCapacity); grow(minCapacity);
}
} }
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
@ -467,6 +587,15 @@ public class BitmapsCache {
count += 1; count += 1;
} }
public void writeInt(int value) {
ensureCapacity(count + 4);
buf[count] = (byte) (value >>> 24);
buf[count + 1] = (byte) (value >>> 16);
buf[count + 2] = (byte) (value >>> 8);
buf[count + 3] = (byte) (value);
count += 4;
}
public synchronized void write(byte b[], int off, int len) { public synchronized void write(byte b[], int off, int len) {
if ((off < 0) || (off > b.length) || (len < 0) || if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) - b.length > 0)) { ((off + len) - b.length > 0)) {
@ -484,6 +613,8 @@ public class BitmapsCache {
public synchronized void reset() { public synchronized void reset() {
count = 0; count = 0;
} }
} }
public static class Metadata { public static class Metadata {
@ -494,4 +625,61 @@ public class BitmapsCache {
public int compressQuality = 100; public int compressQuality = 100;
public boolean fallback = false; public boolean fallback = false;
} }
private static class CacheGeneratorSharedTools {
ByteArrayOutputStream[] byteArrayOutputStream = new ByteArrayOutputStream[N];
private Bitmap[] bitmap = new Bitmap[N];
private int lastSize;
void allocate(int h, int w) {
int size = (w << 16) + h;
boolean recreateBitmaps = false;
if (lastSize != size) {
recreateBitmaps = true;
}
lastSize = size;
for (int i = 0; i < N; i++) {
if (recreateBitmaps || bitmap[i] == null) {
if (bitmap[i] != null) {
Bitmap bitmapToRecycle = bitmap[i];
Utilities.globalQueue.postRunnable(() -> {
try {
bitmapToRecycle.recycle();
} catch (Exception e) {
}
});
}
bitmap[i] = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
}
if (byteArrayOutputStream[i] == null) {
byteArrayOutputStream[i] = new ByteArrayOutputStream(w * h * 2);
}
}
}
void release() {
ArrayList<Bitmap> bitmapsToRecycle = null;
for (int i = 0; i < N; i++) {
if (bitmap[i] != null) {
if (bitmapsToRecycle == null) {
bitmapsToRecycle = new ArrayList<>();
}
bitmapsToRecycle.add(bitmap[i]);
}
bitmap[i] = null;
byteArrayOutputStream[i] = null;
}
if (!bitmapsToRecycle.isEmpty()) {
ArrayList<Bitmap> finalBitmapsToRecycle = bitmapsToRecycle;
Utilities.globalQueue.postRunnable(() -> {
for (Bitmap bitmap : finalBitmapsToRecycle) {
bitmap.recycle();
}
});
}
}
}
} }

View file

@ -18,6 +18,7 @@ import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLoader; import org.telegram.messenger.ImageLoader;
import org.telegram.messenger.MessageObject; import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.SharedConfig; import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
@ -68,11 +69,10 @@ public class TLRPC {
public static final int MESSAGE_FLAG_HAS_BOT_ID = 0x00000800; public static final int MESSAGE_FLAG_HAS_BOT_ID = 0x00000800;
public static final int MESSAGE_FLAG_EDITED = 0x00008000; public static final int MESSAGE_FLAG_EDITED = 0x00008000;
public static final int LAYER = 148; public static final int LAYER = 149;
public static class TL_stats_megagroupStats extends TLObject { public static class TL_stats_megagroupStats extends TLObject {
public static int constructor = 0xef7ff916; public static int constructor = 0xef7ff916;
public TL_statsDateRangeDays period; public TL_statsDateRangeDays period;
public TL_statsAbsValueAndPrev members; public TL_statsAbsValueAndPrev members;
public TL_statsAbsValueAndPrev messages; public TL_statsAbsValueAndPrev messages;
@ -3112,6 +3112,7 @@ public class TLRPC {
public ArrayList<Message> messages = new ArrayList<>(); public ArrayList<Message> messages = new ArrayList<>();
public ArrayList<Chat> chats = new ArrayList<>(); public ArrayList<Chat> chats = new ArrayList<>();
public ArrayList<User> users = new ArrayList<>(); public ArrayList<User> users = new ArrayList<>();
public ArrayList<TL_forumTopic> topics = new ArrayList<>();
public int flags; public int flags;
public boolean inexact; public boolean inexact;
public int pts; public int pts;
@ -3129,7 +3130,7 @@ public class TLRPC {
case 0x8c718e87: case 0x8c718e87:
result = new TL_messages_messages(); result = new TL_messages_messages();
break; break;
case 0x64479808: case 0xc776ba4e:
result = new TL_messages_channelMessages(); result = new TL_messages_channelMessages();
break; break;
case 0x74535f21: case 0x74535f21:
@ -3315,8 +3316,7 @@ public class TLRPC {
} }
public static class TL_messages_channelMessages extends messages_Messages { public static class TL_messages_channelMessages extends messages_Messages {
public static int constructor = 0x64479808; public static int constructor = 0xc776ba4e;
public void readParams(AbstractSerializedData stream, boolean exception) { public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception); flags = stream.readInt32(exception);
@ -3349,6 +3349,21 @@ public class TLRPC {
return; return;
} }
count = stream.readInt32(exception); count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TL_forumTopic object = TL_forumTopic.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
topics.add(object);
}
magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
count = stream.readInt32(exception);
for (int a = 0; a < count; a++) { for (int a = 0; a < count; a++) {
Chat object = Chat.TLdeserialize(stream, stream.readInt32(exception), exception); Chat object = Chat.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) { if (object == null) {
@ -3389,6 +3404,12 @@ public class TLRPC {
messages.get(a).serializeToStream(stream); messages.get(a).serializeToStream(stream);
} }
stream.writeInt32(0x1cb5c415); stream.writeInt32(0x1cb5c415);
count = topics.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
topics.get(a).serializeToStream(stream);
}
stream.writeInt32(0x1cb5c415);
count = chats.size(); count = chats.size();
stream.writeInt32(count); stream.writeInt32(count);
for (int a = 0; a < count; a++) { for (int a = 0; a < count; a++) {
@ -30931,7 +30952,10 @@ public class TLRPC {
case 0x14b85813: case 0x14b85813:
result = new TL_updateBotMenuButton(); result = new TL_updateBotMenuButton();
break; break;
case 0xf694b0ae: case 0xfe198602:
result = new TL_updateChannelPinnedTopics();
break;
case 0x192efbe3:
result = new TL_updateChannelPinnedTopic(); result = new TL_updateChannelPinnedTopic();
break; break;
} }
@ -33144,18 +33168,28 @@ public class TLRPC {
} }
} }
public static class TL_updateChannelPinnedTopic extends Update { public static class TL_updateChannelPinnedTopics extends Update {
public static int constructor = 0xf694b0ae; public static int constructor = 0xfe198602;
public int flags; public int flags;
public long channel_id; public long channel_id;
public int topic_id; public ArrayList<Integer> order = new ArrayList<>();
public void readParams(AbstractSerializedData stream, boolean exception) { public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception); flags = stream.readInt32(exception);
channel_id = stream.readInt64(exception); channel_id = stream.readInt64(exception);
if ((flags & 1) != 0) { if ((flags & 1) != 0) {
topic_id = stream.readInt32(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++) {
order.add(stream.readInt32(exception));
}
} }
} }
@ -33164,11 +33198,40 @@ public class TLRPC {
stream.writeInt32(flags); stream.writeInt32(flags);
stream.writeInt64(channel_id); stream.writeInt64(channel_id);
if ((flags & 1) != 0) { if ((flags & 1) != 0) {
stream.writeInt32(topic_id); stream.writeInt32(0x1cb5c415);
int count = order.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
stream.writeInt32(order.get(a));
}
} }
} }
} }
public static class TL_updateChannelPinnedTopic extends Update {
public static int constructor = 0x192efbe3;
public int flags;
public boolean pinned;
public long channel_id;
public int topic_id;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
pinned = (flags & 1) != 0;
channel_id = stream.readInt64(exception);
topic_id = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = pinned ? (flags | 1) : (flags &~ 1);
stream.writeInt32(flags);
stream.writeInt64(channel_id);
stream.writeInt32(topic_id);
}
}
public static class TL_receivedNotifyMessage extends TLObject { public static class TL_receivedNotifyMessage extends TLObject {
public static int constructor = 0xa384b779; public static int constructor = 0xa384b779;
@ -61570,6 +61633,7 @@ public class TLRPC {
public static class TL_dialog extends Dialog { public static class TL_dialog extends Dialog {
public static int constructor = 0xa8edd0f5; public static int constructor = 0xa8edd0f5;
public int stableId = MessagesController.stableIdPointer++;
public void readParams(AbstractSerializedData stream, boolean exception) { public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception); flags = stream.readInt32(exception);
@ -64032,11 +64096,9 @@ public class TLRPC {
} }
} }
public static class TL_forumTopicDeleted extends ForumTopic { public static class TL_forumTopicDeleted extends TL_forumTopic {
public static int constructor = 0x23f109b; public static int constructor = 0x23f109b;
public int id;
public void readParams(AbstractSerializedData stream, boolean exception) { public void readParams(AbstractSerializedData stream, boolean exception) {
id = stream.readInt32(exception); id = stream.readInt32(exception);
} }
@ -64103,6 +64165,7 @@ public class TLRPC {
public boolean my; public boolean my;
public boolean closed; public boolean closed;
public boolean pinned; public boolean pinned;
public boolean isShort;
public int id; public int id;
public int date; public int date;
public String title; public String title;
@ -64121,10 +64184,14 @@ public class TLRPC {
public ArrayList<MessageObject> groupedMessages; // custom public ArrayList<MessageObject> groupedMessages; // custom
public Message topMessage; // custom public Message topMessage; // custom
public String searchQuery; //custom public String searchQuery; //custom
public int pinnedOrder; // custom
public static TL_forumTopic TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) { public static TL_forumTopic TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
TL_forumTopic result = null; TL_forumTopic result = null;
switch (constructor) { switch (constructor) {
case 0x23f109b:
result = new TL_forumTopicDeleted();
break;
case 0x5920d6dc: case 0x5920d6dc:
result = new TL_forumTopic_layer147(); result = new TL_forumTopic_layer147();
break; break;
@ -64146,6 +64213,7 @@ public class TLRPC {
my = (flags & 2) != 0; my = (flags & 2) != 0;
closed = (flags & 4) != 0; closed = (flags & 4) != 0;
pinned = (flags & 8) != 0; pinned = (flags & 8) != 0;
isShort = (flags & 32) != 0;
id = stream.readInt32(exception); id = stream.readInt32(exception);
date = stream.readInt32(exception); date = stream.readInt32(exception);
title = stream.readString(exception); title = stream.readString(exception);
@ -64171,6 +64239,7 @@ public class TLRPC {
flags = my ? (flags | 2) : (flags &~ 2); flags = my ? (flags | 2) : (flags &~ 2);
flags = closed ? (flags | 4) : (flags &~ 4); flags = closed ? (flags | 4) : (flags &~ 4);
flags = pinned ? (flags | 8) : (flags &~ 8); flags = pinned ? (flags | 8) : (flags &~ 8);
flags = isShort ? (flags | 32) : (flags &~ 32);
stream.writeInt32(flags); stream.writeInt32(flags);
stream.writeInt32(id); stream.writeInt32(id);
stream.writeInt32(date); stream.writeInt32(date);
@ -64614,6 +64683,32 @@ public class TLRPC {
channel.serializeToStream(stream); channel.serializeToStream(stream);
} }
} }
public static class TL_channels_reorderPinnedForumTopics extends TLObject {
public static int constructor = 0x2950a18f;
public int flags;
public boolean force;
public InputChannel channel;
public ArrayList<Integer> order = new ArrayList<>();
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return Updates.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = force ? (flags | 1) : (flags &~ 1);
stream.writeInt32(flags);
channel.serializeToStream(stream);
stream.writeInt32(0x1cb5c415);
int count = order.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
stream.writeInt32(order.get(a));
}
}
}
//functions //functions
public static class Vector extends TLObject { public static class Vector extends TLObject {

View file

@ -78,7 +78,7 @@ public class ActionBar extends FrameLayout {
private int actionModeColor; private int actionModeColor;
private int actionBarColor; private int actionBarColor;
private boolean isMenuOffsetSuppressed; private boolean isMenuOffsetSuppressed;
private ActionBarMenu menu; public ActionBarMenu menu;
private ActionBarMenu actionMode; private ActionBarMenu actionMode;
private String actionModeTag; private String actionModeTag;
private boolean ignoreLayoutRequest; private boolean ignoreLayoutRequest;

View file

@ -2957,6 +2957,7 @@ public class Theme {
public static Drawable dialogs_mentionDrawable; public static Drawable dialogs_mentionDrawable;
public static Drawable dialogs_reactionsMentionDrawable; public static Drawable dialogs_reactionsMentionDrawable;
public static Drawable dialogs_holidayDrawable; public static Drawable dialogs_holidayDrawable;
public static Drawable dialogs_forum_arrowDrawable;
public static RLottieDrawable dialogs_archiveAvatarDrawable; public static RLottieDrawable dialogs_archiveAvatarDrawable;
public static RLottieDrawable dialogs_archiveDrawable; public static RLottieDrawable dialogs_archiveDrawable;
public static RLottieDrawable dialogs_unarchiveDrawable; public static RLottieDrawable dialogs_unarchiveDrawable;
@ -3039,6 +3040,7 @@ public class Theme {
public static TextPaint chat_forwardNamePaint; public static TextPaint chat_forwardNamePaint;
public static TextPaint chat_replyNamePaint; public static TextPaint chat_replyNamePaint;
public static TextPaint chat_replyTextPaint; public static TextPaint chat_replyTextPaint;
public static TextPaint chat_topicTextPaint;
public static TextPaint chat_commentTextPaint; public static TextPaint chat_commentTextPaint;
public static TextPaint chat_contextResult_titleTextPaint; public static TextPaint chat_contextResult_titleTextPaint;
public static TextPaint chat_contextResult_descriptionTextPaint; public static TextPaint chat_contextResult_descriptionTextPaint;
@ -3229,6 +3231,7 @@ public class Theme {
public static final String key_windowBackgroundWhiteRedText4 = "windowBackgroundWhiteRedText4"; public static final String key_windowBackgroundWhiteRedText4 = "windowBackgroundWhiteRedText4";
public static final String key_windowBackgroundWhiteRedText5 = "windowBackgroundWhiteRedText5"; public static final String key_windowBackgroundWhiteRedText5 = "windowBackgroundWhiteRedText5";
public static final String key_windowBackgroundWhiteRedText6 = "windowBackgroundWhiteRedText6"; public static final String key_windowBackgroundWhiteRedText6 = "windowBackgroundWhiteRedText6";
public static final String key_windowBackgroundWhiteYellowText = "windowBackgroundWhiteYellowText";
public static final String key_windowBackgroundWhiteGrayText = "windowBackgroundWhiteGrayText"; public static final String key_windowBackgroundWhiteGrayText = "windowBackgroundWhiteGrayText";
public static final String key_windowBackgroundWhiteGrayText2 = "windowBackgroundWhiteGrayText2"; public static final String key_windowBackgroundWhiteGrayText2 = "windowBackgroundWhiteGrayText2";
public static final String key_windowBackgroundWhiteGrayText3 = "windowBackgroundWhiteGrayText3"; public static final String key_windowBackgroundWhiteGrayText3 = "windowBackgroundWhiteGrayText3";
@ -3294,6 +3297,7 @@ public class Theme {
public static final String key_avatar_text = "avatar_text"; public static final String key_avatar_text = "avatar_text";
public static final String key_avatar_backgroundSaved = "avatar_backgroundSaved"; public static final String key_avatar_backgroundSaved = "avatar_backgroundSaved";
public static final String key_avatar_background2Saved = "avatar_background2Saved";
public static final String key_avatar_backgroundArchived = "avatar_backgroundArchived"; public static final String key_avatar_backgroundArchived = "avatar_backgroundArchived";
public static final String key_avatar_backgroundArchivedHidden = "avatar_backgroundArchivedHidden"; public static final String key_avatar_backgroundArchivedHidden = "avatar_backgroundArchivedHidden";
public static final String key_avatar_backgroundRed = "avatar_backgroundRed"; public static final String key_avatar_backgroundRed = "avatar_backgroundRed";
@ -3303,6 +3307,13 @@ public class Theme {
public static final String key_avatar_backgroundCyan = "avatar_backgroundCyan"; public static final String key_avatar_backgroundCyan = "avatar_backgroundCyan";
public static final String key_avatar_backgroundBlue = "avatar_backgroundBlue"; public static final String key_avatar_backgroundBlue = "avatar_backgroundBlue";
public static final String key_avatar_backgroundPink = "avatar_backgroundPink"; public static final String key_avatar_backgroundPink = "avatar_backgroundPink";
public static final String key_avatar_background2Red = "avatar_background2Red";
public static final String key_avatar_background2Orange = "avatar_background2Orange";
public static final String key_avatar_background2Violet = "avatar_background2Violet";
public static final String key_avatar_background2Green = "avatar_background2Green";
public static final String key_avatar_background2Cyan = "avatar_background2Cyan";
public static final String key_avatar_background2Blue = "avatar_background2Blue";
public static final String key_avatar_background2Pink = "avatar_background2Pink";
public static final String key_avatar_backgroundInProfileBlue = "avatar_backgroundInProfileBlue"; public static final String key_avatar_backgroundInProfileBlue = "avatar_backgroundInProfileBlue";
public static final String key_avatar_backgroundActionBarBlue = "avatar_backgroundActionBarBlue"; public static final String key_avatar_backgroundActionBarBlue = "avatar_backgroundActionBarBlue";
@ -3319,6 +3330,7 @@ public class Theme {
public static final String key_avatar_nameInMessagePink = "avatar_nameInMessagePink"; public static final String key_avatar_nameInMessagePink = "avatar_nameInMessagePink";
public static String[] keys_avatar_background = {key_avatar_backgroundRed, key_avatar_backgroundOrange, key_avatar_backgroundViolet, key_avatar_backgroundGreen, key_avatar_backgroundCyan, key_avatar_backgroundBlue, key_avatar_backgroundPink}; public static String[] keys_avatar_background = {key_avatar_backgroundRed, key_avatar_backgroundOrange, key_avatar_backgroundViolet, key_avatar_backgroundGreen, key_avatar_backgroundCyan, key_avatar_backgroundBlue, key_avatar_backgroundPink};
public static String[] keys_avatar_background2 = {key_avatar_background2Red, key_avatar_background2Orange, key_avatar_background2Violet, key_avatar_background2Green, key_avatar_background2Cyan, key_avatar_background2Blue, key_avatar_background2Pink};
public static String[] keys_avatar_nameInMessage = {key_avatar_nameInMessageRed, key_avatar_nameInMessageOrange, key_avatar_nameInMessageViolet, key_avatar_nameInMessageGreen, key_avatar_nameInMessageCyan, key_avatar_nameInMessageBlue, key_avatar_nameInMessagePink}; public static String[] keys_avatar_nameInMessage = {key_avatar_nameInMessageRed, key_avatar_nameInMessageOrange, key_avatar_nameInMessageViolet, key_avatar_nameInMessageGreen, key_avatar_nameInMessageCyan, key_avatar_nameInMessageBlue, key_avatar_nameInMessagePink};
public static final String key_actionBarDefault = "actionBarDefault"; public static final String key_actionBarDefault = "actionBarDefault";
@ -3974,6 +3986,8 @@ public class Theme {
public static final String key_premiumGradientBottomSheet1 = "premiumGradientBottomSheet1"; public static final String key_premiumGradientBottomSheet1 = "premiumGradientBottomSheet1";
public static final String key_premiumGradientBottomSheet2 = "premiumGradientBottomSheet2"; public static final String key_premiumGradientBottomSheet2 = "premiumGradientBottomSheet2";
public static final String key_premiumGradientBottomSheet3 = "premiumGradientBottomSheet3"; public static final String key_premiumGradientBottomSheet3 = "premiumGradientBottomSheet3";
public static final String key_topics_unreadCounter = "topics_unreadCounter";
public static final String key_topics_unreadCounterMuted = "topics_unreadCounterMuted";
public static final String key_drawable_botInline = "drawableBotInline"; public static final String key_drawable_botInline = "drawableBotInline";
public static final String key_drawable_botLink = "drawableBotLink"; public static final String key_drawable_botLink = "drawableBotLink";
@ -4025,7 +4039,6 @@ public class Theme {
public static final String key_drawable_chat_pollHintDrawableOut = "drawable_chat_pollHintDrawableOut"; public static final String key_drawable_chat_pollHintDrawableOut = "drawable_chat_pollHintDrawableOut";
public static final String key_drawable_chat_pollHintDrawableIn = "drawable_chat_pollHintDrawableIn"; public static final String key_drawable_chat_pollHintDrawableIn = "drawable_chat_pollHintDrawableIn";
private static final HashMap<String, Drawable> defaultChatDrawables = new HashMap<>(); private static final HashMap<String, Drawable> defaultChatDrawables = new HashMap<>();
private static final HashMap<String, String> defaultChatDrawableColorKeys = new HashMap<>(); private static final HashMap<String, String> defaultChatDrawableColorKeys = new HashMap<>();
@ -4138,6 +4151,7 @@ public class Theme {
defaultColors.put(key_windowBackgroundWhiteRedText4, 0xffcf3030); defaultColors.put(key_windowBackgroundWhiteRedText4, 0xffcf3030);
defaultColors.put(key_windowBackgroundWhiteRedText5, 0xffed3939); defaultColors.put(key_windowBackgroundWhiteRedText5, 0xffed3939);
defaultColors.put(key_windowBackgroundWhiteRedText6, 0xffff6666); defaultColors.put(key_windowBackgroundWhiteRedText6, 0xffff6666);
defaultColors.put(key_windowBackgroundWhiteYellowText, 0xffD87B29);
defaultColors.put(key_windowBackgroundWhiteGrayText, 0xff838c96); defaultColors.put(key_windowBackgroundWhiteGrayText, 0xff838c96);
defaultColors.put(key_windowBackgroundWhiteGrayText2, 0xff82868a); defaultColors.put(key_windowBackgroundWhiteGrayText2, 0xff82868a);
defaultColors.put(key_windowBackgroundWhiteGrayText3, 0xff999999); defaultColors.put(key_windowBackgroundWhiteGrayText3, 0xff999999);
@ -4192,16 +4206,25 @@ public class Theme {
defaultColors.put(key_avatar_text, 0xffffffff); defaultColors.put(key_avatar_text, 0xffffffff);
defaultColors.put(key_avatar_backgroundSaved, 0xff66bffa); defaultColors.put(key_avatar_backgroundSaved, 0xff69BFFA);
defaultColors.put(key_avatar_backgroundArchived, 0xffa9b6c1); defaultColors.put(key_avatar_background2Saved, 0xff3D9DE0);
defaultColors.put(key_avatar_backgroundArchived, 0xffB8C2CC);
defaultColors.put(key_avatar_backgroundArchivedHidden, 0xff66bffa); defaultColors.put(key_avatar_backgroundArchivedHidden, 0xff66bffa);
defaultColors.put(key_avatar_backgroundRed, 0xffe56555); defaultColors.put(key_avatar_backgroundRed, 0xffFF845E);
defaultColors.put(key_avatar_backgroundOrange, 0xfff28c48); defaultColors.put(key_avatar_backgroundOrange, 0xffFEBB5B);
defaultColors.put(key_avatar_backgroundViolet, 0xff8e85ee); defaultColors.put(key_avatar_backgroundViolet, 0xffB694F9);
defaultColors.put(key_avatar_backgroundGreen, 0xff76c84d); defaultColors.put(key_avatar_backgroundGreen, 0xff9AD164);
defaultColors.put(key_avatar_backgroundCyan, 0xff5fbed5); defaultColors.put(key_avatar_backgroundCyan, 0xff5BCBE3);
defaultColors.put(key_avatar_backgroundBlue, 0xff549cdd); defaultColors.put(key_avatar_backgroundBlue, 0xff5CAFFA);
defaultColors.put(key_avatar_backgroundPink, 0xfff2749a); defaultColors.put(key_avatar_backgroundPink, 0xffFF8AAC);
defaultColors.put(key_avatar_background2Red, 0xffD45246);
defaultColors.put(key_avatar_background2Orange, 0xffF68136);
defaultColors.put(key_avatar_background2Violet, 0xff6C61DF);
defaultColors.put(key_avatar_background2Green, 0xff46BA43);
defaultColors.put(key_avatar_background2Cyan, 0xff359AD4);
defaultColors.put(key_avatar_background2Blue, 0xff408ACF);
defaultColors.put(key_avatar_background2Pink, 0xffD95574);
defaultColors.put(key_avatar_backgroundInProfileBlue, 0xff5085b1); defaultColors.put(key_avatar_backgroundInProfileBlue, 0xff5085b1);
defaultColors.put(key_avatar_backgroundActionBarBlue, 0xff598fba); defaultColors.put(key_avatar_backgroundActionBarBlue, 0xff598fba);
@ -4211,11 +4234,11 @@ public class Theme {
defaultColors.put(key_avatar_nameInMessageRed, 0xffca5650); defaultColors.put(key_avatar_nameInMessageRed, 0xffca5650);
defaultColors.put(key_avatar_nameInMessageOrange, 0xffd87b29); defaultColors.put(key_avatar_nameInMessageOrange, 0xffd87b29);
defaultColors.put(key_avatar_nameInMessageViolet, 0xff4e92cc); defaultColors.put(key_avatar_nameInMessageViolet, 0xff9B66DC);
defaultColors.put(key_avatar_nameInMessageGreen, 0xff50b232); defaultColors.put(key_avatar_nameInMessageGreen, 0xff50b232);
defaultColors.put(key_avatar_nameInMessageCyan, 0xff379eb8); defaultColors.put(key_avatar_nameInMessageCyan, 0xff379eb8);
defaultColors.put(key_avatar_nameInMessageBlue, 0xff4e92cc); defaultColors.put(key_avatar_nameInMessageBlue, 0xff4e92cc);
defaultColors.put(key_avatar_nameInMessagePink, 0xff4e92cc); defaultColors.put(key_avatar_nameInMessagePink, 0xffCF5C95);
defaultColors.put(key_actionBarDefault, 0xff527da3); defaultColors.put(key_actionBarDefault, 0xff527da3);
defaultColors.put(key_actionBarDefaultIcon, 0xffffffff); defaultColors.put(key_actionBarDefaultIcon, 0xffffffff);
@ -4867,6 +4890,8 @@ public class Theme {
defaultColors.put(key_premiumGradientBottomSheet1, 0xff5B9DE7); defaultColors.put(key_premiumGradientBottomSheet1, 0xff5B9DE7);
defaultColors.put(key_premiumGradientBottomSheet2, 0xffAB87DD); defaultColors.put(key_premiumGradientBottomSheet2, 0xffAB87DD);
defaultColors.put(key_premiumGradientBottomSheet3, 0xffE794BE); defaultColors.put(key_premiumGradientBottomSheet3, 0xffE794BE);
defaultColors.put(key_topics_unreadCounter, 0xff4ecc5e);
defaultColors.put(key_topics_unreadCounterMuted, 0xff8b8d8f);
fallbackKeys.put(key_chat_inAdminText, key_chat_inTimeText); fallbackKeys.put(key_chat_inAdminText, key_chat_inTimeText);
fallbackKeys.put(key_chat_inAdminSelectedText, key_chat_inTimeSelectedText); fallbackKeys.put(key_chat_inAdminSelectedText, key_chat_inTimeSelectedText);
@ -4984,6 +5009,7 @@ public class Theme {
fallbackKeys.put(key_chat_outPollCorrectAnswer, key_chat_attachLocationBackground); fallbackKeys.put(key_chat_outPollCorrectAnswer, key_chat_attachLocationBackground);
fallbackKeys.put(key_chat_inPollWrongAnswer, key_chat_attachAudioBackground); fallbackKeys.put(key_chat_inPollWrongAnswer, key_chat_attachAudioBackground);
fallbackKeys.put(key_chat_outPollWrongAnswer, key_chat_attachAudioBackground); fallbackKeys.put(key_chat_outPollWrongAnswer, key_chat_attachAudioBackground);
fallbackKeys.put(key_windowBackgroundWhiteYellowText, key_avatar_nameInMessageOrange);
fallbackKeys.put(key_profile_tabText, key_windowBackgroundWhiteGrayText); fallbackKeys.put(key_profile_tabText, key_windowBackgroundWhiteGrayText);
fallbackKeys.put(key_profile_tabSelectedText, key_windowBackgroundWhiteBlueHeader); fallbackKeys.put(key_profile_tabSelectedText, key_windowBackgroundWhiteBlueHeader);
@ -5014,8 +5040,19 @@ public class Theme {
fallbackKeys.put(key_chat_inReactionButtonTextSelected, key_windowBackgroundWhite); fallbackKeys.put(key_chat_inReactionButtonTextSelected, key_windowBackgroundWhite);
fallbackKeys.put(key_chat_outReactionButtonTextSelected, key_windowBackgroundWhite); fallbackKeys.put(key_chat_outReactionButtonTextSelected, key_windowBackgroundWhite);
fallbackKeys.put(key_dialogReactionMentionBackground, key_voipgroup_mutedByAdminGradient2); fallbackKeys.put(key_dialogReactionMentionBackground, key_voipgroup_mutedByAdminGradient2);
fallbackKeys.put(key_topics_unreadCounter, key_chats_unreadCounter);
fallbackKeys.put(key_topics_unreadCounterMuted, key_chats_message);
fallbackKeys.put(key_avatar_background2Red, key_avatar_backgroundRed);
fallbackKeys.put(key_avatar_background2Orange, key_avatar_backgroundOrange);
fallbackKeys.put(key_avatar_background2Violet, key_avatar_backgroundViolet);
fallbackKeys.put(key_avatar_background2Green, key_avatar_backgroundGreen);
fallbackKeys.put(key_avatar_background2Cyan, key_avatar_backgroundCyan);
fallbackKeys.put(key_avatar_background2Blue, key_avatar_backgroundBlue);
fallbackKeys.put(key_avatar_background2Pink, key_avatar_backgroundPink);
themeAccentExclusionKeys.addAll(Arrays.asList(keys_avatar_background)); themeAccentExclusionKeys.addAll(Arrays.asList(keys_avatar_background));
themeAccentExclusionKeys.addAll(Arrays.asList(keys_avatar_background2));
themeAccentExclusionKeys.addAll(Arrays.asList(keys_avatar_nameInMessage)); themeAccentExclusionKeys.addAll(Arrays.asList(keys_avatar_nameInMessage));
themeAccentExclusionKeys.add(key_chat_attachFileBackground); themeAccentExclusionKeys.add(key_chat_attachFileBackground);
themeAccentExclusionKeys.add(key_chat_attachGalleryBackground); themeAccentExclusionKeys.add(key_chat_attachGalleryBackground);
@ -8924,6 +8961,7 @@ public class Theme {
dialogs_mentionDrawable = resources.getDrawable(R.drawable.mentionchatslist); dialogs_mentionDrawable = resources.getDrawable(R.drawable.mentionchatslist);
dialogs_reactionsMentionDrawable = resources.getDrawable(R.drawable.reactionchatslist); dialogs_reactionsMentionDrawable = resources.getDrawable(R.drawable.reactionchatslist);
dialogs_pinnedDrawable = resources.getDrawable(R.drawable.list_pin); dialogs_pinnedDrawable = resources.getDrawable(R.drawable.list_pin);
dialogs_forum_arrowDrawable = resources.getDrawable(R.drawable.msg_mini_forumarrow);
moveUpDrawable = resources.getDrawable(R.drawable.preview_arrow); moveUpDrawable = resources.getDrawable(R.drawable.preview_arrow);
RectF rect = new RectF(); RectF rect = new RectF();
@ -8997,6 +9035,7 @@ public class Theme {
setDrawableColorByKey(dialogs_muteDrawable, key_chats_muteIcon); setDrawableColorByKey(dialogs_muteDrawable, key_chats_muteIcon);
setDrawableColorByKey(dialogs_unmuteDrawable, key_chats_muteIcon); setDrawableColorByKey(dialogs_unmuteDrawable, key_chats_muteIcon);
setDrawableColorByKey(dialogs_mentionDrawable, key_chats_mentionIcon); setDrawableColorByKey(dialogs_mentionDrawable, key_chats_mentionIcon);
setDrawableColorByKey(dialogs_forum_arrowDrawable, key_chats_message);
setDrawableColorByKey(dialogs_reactionsMentionDrawable, key_chats_mentionIcon); setDrawableColorByKey(dialogs_reactionsMentionDrawable, key_chats_mentionIcon);
setDrawableColorByKey(dialogs_verifiedDrawable, key_chats_verifiedBackground); setDrawableColorByKey(dialogs_verifiedDrawable, key_chats_verifiedBackground);
setDrawableColorByKey(dialogs_verifiedCheckDrawable, key_chats_verifiedCheck); setDrawableColorByKey(dialogs_verifiedCheckDrawable, key_chats_verifiedCheck);
@ -9042,6 +9081,8 @@ public class Theme {
chat_replyNamePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); chat_replyNamePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
chat_replyNamePaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); chat_replyNamePaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
chat_replyTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); chat_replyTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
chat_topicTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
chat_topicTextPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
chat_forwardNamePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); chat_forwardNamePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
chat_adminPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); chat_adminPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
chat_timePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); chat_timePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
@ -9062,6 +9103,7 @@ public class Theme {
chat_namePaint.setTextSize(AndroidUtilities.dp(smallerDp)); chat_namePaint.setTextSize(AndroidUtilities.dp(smallerDp));
chat_replyNamePaint.setTextSize(AndroidUtilities.dp(smallerDp)); chat_replyNamePaint.setTextSize(AndroidUtilities.dp(smallerDp));
chat_replyTextPaint.setTextSize(AndroidUtilities.dp(smallerDp)); chat_replyTextPaint.setTextSize(AndroidUtilities.dp(smallerDp));
chat_topicTextPaint.setTextSize(AndroidUtilities.dp(smallerDp - 1));
chat_forwardNamePaint.setTextSize(AndroidUtilities.dp(smallerDp)); chat_forwardNamePaint.setTextSize(AndroidUtilities.dp(smallerDp));
chat_adminPaint.setTextSize(AndroidUtilities.dp(smallerDp - 1)); chat_adminPaint.setTextSize(AndroidUtilities.dp(smallerDp - 1));
// float timeDp = 2 * (SharedConfig.fontSize - 16) / 3f + 12; // float timeDp = 2 * (SharedConfig.fontSize - 16) / 3f + 12;
@ -9122,6 +9164,8 @@ public class Theme {
chat_replyNamePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); chat_replyNamePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
chat_replyNamePaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); chat_replyNamePaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
chat_replyTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); chat_replyTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
chat_topicTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
chat_topicTextPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
chat_commentTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); chat_commentTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
chat_instantViewPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); chat_instantViewPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
chat_instantViewPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); chat_instantViewPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
@ -9462,6 +9506,7 @@ public class Theme {
chat_namePaint.setTextSize(AndroidUtilities.dp(smallerDp)); chat_namePaint.setTextSize(AndroidUtilities.dp(smallerDp));
chat_replyNamePaint.setTextSize(AndroidUtilities.dp(smallerDp)); chat_replyNamePaint.setTextSize(AndroidUtilities.dp(smallerDp));
chat_replyTextPaint.setTextSize(AndroidUtilities.dp(smallerDp)); chat_replyTextPaint.setTextSize(AndroidUtilities.dp(smallerDp));
chat_topicTextPaint.setTextSize(AndroidUtilities.dp(smallerDp - 1));
chat_forwardNamePaint.setTextSize(AndroidUtilities.dp(smallerDp)); chat_forwardNamePaint.setTextSize(AndroidUtilities.dp(smallerDp));
chat_adminPaint.setTextSize(AndroidUtilities.dp(smallerDp - 1)); chat_adminPaint.setTextSize(AndroidUtilities.dp(smallerDp - 1));
float timeDp = 2 * (SharedConfig.fontSize - 16) / 3f + 12; float timeDp = 2 * (SharedConfig.fontSize - 16) / 3f + 12;

View file

@ -17,7 +17,6 @@ import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.os.SystemClock; import android.os.SystemClock;
import android.text.TextUtils;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
import android.view.View; import android.view.View;
@ -66,7 +65,7 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
public class DialogsAdapter extends RecyclerListView.SelectionAdapter { public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements DialogCell.DialogCellDelegate {
public final static int VIEW_TYPE_DIALOG = 0, public final static int VIEW_TYPE_DIALOG = 0,
VIEW_TYPE_FLICKER = 1, VIEW_TYPE_FLICKER = 1,
VIEW_TYPE_RECENTLY_VIEWED = 2, VIEW_TYPE_RECENTLY_VIEWED = 2,
@ -413,6 +412,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
DialogCell dialogCell = new DialogCell(parentFragment, mContext, true, false, currentAccount, null); DialogCell dialogCell = new DialogCell(parentFragment, mContext, true, false, currentAccount, null);
dialogCell.setArchivedPullAnimation(pullForegroundDrawable); dialogCell.setArchivedPullAnimation(pullForegroundDrawable);
dialogCell.setPreloader(preloader); dialogCell.setPreloader(preloader);
dialogCell.setDialogCellDelegate(this);
view = dialogCell; view = dialogCell;
} }
break; break;
@ -887,6 +887,21 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
} }
} }
@Override
public void onButtonClicked(DialogCell dialogCell) {
}
@Override
public void onButtonLongPress(DialogCell dialogCell) {
}
@Override
public boolean canClickButtonInside() {
return selectedDialogs.isEmpty();
}
public static class DialogsPreloader { public static class DialogsPreloader {
private final int MAX_REQUEST_COUNT = 4; private final int MAX_REQUEST_COUNT = 4;
@ -1063,6 +1078,5 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
} }
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), height); setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), height);
} }
} }
} }

View file

@ -1035,7 +1035,12 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
view = new GraySectionCell(mContext); view = new GraySectionCell(mContext);
break; break;
case VIEW_TYPE_DIALOG_CELL: case VIEW_TYPE_DIALOG_CELL:
view = new DialogCell(null, mContext, false, true); view = new DialogCell(null, mContext, false, true) {
@Override
protected boolean isForumCell() {
return false;
}
};
break; break;
case VIEW_TYPE_LOADING: case VIEW_TYPE_LOADING:
FlickerLoadingView flickerLoadingView = new FlickerLoadingView(mContext); FlickerLoadingView flickerLoadingView = new FlickerLoadingView(mContext);

View file

@ -10554,7 +10554,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
progressView.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(39), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(39), MeasureSpec.EXACTLY)); progressView.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(39), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(39), MeasureSpec.EXACTLY));
imageView.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(39), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(39), MeasureSpec.EXACTLY)); imageView.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(39), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(39), MeasureSpec.EXACTLY));
if (currentBlock != null) { if (currentBlock != null) {
textLayout = createLayoutForText(this, currentBlock.channel.title, null, width - AndroidUtilities.dp(36 + 16) - buttonWidth, textY, currentBlock, StaticLayoutEx.ALIGN_LEFT(), parentAdapter); textLayout = createLayoutForText(this, currentBlock.channel.title, null, width - AndroidUtilities.dp(36 + 16) - buttonWidth, textY, currentBlock, StaticLayoutEx.ALIGN_LEFT(), 1, parentAdapter);
if (parentAdapter.isRtl) { if (parentAdapter.isRtl) {
textX2 = textX; textX2 = textX;
} else { } else {

View file

@ -75,6 +75,7 @@ import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils; import androidx.core.graphics.ColorUtils;
import androidx.core.math.MathUtils;
import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.messenger.AccountInstance; import org.telegram.messenger.AccountInstance;
@ -112,6 +113,7 @@ import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ChatActivity; import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.AnimatedColor;
import org.telegram.ui.Components.AnimatedEmojiDrawable; import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan; import org.telegram.ui.Components.AnimatedEmojiSpan;
import org.telegram.ui.Components.AnimatedFileDrawable; import org.telegram.ui.Components.AnimatedFileDrawable;
@ -127,10 +129,10 @@ import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.EmptyStubSpan; import org.telegram.ui.Components.EmptyStubSpan;
import org.telegram.ui.Components.FloatSeekBarAccessibilityDelegate; import org.telegram.ui.Components.FloatSeekBarAccessibilityDelegate;
import org.telegram.ui.Components.Forum.ForumUtilities; import org.telegram.ui.Components.Forum.ForumUtilities;
import org.telegram.ui.Components.Forum.MessageTopicButton;
import org.telegram.ui.Components.InfiniteProgress; import org.telegram.ui.Components.InfiniteProgress;
import org.telegram.ui.Components.LinkPath; import org.telegram.ui.Components.LinkPath;
import org.telegram.ui.Components.LinkSpanDrawable; import org.telegram.ui.Components.LinkSpanDrawable;
import org.telegram.ui.Components.LocationMessageLoadingDrawable;
import org.telegram.ui.Components.MediaActionDrawable; import org.telegram.ui.Components.MediaActionDrawable;
import org.telegram.ui.Components.MessageBackgroundDrawable; import org.telegram.ui.Components.MessageBackgroundDrawable;
import org.telegram.ui.Components.MotionBackgroundDrawable; import org.telegram.ui.Components.MotionBackgroundDrawable;
@ -523,6 +525,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
default boolean didPressAnimatedEmoji(AnimatedEmojiSpan span) { default boolean didPressAnimatedEmoji(AnimatedEmojiSpan span) {
return false; return false;
} }
default void didPressTopicButton(ChatMessageCell cell) {}
} }
private final static int DOCUMENT_ATTACH_TYPE_NONE = 0; private final static int DOCUMENT_ATTACH_TYPE_NONE = 0;
@ -961,6 +965,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private float replyTouchX, replyTouchY; private float replyTouchX, replyTouchY;
private TLRPC.PhotoSize currentReplyPhoto; private TLRPC.PhotoSize currentReplyPhoto;
private boolean drawTopic;
private MessageTopicButton topicButton;
private int drawSideButton; private int drawSideButton;
private boolean sideButtonPressed; private boolean sideButtonPressed;
private float sideStartX; private float sideStartX;
@ -1237,7 +1244,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
pollAvatarImages[a] = new ImageReceiver(this); pollAvatarImages[a] = new ImageReceiver(this);
pollAvatarImages[a].setRoundRadius(AndroidUtilities.dp(8)); pollAvatarImages[a].setRoundRadius(AndroidUtilities.dp(8));
pollAvatarDrawables[a] = new AvatarDrawable(); pollAvatarDrawables[a] = new AvatarDrawable();
pollAvatarDrawables[a].setTextSize(AndroidUtilities.dp(6)); pollAvatarDrawables[a].setTextSize(AndroidUtilities.dp(22));
} }
pollCheckBox = new CheckBoxBase[10]; pollCheckBox = new CheckBoxBase[10];
for (int a = 0; a < pollCheckBox.length; a++) { for (int a = 0; a < pollCheckBox.length; a++) {
@ -2645,6 +2652,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (!result) { if (!result) {
result = checkTextSelection(event); result = checkTextSelection(event);
} }
if (!result && topicButton != null) {
result = topicButton.checkTouchEvent(event);
}
if (!result) { if (!result) {
result = checkOtherButtonMotionEvent(event); result = checkOtherButtonMotionEvent(event);
} }
@ -3692,6 +3702,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
unregisterFlagSecure.run(); unregisterFlagSecure.run();
unregisterFlagSecure = null; unregisterFlagSecure = null;
} }
if (topicButton != null) {
topicButton.onDetached(this);
}
} }
@Override @Override
@ -3763,6 +3777,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (currentMessageObject != null && currentMessageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW && unlockLayout != null) { if (currentMessageObject != null && currentMessageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW && unlockLayout != null) {
invalidate(); invalidate();
} }
if (topicButton != null) {
topicButton.onAttached(this);
}
} }
boolean imageReceiversAttachState; boolean imageReceiversAttachState;
@ -4501,6 +4519,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
int maxChildWidth = Math.max(backgroundWidth, nameWidth); int maxChildWidth = Math.max(backgroundWidth, nameWidth);
maxChildWidth = Math.max(maxChildWidth, forwardedNameWidth); maxChildWidth = Math.max(maxChildWidth, forwardedNameWidth);
maxChildWidth = Math.max(maxChildWidth, replyNameWidth); maxChildWidth = Math.max(maxChildWidth, replyNameWidth);
if (topicButton != null) {
maxChildWidth = Math.max(maxChildWidth, topicButton.width());
}
maxChildWidth = Math.max(maxChildWidth, replyTextWidth); maxChildWidth = Math.max(maxChildWidth, replyTextWidth);
if (commentLayout != null && drawSideButton != 3) { if (commentLayout != null && drawSideButton != 3) {
maxChildWidth = Math.max(maxChildWidth, totalCommentWidth); maxChildWidth = Math.max(maxChildWidth, totalCommentWidth);
@ -4563,7 +4584,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
"telegram_user".equals(type) || "telegram_channel".equals(type) || "telegram_user".equals(type) || "telegram_channel".equals(type) ||
"telegram_megagroup".equals(type) || "telegram_voicechat".equals(type) || "telegram_megagroup".equals(type) || "telegram_voicechat".equals(type) ||
"telegram_livestream".equals(type); "telegram_livestream".equals(type);
smallImage = !slideshow && (!drawInstantView || drawInstantViewType == 1 || drawInstantViewType == 9 || drawInstantViewType == 11 || drawInstantViewType == 13) && document == null && isSmallImageType; smallImage = !slideshow && (!drawInstantView || drawInstantViewType == 1 || drawInstantViewType == 2 || drawInstantViewType == 9 || drawInstantViewType == 11 || drawInstantViewType == 13) && document == null && isSmallImageType;
isSmallImage = smallImage && type != null && currentMessageObject.photoThumbs != null; isSmallImage = smallImage && type != null && currentMessageObject.photoThumbs != null;
} else if (hasInvoicePreview) { } else if (hasInvoicePreview) {
TLRPC.TL_messageMediaInvoice invoice = (TLRPC.TL_messageMediaInvoice) MessageObject.getMedia(messageObject.messageOwner); TLRPC.TL_messageMediaInvoice invoice = (TLRPC.TL_messageMediaInvoice) MessageObject.getMedia(messageObject.messageOwner);
@ -6114,13 +6135,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
currentMapProvider = MessagesController.getInstance(messageObject.currentAccount).mapProvider; currentMapProvider = MessagesController.getInstance(messageObject.currentAccount).mapProvider;
} }
if (locationLoadingThumb == null) { if (locationLoadingThumb == null) {
SvgHelper.SvgDrawable svgThumb = DocumentObject.getSvgThumb(R.raw.map_placeholder, Theme.key_windowBackgroundWhiteGrayIcon, 1f); SvgHelper.SvgDrawable svgThumb = DocumentObject.getSvgThumb(R.raw.map_placeholder, Theme.key_chat_outLocationIcon, (Theme.isCurrentThemeDark() ? 3 : 6) * .12f);
svgThumb.setAspectCenter(true); svgThumb.setAspectCenter(true);
locationLoadingThumb = new ClipRoundedDrawable(svgThumb); locationLoadingThumb = new ClipRoundedDrawable(svgThumb);
} }
if (locationLoadingThumb instanceof ClipRoundedDrawable && ((ClipRoundedDrawable) locationLoadingThumb).getDrawable() instanceof SvgHelper.SvgDrawable) { if (locationLoadingThumb instanceof ClipRoundedDrawable && ((ClipRoundedDrawable) locationLoadingThumb).getDrawable() instanceof SvgHelper.SvgDrawable) {
SvgHelper.SvgDrawable drawable = (SvgHelper.SvgDrawable) ((ClipRoundedDrawable) locationLoadingThumb).getDrawable(); SvgHelper.SvgDrawable drawable = (SvgHelper.SvgDrawable) ((ClipRoundedDrawable) locationLoadingThumb).getDrawable();
drawable.setColorKey(messageObject.isOutOwner() ? Theme.key_chat_outBubbleLocationPlaceholder : Theme.key_chat_inBubbleLocationPlaceholder); drawable.setColorKey(messageObject.isOutOwner() ? Theme.key_chat_outLocationIcon : Theme.key_chat_inLocationIcon, resourcesProvider);
} }
photoImage.setCrossfadeDuration(2 * ImageReceiver.DEFAULT_CROSSFADE_DURATION); photoImage.setCrossfadeDuration(2 * ImageReceiver.DEFAULT_CROSSFADE_DURATION);
photoImage.setCrossfadeByScale(.05f); photoImage.setCrossfadeByScale(.05f);
@ -6176,7 +6197,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
additionHeight += reactionsLayoutInBubble.totalHeight + AndroidUtilities.dp(8); additionHeight += reactionsLayoutInBubble.totalHeight + AndroidUtilities.dp(8);
reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(8); reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(8);
} }
additionHeight -= AndroidUtilities.dp(17); if (!(drawTopic && (currentMessageObject != null && currentMessageObject.replyMessageObject != null || forwardedNameLayout != null && forwardedNameLayout[0] != null))) {
additionHeight -= AndroidUtilities.dp(17);
}
} else if (messageObject.isAnyKindOfSticker()) { } else if (messageObject.isAnyKindOfSticker()) {
drawBackground = false; drawBackground = false;
@ -6970,13 +6993,23 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) == 0) { if ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) == 0) {
photoHeight += AndroidUtilities.dp(1); photoHeight += AndroidUtilities.dp(1);
} }
} else if (currentPosition != null && currentMessageObject.isDocument()) {
if ((currentPosition.flags & MessageObject.POSITION_FLAG_TOP) == 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 && !messageObject.isOutOwner()) {
totalHeight -= AndroidUtilities.dp(2);
}
} }
int y = 0; int y = 0;
if (currentMessageObject.type != MessageObject.TYPE_EMOJIS) { if (currentMessageObject.type != MessageObject.TYPE_EMOJIS) {
if (drawPinnedTop) { if (drawPinnedTop) {
namesOffset -= AndroidUtilities.dp(1); namesOffset -= AndroidUtilities.dp(documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT ? 2 : 1);
} }
if (drawPinnedTop && !messageObject.isOutOwner()) {
totalHeight += AndroidUtilities.dp(documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT ? 2 : 0);
}
// if (drawPinnedBottom && !messageObject.isOutOwner()) {
// totalHeight += AndroidUtilities.dp(documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT ? 1 : 0);
// }
if (namesOffset > 0) { if (namesOffset > 0) {
y = AndroidUtilities.dp(7); y = AndroidUtilities.dp(7);
totalHeight -= AndroidUtilities.dp(2); totalHeight -= AndroidUtilities.dp(2);
@ -7542,6 +7575,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (replySelector != null) { if (replySelector != null) {
replySelector.setState(new int[]{}); replySelector.setState(new int[]{});
} }
if (topicButton != null) {
topicButton.resetClick();
}
if (pressedEmoji != null) { if (pressedEmoji != null) {
// hadLongPress = true; // hadLongPress = true;
// if (delegate.didPressAnimatedEmoji(pressedEmoji)) { // if (delegate.didPressAnimatedEmoji(pressedEmoji)) {
@ -7682,6 +7718,16 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
); );
} }
public void invalidateOutbounds() {
if (delegate == null || !delegate.canDrawOutboundsContent()) {
if (getParent() instanceof View) {
((View) getParent()).invalidate();
}
} else {
super.invalidate();
}
}
@Override @Override
public void invalidate() { public void invalidate() {
if (currentMessageObject == null) { if (currentMessageObject == null) {
@ -9786,7 +9832,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
linkPreviewY += currentMessageObject.textHeight + AndroidUtilities.dp(4); linkPreviewY += currentMessageObject.textHeight + AndroidUtilities.dp(4);
} }
if (drawPhotoImage && drawInstantView && drawInstantViewType != 9 && drawInstantViewType != 13 && drawInstantViewType != 11 && drawInstantViewType != 1 || drawInstantViewType == 6 && imageBackgroundColor != 0) { if (drawPhotoImage && drawInstantView && drawInstantViewType != 9 && drawInstantViewType != 2 && drawInstantViewType != 13 && drawInstantViewType != 11 && drawInstantViewType != 1 || drawInstantViewType == 6 && imageBackgroundColor != 0) {
if (linkPreviewY != startY) { if (linkPreviewY != startY) {
linkPreviewY += AndroidUtilities.dp(2); linkPreviewY += AndroidUtilities.dp(2);
} }
@ -9919,7 +9965,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
linkPreviewY += descriptionLayout.getLineBottom(descriptionLayout.getLineCount() - 1); linkPreviewY += descriptionLayout.getLineBottom(descriptionLayout.getLineCount() - 1);
} }
if (drawPhotoImage && (!drawInstantView || drawInstantViewType == 9 || drawInstantViewType == 11 || drawInstantViewType == 13 || drawInstantViewType == 1)) { if (drawPhotoImage && (!drawInstantView || drawInstantViewType == 9 || drawInstantViewType == 2 || drawInstantViewType == 11 || drawInstantViewType == 13 || drawInstantViewType == 1)) {
if (linkPreviewY != startY) { if (linkPreviewY != startY) {
linkPreviewY += AndroidUtilities.dp(2); linkPreviewY += AndroidUtilities.dp(2);
} }
@ -10344,7 +10390,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (currentMessageObject == null || currentMessageObject != null && currentMessageObject.hasExtendedMedia()) { if (currentMessageObject == null || currentMessageObject != null && currentMessageObject.hasExtendedMedia()) {
return MediaActionDrawable.ICON_NONE; return MediaActionDrawable.ICON_NONE;
} }
if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject.isVoiceTranscriptionOpen() && (currentMessageObject != null && currentMessageObject.attachPathExists && !TextUtils.isEmpty(currentMessageObject.messageOwner.attachPath) || currentMessageObject.mediaExists)) { if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject.isVoiceTranscriptionOpen() && canStreamVideo) {
if (buttonState == 1 || buttonState == 4) { if (buttonState == 1 || buttonState == 4) {
return MediaActionDrawable.ICON_PAUSE; return MediaActionDrawable.ICON_PAUSE;
} }
@ -10529,7 +10575,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
boolean fromBot = currentMessageObject.messageOwner.params != null && currentMessageObject.messageOwner.params.containsKey("query_id"); boolean fromBot = currentMessageObject.messageOwner.params != null && currentMessageObject.messageOwner.params.containsKey("query_id");
if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject != null && currentMessageObject.isVoiceTranscriptionOpen() && fileExists) { if (documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject != null && currentMessageObject.isVoiceTranscriptionOpen() && canStreamVideo) {
if (currentMessageObject.isOut() && (currentMessageObject.isSending() && !currentMessageObject.isForwarded() || currentMessageObject.isEditing() && currentMessageObject.isEditingMedia()) || currentMessageObject.isSendError() && fromBot) { if (currentMessageObject.isOut() && (currentMessageObject.isSending() && !currentMessageObject.isForwarded() || currentMessageObject.isEditing() && currentMessageObject.isEditingMedia()) || currentMessageObject.isSendError() && fromBot) {
if (!TextUtils.isEmpty(currentMessageObject.messageOwner.attachPath)) { if (!TextUtils.isEmpty(currentMessageObject.messageOwner.attachPath)) {
DownloadController.getInstance(currentAccount).addLoadingFileObserver(currentMessageObject.messageOwner.attachPath, currentMessageObject, this); DownloadController.getInstance(currentAccount).addLoadingFileObserver(currentMessageObject.messageOwner.attachPath, currentMessageObject, this);
@ -11886,6 +11932,42 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
} }
drawTopic = false;
if (!isThreadChat && !pinnedTop && (MessageObject.getTopicId(messageObject.messageOwner) != 0 || messageObject.replyToForumTopic != null)) {
if (currentPosition == null || currentPosition.minY == 0) {
int topicId = MessageObject.getTopicId(messageObject.messageOwner);
TLRPC.TL_forumTopic topic = messageObject.replyToForumTopic == null ? MessagesController.getInstance(currentAccount).getTopicsController().findTopic(-messageObject.getDialogId(), topicId) : messageObject.replyToForumTopic;
if (topic != null) {
drawTopic = true;
int maxWidth = getMaxNameWidth();
if (!messageObject.shouldDrawWithoutBackground()) {
maxWidth -= AndroidUtilities.dp(10);
} else if (messageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
maxWidth += AndroidUtilities.dp(13 + 35);
} else if (messageObject.isAnyKindOfSticker()) {
maxWidth += AndroidUtilities.dp(25);
}
if (topicButton == null) {
topicButton = new MessageTopicButton(getContext(), resourcesProvider) {
@Override
protected void onClick() {
if (delegate != null) {
delegate.didPressTopicButton(ChatMessageCell.this);
}
}
};
}
namesOffset += topicButton.set(this, messageObject, topic, maxWidth);
}
}
}
if (!drawTopic && topicButton != null) {
topicButton.onDetached(this);
topicButton = null;
}
if ((!isThreadChat || messageObject.getReplyTopMsgId() != 0) && messageObject.hasValidReplyMessageObject() || messageObject.messageOwner.fwd_from != null && messageObject.isDice()) { if ((!isThreadChat || messageObject.getReplyTopMsgId() != 0) && messageObject.hasValidReplyMessageObject() || messageObject.messageOwner.fwd_from != null && messageObject.isDice()) {
if (currentPosition == null || currentPosition.minY == 0) { if (currentPosition == null || currentPosition.minY == 0) {
if (!messageObject.isAnyKindOfSticker() && messageObject.type != MessageObject.TYPE_ROUND_VIDEO) { if (!messageObject.isAnyKindOfSticker() && messageObject.type != MessageObject.TYPE_ROUND_VIDEO) {
@ -12005,16 +12087,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
mess = mess.replace('\n', ' '); mess = mess.replace('\n', ' ');
stringFinalText = Emoji.replaceEmoji(mess, Theme.chat_replyTextPaint.getFontMetricsInt(), AndroidUtilities.dp(14), false); stringFinalText = Emoji.replaceEmoji(mess, Theme.chat_replyTextPaint.getFontMetricsInt(), AndroidUtilities.dp(14), false);
if (messageObject.replyMessageObject.messageOwner != null) { if (messageObject.replyMessageObject.messageOwner != null) {
stringFinalText = MessageObject.replaceAnimatedEmoji(stringFinalText, messageObject.replyMessageObject.messageOwner.entities, Theme.chat_replyTextPaint.getFontMetricsInt()); stringFinalText = MessageObject.replaceAnimatedEmoji(stringFinalText, messageObject.replyMessageObject.messageOwner.entities, Theme.chat_replyTextPaint.getFontMetricsInt(), true);
} }
stringFinalText = TextUtils.ellipsize(stringFinalText, Theme.chat_replyTextPaint, maxWidth, TextUtils.TruncateAt.END); stringFinalText = TextUtils.ellipsize(stringFinalText, Theme.chat_replyTextPaint, maxWidth, TextUtils.TruncateAt.END);
if (stringFinalText instanceof Spannable && messageObject.replyMessageObject.messageOwner != null) { if (stringFinalText instanceof Spannable && messageObject.replyMessageObject.messageOwner != null) {
MediaDataController.addTextStyleRuns(messageObject.replyMessageObject.messageOwner.entities, messageObject.replyMessageObject.caption, (Spannable) stringFinalText); MediaDataController.addTextStyleRuns(messageObject.replyMessageObject.messageOwner.entities, messageObject.replyMessageObject.caption, (Spannable) stringFinalText);
} }
} else if (messageObject.replyMessageObject != null && messageObject.replyMessageObject.messageOwner != null && messageObject.replyMessageObject.messageOwner.action instanceof TLRPC.TL_messageActionTopicCreate) {
TLRPC.TL_messageActionTopicCreate topicCreate = (TLRPC.TL_messageActionTopicCreate) messageObject.replyMessageObject.messageOwner.action;
TLRPC.TL_forumTopic topic = MessagesController.getInstance(currentAccount).getTopicsController().findTopic(-messageObject.getDialogId(), messageObject.replyMessageObject.messageOwner.id);
stringFinalText = ForumUtilities.getTopicSpannedName(topic, Theme.chat_replyTextPaint);
} else if (messageObject.replyMessageObject != null && messageObject.replyMessageObject.messageText != null && messageObject.replyMessageObject.messageText.length() > 0) { } else if (messageObject.replyMessageObject != null && messageObject.replyMessageObject.messageText != null && messageObject.replyMessageObject.messageText.length() > 0) {
String mess = messageObject.replyMessageObject.messageText.toString(); String mess = messageObject.replyMessageObject.messageText.toString();
if (mess.length() > 150) { if (mess.length() > 150) {
@ -12023,7 +12101,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
mess = mess.replace('\n', ' '); mess = mess.replace('\n', ' ');
stringFinalText = Emoji.replaceEmoji(mess, Theme.chat_replyTextPaint.getFontMetricsInt(), AndroidUtilities.dp(14), false); stringFinalText = Emoji.replaceEmoji(mess, Theme.chat_replyTextPaint.getFontMetricsInt(), AndroidUtilities.dp(14), false);
if (messageObject.replyMessageObject.messageOwner != null) { if (messageObject.replyMessageObject.messageOwner != null) {
stringFinalText = MessageObject.replaceAnimatedEmoji(stringFinalText, messageObject.replyMessageObject.messageOwner.entities, Theme.chat_replyTextPaint.getFontMetricsInt()); stringFinalText = MessageObject.replaceAnimatedEmoji(stringFinalText, messageObject.replyMessageObject.messageOwner.entities, Theme.chat_replyTextPaint.getFontMetricsInt(), true);
} }
stringFinalText = TextUtils.ellipsize(stringFinalText, Theme.chat_replyTextPaint, maxWidth, TextUtils.TruncateAt.END); stringFinalText = TextUtils.ellipsize(stringFinalText, Theme.chat_replyTextPaint, maxWidth, TextUtils.TruncateAt.END);
if (stringFinalText instanceof Spannable) { if (stringFinalText instanceof Spannable) {
@ -12107,8 +12185,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
replyTextOffset = (int) replyTextLayout.getLineLeft(0); replyTextOffset = (int) replyTextLayout.getLineLeft(0);
} }
replySpoilers.clear(); replySpoilers.clear();
if (getMessageObject().replyMessageObject != null && !getMessageObject().replyMessageObject.isSpoilersRevealed) if (getMessageObject().replyMessageObject != null && !getMessageObject().replyMessageObject.isSpoilersRevealed) {
SpoilerEffect.addSpoilers(this, replyTextLayout, replySpoilersPool, replySpoilers); SpoilerEffect.addSpoilers(this, replyTextLayout, replySpoilersPool, replySpoilers);
}
animatedEmojiReplyStack = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, false, animatedEmojiReplyStack, replyTextLayout); animatedEmojiReplyStack = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, false, animatedEmojiReplyStack, replyTextLayout);
} }
} catch (Exception e) { } catch (Exception e) {
@ -12116,7 +12195,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
} }
} else if (!isThreadChat && messageObject.getReplyMsgId() != 0) { } else if (!isThreadChat && messageObject.getReplyMsgId() != 0) {
if (!(messageObject.replyMessageObject != null && messageObject.replyMessageObject.messageOwner instanceof TLRPC.TL_messageEmpty)) { if (!(messageObject.replyMessageObject != null && (messageObject.replyMessageObject.messageOwner instanceof TLRPC.TL_messageEmpty || messageObject.replyMessageObject.messageOwner != null && messageObject.replyMessageObject.messageOwner.action instanceof TLRPC.TL_messageActionTopicCreate))) {
if (!messageObject.isAnyKindOfSticker() && messageObject.type != MessageObject.TYPE_ROUND_VIDEO) { if (!messageObject.isAnyKindOfSticker() && messageObject.type != MessageObject.TYPE_ROUND_VIDEO) {
namesOffset += AndroidUtilities.dp(14) + (Theme.chat_replyTextPaint.getTextSize() + Theme.chat_replyNamePaint.getTextSize()); namesOffset += AndroidUtilities.dp(14) + (Theme.chat_replyTextPaint.getTextSize() + Theme.chat_replyNamePaint.getTextSize());
if (messageObject.type != MessageObject.TYPE_TEXT) { if (messageObject.type != MessageObject.TYPE_TEXT) {
@ -12451,6 +12530,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
replyStartY = forwardNameY + forwardHeight + AndroidUtilities.dp(6); replyStartY = forwardNameY + forwardHeight + AndroidUtilities.dp(6);
} else { } else {
replyStartY = AndroidUtilities.dp(12); replyStartY = AndroidUtilities.dp(12);
if (drawTopic && topicButton != null) {
replyStartY += topicButton.height() + AndroidUtilities.dp(10);
}
} }
} else { } else {
if (currentMessageObject.isOutOwner()) { if (currentMessageObject.isOutOwner()) {
@ -12464,6 +12546,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
forwardHeight = AndroidUtilities.dp(4) + (int) Theme.chat_forwardNamePaint.getTextSize() * 2; forwardHeight = AndroidUtilities.dp(4) + (int) Theme.chat_forwardNamePaint.getTextSize() * 2;
replyStartY = AndroidUtilities.dp(12) + (drawNameLayout && nameLayout != null ? AndroidUtilities.dp(6) + (int) Theme.chat_namePaint.getTextSize() : 0) + (drawForwardedName && forwardedNameLayout[0] != null ? AndroidUtilities.dp(4) + forwardHeight : 0); replyStartY = AndroidUtilities.dp(12) + (drawNameLayout && nameLayout != null ? AndroidUtilities.dp(6) + (int) Theme.chat_namePaint.getTextSize() : 0) + (drawForwardedName && forwardedNameLayout[0] != null ? AndroidUtilities.dp(4) + forwardHeight : 0);
if (drawTopic && topicButton != null) {
replyStartY += topicButton.height() + AndroidUtilities.dp(5);
}
} }
} }
if (currentPosition == null && !transitionParams.animateBackgroundBoundsInner && !(enterTransitionInProgress && !currentMessageObject.isVoice())) { if (currentPosition == null && !transitionParams.animateBackgroundBoundsInner && !(enterTransitionInProgress && !currentMessageObject.isVoice())) {
@ -13004,6 +13089,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
drawSideButton != 0 || drawSideButton != 0 ||
drawNameLayout && nameLayout != null && currentNameStatusDrawable != null && currentNameStatusDrawable.getDrawable() != null || drawNameLayout && nameLayout != null && currentNameStatusDrawable != null && currentNameStatusDrawable.getDrawable() != null ||
animatedEmojiStack != null && !animatedEmojiStack.holders.isEmpty() || animatedEmojiStack != null && !animatedEmojiStack.holders.isEmpty() ||
drawTopic && topicButton != null && (currentPosition == null || currentPosition.minY == 0 && currentPosition.minX == 0) ||
currentMessagesGroup == null && currentMessagesGroup == null &&
(transitionParams.animateReplaceCaptionLayout && transitionParams.animateChangeProgress != 1f || transitionParams.animateChangeProgress != 1.0f && transitionParams.animateMessageText) && (transitionParams.animateReplaceCaptionLayout && transitionParams.animateChangeProgress != 1f || transitionParams.animateChangeProgress != 1.0f && transitionParams.animateMessageText) &&
transitionParams.animateOutAnimateEmoji != null && !transitionParams.animateOutAnimateEmoji.holders.isEmpty() transitionParams.animateOutAnimateEmoji != null && !transitionParams.animateOutAnimateEmoji.holders.isEmpty()
@ -13079,6 +13165,31 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
currentNameStatusDrawable.draw(canvas); currentNameStatusDrawable.draw(canvas);
} }
if (drawTopic && topicButton != null && (currentPosition == null || currentPosition.minY == 0 && currentPosition.minX == 0)) {
float replyForwardAlpha = 1f;
if (isRoundVideo && !hasLinkPreview) {
replyForwardAlpha *= 1f - getVideoTranscriptionProgress();
if (transitionParams.animatePlayingRound) {
if (isPlayingRound) {
replyForwardAlpha *= (1f - transitionParams.animateChangeProgress);
} else {
replyForwardAlpha *= transitionParams.animateChangeProgress;
}
} else if (isPlayingRound) {
replyForwardAlpha = 0;
}
}
float animatingAlpha = 1f;
if (transitionParams.animateForwardedLayout) {
if (!currentMessageObject.needDrawForwarded()) {
animatingAlpha = 1f - transitionParams.animateChangeProgress;
} else {
animatingAlpha = transitionParams.animateChangeProgress;
}
}
topicButton.drawOutbounds(canvas, animatingAlpha * replyForwardAlpha);
}
if (!transitionParams.transitionBotButtons.isEmpty() && transitionParams.animateBotButtonsChanged) { if (!transitionParams.transitionBotButtons.isEmpty() && transitionParams.animateBotButtonsChanged) {
drawBotButtons(canvas, transitionParams.transitionBotButtons, 1f - transitionParams.animateChangeProgress); drawBotButtons(canvas, transitionParams.transitionBotButtons, 1f - transitionParams.animateChangeProgress);
} }
@ -13433,13 +13544,21 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
public boolean hasNameLayout() { public boolean hasNameLayout() {
return drawNameLayout && nameLayout != null || return drawNameLayout && nameLayout != null ||
drawForwardedName && forwardedNameLayout[0] != null && forwardedNameLayout[1] != null && (currentPosition == null || currentPosition.minY == 0 && currentPosition.minX == 0) || drawForwardedName && forwardedNameLayout[0] != null && forwardedNameLayout[1] != null && (currentPosition == null || currentPosition.minY == 0 && currentPosition.minX == 0) ||
replyNameLayout != null; replyNameLayout != null || drawTopic;
} }
public boolean isDrawNameLayout() { public boolean isDrawNameLayout() {
return drawNameLayout && nameLayout != null; return drawNameLayout && nameLayout != null;
} }
public boolean isDrawTopic() {
return drawTopic;
}
public float getDrawTopicHeight() {
return topicButton != null ? topicButton.height() : 0;
}
public boolean isAdminLayoutChanged() { public boolean isAdminLayoutChanged() {
return !TextUtils.equals(lastPostAuthor, currentMessageObject.messageOwner.post_author); return !TextUtils.equals(lastPostAuthor, currentMessageObject.messageOwner.post_author);
} }
@ -13657,7 +13776,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (!currentMessageObject.isVoiceTranscriptionOpen() && (currentMessageObject.isOutOwner() && currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO && transitionParams.animatePlayingRound || isPlayingRound)) { if (!currentMessageObject.isVoiceTranscriptionOpen() && (currentMessageObject.isOutOwner() && currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO && transitionParams.animatePlayingRound || isPlayingRound)) {
forwardNameXLocal -= AndroidUtilities.dp(78) * (isPlayingRound ? transitionParams.animateChangeProgress : (1f - transitionParams.animateChangeProgress)); forwardNameXLocal -= AndroidUtilities.dp(78) * (isPlayingRound ? transitionParams.animateChangeProgress : (1f - transitionParams.animateChangeProgress));
} }
forwardNameY = AndroidUtilities.dp(12); forwardNameY = AndroidUtilities.dp(12) + (drawTopic && topicButton != null ? topicButton.height() + AndroidUtilities.dp(14) : 0);
forwardHeight = AndroidUtilities.dp(4) + (int) Theme.chat_forwardNamePaint.getTextSize() * 2; forwardHeight = AndroidUtilities.dp(4) + (int) Theme.chat_forwardNamePaint.getTextSize() * 2;
int backWidth = forwardedNameWidthLocal + AndroidUtilities.dp(14); int backWidth = forwardedNameWidthLocal + AndroidUtilities.dp(14);
@ -13689,7 +13808,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha(oldAlpha2); Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha(oldAlpha2);
} }
} else { } else {
forwardNameY = AndroidUtilities.dp(10) + (drawNameLayout ? AndroidUtilities.dp(5) + (int) Theme.chat_namePaint.getTextSize() : 0); forwardNameY = AndroidUtilities.dp(10) + (drawNameLayout ? AndroidUtilities.dp(5) + (int) Theme.chat_namePaint.getTextSize() : 0) + (drawTopic && topicButton != null ? topicButton.height() + AndroidUtilities.dp(7 + (currentMessageObject.type != MessageObject.TYPE_TEXT ? 3 : 0)) : 0);
forwardHeight = AndroidUtilities.dp(4) + (int) Theme.chat_forwardNamePaint.getTextSize() * 2; forwardHeight = AndroidUtilities.dp(4) + (int) Theme.chat_forwardNamePaint.getTextSize() * 2;
if (currentMessageObject.isOutOwner()) { if (currentMessageObject.isOutOwner()) {
if (hasPsaHint) { if (hasPsaHint) {
@ -13793,6 +13912,37 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
} }
if (drawTopic && (animatingAlpha > 0 && replyForwardAlpha > 0) && (currentPosition == null || currentPosition.minY == 0 && currentPosition.minX == 0)) {
float x, y;
if (currentMessageObject.shouldDrawWithoutBackground()) {
if (currentMessageObject.isOutOwner()) {
x = AndroidUtilities.dp(23);
if (isPlayingRound) {
x -= (AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize);
}
} else if (currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
x = backgroundDrawableLeft + backgroundDrawableRight + AndroidUtilities.dp(4);
} else {
x = backgroundDrawableLeft + backgroundDrawableRight + AndroidUtilities.dp(17);
}
y = AndroidUtilities.dp(12);
x -= AndroidUtilities.dp(8);
} else {
if (currentMessageObject.isOutOwner()) {
x = backgroundDrawableLeft + AndroidUtilities.dp(12) + getExtraTextX();
} else {
if (mediaBackground) {
x = backgroundDrawableLeft + AndroidUtilities.dp(12) + getExtraTextX();
} else {
x = backgroundDrawableLeft + AndroidUtilities.dp(drawPinnedBottom ? 12 : 18) + getExtraTextX();
}
}
x -= AndroidUtilities.dp(2.33f);
y = AndroidUtilities.dp(12) + (drawNameLayout && nameLayout != null ? AndroidUtilities.dp(6) + (int) Theme.chat_namePaint.getTextSize() : 0);
}
topicButton.draw(canvas, x, y, animatingAlpha * replyForwardAlpha);
}
if (hasReply) { if (hasReply) {
float replyStartX = this.replyStartX; float replyStartX = this.replyStartX;
float replyStartY = this.replyStartY; float replyStartY = this.replyStartY;
@ -13879,14 +14029,14 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
(int) (replyStartY + replyHeight + AndroidUtilities.dp(7)) (int) (replyStartY + replyHeight + AndroidUtilities.dp(7))
); );
} else { } else {
if (drawNameLayout || (drawForwardedName && forwardedNameLayout[0] != null)) { if (drawTopic || drawNameLayout || (drawForwardedName && forwardedNameLayout[0] != null)) {
leftRad = bottomRad; leftRad = bottomRad;
} else if (currentMessageObject.isOutOwner() || !drawPinnedTop) { } else if (currentMessageObject.isOutOwner() || !drawPinnedTop) {
leftRad = AndroidUtilities.dp(SharedConfig.bubbleRadius / 3f); leftRad = AndroidUtilities.dp(SharedConfig.bubbleRadius / 3f);
} else { } else {
leftRad = AndroidUtilities.dp(Math.min(6, SharedConfig.bubbleRadius) / 3f); leftRad = AndroidUtilities.dp(Math.min(6, SharedConfig.bubbleRadius) / 3f);
} }
if (drawNameLayout || (drawForwardedName && forwardedNameLayout[0] != null)) { if (drawTopic || drawNameLayout || (drawForwardedName && forwardedNameLayout[0] != null)) {
rightRad = bottomRad; rightRad = bottomRad;
} else if (!currentMessageObject.isOutOwner() || !drawPinnedTop) { } else if (!currentMessageObject.isOutOwner() || !drawPinnedTop) {
rightRad = AndroidUtilities.dp(SharedConfig.bubbleRadius / 3f); rightRad = AndroidUtilities.dp(SharedConfig.bubbleRadius / 3f);
@ -14609,8 +14759,16 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
paint = getThemedPaint(Theme.key_paint_chatTimeBackground); paint = getThemedPaint(Theme.key_paint_chatTimeBackground);
} }
int oldAlpha = paint.getAlpha(); int oldAlpha = paint.getAlpha();
paint.setAlpha((int) (oldAlpha * timeAlpha * alpha)); float oldAlpha3 = alpha;
Theme.chat_timePaint.setAlpha((int) (255 * timeAlpha * alpha)); Theme.chat_timePaint.setAlpha((int) (255 * timeAlpha * alpha));
if (currentMessageObject != null && currentMessageObject.type == MessageObject.TYPE_GEO) {
float progress = photoImage.isCrossfadingWithOldImage() ? 1 : photoImage.getCurrentAlpha();
if (!photoImage.hasNotThumb()) {
progress = 0;
}
alpha = AndroidUtilities.lerp(0.35f, 1f, progress);
}
paint.setAlpha((int) (oldAlpha * timeAlpha * alpha));
int r; int r;
if (documentAttachType != DOCUMENT_ATTACH_TYPE_ROUND && documentAttachType != DOCUMENT_ATTACH_TYPE_STICKER && currentMessageObject.type != MessageObject.TYPE_EMOJIS) { if (documentAttachType != DOCUMENT_ATTACH_TYPE_ROUND && documentAttachType != DOCUMENT_ATTACH_TYPE_STICKER && currentMessageObject.type != MessageObject.TYPE_EMOJIS) {
@ -14641,6 +14799,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
paint.setAlpha(oldAlpha); paint.setAlpha(oldAlpha);
alpha = oldAlpha3;
float additionalX = -timeLayout.getLineLeft(0); float additionalX = -timeLayout.getLineLeft(0);
if (reactionsLayoutInBubble.isSmall) { if (reactionsLayoutInBubble.isSmall) {
updateReactionLayoutPosition(); updateReactionLayoutPosition();
@ -15705,9 +15865,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
float progress = photoImage.isCrossfadingWithOldImage() ? 1 : photoImage.getCurrentAlpha(); float progress = photoImage.isCrossfadingWithOldImage() ? 1 : photoImage.getCurrentAlpha();
if (progress > 0 && photoImage.hasNotThumb()) { if (progress > 0 && (photoImage.hasNotThumb() || photoImage.isCrossfadingWithOldImage())) {
int cx = (int) (photoImage.getImageX() + photoImage.getImageWidth() / 2 - AndroidUtilities.dp(31)); int cx = (int) (photoImage.getImageX() + photoImage.getImageWidth() / 2 - AndroidUtilities.dp(31));
cy = (int) (photoImage.getImageY() + photoImage.getImageHeight() / 2 - AndroidUtilities.dp(38) - AndroidUtilities.dp(16) * (1f - CubicBezierInterpolator.EASE_OUT_BACK.getInterpolation(photoImage.getCurrentAlpha()))); cy = (int) (photoImage.getImageY() + photoImage.getImageHeight() / 2 - AndroidUtilities.dp(38) - AndroidUtilities.dp(16) * (1f - CubicBezierInterpolator.EASE_OUT_BACK.getInterpolation(progress)));
setDrawableBounds(Theme.chat_msgAvatarLiveLocationDrawable, cx, cy); setDrawableBounds(Theme.chat_msgAvatarLiveLocationDrawable, cx, cy);
Theme.chat_msgAvatarLiveLocationDrawable.setAlpha((int) (255 * Math.min(1, progress * 5))); Theme.chat_msgAvatarLiveLocationDrawable.setAlpha((int) (255 * Math.min(1, progress * 5)));
@ -16178,7 +16338,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
boolean restore = false; boolean restore = false;
boolean on = false; boolean on = false;
if (currentMessageObject != null && currentMessageObject.isRoundVideo() && (getVideoTranscriptionProgress() <= 0 && !currentMessageObject.mediaExists)) { if (currentMessageObject != null && currentMessageObject.isRoundVideo() && !currentMessageObject.mediaExists) {
radialProgress.setProgressRect( radialProgress.setProgressRect(
photoImage.getImageX() + (photoImage.getImageWidth() - radialProgress.getRadius()) / 2f, photoImage.getImageX() + (photoImage.getImageWidth() - radialProgress.getRadius()) / 2f,
photoImage.getImageY() + (photoImage.getImageHeight() - radialProgress.getRadius()) / 2f, photoImage.getImageY() + (photoImage.getImageHeight() - radialProgress.getRadius()) / 2f,

View file

@ -61,6 +61,7 @@ import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject; import org.telegram.messenger.UserObject;
import org.telegram.messenger.browser.Browser;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBar;
@ -80,7 +81,9 @@ import org.telegram.ui.Components.CircularProgressDrawable;
import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.EditTextBoldCursor; import org.telegram.ui.Components.EditTextBoldCursor;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.LinkSpanDrawable;
import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.TypefaceSpan;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -585,19 +588,19 @@ public class ChangeUsernameActivity extends BaseFragment {
} }
private UsernameHelpCell helpCell; private UsernameHelpCell helpCell;
private TextView statusTextView; private LinkSpanDrawable.LinksTextView statusTextView;
private class UsernameHelpCell extends FrameLayout { private class UsernameHelpCell extends FrameLayout {
private TextView text1View; private TextView text1View;
private TextView text2View; private LinkSpanDrawable.LinksTextView text2View;
public UsernameHelpCell(Context context) { public UsernameHelpCell(Context context) {
super(context); super(context);
helpCell = this; helpCell = this;
setPadding(AndroidUtilities.dp(21), AndroidUtilities.dp(10), AndroidUtilities.dp(21), AndroidUtilities.dp(17)); setPadding(AndroidUtilities.dp(18), AndroidUtilities.dp(10), AndroidUtilities.dp(18), AndroidUtilities.dp(17));
setBackgroundDrawable(Theme.getThemedDrawable(context, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow)); setBackgroundDrawable(Theme.getThemedDrawable(context, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow));
setClipChildren(false); setClipChildren(false);
@ -607,13 +610,50 @@ public class ChangeUsernameActivity extends BaseFragment {
text1View.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); text1View.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
text1View.setLinkTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteLinkText)); text1View.setLinkTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteLinkText));
text1View.setHighlightColor(Theme.getColor(Theme.key_windowBackgroundWhiteLinkSelection)); text1View.setHighlightColor(Theme.getColor(Theme.key_windowBackgroundWhiteLinkSelection));
text1View.setPadding(AndroidUtilities.dp(3), 0, AndroidUtilities.dp(3), 0);
text2View = statusTextView = new TextView(context); text2View = statusTextView = new LinkSpanDrawable.LinksTextView(context) {
@Override
public void setText(CharSequence text, BufferType type) {
if (text != null) {
SpannableStringBuilder tagsString = AndroidUtilities.replaceTags(text.toString());
int index = tagsString.toString().indexOf('\n');
if (index >= 0) {
tagsString.replace(index, index + 1, " ");
tagsString.setSpan(new ForegroundColorSpan(getThemedColor(Theme.key_windowBackgroundWhiteRedText4)), 0, index, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
TypefaceSpan[] spans = tagsString.getSpans(0, tagsString.length(), TypefaceSpan.class);
for (int i = 0; i < spans.length; ++i) {
tagsString.setSpan(
new ClickableSpan() {
@Override
public void onClick(@NonNull View view) {
Browser.openUrl(getContext(), "https://fragment.com/username/" + username);
}
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
},
tagsString.getSpanStart(spans[i]),
tagsString.getSpanEnd(spans[i]),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
);
tagsString.removeSpan(spans[i]);
}
text = tagsString;
}
super.setText(text, type);
}
};
text2View.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); text2View.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
text2View.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText8)); text2View.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText8));
text2View.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); text2View.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
text2View.setLinkTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteLinkText)); text2View.setLinkTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteLinkText));
text2View.setHighlightColor(Theme.getColor(Theme.key_windowBackgroundWhiteLinkSelection)); text2View.setHighlightColor(Theme.getColor(Theme.key_windowBackgroundWhiteLinkSelection));
text2View.setPadding(AndroidUtilities.dp(3), 0, AndroidUtilities.dp(3), 0);
addView(text1View, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP)); addView(text1View, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP));
addView(text2View, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP)); addView(text2View, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP));
@ -1120,7 +1160,7 @@ public class ChangeUsernameActivity extends BaseFragment {
} }
} }
} }
if (name == null || name.length() < 5) { if (name == null || name.length() < 4) {
if (alert) { if (alert) {
AlertsCreator.showSimpleAlert(this, LocaleController.getString("UsernameInvalidShort", R.string.UsernameInvalidShort)); AlertsCreator.showSimpleAlert(this, LocaleController.getString("UsernameInvalidShort", R.string.UsernameInvalidShort));
} else { } else {
@ -1196,9 +1236,23 @@ public class ChangeUsernameActivity extends BaseFragment {
lastNameAvailable = true; lastNameAvailable = true;
} else { } else {
if (statusTextView != null) { if (statusTextView != null) {
statusTextView.setText(LocaleController.getString("UsernameInUse", R.string.UsernameInUse)); if (error != null && "USERNAME_INVALID".equals(error.text) && req.username.length() == 4) {
statusTextView.setTag(Theme.key_windowBackgroundWhiteRedText4); statusTextView.setText(LocaleController.getString("UsernameInvalidShort", R.string.UsernameInvalidShort));
statusTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteRedText4)); statusTextView.setTag(Theme.key_windowBackgroundWhiteRedText4);
statusTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteRedText4));
} else if (error != null && "USERNAME_PURCHASE_AVAILABLE".equals(error.text)) {
if (req.username.length() == 4) {
statusTextView.setText(LocaleController.getString("UsernameInvalidShortPurchase", R.string.UsernameInvalidShortPurchase));
} else {
statusTextView.setText(LocaleController.getString("UsernameInUsePurchase", R.string.UsernameInUsePurchase));
}
statusTextView.setTag(Theme.key_windowBackgroundWhiteGrayText8);
statusTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText8));
} else {
statusTextView.setText(LocaleController.getString("UsernameInUse", R.string.UsernameInUse));
statusTextView.setTag(Theme.key_windowBackgroundWhiteRedText4);
statusTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteRedText4));
}
if (helpCell != null) { if (helpCell != null) {
helpCell.update(); helpCell.update();
} }
@ -1265,6 +1319,15 @@ public class ChangeUsernameActivity extends BaseFragment {
} }
finishFragment(); finishFragment();
}); });
} else if ("USERNAME_PURCHASE_AVAILABLE".equals(error.text) || "USERNAME_INVALID".equals(error.text)) {
AndroidUtilities.runOnUIThread(() -> {
try {
progressDialog.dismiss();
} catch (Exception e) {
FileLog.e(e);
}
shakeIfOff();
});
} else { } else {
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
try { try {

View file

@ -26,8 +26,13 @@ import android.os.Vibrator;
import android.text.Editable; import android.text.Editable;
import android.text.InputFilter; import android.text.InputFilter;
import android.text.InputType; import android.text.InputType;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
import android.view.View; import android.view.View;
@ -38,7 +43,8 @@ import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ScrollView; import android.widget.ScrollView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.ViewAnimator;
import androidx.annotation.NonNull;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ChatObject; import org.telegram.messenger.ChatObject;
@ -48,6 +54,7 @@ import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.browser.Browser;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBar;
@ -64,20 +71,22 @@ import org.telegram.ui.Cells.ShadowSectionCell;
import org.telegram.ui.Cells.TextBlockCell; import org.telegram.ui.Cells.TextBlockCell;
import org.telegram.ui.Cells.TextInfoPrivacyCell; import org.telegram.ui.Cells.TextInfoPrivacyCell;
import org.telegram.ui.Components.AvatarDrawable; import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CircularProgressDrawable; import org.telegram.ui.Components.CircularProgressDrawable;
import org.telegram.ui.Components.CrossfadeDrawable; import org.telegram.ui.Components.CrossfadeDrawable;
import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.EditTextBoldCursor;
import org.telegram.ui.Components.EditTextEmoji; import org.telegram.ui.Components.EditTextEmoji;
import org.telegram.ui.Components.ImageUpdater; import org.telegram.ui.Components.ImageUpdater;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.EditTextBoldCursor;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.LinkActionView; import org.telegram.ui.Components.LinkActionView;
import org.telegram.ui.Components.LinkSpanDrawable;
import org.telegram.ui.Components.Premium.LimitReachedBottomSheet; import org.telegram.ui.Components.Premium.LimitReachedBottomSheet;
import org.telegram.ui.Components.RLottieDrawable; import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.RLottieImageView; import org.telegram.ui.Components.RLottieImageView;
import org.telegram.ui.Components.RadialProgressView; import org.telegram.ui.Components.RadialProgressView;
import org.telegram.ui.Components.SizeNotifierFrameLayout; import org.telegram.ui.Components.SizeNotifierFrameLayout;
import org.telegram.ui.Components.TypefaceSpan;
import java.util.ArrayList; import java.util.ArrayList;
@ -790,11 +799,50 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
permanentLinkView.setUsers(0, null); permanentLinkView.setUsers(0, null);
privateContainer.addView(permanentLinkView); privateContainer.addView(permanentLinkView);
checkTextView = new TextView(context); checkTextView = new LinkSpanDrawable.LinksTextView(context) {
@Override
public void setText(CharSequence text, BufferType type) {
if (text != null) {
SpannableStringBuilder tagsString = AndroidUtilities.replaceTags(text.toString());
int index = tagsString.toString().indexOf('\n');
if (index >= 0) {
tagsString.replace(index, index + 1, " ");
tagsString.setSpan(new ForegroundColorSpan(getThemedColor(Theme.key_windowBackgroundWhiteRedText4)), 0, index, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
TypefaceSpan[] spans = tagsString.getSpans(0, tagsString.length(), TypefaceSpan.class);
final String username = descriptionTextView == null || descriptionTextView.getText() == null ? "" : descriptionTextView.getText().toString();
for (int i = 0; i < spans.length; ++i) {
tagsString.setSpan(
new ClickableSpan() {
@Override
public void onClick(@NonNull View view) {
Browser.openUrl(getContext(), "https://fragment.com/username/" + username);
}
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
},
tagsString.getSpanStart(spans[i]),
tagsString.getSpanEnd(spans[i]),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
);
tagsString.removeSpan(spans[i]);
}
text = tagsString;
}
super.setText(text, type);
}
};
checkTextView.setLinkTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteLinkText));
checkTextView.setHighlightColor(Theme.getColor(Theme.key_windowBackgroundWhiteLinkSelection));
checkTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); checkTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
checkTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); checkTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
checkTextView.setVisibility(View.GONE); checkTextView.setVisibility(View.GONE);
linkContainer.addView(checkTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT, 17, 3, 17, 7)); checkTextView.setPadding(AndroidUtilities.dp(3), 0, AndroidUtilities.dp(3), 0);
linkContainer.addView(checkTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT, 18, 3, 18, 7));
typeInfoCell = new TextInfoPrivacyCell(context); typeInfoCell = new TextInfoPrivacyCell(context);
typeInfoCell.setBackgroundDrawable(Theme.getThemedDrawable(context, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow)); typeInfoCell.setBackgroundDrawable(Theme.getThemedDrawable(context, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow));
@ -1179,7 +1227,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
} }
} }
} }
if (name == null || name.length() < 5) { if (name == null || name.length() < 4) {
checkTextView.setText(LocaleController.getString("LinkInvalidShort", R.string.LinkInvalidShort)); checkTextView.setText(LocaleController.getString("LinkInvalidShort", R.string.LinkInvalidShort));
checkTextView.setTag(Theme.key_windowBackgroundWhiteRedText4); checkTextView.setTag(Theme.key_windowBackgroundWhiteRedText4);
checkTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteRedText4)); checkTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteRedText4));
@ -1209,14 +1257,24 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
checkTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGreenText)); checkTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGreenText));
lastNameAvailable = true; lastNameAvailable = true;
} else { } else {
if (error != null && error.text.equals("CHANNELS_ADMIN_PUBLIC_TOO_MUCH")) { if (error != null && "USERNAME_INVALID".equals(error.text) && req.username.length() == 4) {
checkTextView.setText(LocaleController.getString("UsernameInvalidShort", R.string.UsernameInvalidShort));
checkTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteRedText4));
} else if (error != null && "USERNAME_PURCHASE_AVAILABLE".equals(error.text)) {
if (req.username.length() == 4) {
checkTextView.setText(LocaleController.getString("UsernameInvalidShortPurchase", R.string.UsernameInvalidShortPurchase));
} else {
checkTextView.setText(LocaleController.getString("UsernameInUsePurchase", R.string.UsernameInUsePurchase));
}
checkTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText8));
} else if (error != null && "CHANNELS_ADMIN_PUBLIC_TOO_MUCH".equals(error.text)) {
checkTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteRedText4));
canCreatePublic = false; canCreatePublic = false;
showPremiumIncreaseLimitDialog(); showPremiumIncreaseLimitDialog();
} else { } else {
checkTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteRedText4));
checkTextView.setText(LocaleController.getString("LinkInUse", R.string.LinkInUse)); checkTextView.setText(LocaleController.getString("LinkInUse", R.string.LinkInUse));
} }
checkTextView.setTag(Theme.key_windowBackgroundWhiteRedText4);
checkTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteRedText4));
lastNameAvailable = false; lastNameAvailable = false;
} }
} }

View file

@ -64,6 +64,7 @@ import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan; import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan; import android.text.style.ImageSpan;
import android.text.style.URLSpan; import android.text.style.URLSpan;
import android.util.Pair;
import android.util.Property; import android.util.Property;
import android.util.SparseArray; import android.util.SparseArray;
import android.util.SparseIntArray; import android.util.SparseIntArray;
@ -198,6 +199,7 @@ import org.telegram.ui.Components.Bulletin;
import org.telegram.ui.Components.BulletinFactory; import org.telegram.ui.Components.BulletinFactory;
import org.telegram.ui.Components.ChatActivityEnterTopView; import org.telegram.ui.Components.ChatActivityEnterTopView;
import org.telegram.ui.Components.ChatActivityEnterView; import org.telegram.ui.Components.ChatActivityEnterView;
import org.telegram.ui.Components.ChatActivityInterface;
import org.telegram.ui.Components.ChatAttachAlert; import org.telegram.ui.Components.ChatAttachAlert;
import org.telegram.ui.Components.ChatAttachAlertDocumentLayout; import org.telegram.ui.Components.ChatAttachAlertDocumentLayout;
import org.telegram.ui.Components.ChatAvatarContainer; import org.telegram.ui.Components.ChatAvatarContainer;
@ -305,7 +307,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public class ChatActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate, DialogsActivity.DialogsActivityDelegate, LocationActivity.LocationActivityDelegate, ChatAttachAlertDocumentLayout.DocumentSelectActivityDelegate, FragmentContextView.ChatActivityInterface, FloatingDebugProvider { public class ChatActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate, DialogsActivity.DialogsActivityDelegate, LocationActivity.LocationActivityDelegate, ChatAttachAlertDocumentLayout.DocumentSelectActivityDelegate, ChatActivityInterface, FloatingDebugProvider {
private final static boolean PULL_DOWN_BACK_FRAGMENT = false; private final static boolean PULL_DOWN_BACK_FRAGMENT = false;
private final static boolean DISABLE_PROGRESS_VIEW = true; private final static boolean DISABLE_PROGRESS_VIEW = true;
private final static int SKELETON_DISAPPEAR_MS = 200; private final static int SKELETON_DISAPPEAR_MS = 200;
@ -351,6 +353,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private ActionBarMenuSubItem clearHistoryItem; private ActionBarMenuSubItem clearHistoryItem;
private ActionBarMenuSubItem viewAsTopics; private ActionBarMenuSubItem viewAsTopics;
private ActionBarMenuSubItem closeTopicItem; private ActionBarMenuSubItem closeTopicItem;
private ActionBarMenuSubItem openForumItem;
private ClippingImageView animatingImageView; private ClippingImageView animatingImageView;
private RecyclerListView chatListView; private RecyclerListView chatListView;
private ChatListItemAnimator chatListItemAnimator; private ChatListItemAnimator chatListItemAnimator;
@ -507,6 +510,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private int reportType = -1; private int reportType = -1;
private MessageObject threadMessageObject; private MessageObject threadMessageObject;
private MessageObject topicStarterMessageObject;
private boolean threadMessageVisible = true; private boolean threadMessageVisible = true;
private ArrayList<MessageObject> threadMessageObjects; private ArrayList<MessageObject> threadMessageObjects;
private MessageObject replyMessageHeaderObject; private MessageObject replyMessageHeaderObject;
@ -1179,6 +1183,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private final static int search = 40; private final static int search = 40;
private final static int topic_close = 60; private final static int topic_close = 60;
private final static int open_forum = 61;
private final static int id_chat_compose_panel = 1000; private final static int id_chat_compose_panel = 1000;
@ -1681,7 +1686,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} else if (!forceHistoryEmpty) { } else if (!forceHistoryEmpty) {
loading = true; loading = true;
} }
if (isThreadChat()) { if (isThreadChat() && !isTopic) {
if (highlightMessageId == startLoadFromMessageId) { if (highlightMessageId == startLoadFromMessageId) {
needSelectFromMessageId = true; needSelectFromMessageId = true;
} }
@ -1695,11 +1700,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (startLoadFromMessageId == 0) { if (startLoadFromMessageId == 0) {
SharedPreferences sharedPreferences = MessagesController.getNotificationsSettings(currentAccount); SharedPreferences sharedPreferences = MessagesController.getNotificationsSettings(currentAccount);
int messageId = sharedPreferences.getInt("diditem" + dialog_id, 0); int messageId = sharedPreferences.getInt("diditem" + NotificationsController.getSharedPrefKey(dialog_id, getTopicId()), 0);
if (messageId != 0) { if (messageId != 0) {
wasManualScroll = true; wasManualScroll = true;
loadingFromOldPosition = true; loadingFromOldPosition = true;
startLoadFromMessageOffset = sharedPreferences.getInt("diditemo" + dialog_id, 0); startLoadFromMessageOffset = sharedPreferences.getInt("diditemo" + NotificationsController.getSharedPrefKey(dialog_id, getTopicId()), 0);
startLoadFromMessageId = messageId; startLoadFromMessageId = messageId;
} }
} else { } else {
@ -1743,7 +1748,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
waitingForLoad.add(lastLoadIndex); waitingForLoad.add(lastLoadIndex);
if (startLoadFromDate != 0) { if (startLoadFromDate != 0) {
getMessagesController().loadMessages(dialog_id, mergeDialogId, false, 30, 0, startLoadFromDate, true, 0, classGuid, 4, 0, chatMode, threadMessageId, replyMaxReadId, lastLoadIndex++, isTopic); getMessagesController().loadMessages(dialog_id, mergeDialogId, false, 30, 0, startLoadFromDate, true, 0, classGuid, 4, 0, chatMode, threadMessageId, replyMaxReadId, lastLoadIndex++, isTopic);
} else if (startLoadFromMessageId != 0 && (!isThreadChat() || startLoadFromMessageId == highlightMessageId)) { } else if (startLoadFromMessageId != 0 && (!isThreadChat() || startLoadFromMessageId == highlightMessageId || isTopic)) {
startLoadFromMessageIdSaved = startLoadFromMessageId; startLoadFromMessageIdSaved = startLoadFromMessageId;
if (migrated_to != 0) { if (migrated_to != 0) {
mergeDialogId = migrated_to; mergeDialogId = migrated_to;
@ -2358,43 +2363,50 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
updateTopicButtons(); updateTopicButtons();
updateBottomOverlay(); updateBottomOverlay();
updateTopPanel(true); updateTopPanel(true);
} else if (id == open_forum) {
TopicsFragment.prepareToSwitchAnimation(ChatActivity.this);
// Bundle bundle = new Bundle();
// bundle.putLong("chat_id", -dialog_id);
// presentFragment(new TopicsFragment(bundle));
} }
} }
}); });
View backButton = actionBar.getBackButton(); View backButton = actionBar.getBackButton();
backButton.setOnLongClickListener(e -> { backButton.setOnTouchListener(new LongPressListenerWithMovingGesture() {
scrimPopupWindow = BackButtonMenu.show(this, backButton, dialog_id, themeDelegate); @Override
if (scrimPopupWindow != null) { public void onLongPress() {
scrimPopupWindow.setOnDismissListener(() -> { scrimPopupWindow = BackButtonMenu.show(ChatActivity.this, backButton, dialog_id, getTopicId(), themeDelegate);
scrimPopupWindow = null; if (scrimPopupWindow != null) {
menuDeleteItem = null; setSubmenu(scrimPopupWindow);
scrimPopupWindowItems = null; scrimPopupWindow.setOnDismissListener(() -> {
chatLayoutManager.setCanScrollVertically(true); setSubmenu(null);
if (scrimPopupWindowHideDimOnDismiss) { scrimPopupWindow = null;
dimBehindView(false); menuDeleteItem = null;
} else { scrimPopupWindowItems = null;
scrimPopupWindowHideDimOnDismiss = true; chatLayoutManager.setCanScrollVertically(true);
if (scrimPopupWindowHideDimOnDismiss) {
dimBehindView(false);
} else {
scrimPopupWindowHideDimOnDismiss = true;
}
if (chatActivityEnterView != null) {
chatActivityEnterView.getEditField().setAllowDrawCursor(true);
}
});
chatListView.stopScroll();
chatLayoutManager.setCanScrollVertically(false);
dimBehindView(backButton, 0.3f);
hideHints(false);
if (topUndoView != null) {
topUndoView.hide(true, 1);
}
if (undoView != null) {
undoView.hide(true, 1);
} }
if (chatActivityEnterView != null) { if (chatActivityEnterView != null) {
chatActivityEnterView.getEditField().setAllowDrawCursor(true); chatActivityEnterView.getEditField().setAllowDrawCursor(false);
} }
});
chatListView.stopScroll();
chatLayoutManager.setCanScrollVertically(false);
dimBehindView(backButton, 0.3f);
hideHints(false);
if (topUndoView != null) {
topUndoView.hide(true, 1);
} }
if (undoView != null) {
undoView.hide(true, 1);
}
if (chatActivityEnterView != null) {
chatActivityEnterView.getEditField().setAllowDrawCursor(false);
}
return true;
} else {
return false;
} }
}); });
actionBar.setInterceptTouchEventListener((view, motionEvent) -> { actionBar.setInterceptTouchEventListener((view, motionEvent) -> {
@ -2834,6 +2846,22 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
updateBotButtons(); updateBotButtons();
} }
} }
if (ChatObject.isForum(currentChat) && isTopic) {
if (getParentLayout() != null && getParentLayout().getFragmentStack() != null) {
boolean hasMyForum = false;
for (int i = 0; i < getParentLayout().getFragmentStack().size(); ++i) {
BaseFragment fragment = getParentLayout().getFragmentStack().get(i);
if (fragment instanceof TopicsFragment && ((TopicsFragment) fragment).getDialogId() == dialog_id) {
hasMyForum = true;
break;
}
}
if (!hasMyForum) {
openForumItem = headerItem.addSubItem(open_forum, R.drawable.msg_discussion, LocaleController.getString("OpenAllTopics", R.string.OpenAllTopics), themeDelegate);
}
}
}
if (currentChat != null && forumTopic != null) { if (currentChat != null && forumTopic != null) {
closeTopicItem = headerItem.addSubItem(topic_close, R.drawable.msg_topic_close, LocaleController.getString("CloseTopic", R.string.CloseTopic), themeDelegate); closeTopicItem = headerItem.addSubItem(topic_close, R.drawable.msg_topic_close, LocaleController.getString("CloseTopic", R.string.CloseTopic), themeDelegate);
closeTopicItem.setVisibility(currentChat != null && ChatObject.canManageTopic(currentAccount, currentChat, forumTopic) && forumTopic != null && !forumTopic.closed ? View.VISIBLE : View.GONE); closeTopicItem.setVisibility(currentChat != null && ChatObject.canManageTopic(currentAccount, currentChat, forumTopic) && forumTopic != null && !forumTopic.closed ? View.VISIBLE : View.GONE);
@ -2986,6 +3014,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (mentionContainer != null) { if (mentionContainer != null) {
mentionContainer.onPanTransitionEnd(); mentionContainer.onPanTransitionEnd();
} }
if (voiceHintTextView != null && voiceHintTextView.getVisibility() == View.VISIBLE) {
voiceHintTextView.showForView(chatActivityEnterView.getAudioVideoButtonContainer(), false);
}
} }
@Override @Override
@ -3023,6 +3054,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
((DialogsActivity)mainFragment).setPanTranslationOffset(y); ((DialogsActivity)mainFragment).setPanTranslationOffset(y);
} }
} }
if (voiceHintTextView != null && voiceHintTextView.getVisibility() == View.VISIBLE) {
voiceHintTextView.showForView(chatActivityEnterView.getAudioVideoButtonContainer(), false);
}
} }
@Override @Override
@ -3094,7 +3128,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} else { } else {
expandY = chatActivityEnterView.getY(); expandY = chatActivityEnterView.getY();
} }
if (scrimView != null || chatActivityEnterView != null && chatActivityEnterView.isStickersExpanded() && ev.getY() < expandY) { if ((scrimView != null && scrimView != actionBar.getBackButton()) || chatActivityEnterView != null && chatActivityEnterView.isStickersExpanded() && ev.getY() < expandY) {
return false; return false;
} }
@ -4309,6 +4343,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (textSelectionHelper != null && textSelectionHelper.isSelectionMode()) { if (textSelectionHelper != null && textSelectionHelper.isSelectionMode()) {
textSelectionHelper.invalidate(); textSelectionHelper.invalidate();
} }
isSkeletonVisible();
} }
private void setGroupTranslationX(ChatMessageCell view, float dx) { private void setGroupTranslationX(ChatMessageCell view, float dx) {
@ -4810,8 +4845,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
maxTop = top; maxTop = top;
} }
} }
if (maxTop <= 0) { if (maxTop <= chatListViewPaddingTop) {
checkDispatchHideSkeletons(true); checkDispatchHideSkeletons(fragmentBeginToShow);
} }
boolean visible = (!endReached[0] || mergeDialogId != 0 && !endReached[1] || messages.isEmpty()) && loading && maxTop > 0 && (messages.isEmpty() ? animateProgressViewTo : childHeight != 0); boolean visible = (!endReached[0] || mergeDialogId != 0 && !endReached[1] || messages.isEmpty()) && loading && maxTop > 0 && (messages.isEmpty() ? animateProgressViewTo : childHeight != 0);
@ -4904,12 +4939,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
MessageObject.GroupedMessages group = ((ChatMessageCell) v).getCurrentMessagesGroup(); MessageObject.GroupedMessages group = ((ChatMessageCell) v).getCurrentMessagesGroup();
Rect bounds = ((ChatMessageCell) v).getCurrentBackgroundDrawable(true).getBounds(); Rect bounds = ((ChatMessageCell) v).getCurrentBackgroundDrawable(true).getBounds();
int newTop = (int) (v.getTop() + bounds.top + (group != null ? group.transitionParams.top + group.transitionParams.offsetTop : 0)); int newTop = (int) (v.getTop() + bounds.top + (group != null ? group.transitionParams.top + group.transitionParams.offsetTop : 0));
int top = messages.size() <= 2 && isSkeletonVisible() ? AndroidUtilities.lerp(lastTop, newTop, v.getAlpha()) : v.getAlpha() == 1f ? newTop : lastTop; int top = startMessageAppearTransitionMs == 0 && isSkeletonVisible() ? AndroidUtilities.lerp(lastTop, newTop, v.getAlpha()) : v.getAlpha() == 1f ? newTop : lastTop;
if (top < lastTop) { if (top < lastTop) {
lastTop = top; lastTop = top;
} }
} else if (v instanceof ChatActionCell) { } else if (v instanceof ChatActionCell) {
int top = messages.size() <= 2 && isSkeletonVisible() ? AndroidUtilities.lerp(lastTop, v.getTop(), v.getAlpha()) : v.getAlpha() == 1f ? v.getTop() : lastTop; int top = startMessageAppearTransitionMs == 0 && isSkeletonVisible() ? AndroidUtilities.lerp(lastTop, v.getTop(), v.getAlpha()) : v.getAlpha() == 1f ? v.getTop() : lastTop;
if (top < lastTop) { if (top < lastTop) {
lastTop = top; lastTop = top;
} }
@ -4962,6 +4997,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
servicePaint.setAlpha(wasServiceAlpha); servicePaint.setAlpha(wasServiceAlpha);
skeletonPaint.setAlpha(alpha); skeletonPaint.setAlpha(alpha);
invalidated = false;
invalidate(); invalidate();
} else if (System.currentTimeMillis() - startMessageAppearTransitionMs > SKELETON_DISAPPEAR_MS) { } else if (System.currentTimeMillis() - startMessageAppearTransitionMs > SKELETON_DISAPPEAR_MS) {
messageSkeletons.clear(); messageSkeletons.clear();
@ -5365,6 +5401,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
@Override @Override
public boolean drawChild(Canvas canvas, View child, long drawingTime) { public boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (isSkeletonVisible()) { if (isSkeletonVisible()) {
invalidated = false;
invalidate(); invalidate();
} }
@ -5866,7 +5903,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
@Override @Override
public int getStarForFixGap() { public int getStarForFixGap() {
int padding = (int) chatListViewPaddingTop; int padding = (int) chatListViewPaddingTop;
if (isThreadChat() && !isTopic && pinnedMessageView != null && pinnedMessageView.getVisibility() == View.VISIBLE) { if (isThreadChat() && (!isTopic || topicStarterMessageObject != null) && pinnedMessageView != null && pinnedMessageView.getVisibility() == View.VISIBLE) {
padding -= Math.max(0, AndroidUtilities.dp(48) + pinnedMessageEnterOffset); padding -= Math.max(0, AndroidUtilities.dp(48) + pinnedMessageEnterOffset);
} }
return padding; return padding;
@ -6011,7 +6048,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
View child = chatListView.getChildAt(i); View child = chatListView.getChildAt(i);
float padding = chatListViewPaddingTop; float padding = chatListViewPaddingTop;
if (isThreadChat() && !isTopic && pinnedMessageView != null && pinnedMessageView.getVisibility() == View.VISIBLE) { if (isThreadChat() && (!isTopic || topicStarterMessageObject != null) && pinnedMessageView != null && pinnedMessageView.getVisibility() == View.VISIBLE) {
padding -= Math.max(0, AndroidUtilities.dp(48) + pinnedMessageEnterOffset); padding -= Math.max(0, AndroidUtilities.dp(48) + pinnedMessageEnterOffset);
} }
if (chatListView.getChildAdapterPosition(child) == chatAdapter.getItemCount() - 1) { if (chatListView.getChildAdapterPosition(child) == chatAdapter.getItemCount() - 1) {
@ -7632,6 +7669,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
topUndoView.showWithAction(0, UndoView.ACTION_HINT_SWIPE_TO_REPLY, null, null); topUndoView.showWithAction(0, UndoView.ACTION_HINT_SWIPE_TO_REPLY, null, null);
} }
} }
if (ChatObject.isForum(currentChat) && !isTopic && replyingMessageObject != null) {
int topicId = replyingMessageObject.replyToForumTopic != null ? replyingMessageObject.replyToForumTopic.id : MessageObject.getTopicId(replyingMessageObject.messageOwner);
if (topicId != 0) {
getMediaDataController().cleanDraft(dialog_id, topicId, false);
}
}
hideFieldPanel(notify, scheduleDate, true); hideFieldPanel(notify, scheduleDate, true);
if (chatActivityEnterView != null && chatActivityEnterView.getEmojiView() != null) { if (chatActivityEnterView != null && chatActivityEnterView.getEmojiView() != null) {
chatActivityEnterView.getEmojiView().onMessageSend(); chatActivityEnterView.getEmojiView().onMessageSend();
@ -8152,6 +8196,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
chatActivityEnterTopView.addView(replyCloseImageView, LayoutHelper.createFrame(52, 46, Gravity.RIGHT | Gravity.TOP, 0, 0.5f, 0, 0)); chatActivityEnterTopView.addView(replyCloseImageView, LayoutHelper.createFrame(52, 46, Gravity.RIGHT | Gravity.TOP, 0, 0.5f, 0, 0));
replyCloseImageView.setOnClickListener(v -> { replyCloseImageView.setOnClickListener(v -> {
if (forwardingMessages == null || forwardingMessages.messages.isEmpty()) { if (forwardingMessages == null || forwardingMessages.messages.isEmpty()) {
if (ChatObject.isForum(currentChat) && !isTopic && replyingMessageObject != null) {
int topicId = MessageObject.getTopicId(replyingMessageObject.messageOwner);
if (topicId != 0) {
getMediaDataController().cleanDraft(dialog_id, topicId, false);
}
}
showFieldPanel(false, null, null, null, foundWebPage, true, 0, true, true); showFieldPanel(false, null, null, null, foundWebPage, true, 0, true, true);
} else { } else {
openAnotherForward(); openAnotherForward();
@ -9394,6 +9444,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
if (object != null) { if (object != null) {
fragment.pinnedMessageObjects.put(id, object); fragment.pinnedMessageObjects.put(id, object);
fragment.updatePinnedTopicStarterMessage();
} }
} }
fragment.loadedPinnedMessagesCount = loadedPinnedMessagesCount; fragment.loadedPinnedMessagesCount = loadedPinnedMessagesCount;
@ -9706,7 +9757,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
int adapterPosition = chatListView.getChildAdapterPosition(child); int adapterPosition = chatListView.getChildAdapterPosition(child);
if (adapterPosition == chatAdapter.getItemCount() - 1) { if (adapterPosition == chatAdapter.getItemCount() - 1) {
float padding = chatListViewPaddingTop; float padding = chatListViewPaddingTop;
if (isThreadChat() && !isTopic && pinnedMessageView != null && pinnedMessageView.getVisibility() == View.VISIBLE) { if (isThreadChat() && (!isTopic || topicStarterMessageObject != null) && pinnedMessageView != null && pinnedMessageView.getVisibility() == View.VISIBLE) {
padding -= Math.max(0, AndroidUtilities.dp(48) + pinnedMessageEnterOffset); padding -= Math.max(0, AndroidUtilities.dp(48) + pinnedMessageEnterOffset);
} }
if (child.getTop() > padding) { if (child.getTop() > padding) {
@ -11840,6 +11891,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
replyObjectText = messageObjectToReply.messageTextShort; replyObjectText = messageObjectToReply.messageTextShort;
} }
AnimatedEmojiSpan.applyFontMetricsForString(replyObjectText, replyObjectTextView.getPaint()); AnimatedEmojiSpan.applyFontMetricsForString(replyObjectText, replyObjectTextView.getPaint());
} else if (messageObjectToReply.replyToForumTopic != null) {
replyObjectText = ForumUtilities.getTopicSpannedName(messageObjectToReply.replyToForumTopic, replyObjectTextView.getPaint());
} else if (messageObjectToReply.messageOwner.media instanceof TLRPC.TL_messageMediaGame) { } else if (messageObjectToReply.messageOwner.media instanceof TLRPC.TL_messageMediaGame) {
replyObjectText = Emoji.replaceEmoji(messageObjectToReply.messageOwner.media.game.title, replyObjectTextView.getPaint().getFontMetricsInt(), AndroidUtilities.dp(14), false); replyObjectText = Emoji.replaceEmoji(messageObjectToReply.messageOwner.media.game.title, replyObjectTextView.getPaint().getFontMetricsInt(), AndroidUtilities.dp(14), false);
sourceText = messageObjectToReply.messageOwner.media.game.title; sourceText = messageObjectToReply.messageOwner.media.game.title;
@ -12502,6 +12555,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
boolean blurEnabled = SharedConfig.chatBlurEnabled() && Color.alpha(Theme.getColor(Theme.key_chat_BlurAlpha)) != 255; boolean blurEnabled = SharedConfig.chatBlurEnabled() && Color.alpha(Theme.getColor(Theme.key_chat_BlurAlpha)) != 255;
MessageObject messageStarter = isTopic ? topicStarterMessageObject : threadMessageObject;
for (int a = 0; a < count; a++) { for (int a = 0; a < count; a++) {
View view = chatListView.getChildAt(a); View view = chatListView.getChildAt(a);
MessageObject messageObject = null; MessageObject messageObject = null;
@ -12558,7 +12613,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
messageCell.setParentBounds(chatListViewPaddingTop - chatListViewPaddingVisibleOffset - AndroidUtilities.dp(4), chatListView.getMeasuredHeight() - blurredViewBottomOffset); messageCell.setParentBounds(chatListViewPaddingTop - chatListViewPaddingVisibleOffset - AndroidUtilities.dp(4), chatListView.getMeasuredHeight() - blurredViewBottomOffset);
messageCell.setVisiblePart(viewTop, viewBottom - viewTop, recyclerChatViewHeight, keyboardOffset, view.getY() + (isKeyboardVisible() ? chatListView.getTop() : actionBar.getMeasuredHeight()) - contentView.getBackgroundTranslationY(), contentView.getMeasuredWidth(), contentView.getBackgroundSizeY(), blurredViewTopOffset, blurredViewBottomOffset); messageCell.setVisiblePart(viewTop, viewBottom - viewTop, recyclerChatViewHeight, keyboardOffset, view.getY() + (isKeyboardVisible() ? chatListView.getTop() : actionBar.getMeasuredHeight()) - contentView.getBackgroundTranslationY(), contentView.getMeasuredWidth(), contentView.getBackgroundSizeY(), blurredViewTopOffset, blurredViewBottomOffset);
markSponsoredAsRead(messageObject); markSponsoredAsRead(messageObject);
if (!threadMessageVisible && threadMessageObject != null && messageObject == threadMessageObject && messageCell.getBottom() > chatListViewPaddingTop) { if (!threadMessageVisible && messageStarter != null && (messageObject == messageStarter || isTopic && messageObject != null && messageObject.getId() == messageStarter.getId()) && messageCell.getBottom() > chatListViewPaddingTop) {
threadMessageVisible = true; threadMessageVisible = true;
} }
if (videoPlayerContainer != null && (messageObject.isVideo() || messageObject.isRoundVideo()) && !messageObject.isVoiceTranscriptionOpen() && MediaController.getInstance().isPlayingMessage(messageObject)) { if (videoPlayerContainer != null && (messageObject.isVideo() || messageObject.isRoundVideo()) && !messageObject.isVoiceTranscriptionOpen() && MediaController.getInstance().isPlayingMessage(messageObject)) {
@ -12817,7 +12872,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
hideFloatingDateView(true); hideFloatingDateView(true);
floatingDateViewOffset = 0; floatingDateViewOffset = 0;
} }
if (isThreadChat() && !isTopic) { if (isThreadChat()) {
if (previousThreadMessageVisible != threadMessageVisible) { if (previousThreadMessageVisible != threadMessageVisible) {
updatePinnedMessageView(openAnimationStartTime != 0 && SystemClock.elapsedRealtime() >= openAnimationStartTime + 150); updatePinnedMessageView(openAnimationStartTime != 0 && SystemClock.elapsedRealtime() >= openAnimationStartTime + 150);
} }
@ -15444,6 +15499,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (!postponedScroll) { if (!postponedScroll) {
chatAdapter.notifyDataSetChanged(true); chatAdapter.notifyDataSetChanged(true);
} }
if (isTopic && startLoadFromMessageId == getTopicId() && messArr.size() > 0 && messages.size() > 0) {
scrollToMessage = messages.get(messArr.size() - 1);
}
if (scrollToMessage != null) { if (scrollToMessage != null) {
addSponsoredMessages(!isFirstLoading); addSponsoredMessages(!isFirstLoading);
int yOffset; int yOffset;
@ -17079,6 +17137,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
} }
} }
updatePinnedTopicStarterMessage();
} else if (id == NotificationCenter.didReceivedWebpages) { } else if (id == NotificationCenter.didReceivedWebpages) {
ArrayList<TLRPC.Message> arrayList = (ArrayList<TLRPC.Message>) args[0]; ArrayList<TLRPC.Message> arrayList = (ArrayList<TLRPC.Message>) args[0];
boolean updated = false; boolean updated = false;
@ -17276,12 +17335,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
SparseArray<TLRPC.MessageReplies> array = channelReplies.get(dialog_id); SparseArray<TLRPC.MessageReplies> array = channelReplies.get(dialog_id);
boolean hasChatInBack = false; boolean hasChatInBack = false;
if (threadMessageObject != null && parentLayout != null) { if (threadMessageObject != null && !isTopic && parentLayout != null) {
for (int a = 0, N = parentLayout.getFragmentStack().size() - 1; a < N; a++) { for (int a = 0, N = parentLayout.getFragmentStack().size() - 1; a < N; a++) {
BaseFragment fragment = parentLayout.getFragmentStack().get(a); BaseFragment fragment = parentLayout.getFragmentStack().get(a);
if (fragment != this && fragment instanceof ChatActivity) { if (fragment != this && fragment instanceof ChatActivity) {
ChatActivity chatActivity = (ChatActivity) fragment; ChatActivity chatActivity = (ChatActivity) fragment;
if (chatActivity.needRemovePreviousSameChatActivity && chatActivity.dialog_id == dialog_id && chatActivity.getChatMode() == getChatMode()) { if (chatActivity.needRemovePreviousSameChatActivity && chatActivity.dialog_id == dialog_id && chatActivity.getTopicId() == getTopicId() && chatActivity.getChatMode() == getChatMode()) {
hasChatInBack = true; hasChatInBack = true;
break; break;
} }
@ -18717,12 +18776,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
boolean hasChatInBack = false; boolean hasChatInBack = false;
boolean updatedReplies = false; boolean updatedReplies = false;
if (threadMessageObject != null && parentLayout != null) { if (threadMessageObject != null && !isTopic && parentLayout != null) {
for (int a = 0, N = parentLayout.getFragmentStack().size() - 1; a < N; a++) { for (int a = 0, N = parentLayout.getFragmentStack().size() - 1; a < N; a++) {
BaseFragment fragment = parentLayout.getFragmentStack().get(a); BaseFragment fragment = parentLayout.getFragmentStack().get(a);
if (fragment != this && fragment instanceof ChatActivity) { if (fragment != this && fragment instanceof ChatActivity) {
ChatActivity chatActivity = (ChatActivity) fragment; ChatActivity chatActivity = (ChatActivity) fragment;
if (chatActivity.needRemovePreviousSameChatActivity && chatActivity.dialog_id == dialog_id && chatActivity.getChatMode() == getChatMode()) { if (chatActivity.needRemovePreviousSameChatActivity && chatActivity.dialog_id == dialog_id && getTopicId() == getTopicId() && chatActivity.getChatMode() == getChatMode()) {
hasChatInBack = true; hasChatInBack = true;
break; break;
} }
@ -19084,6 +19143,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
} }
} }
updatePinnedTopicStarterMessage();
} }
private void migrateToNewChat(MessageObject obj) { private void migrateToNewChat(MessageObject obj) {
@ -19365,7 +19425,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
BaseFragment fragment = parentLayout.getFragmentStack().get(a); BaseFragment fragment = parentLayout.getFragmentStack().get(a);
if (fragment != this && fragment instanceof ChatActivity) { if (fragment != this && fragment instanceof ChatActivity) {
ChatActivity chatActivity = (ChatActivity) fragment; ChatActivity chatActivity = (ChatActivity) fragment;
if (chatActivity.needRemovePreviousSameChatActivity && chatActivity.dialog_id == dialog_id && chatActivity.getChatMode() == getChatMode() && chatActivity.threadMessageId == threadMessageId && chatActivity.reportType == reportType) { if (chatActivity.needRemovePreviousSameChatActivity && chatActivity.dialog_id == dialog_id && chatActivity.getTopicId() == getTopicId() && chatActivity.getChatMode() == getChatMode() && chatActivity.threadMessageId == threadMessageId && chatActivity.reportType == reportType) {
fragment.removeSelfFromStack(); fragment.removeSelfFromStack();
break; break;
} }
@ -19899,9 +19959,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private void updateTopicHeader() { private void updateTopicHeader() {
avatarContainer.setTitle(forumTopic.title); avatarContainer.setTitle(forumTopic.title);
if (currentChat != null) {
avatarContainer.setSubtitle(LocaleController.formatString("TopicProfileStatus", R.string.TopicProfileStatus, currentChat.title));
}
updateTopicTitleIcon(); updateTopicTitleIcon();
} }
@ -20058,6 +20115,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if ((isThreadChat() && !isTopic) || pinnedListButton == null) { if ((isThreadChat() && !isTopic) || pinnedListButton == null) {
return; return;
} }
if (!fragmentOpened) {
animated = false;
}
boolean show = pinnedMessageIds.size() > 1 && !pinnedMessageButtonShown; boolean show = pinnedMessageIds.size() > 1 && !pinnedMessageButtonShown;
boolean visible = pinnedListButton.getTag() != null; boolean visible = pinnedListButton.getTag() != null;
boolean progressIsVisible = pinnedProgress.getTag() != null; boolean progressIsVisible = pinnedProgress.getTag() != null;
@ -20157,7 +20217,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
int pinned_msg_id; int pinned_msg_id;
boolean changed = false; boolean changed = false;
MessageObject pinnedMessageObject; MessageObject pinnedMessageObject;
if (isThreadChat() && !isTopic) { if (isThreadChat() && threadMessageVisible) {
pinnedMessageObject = null;
pinned_msg_id = 0;
} else if (isThreadChat() && !isTopic) {
if (!threadMessageVisible) { if (!threadMessageVisible) {
pinnedMessageObject = threadMessageObject; pinnedMessageObject = threadMessageObject;
pinned_msg_id = threadMessageId; pinned_msg_id = threadMessageId;
@ -21455,10 +21518,20 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (chatMode == 0) { if (chatMode == 0) {
CharSequence[] message = new CharSequence[]{draftMessage}; CharSequence[] message = new CharSequence[]{draftMessage};
ArrayList<TLRPC.MessageEntity> entities = getMediaDataController().getEntities(message, currentEncryptedChat == null || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 101); ArrayList<TLRPC.MessageEntity> entities = getMediaDataController().getEntities(message, currentEncryptedChat == null || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 101);
getMediaDataController().saveDraft(dialog_id, threadMessageId, message[0], entities, (replyMessage != null && !replyMessage.isTopicMainMessage) ? replyMessage.messageOwner : null, !searchWebpage); int draftThreadId;
if (ChatObject.isForum(currentChat) && !isTopic && replyMessage != null) {
if (replyMessage.replyToForumTopic != null) {
draftThreadId = replyMessage.replyToForumTopic.id;
} else {
draftThreadId = MessageObject.getTopicId(replyMessage.messageOwner);
}
} else {
draftThreadId = threadMessageId;
}
getMediaDataController().saveDraft(dialog_id, draftThreadId, message[0], entities, (replyMessage != null && !replyMessage.isTopicMainMessage && replyMessage.replyToForumTopic == null) ? replyMessage.messageOwner : null, !searchWebpage);
getMessagesController().cancelTyping(0, dialog_id, threadMessageId); getMessagesController().cancelTyping(0, dialog_id, threadMessageId);
if (!pausedOnLastMessage && !firstLoading) { if (!pausedOnLastMessage && !firstLoading && (!isThreadChat() || isTopic)) {
SharedPreferences.Editor editor = MessagesController.getNotificationsSettings(currentAccount).edit(); SharedPreferences.Editor editor = MessagesController.getNotificationsSettings(currentAccount).edit();
int messageId = 0; int messageId = 0;
int offset = 0; int offset = 0;
@ -21522,12 +21595,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
} }
if (messageId != 0) { if (messageId != 0) {
editor.putInt("diditem" + dialog_id, messageId); editor.putInt("diditem" + NotificationsController.getSharedPrefKey(dialog_id, getTopicId()), messageId);
editor.putInt("diditemo" + dialog_id, offset); editor.putInt("diditemo" + NotificationsController.getSharedPrefKey(dialog_id, getTopicId()), offset);
} else { } else {
pausedOnLastMessage = true; pausedOnLastMessage = true;
editor.remove("diditem" + dialog_id); editor.remove("diditem" + NotificationsController.getSharedPrefKey(dialog_id, getTopicId()));
editor.remove("diditemo" + dialog_id); editor.remove("diditemo" + NotificationsController.getSharedPrefKey(dialog_id, getTopicId()));
} }
editor.commit(); editor.commit();
} }
@ -21554,8 +21627,18 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (chatActivityEnterView == null || chatMode != 0) { if (chatActivityEnterView == null || chatMode != 0) {
return; return;
} }
TLRPC.DraftMessage draftMessage = getMediaDataController().getDraft(dialog_id, threadMessageId); TLRPC.DraftMessage draftMessage = null;
TLRPC.Message draftReplyMessage = draftMessage != null && draftMessage.reply_to_msg_id != 0 ? getMediaDataController().getDraftMessage(dialog_id, threadMessageId) : null; Integer topicId = null;
if (ChatObject.isForum(currentChat) && !isTopic) {
Pair<Integer, TLRPC.DraftMessage> pair = getMediaDataController().getOneThreadDraft(dialog_id);;
if (pair != null) {
topicId = pair.first;
draftMessage = pair.second;
}
} else {
draftMessage = getMediaDataController().getDraft(dialog_id, threadMessageId);
}
TLRPC.Message draftReplyMessage = draftMessage != null && draftMessage.reply_to_msg_id != 0 ? getMediaDataController().getDraftMessage(dialog_id, topicId != null ? topicId : threadMessageId) : null;
if (chatActivityEnterView.getFieldText() == null) { if (chatActivityEnterView.getFieldText() == null) {
if (draftMessage != null) { if (draftMessage != null) {
chatActivityEnterView.setWebPage(null, !draftMessage.no_webpage); chatActivityEnterView.setWebPage(null, !draftMessage.no_webpage);
@ -21643,6 +21726,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
replyingMessageObject = new MessageObject(currentAccount, draftReplyMessage, getMessagesController().getUsers(), false, false); replyingMessageObject = new MessageObject(currentAccount, draftReplyMessage, getMessagesController().getUsers(), false, false);
showFieldPanelForReply(replyingMessageObject); showFieldPanelForReply(replyingMessageObject);
updateBottomOverlay(); updateBottomOverlay();
} else if (topicId != null && topicId != 0 && currentChat != null) {
TLRPC.TL_forumTopic topic = getMessagesController().getTopicsController().findTopic(currentChat.id, topicId);
if (topic != null && topic.topicStartMessage != null) {
replyingMessageObject = new MessageObject(currentAccount, topic.topicStartMessage, getMessagesController().getUsers(), false, false);
replyingMessageObject.replyToForumTopic = topic;
showFieldPanelForReply(replyingMessageObject);
updateBottomOverlay();
}
} }
} }
@ -22085,7 +22176,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
final ArrayList<Integer> options = new ArrayList<>(); final ArrayList<Integer> options = new ArrayList<>();
View optionsView = null; View optionsView = null;
if (!getUserConfig().isPremium() && !getMessagesController().premiumLocked && message.getDocument() != null && message.getDocument().size >= 500 * 1024 * 1024 && FileLoader.getInstance(currentAccount).isLoadingFile(FileLoader.getAttachFileName(message.getDocument()))) { if (!getUserConfig().isPremium() && !getMessagesController().premiumLocked && message.getDocument() != null && message.getDocument().size >= 300 * 1024 * 1024 && FileLoader.getInstance(currentAccount).isLoadingFile(FileLoader.getAttachFileName(message.getDocument()))) {
items.add(LocaleController.getString(R.string.PremiumSpeedPromo)); items.add(LocaleController.getString(R.string.PremiumSpeedPromo));
options.add(OPTION_SPEED_PROMO); options.add(OPTION_SPEED_PROMO);
icons.add(R.drawable.msg_speed); icons.add(R.drawable.msg_speed);
@ -22102,7 +22193,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} }
} }
if (index != -1) { if (index != -1) {
FileLoader.getInstance(currentAccount).loadFile(premiumPromo.videos.get(index), null, FileLoader.PRIORITY_HIGH, 0); FileLoader.getInstance(currentAccount).loadFile(premiumPromo.videos.get(index), premiumPromo, FileLoader.PRIORITY_HIGH, 0);
} }
} }
} }
@ -24599,7 +24690,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} else { } else {
MessagesStorage.TopicKey topicKey = dids.get(0); MessagesStorage.TopicKey topicKey = dids.get(0);
long did = topicKey.dialogId; long did = topicKey.dialogId;
if (did != dialog_id || chatMode == MODE_PINNED) { if (did != dialog_id || getTopicId() != topicKey.topicId || chatMode == MODE_PINNED) {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putBoolean("scrollToTopOnResume", scrollToTopOnResume); args.putBoolean("scrollToTopOnResume", scrollToTopOnResume);
if (DialogObject.isEncryptedDialog(did)) { if (DialogObject.isEncryptedDialog(did)) {
@ -24628,7 +24719,21 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
fragment.finishFragment(); fragment.finishFragment();
} }
} else { } else {
fragment.finishFragment(); List<BaseFragment> fragments = new ArrayList<>(getParentLayout().getFragmentStack());
if (!fragments.isEmpty() && fragments.get(fragments.size() - 1) == fragment) {
fragment.finishFragment();
} else {
int fragmentIndex = fragments.indexOf(fragment);
if (fragmentIndex > 0) {
for (int i = fragmentIndex; i < fragments.size(); i++) {
if (i == fragments.size() - 1) {
fragments.get(i).finishFragment();
} else {
fragment.removeSelfFromStack();
}
}
}
}
moveScrollToLastMessage(false); moveScrollToLastMessage(false);
showFieldPanelForForward(true, fmessages); showFieldPanelForForward(true, fmessages);
if (AndroidUtilities.isTablet()) { if (AndroidUtilities.isTablet()) {
@ -24736,10 +24841,18 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (isTopic) { if (isTopic) {
replyingMessageObject.isTopicMainMessage = true; replyingMessageObject.isTopicMainMessage = true;
} }
updatePinnedTopicStarterMessage();
updateTopPanel(false); updateTopPanel(false);
updateBottomOverlay(); updateBottomOverlay();
} }
private void updatePinnedTopicStarterMessage() {
topicStarterMessageObject = isTopic && !pinnedMessageObjects.isEmpty() && pinnedMessageIds.size() == 1 ? pinnedMessageObjects.get(pinnedMessageIds.get(0)) : null;
if (isTopic && topicStarterMessageObject != null && topicStarterMessageObject.messageOwner != null && forumTopic != null && !MessageObject.peersEqual(forumTopic.from_id, topicStarterMessageObject.messageOwner.from_id) && !MessageObject.peersEqual(currentChat, topicStarterMessageObject.messageOwner.from_id)) {
topicStarterMessageObject = null;
}
}
public void setHighlightMessageId(int id) { public void setHighlightMessageId(int id) {
highlightMessageId = id; highlightMessageId = id;
} }
@ -26682,6 +26795,20 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
return true; return true;
} }
@Override
public void didPressTopicButton(ChatMessageCell cell) {
MessageObject message = cell.getMessageObject();
if (message != null) {
int topicId = MessageObject.getTopicId(message.messageOwner);
if (topicId != 0) {
TLRPC.TL_forumTopic topic = getMessagesController().getTopicsController().findTopic(currentChat.id, topicId);
if (topic != null) {
ForumUtilities.openTopic(ChatActivity.this, currentChat.id, topic, message.getId());
}
}
}
}
@Override @Override
public void didPressExtendedMediaPreview(ChatMessageCell cell, TLRPC.KeyboardButton button) { public void didPressExtendedMediaPreview(ChatMessageCell cell, TLRPC.KeyboardButton button) {
getSendMessagesHelper().sendCallback(true, cell.getMessageObject(), button, ChatActivity.this); getSendMessagesHelper().sendCallback(true, cell.getMessageObject(), button, ChatActivity.this);
@ -29716,6 +29843,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
return skeleton; return skeleton;
} }
@Override
public SizeNotifierFrameLayout getContentView() {
return contentView;
}
private final static class MessageSkeleton { private final static class MessageSkeleton {
int width; int width;
int height; int height;

View file

@ -19,8 +19,13 @@ import android.graphics.drawable.Drawable;
import android.os.Vibrator; import android.os.Vibrator;
import android.text.Editable; import android.text.Editable;
import android.text.InputType; import android.text.InputType;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
@ -41,6 +46,7 @@ import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.browser.Browser;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBar;
@ -69,6 +75,7 @@ import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.LinkActionView; import org.telegram.ui.Components.LinkActionView;
import org.telegram.ui.Components.Premium.LimitReachedBottomSheet; import org.telegram.ui.Components.Premium.LimitReachedBottomSheet;
import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.TypefaceSpan;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -464,7 +471,43 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
permanentLinkView.setUsers(0, null); permanentLinkView.setUsers(0, null);
privateContainer.addView(permanentLinkView); privateContainer.addView(permanentLinkView);
checkTextView = new TextInfoPrivacyCell(context); checkTextView = new TextInfoPrivacyCell(context) {
@Override
public void setText(CharSequence text) {
if (text != null) {
SpannableStringBuilder tagsString = AndroidUtilities.replaceTags(text.toString());
int index = tagsString.toString().indexOf('\n');
if (index >= 0) {
tagsString.replace(index, index + 1, " ");
tagsString.setSpan(new ForegroundColorSpan(getThemedColor(Theme.key_windowBackgroundWhiteRedText4)), 0, index, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
TypefaceSpan[] spans = tagsString.getSpans(0, tagsString.length(), TypefaceSpan.class);
final String username = usernameTextView == null || usernameTextView.getText() == null ? "" : usernameTextView.getText().toString();
for (int i = 0; i < spans.length; ++i) {
tagsString.setSpan(
new ClickableSpan() {
@Override
public void onClick(@NonNull View view) {
Browser.openUrl(getContext(), "https://fragment.com/username/" + username);
}
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
},
tagsString.getSpanStart(spans[i]),
tagsString.getSpanEnd(spans[i]),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
);
tagsString.removeSpan(spans[i]);
}
text = tagsString;
}
super.setText(text);
}
};
checkTextView.setBackgroundDrawable(Theme.getThemedDrawable(context, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow)); checkTextView.setBackgroundDrawable(Theme.getThemedDrawable(context, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow));
checkTextView.setBottomPadding(6); checkTextView.setBottomPadding(6);
linearLayout.addView(checkTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT)); linearLayout.addView(checkTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
@ -1344,7 +1387,7 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
} }
} }
} }
if (name == null || name.length() < 5) { if (name == null || name.length() < 4) {
if (isChannel) { if (isChannel) {
checkTextView.setText(LocaleController.getString("LinkInvalidShort", R.string.LinkInvalidShort)); checkTextView.setText(LocaleController.getString("LinkInvalidShort", R.string.LinkInvalidShort));
} else { } else {
@ -1374,13 +1417,23 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
checkTextView.setTextColor(Theme.key_windowBackgroundWhiteGreenText); checkTextView.setTextColor(Theme.key_windowBackgroundWhiteGreenText);
lastNameAvailable = true; lastNameAvailable = true;
} else { } else {
if (error != null && error.text.equals("CHANNELS_ADMIN_PUBLIC_TOO_MUCH")) { if (error != null && "USERNAME_INVALID".equals(error.text) && req.username.length() == 4) {
checkTextView.setText(LocaleController.getString("UsernameInvalidShort", R.string.UsernameInvalidShort));
checkTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteRedText4));
} else if (error != null && "USERNAME_PURCHASE_AVAILABLE".equals(error.text)) {
if (req.username.length() == 4) {
checkTextView.setText(LocaleController.getString("UsernameInvalidShortPurchase", R.string.UsernameInvalidShortPurchase));
} else {
checkTextView.setText(LocaleController.getString("UsernameInUsePurchase", R.string.UsernameInUsePurchase));
}
checkTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText8));
} else if (error != null && "CHANNELS_ADMIN_PUBLIC_TOO_MUCH".equals(error.text)) {
canCreatePublic = false; canCreatePublic = false;
showPremiumIncreaseLimitDialog(); showPremiumIncreaseLimitDialog();
} else { } else {
checkTextView.setText(LocaleController.getString("LinkInUse", R.string.LinkInUse)); checkTextView.setText(LocaleController.getString("LinkInUse", R.string.LinkInUse));
checkTextView.setTextColor(Theme.key_windowBackgroundWhiteRedText4);
} }
checkTextView.setTextColor(Theme.key_windowBackgroundWhiteRedText4);
lastNameAvailable = false; lastNameAvailable = false;
} }
} }

View file

@ -0,0 +1,174 @@
package org.telegram.ui.Components;
import android.animation.TimeInterpolator;
import android.os.SystemClock;
import android.view.View;
import androidx.core.graphics.ColorUtils;
import androidx.core.math.MathUtils;
public class AnimatedColor {
private View parent;
private Runnable invalidate;
private int value;
private int targetValue;
private boolean firstSet;
private long transitionDelay = 0;
private long transitionDuration = 200;
private TimeInterpolator transitionInterpolator = CubicBezierInterpolator.DEFAULT;
private boolean transition;
private long transitionStart;
private int startValue;
public AnimatedColor() {
this.parent = null;
this.firstSet = true;
}
public AnimatedColor(long transitionDuration, TimeInterpolator transitionInterpolator) {
this.parent = null;
this.transitionDuration = transitionDuration;
this.transitionInterpolator = transitionInterpolator;
this.firstSet = true;
}
public AnimatedColor(long transitionDelay, long transitionDuration, TimeInterpolator transitionInterpolator) {
this.parent = null;
this.transitionDelay = transitionDelay;
this.transitionDuration = transitionDuration;
this.transitionInterpolator = transitionInterpolator;
this.firstSet = true;
}
public AnimatedColor(View parentToInvalidate) {
this.parent = parentToInvalidate;
this.firstSet = true;
}
public AnimatedColor(View parentToInvalidate, long transitionDuration, TimeInterpolator transitionInterpolator) {
this.parent = parentToInvalidate;
this.transitionDuration = transitionDuration;
this.transitionInterpolator = transitionInterpolator;
this.firstSet = true;
}
public AnimatedColor(View parentToInvalidate, long transitionDelay, long transitionDuration, TimeInterpolator transitionInterpolator) {
this.parent = parentToInvalidate;
this.transitionDelay = transitionDelay;
this.transitionDuration = transitionDuration;
this.transitionInterpolator = transitionInterpolator;
this.firstSet = true;
}
public AnimatedColor(Runnable invalidate) {
this.invalidate = invalidate;
this.firstSet = true;
}
public AnimatedColor(Runnable invalidate, long transitionDuration, TimeInterpolator transitionInterpolator) {
this.invalidate = invalidate;
this.transitionDuration = transitionDuration;
this.transitionInterpolator = transitionInterpolator;
this.firstSet = true;
}
public AnimatedColor(int initialValue, View parentToInvalidate) {
this.parent = parentToInvalidate;
this.value = targetValue = initialValue;
this.firstSet = false;
}
public AnimatedColor(int initialValue, Runnable invalidate) {
this.invalidate = invalidate;
this.value = targetValue = initialValue;
this.firstSet = false;
}
public AnimatedColor(int initialValue, View parentToInvalidate, long transitionDelay, long transitionDuration, TimeInterpolator transitionInterpolator) {
this.parent = parentToInvalidate;
this.value = targetValue = initialValue;
this.transitionDelay = transitionDelay;
this.transitionDuration = transitionDuration;
this.transitionInterpolator = transitionInterpolator;
this.firstSet = false;
}
public AnimatedColor(int initialValue, Runnable invalidate, long transitionDelay, long transitionDuration, TimeInterpolator transitionInterpolator) {
this.invalidate = invalidate;
this.value = targetValue = initialValue;
this.transitionDelay = transitionDelay;
this.transitionDuration = transitionDuration;
this.transitionInterpolator = transitionInterpolator;
this.firstSet = false;
}
public int get() {
return value;
}
// set() must be called inside onDraw/dispatchDraw
// the main purpose of AnimatedColor is to interpolate between abrupt changing states
public int set(int mustBeColor) {
return this.set(mustBeColor, false);
}
public int set(int mustBeColor, boolean force) {
final long now = SystemClock.elapsedRealtime();
if (force || transitionDuration <= 0 || firstSet) {
value = targetValue = mustBeColor;
transition = false;
firstSet = false;
} else if (targetValue != mustBeColor) {
transition = true;
targetValue = mustBeColor;
startValue = value;
transitionStart = now;
}
if (transition) {
final float t = MathUtils.clamp((now - transitionStart - transitionDelay) / (float) transitionDuration, 0, 1);
if (now - transitionStart >= transitionDelay) {
if (transitionInterpolator == null) {
value = ColorUtils.blendARGB(startValue, targetValue, t);
} else {
value = ColorUtils.blendARGB(startValue, targetValue, transitionInterpolator.getInterpolation(t));
}
}
if (t >= 1f) {
transition = false;
} else {
if (parent != null) {
parent.invalidate();
}
if (invalidate != null) {
invalidate.run();
}
}
}
return value;
}
public float getTransitionProgress() {
if (!transition) {
return 0;
}
final long now = SystemClock.elapsedRealtime();
return MathUtils.clamp((now - transitionStart - transitionDelay) / (float) transitionDuration, 0, 1);
}
public float getTransitionProgressInterpolated() {
if (transitionInterpolator != null) {
return transitionInterpolator.getInterpolation(getTransitionProgress());
} else {
return getTransitionProgress();
}
}
public void setParent(View parent) {
this.parent = parent;
}
}

View file

@ -38,6 +38,7 @@ import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.NativeByteBuffer; import org.telegram.tgnet.NativeByteBuffer;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.Premium.PremiumLockIconView;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -687,6 +688,28 @@ public class AnimatedEmojiDrawable extends Drawable {
return imageReceiver; return imageReceiver;
} }
private static HashMap<Long, Integer> dominantColors;
public static int getDominantColor(AnimatedEmojiDrawable yourDrawable) {
if (yourDrawable == null) {
return 0;
}
long documentId = yourDrawable.getDocumentId();
if (documentId == 0) {
return 0;
}
if (dominantColors == null) {
dominantColors = new HashMap<>();
}
Integer color = dominantColors.get(documentId);
if (color == null) {
if (yourDrawable.getImageReceiver() != null && yourDrawable.getImageReceiver().getBitmap() != null) {
dominantColors.put(documentId, color = PremiumLockIconView.getDominantColor(yourDrawable.getImageReceiver().getBitmap()));
}
}
return color == null ? 0 : color;
}
public static class WrapSizeDrawable extends Drawable { public static class WrapSizeDrawable extends Drawable {
private Drawable drawable; private Drawable drawable;

View file

@ -34,6 +34,7 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
private float scale; private float scale;
public boolean standard; public boolean standard;
public boolean full = false; public boolean full = false;
public boolean top = false;
private Paint.FontMetricsInt fontMetrics; private Paint.FontMetricsInt fontMetrics;
private float size = AndroidUtilities.dp(20); private float size = AndroidUtilities.dp(20);
@ -101,6 +102,10 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
@Override @Override
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
if (fm == null && top) {
fm = paint.getFontMetricsInt();
}
int ascent = fm == null ? 0 : fm.ascent, descent = fm == null ? 0 : fm.descent;
if (fontMetrics == null) { if (fontMetrics == null) {
int sz = (int) size; int sz = (int) size;
@ -137,6 +142,11 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
} }
} }
} }
if (fm != null && top) {
int diff = ((ascent - fm.ascent) + (descent - fm.descent)) / 2;
fm.ascent += diff;
fm.descent -= diff;
}
return measuredSize - 1; return measuredSize - 1;
} }
@ -221,7 +231,7 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
public SpansChunk spansChunk; public SpansChunk spansChunk;
public boolean insideSpoiler; public boolean insideSpoiler;
ImageReceiver.BackgroundThreadDrawHolder backgroundDrawHolder; private ImageReceiver.BackgroundThreadDrawHolder[] backgroundDrawHolder = new ImageReceiver.BackgroundThreadDrawHolder[DrawingInBackgroundThreadDrawable.THREAD_COUNT];
public AnimatedEmojiHolder(View view, boolean invalidateInParent) { public AnimatedEmojiHolder(View view, boolean invalidateInParent) {
this.view = view; this.view = view;
@ -232,7 +242,7 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
return drawableBounds.bottom < boundTop || drawableBounds.top > boundBottom; return drawableBounds.bottom < boundTop || drawableBounds.top > boundBottom;
} }
public void prepareForBackgroundDraw(long updateTime) { public void prepareForBackgroundDraw(long updateTime, int threadIndex) {
if (drawable == null) { if (drawable == null) {
return; return;
} }
@ -245,16 +255,16 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
} }
imageReceiver.setAlpha(alpha); imageReceiver.setAlpha(alpha);
imageReceiver.setImageCoords(drawableBounds); imageReceiver.setImageCoords(drawableBounds);
backgroundDrawHolder = imageReceiver.setDrawInBackgroundThread(backgroundDrawHolder); backgroundDrawHolder[threadIndex] = imageReceiver.setDrawInBackgroundThread(backgroundDrawHolder[threadIndex], threadIndex);
backgroundDrawHolder.overrideAlpha = alpha; backgroundDrawHolder[threadIndex].overrideAlpha = alpha;
backgroundDrawHolder.setBounds(drawableBounds); backgroundDrawHolder[threadIndex].setBounds(drawableBounds);
backgroundDrawHolder.time = updateTime; backgroundDrawHolder[threadIndex].time = updateTime;
} }
} }
public void releaseDrawInBackground() { public void releaseDrawInBackground(int threadIndex) {
if (backgroundDrawHolder != null) { if (backgroundDrawHolder[threadIndex] != null) {
backgroundDrawHolder.release(); backgroundDrawHolder[threadIndex].release();
} }
} }
@ -667,8 +677,8 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
public void drawInBackground(Canvas canvas) { public void drawInBackground(Canvas canvas) {
for (int i = 0; i < backgroundHolders.size(); i++) { for (int i = 0; i < backgroundHolders.size(); i++) {
AnimatedEmojiHolder holder = backgroundHolders.get(i); AnimatedEmojiHolder holder = backgroundHolders.get(i);
if (holder != null && holder.backgroundDrawHolder != null) { if (holder != null && holder.backgroundDrawHolder[threadIndex] != null) {
holder.drawable.draw(canvas, holder.backgroundDrawHolder, true); holder.drawable.draw(canvas, holder.backgroundDrawHolder[threadIndex], true);
} }
} }
} }
@ -695,9 +705,7 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
backgroundHolders.remove(i--); backgroundHolders.remove(i--);
continue; continue;
} }
if (holder != null) { holder.prepareForBackgroundDraw(time, threadIndex);
holder.prepareForBackgroundDraw(time);
}
} }
} }
@ -705,7 +713,7 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
public void onFrameReady() { public void onFrameReady() {
for (int i = 0; i < backgroundHolders.size(); i++) { for (int i = 0; i < backgroundHolders.size(); i++) {
if (backgroundHolders.get(i) != null) { if (backgroundHolders.get(i) != null) {
backgroundHolders.get(i).releaseDrawInBackground(); backgroundHolders.get(i).releaseDrawInBackground(threadIndex);
} }
} }
backgroundHolders.clear(); backgroundHolders.clear();

View file

@ -28,6 +28,7 @@ import android.view.View;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.AnimatedFileDrawableStream; import org.telegram.messenger.AnimatedFileDrawableStream;
import org.telegram.messenger.DispatchQueue; import org.telegram.messenger.DispatchQueue;
import org.telegram.messenger.DispatchQueuePoolBackground;
import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLocation; import org.telegram.messenger.ImageLocation;
@ -109,16 +110,16 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
private RectF actualDrawRect = new RectF(); private RectF actualDrawRect = new RectF();
private BitmapShader renderingShader; private BitmapShader[] renderingShader = new BitmapShader[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private BitmapShader nextRenderingShader; private BitmapShader[] nextRenderingShader = new BitmapShader[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private BitmapShader backgroundShader; private BitmapShader[] backgroundShader = new BitmapShader[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private BitmapShader renderingShaderBackgroundDraw; private BitmapShader renderingShaderBackgroundDraw;
private int[] roundRadius = new int[4]; private int[] roundRadius = new int[4];
private int[] roundRadiusBackup; private int[] roundRadiusBackup;
private Matrix shaderMatrix = new Matrix(); private Matrix[] shaderMatrix = new Matrix[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private Path roundPath = new Path(); private Path[] roundPath = new Path[1 + DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private static float[] radii = new float[8]; private static float[] radii = new float[8];
private Matrix shaderMatrixBackgroundDraw; private Matrix shaderMatrixBackgroundDraw;
@ -139,8 +140,10 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
private float scaleFactor = 1f; private float scaleFactor = 1f;
public boolean isWebmSticker; public boolean isWebmSticker;
private final TLRPC.Document document; private final TLRPC.Document document;
private RectF dstRectBackground; private RectF[] dstRectBackground = new RectF[DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private Paint backgroundPaint; private Paint[] backgroundPaint = new Paint[DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private Matrix[] shaderMatrixBackground = new Matrix[DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private Path[] roundPathBackground = new Path[DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private View parentView; private View parentView;
private ArrayList<View> secondParentViews = new ArrayList<>(); private ArrayList<View> secondParentViews = new ArrayList<>();
@ -175,16 +178,21 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
private Runnable uiRunnableGenerateCache = new Runnable() { private Runnable uiRunnableGenerateCache = new Runnable() {
@Override @Override
public void run() { public void run() {
if (!isRecycled && !destroyWhenDone && !generatingCache) { if (!isRecycled && !destroyWhenDone && !generatingCache && cacheGenRunnable == null) {
startTime = System.currentTimeMillis(); startTime = System.currentTimeMillis();
if (RLottieDrawable.lottieCacheGenerateQueue == null) { if (RLottieDrawable.lottieCacheGenerateQueue == null) {
RLottieDrawable.createCacheGenQueue(); RLottieDrawable.createCacheGenQueue();
} }
generatingCache = true; generatingCache = true;
loadFrameTask = null; loadFrameTask = null;
BitmapsCache.incrementTaskCounter();
RLottieDrawable.lottieCacheGenerateQueue.postRunnable(cacheGenRunnable = () -> { RLottieDrawable.lottieCacheGenerateQueue.postRunnable(cacheGenRunnable = () -> {
bitmapsCache.createCache(); bitmapsCache.createCache();
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
if (cacheGenRunnable != null) {
BitmapsCache.decrementTaskCounter();
cacheGenRunnable = null;
}
generatingCache = false; generatingCache = false;
scheduleNextGetFrame(); scheduleNextGetFrame();
}); });
@ -241,7 +249,10 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
loadFrameTask = null; loadFrameTask = null;
nextRenderingBitmap = backgroundBitmap; nextRenderingBitmap = backgroundBitmap;
nextRenderingBitmapTime = backgroundBitmapTime; nextRenderingBitmapTime = backgroundBitmapTime;
nextRenderingShader = backgroundShader; for (int i = 0; i < backgroundShader.length; i++) {
nextRenderingShader[i] = backgroundShader[i];
}
if (isRestarted) { if (isRestarted) {
isRestarted = false; isRestarted = false;
repeatCount++; repeatCount++;
@ -342,8 +353,8 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
} catch (Throwable e) { } catch (Throwable e) {
FileLog.e(e); FileLog.e(e);
} }
if (backgroundShader == null && backgroundBitmap != null && hasRoundRadius()) { if (backgroundShader[0] == null && backgroundBitmap != null && hasRoundRadius()) {
backgroundShader = new BitmapShader(backgroundBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); backgroundShader[0] = new BitmapShader(backgroundBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
} }
} }
boolean seekWas = false; boolean seekWas = false;
@ -508,6 +519,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
} }
private Runnable cancelCache; private Runnable cancelCache;
public void checkCacheCancel() { public void checkCacheCancel() {
if (bitmapsCache == null) { if (bitmapsCache == null) {
return; return;
@ -591,7 +603,9 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
isRunning = false; isRunning = false;
isRecycled = true; isRecycled = true;
if (cacheGenRunnable != null) { if (cacheGenRunnable != null) {
BitmapsCache.decrementTaskCounter();
RLottieDrawable.lottieCacheGenerateQueue.cancelRunnable(cacheGenRunnable); RLottieDrawable.lottieCacheGenerateQueue.cancelRunnable(cacheGenRunnable);
cacheGenRunnable = null;
} }
if (loadFrameTask == null) { if (loadFrameTask == null) {
if (nativePtr != 0) { if (nativePtr != 0) {
@ -690,7 +704,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
} }
private void scheduleNextGetFrame() { private void scheduleNextGetFrame() {
if (loadFrameTask != null || !canLoadFrames() || destroyWhenDone || !isRunning && (!decodeSingleFrame || decodeSingleFrame && singleFrameDecoded) || parents.size() == 0 && !ignoreNoParent || generatingCache) { if (loadFrameTask != null || nextRenderingBitmap != null || !canLoadFrames() || destroyWhenDone || !isRunning && (!decodeSingleFrame || decodeSingleFrame && singleFrameDecoded) || parents.size() == 0 && !ignoreNoParent || generatingCache) {
return; return;
} }
long ms = 0; long ms = 0;
@ -698,7 +712,11 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
ms = Math.min(invalidateAfter, Math.max(0, invalidateAfter - (System.currentTimeMillis() - lastFrameDecodeTime))); ms = Math.min(invalidateAfter, Math.max(0, invalidateAfter - (System.currentTimeMillis() - lastFrameDecodeTime)));
} }
if (useSharedQueue) { if (useSharedQueue) {
executor.schedule(loadFrameTask = loadFrameRunnable, ms, TimeUnit.MILLISECONDS); if (limitFps) {
DispatchQueuePoolBackground.execute(loadFrameTask = loadFrameRunnable);
} else {
executor.schedule(loadFrameTask = loadFrameRunnable, ms, TimeUnit.MILLISECONDS);
}
} else { } else {
if (decodeQueue == null) { if (decodeQueue == null) {
decodeQueue = new DispatchQueue("decodeQueue" + this); decodeQueue = new DispatchQueue("decodeQueue" + this);
@ -751,22 +769,22 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
@Override @Override
public void draw(Canvas canvas) { public void draw(Canvas canvas) {
drawInternal(canvas, false, System.currentTimeMillis()); drawInternal(canvas, false, System.currentTimeMillis(), 0);
} }
public void drawInBackground(Canvas canvas, float x, float y, float w, float h, int alpha, ColorFilter colorFilter) { public void drawInBackground(Canvas canvas, float x, float y, float w, float h, int alpha, ColorFilter colorFilter, int threadIndex) {
if (dstRectBackground == null) { if (dstRectBackground[threadIndex] == null) {
dstRectBackground = new RectF(); dstRectBackground[threadIndex] = new RectF();
backgroundPaint = new Paint(); backgroundPaint[threadIndex] = new Paint();
backgroundPaint.setFilterBitmap(true); backgroundPaint[threadIndex].setFilterBitmap(true);
} }
backgroundPaint.setAlpha(alpha); backgroundPaint[threadIndex].setAlpha(alpha);
backgroundPaint.setColorFilter(colorFilter); backgroundPaint[threadIndex].setColorFilter(colorFilter);
dstRectBackground.set(x, y, x + w, y + h); dstRectBackground[threadIndex].set(x, y, x + w, y + h);
drawInternal(canvas, true, 0); drawInternal(canvas, true, 0, threadIndex);
} }
public void drawInternal(Canvas canvas, boolean drawInBackground, long currentTime) { public void drawInternal(Canvas canvas, boolean drawInBackground, long currentTime, int threadIndex) {
if (!canLoadFrames() || destroyWhenDone) { if (!canLoadFrames() || destroyWhenDone) {
return; return;
} }
@ -775,8 +793,8 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
currentTime = System.currentTimeMillis(); currentTime = System.currentTimeMillis();
} }
RectF rect = drawInBackground ? dstRectBackground : dstRect; RectF rect = drawInBackground ? dstRectBackground[threadIndex] : dstRect;
Paint paint = drawInBackground ? backgroundPaint : getPaint(); Paint paint = drawInBackground ? backgroundPaint[threadIndex] : getPaint();
if (!drawInBackground) { if (!drawInBackground) {
updateCurrentFrame(currentTime, false); updateCurrentFrame(currentTime, false);
@ -809,36 +827,47 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
applyTransformation = false; applyTransformation = false;
} }
if (hasRoundRadius()) { if (hasRoundRadius()) {
if (renderingShader == null) { int index = drawInBackground ? threadIndex + 1 : 0;
renderingShader = new BitmapShader(renderingBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); if (renderingShader[index] == null) {
renderingShader[index] = new BitmapShader(renderingBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
} }
paint.setShader(renderingShader); paint.setShader(renderingShader[index]);
shaderMatrix.reset(); Matrix matrix = shaderMatrix[index];
shaderMatrix.setTranslate(rect.left, rect.top); if (matrix == null) {
matrix = shaderMatrix[index] = new Matrix();
}
Path path = roundPath[index];
if (path == null) {
path = roundPath[index] = new Path();
}
matrix.reset();
matrix.setTranslate(rect.left, rect.top);
if (metaData[2] == 90) { if (metaData[2] == 90) {
shaderMatrix.preRotate(90); matrix.preRotate(90);
shaderMatrix.preTranslate(0, -rect.width()); matrix.preTranslate(0, -rect.width());
} else if (metaData[2] == 180) { } else if (metaData[2] == 180) {
shaderMatrix.preRotate(180); matrix.preRotate(180);
shaderMatrix.preTranslate(-rect.width(), -rect.height()); matrix.preTranslate(-rect.width(), -rect.height());
} else if (metaData[2] == 270) { } else if (metaData[2] == 270) {
shaderMatrix.preRotate(270); matrix.preRotate(270);
shaderMatrix.preTranslate(-rect.height(), 0); matrix.preTranslate(-rect.height(), 0);
} }
shaderMatrix.preScale(scaleX, scaleY); matrix.preScale(scaleX, scaleY);
renderingShader.setLocalMatrix(shaderMatrix); renderingShader[index].setLocalMatrix(matrix);
if (invalidatePath) { if (invalidatePath || drawInBackground) {
invalidatePath = false; if (!drawInBackground) {
invalidatePath = false;
}
for (int a = 0; a < roundRadius.length; a++) { for (int a = 0; a < roundRadius.length; a++) {
radii[a * 2] = roundRadius[a]; radii[a * 2] = roundRadius[a];
radii[a * 2 + 1] = roundRadius[a]; radii[a * 2 + 1] = roundRadius[a];
} }
roundPath.reset(); path.reset();
roundPath.addRoundRect(drawInBackground ? rect : actualDrawRect, radii, Path.Direction.CW); path.addRoundRect(drawInBackground ? rect : actualDrawRect, radii, Path.Direction.CW);
roundPath.close(); path.close();
} }
canvas.drawPath(roundPath, paint); canvas.drawPath(path, paint);
} else { } else {
canvas.translate(rect.left, rect.top); canvas.translate(rect.left, rect.top);
if (metaData[2] == 90) { if (metaData[2] == 90) {
@ -1086,28 +1115,43 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
if (renderingBitmap == null && nextRenderingBitmap == null) { if (renderingBitmap == null && nextRenderingBitmap == null) {
scheduleNextGetFrame(); scheduleNextGetFrame();
} else if (nextRenderingBitmap != null && (renderingBitmap == null || (Math.abs(now - lastFrameTime) >= invalidateAfter && !skipFrameUpdate))) { } else if (nextRenderingBitmap != null && (renderingBitmap == null || (Math.abs(now - lastFrameTime) >= invalidateAfter && !skipFrameUpdate))) {
if (precache) { //if (precache) {
backgroundBitmap = renderingBitmap; backgroundBitmap = renderingBitmap;
} // }
renderingBitmap = nextRenderingBitmap; renderingBitmap = nextRenderingBitmap;
renderingBitmapTime = nextRenderingBitmapTime; renderingBitmapTime = nextRenderingBitmapTime;
renderingShader = nextRenderingShader; for (int i = 0; i < backgroundShader.length; i++) {
// if (precache) {
backgroundShader[i] = renderingShader[i];
// }
renderingShader[i] = nextRenderingShader[i];
nextRenderingShader[i] = null;
}
nextRenderingBitmap = null; nextRenderingBitmap = null;
nextRenderingBitmapTime = 0; nextRenderingBitmapTime = 0;
nextRenderingShader = null;
lastFrameTime = now; lastFrameTime = now;
scheduleNextGetFrame();
} else {
invalidateInternal();
} }
} else if (!isRunning && decodeSingleFrame && Math.abs(now - lastFrameTime) >= invalidateAfter && nextRenderingBitmap != null) { } else if (!isRunning && decodeSingleFrame && Math.abs(now - lastFrameTime) >= invalidateAfter && nextRenderingBitmap != null) {
if (precache) { // if (precache) {
backgroundBitmap = renderingBitmap; backgroundBitmap = renderingBitmap;
} // }
renderingBitmap = nextRenderingBitmap; renderingBitmap = nextRenderingBitmap;
renderingBitmapTime = nextRenderingBitmapTime; renderingBitmapTime = nextRenderingBitmapTime;
renderingShader = nextRenderingShader; for (int i = 0; i < backgroundShader.length; i++) {
// if (precache) {
backgroundShader[i] = renderingShader[i];
// }
renderingShader[i] = nextRenderingShader[i];
nextRenderingShader[i] = null;
}
nextRenderingBitmap = null; nextRenderingBitmap = null;
nextRenderingBitmapTime = 0; nextRenderingBitmapTime = 0;
nextRenderingShader = null;
lastFrameTime = now; lastFrameTime = now;
scheduleNextGetFrame();
} }
} }
} }

View file

@ -50,6 +50,10 @@ import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.core.content.FileProvider; import androidx.core.content.FileProvider;
import androidx.core.graphics.ColorUtils;
import androidx.dynamicanimation.animation.FloatValueHolder;
import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.dynamicanimation.animation.SpringForce;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -139,6 +143,7 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
private ActionBarMenuItem searchItem; private ActionBarMenuItem searchItem;
private boolean blurredAnimationInProgress; private boolean blurredAnimationInProgress;
private View[] buttons = new View[5]; private View[] buttons = new View[5];
private SpringAnimation seekBarBufferSpring;
private boolean draggingSeekBar; private boolean draggingSeekBar;
@ -175,6 +180,8 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
long lastRewindingTime; long lastRewindingTime;
long lastUpdateRewindingPlayerTime; long lastUpdateRewindingPlayerTime;
private boolean wasLight;
private final static int menu_speed_slow = 1; private final static int menu_speed_slow = 1;
private final static int menu_speed_normal = 2; private final static int menu_speed_normal = 2;
private final static int menu_speed_fast = 3; private final static int menu_speed_fast = 3;
@ -273,18 +280,15 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
lastMeasturedHeight = totalHeight; lastMeasturedHeight = totalHeight;
} }
ignoreLayout = true; ignoreLayout = true;
if (Build.VERSION.SDK_INT >= 21 && !isFullscreen) {
setPadding(backgroundPaddingLeft, AndroidUtilities.statusBarHeight, backgroundPaddingLeft, 0);
}
playerLayout.setVisibility(searchWas || keyboardVisible ? INVISIBLE : VISIBLE); playerLayout.setVisibility(searchWas || keyboardVisible ? INVISIBLE : VISIBLE);
playerShadow.setVisibility(playerLayout.getVisibility()); playerShadow.setVisibility(playerLayout.getVisibility());
int availableHeight = totalHeight - getPaddingTop(); int availableHeight = totalHeight - getPaddingTop();
LayoutParams layoutParams = (LayoutParams) listView.getLayoutParams(); LayoutParams layoutParams = (LayoutParams) listView.getLayoutParams();
layoutParams.topMargin = ActionBar.getCurrentActionBarHeight(); layoutParams.topMargin = ActionBar.getCurrentActionBarHeight() + AndroidUtilities.statusBarHeight;
layoutParams = (LayoutParams) actionBarShadow.getLayoutParams(); layoutParams = (LayoutParams) actionBarShadow.getLayoutParams();
layoutParams.topMargin = ActionBar.getCurrentActionBarHeight(); layoutParams.topMargin = ActionBar.getCurrentActionBarHeight() + AndroidUtilities.statusBarHeight;
layoutParams = (LayoutParams) blurredView.getLayoutParams(); layoutParams = (LayoutParams) blurredView.getLayoutParams();
layoutParams.topMargin = -getPaddingTop(); layoutParams.topMargin = -getPaddingTop();
@ -397,11 +401,6 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
Theme.dialogs_onlineCirclePaint.setAlpha((int) (alpha * alphaProgress * rad)); Theme.dialogs_onlineCirclePaint.setAlpha((int) (alpha * alphaProgress * rad));
canvas.drawRoundRect(rect, AndroidUtilities.dp(2), AndroidUtilities.dp(2), Theme.dialogs_onlineCirclePaint); canvas.drawRoundRect(rect, AndroidUtilities.dp(2), AndroidUtilities.dp(2), Theme.dialogs_onlineCirclePaint);
} }
int color1 = getThemedColor(Theme.key_dialogBackground);
int finalColor = Color.argb((int) (255 * actionBar.getAlpha()), (int) (Color.red(color1) * 0.8f), (int) (Color.green(color1) * 0.8f), (int) (Color.blue(color1) * 0.8f));
Theme.dialogs_onlineCirclePaint.setColor(finalColor);
canvas.drawRect(backgroundPaddingLeft, 0, getMeasuredWidth() - backgroundPaddingLeft, AndroidUtilities.statusBarHeight, Theme.dialogs_onlineCirclePaint);
} }
} }
@ -439,7 +438,7 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
actionBar.setTitleColor(getThemedColor(Theme.key_player_actionBarTitle)); actionBar.setTitleColor(getThemedColor(Theme.key_player_actionBarTitle));
actionBar.setTitle(LocaleController.getString("AttachMusic", R.string.AttachMusic)); actionBar.setTitle(LocaleController.getString("AttachMusic", R.string.AttachMusic));
actionBar.setSubtitleColor(getThemedColor(Theme.key_player_actionBarSubtitle)); actionBar.setSubtitleColor(getThemedColor(Theme.key_player_actionBarSubtitle));
actionBar.setOccupyStatusBar(false); actionBar.setOccupyStatusBar(true);
actionBar.setAlpha(0.0f); actionBar.setAlpha(0.0f);
if (messageObject != null && !MediaController.getInstance().currentPlaylistIsGlobalSearch()) { if (messageObject != null && !MediaController.getInstance().currentPlaylistIsGlobalSearch()) {
@ -648,6 +647,12 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
seekBarView.setReportChanges(true); seekBarView.setReportChanges(true);
playerLayout.addView(seekBarView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 38, Gravity.TOP | Gravity.LEFT, 5, 70, 5, 0)); playerLayout.addView(seekBarView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 38, Gravity.TOP | Gravity.LEFT, 5, 70, 5, 0));
seekBarBufferSpring = new SpringAnimation(new FloatValueHolder(0))
.setSpring(new SpringForce()
.setStiffness(750f)
.setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY))
.addUpdateListener((animation, value, velocity) -> seekBarView.setBufferedProgress(value / 1000f));
progressView = new LineProgressView(context); progressView = new LineProgressView(context);
progressView.setVisibility(View.INVISIBLE); progressView.setVisibility(View.INVISIBLE);
progressView.setBackgroundColor(getThemedColor(Theme.key_player_progressBackground)); progressView.setBackgroundColor(getThemedColor(Theme.key_player_progressBackground));
@ -1656,7 +1661,8 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
} }
} }
if (bufferedProgress != -1) { if (bufferedProgress != -1) {
seekBarView.setBufferedProgress(bufferedProgress); seekBarBufferSpring.getSpring().setFinalPosition(bufferedProgress * 1000);
seekBarBufferSpring.start();
} }
} }
} }
@ -1706,11 +1712,30 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
actionBarAnimation.start(); actionBarAnimation.start();
} }
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams();
newOffset += layoutParams.topMargin - AndroidUtilities.dp(11); newOffset += layoutParams.topMargin - AndroidUtilities.statusBarHeight - AndroidUtilities.dp(11);
if (scrollOffsetY != newOffset) { if (scrollOffsetY != newOffset) {
listView.setTopGlowOffset((scrollOffsetY = newOffset) - layoutParams.topMargin); listView.setTopGlowOffset((scrollOffsetY = newOffset) - layoutParams.topMargin - AndroidUtilities.statusBarHeight);
containerView.invalidate(); containerView.invalidate();
} }
int offset = AndroidUtilities.dp(13);
top = scrollOffsetY - backgroundPaddingTop - offset;
if (currentSheetAnimationType == 1) {
top += listView.getTranslationY();
}
float rad = 1.0f;
if (top + backgroundPaddingTop < ActionBar.getCurrentActionBarHeight()) {
float toMove = offset + AndroidUtilities.dp(11 - 7);
float moveProgress = Math.min(1.0f, (ActionBar.getCurrentActionBarHeight() - top - backgroundPaddingTop) / toMove);
rad = 1.0f - moveProgress;
}
boolean light = rad <= 0.5f && ColorUtils.calculateLuminance(getThemedColor(Theme.key_dialogBackground)) > 0.7f;
if (light != wasLight) {
AndroidUtilities.setLightStatusBar(getWindow(), wasLight = light);
}
} }
@Override @Override
@ -1841,7 +1866,8 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
} }
} }
if (bufferedProgress != -1) { if (bufferedProgress != -1) {
seekBarView.setBufferedProgress(bufferedProgress); seekBarBufferSpring.getSpring().setFinalPosition(bufferedProgress * 1000);
seekBarBufferSpring.start();
} }
if (updateRewinding) { if (updateRewinding) {
newTime = (int) (messageObject.getDuration() * seekBarView.getProgress()); newTime = (int) (messageObject.getDuration() * seekBarView.getProgress());

View file

@ -10,9 +10,11 @@ package org.telegram.ui.Components;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.ColorFilter; import android.graphics.ColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.PixelFormat; import android.graphics.PixelFormat;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.text.Layout; import android.text.Layout;
@ -32,7 +34,8 @@ import org.telegram.ui.ActionBar.Theme;
public class AvatarDrawable extends Drawable { public class AvatarDrawable extends Drawable {
private TextPaint namePaint; private TextPaint namePaint;
private int color; private boolean hasGradient;
private int color, color2;
private boolean needApplyColorAccent; private boolean needApplyColorAccent;
private StaticLayout textLayout; private StaticLayout textLayout;
private float textWidth; private float textWidth;
@ -46,6 +49,14 @@ public class AvatarDrawable extends Drawable {
private StringBuilder stringBuilder = new StringBuilder(5); private StringBuilder stringBuilder = new StringBuilder(5);
private int roundRadius = -1; private int roundRadius = -1;
private int gradientTop, gradientBottom;
private int gradientColor1, gradientColor2;
private LinearGradient gradient;
private int gradientTop2, gradientBottom2;
private int gradientColor21, gradientColor22;
private LinearGradient gradient2;
public static final int AVATAR_TYPE_NORMAL = 0; public static final int AVATAR_TYPE_NORMAL = 0;
public static final int AVATAR_TYPE_SAVED = 1; public static final int AVATAR_TYPE_SAVED = 1;
public static final int AVATAR_TYPE_ARCHIVED = 2; public static final int AVATAR_TYPE_ARCHIVED = 2;
@ -106,7 +117,7 @@ public class AvatarDrawable extends Drawable {
isProfile = value; isProfile = value;
} }
private static int getColorIndex(long id) { public static int getColorIndex(long id) {
if (id >= 0 && id < 7) { if (id >= 0 && id < 7) {
return (int) id; return (int) id;
} }
@ -165,33 +176,55 @@ public class AvatarDrawable extends Drawable {
public void setAvatarType(int value) { public void setAvatarType(int value) {
avatarType = value; avatarType = value;
if (avatarType == AVATAR_TYPE_REGISTER) { if (avatarType == AVATAR_TYPE_REGISTER) {
color = Theme.getColor(Theme.key_chats_actionBackground); hasGradient = false;
color = color2 = Theme.getColor(Theme.key_chats_actionBackground);
} else if (avatarType == AVATAR_TYPE_ARCHIVED) { } else if (avatarType == AVATAR_TYPE_ARCHIVED) {
color = getThemedColor(Theme.key_avatar_backgroundArchivedHidden); hasGradient = false;
color = color2 = getThemedColor(Theme.key_avatar_backgroundArchivedHidden);
} else if (avatarType == AVATAR_TYPE_REPLIES) { } else if (avatarType == AVATAR_TYPE_REPLIES) {
hasGradient = true;
color = getThemedColor(Theme.key_avatar_backgroundSaved); color = getThemedColor(Theme.key_avatar_backgroundSaved);
color2 = getThemedColor(Theme.key_avatar_background2Saved);
} else if (avatarType == AVATAR_TYPE_SAVED) { } else if (avatarType == AVATAR_TYPE_SAVED) {
hasGradient = true;
color = getThemedColor(Theme.key_avatar_backgroundSaved); color = getThemedColor(Theme.key_avatar_backgroundSaved);
color2 = getThemedColor(Theme.key_avatar_background2Saved);
} else if (avatarType == AVATAR_TYPE_SHARES) { } else if (avatarType == AVATAR_TYPE_SHARES) {
hasGradient = true;
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(5)]); color = getThemedColor(Theme.keys_avatar_background[getColorIndex(5)]);
color2 = getThemedColor(Theme.keys_avatar_background2[getColorIndex(5)]);
} else if (avatarType == AVATAR_TYPE_FILTER_CONTACTS) {
hasGradient = true;
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(5)]);
color2 = getThemedColor(Theme.keys_avatar_background2[getColorIndex(5)]);
} else if (avatarType == AVATAR_TYPE_FILTER_NON_CONTACTS) {
hasGradient = true;
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(4)]);
color2 = getThemedColor(Theme.keys_avatar_background2[getColorIndex(4)]);
} else if (avatarType == AVATAR_TYPE_FILTER_GROUPS) {
hasGradient = true;
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(3)]);
color2 = getThemedColor(Theme.keys_avatar_background2[getColorIndex(3)]);
} else if (avatarType == AVATAR_TYPE_FILTER_CHANNELS) {
hasGradient = true;
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(1)]);
color2 = getThemedColor(Theme.keys_avatar_background2[getColorIndex(1)]);
} else if (avatarType == AVATAR_TYPE_FILTER_BOTS) {
hasGradient = true;
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(0)]);
color2 = getThemedColor(Theme.keys_avatar_background2[getColorIndex(0)]);
} else if (avatarType == AVATAR_TYPE_FILTER_MUTED) {
hasGradient = true;
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(6)]);
color2 = getThemedColor(Theme.keys_avatar_background2[getColorIndex(6)]);
} else if (avatarType == AVATAR_TYPE_FILTER_READ) {
hasGradient = true;
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(5)]);
color2 = getThemedColor(Theme.keys_avatar_background2[getColorIndex(5)]);
} else { } else {
if (avatarType == AVATAR_TYPE_FILTER_CONTACTS) { hasGradient = true;
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(5)]); color = getThemedColor(Theme.keys_avatar_background[getColorIndex(4)]);
} else if (avatarType == AVATAR_TYPE_FILTER_NON_CONTACTS) { color2 = getThemedColor(Theme.keys_avatar_background2[getColorIndex(4)]);
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(4)]);
} else if (avatarType == AVATAR_TYPE_FILTER_GROUPS) {
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(3)]);
} else if (avatarType == AVATAR_TYPE_FILTER_CHANNELS) {
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(1)]);
} else if (avatarType == AVATAR_TYPE_FILTER_BOTS) {
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(0)]);
} else if (avatarType == AVATAR_TYPE_FILTER_MUTED) {
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(6)]);
} else if (avatarType == AVATAR_TYPE_FILTER_READ) {
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(5)]);
} else {
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(4)]);
}
} }
needApplyColorAccent = avatarType != AVATAR_TYPE_ARCHIVED && avatarType != AVATAR_TYPE_SAVED && avatarType != AVATAR_TYPE_REPLIES; needApplyColorAccent = avatarType != AVATAR_TYPE_ARCHIVED && avatarType != AVATAR_TYPE_SAVED && avatarType != AVATAR_TYPE_REPLIES;
} }
@ -216,7 +249,15 @@ public class AvatarDrawable extends Drawable {
} }
public void setColor(int value) { public void setColor(int value) {
hasGradient = false;
color = color2 = value;
needApplyColorAccent = false;
}
public void setColor(int value, int value2) {
hasGradient = true;
color = value; color = value;
color2 = value2;
needApplyColorAccent = false; needApplyColorAccent = false;
} }
@ -232,8 +273,42 @@ public class AvatarDrawable extends Drawable {
return needApplyColorAccent ? Theme.changeColorAccent(color) : color; return needApplyColorAccent ? Theme.changeColorAccent(color) : color;
} }
public int getColor2() {
return needApplyColorAccent ? Theme.changeColorAccent(color2) : color2;
}
private String takeFirstCharacter(String text) {
StringBuilder sequence = new StringBuilder(16);
boolean isInJoin = false;
int codePoint;
for (int i = 0; i < text.length(); i = text.offsetByCodePoints(i, 1)) {
codePoint = text.codePointAt(i);
if (codePoint == 0x200D || codePoint == 0x1f1ea) {
isInJoin = true;
if (sequence.length() == 0)
continue;
} else {
if ((sequence.length() > 0) && (!isInJoin))
break;
isInJoin = false;
}
sequence.appendCodePoint(codePoint);
}
if (isInJoin) {
for (int i = sequence.length()-1; i >= 0; --i) {
if (sequence.charAt(i) == 0x200D)
sequence.deleteCharAt(i);
else
break;
}
}
return sequence.toString();
}
public void setInfo(long id, String firstName, String lastName, String custom) { public void setInfo(long id, String firstName, String lastName, String custom) {
hasGradient = true;
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(id)]); color = getThemedColor(Theme.keys_avatar_background[getColorIndex(id)]);
color2 = getThemedColor(Theme.keys_avatar_background2[getColorIndex(id)]);
needApplyColorAccent = id == 5; // Tinting manually set blue color needApplyColorAccent = id == 5; // Tinting manually set blue color
avatarType = AVATAR_TYPE_NORMAL; avatarType = AVATAR_TYPE_NORMAL;
@ -249,28 +324,27 @@ public class AvatarDrawable extends Drawable {
stringBuilder.append(custom); stringBuilder.append(custom);
} else { } else {
if (firstName != null && firstName.length() > 0) { if (firstName != null && firstName.length() > 0) {
stringBuilder.appendCodePoint(firstName.codePointAt(0)); stringBuilder.append(takeFirstCharacter(firstName));
} }
if (lastName != null && lastName.length() > 0) { if (lastName != null && lastName.length() > 0) {
Integer lastch = null; String lastNameLastWord = lastName;
for (int a = lastName.length() - 1; a >= 0; a--) { int index;
if (lastch != null && lastName.charAt(a) == ' ') { if ((index = lastNameLastWord.lastIndexOf(' ')) >= 0) {
break; lastNameLastWord = lastNameLastWord.substring(index + 1);
}
lastch = lastName.codePointAt(a);
} }
if (Build.VERSION.SDK_INT > 17) { if (Build.VERSION.SDK_INT > 17) {
stringBuilder.append("\u200C"); stringBuilder.append("\u200C");
} }
stringBuilder.appendCodePoint(lastch); stringBuilder.append(takeFirstCharacter(lastNameLastWord));
} else if (firstName != null && firstName.length() > 0) { } else if (firstName != null && firstName.length() > 0) {
for (int a = firstName.length() - 1; a >= 0; a--) { for (int a = firstName.length() - 1; a >= 0; a--) {
if (firstName.charAt(a) == ' ') { if (firstName.charAt(a) == ' ') {
if (a != firstName.length() - 1 && firstName.charAt(a + 1) != ' ') { if (a != firstName.length() - 1 && firstName.charAt(a + 1) != ' ') {
int index = stringBuilder.length();
if (Build.VERSION.SDK_INT > 17) { if (Build.VERSION.SDK_INT > 17) {
stringBuilder.append("\u200C"); stringBuilder.append("\u200C");
} }
stringBuilder.appendCodePoint(firstName.codePointAt(a + 1)); stringBuilder.append(takeFirstCharacter(firstName.substring(index)));
break; break;
} }
} }
@ -304,7 +378,17 @@ public class AvatarDrawable extends Drawable {
} }
int size = bounds.width(); int size = bounds.width();
namePaint.setColor(ColorUtils.setAlphaComponent(getThemedColor(Theme.key_avatar_text), alpha)); namePaint.setColor(ColorUtils.setAlphaComponent(getThemedColor(Theme.key_avatar_text), alpha));
Theme.avatar_backgroundPaint.setColor(ColorUtils.setAlphaComponent(getColor(), alpha)); if (hasGradient) {
int color = ColorUtils.setAlphaComponent(getColor(), alpha);
int color2 = ColorUtils.setAlphaComponent(getColor2(), alpha);
if (gradient == null || gradientBottom != bounds.height() || gradientColor1 != color || gradientColor2 != color2) {
gradient = new LinearGradient(0, 0, 0, gradientBottom = bounds.height(), gradientColor1 = color, gradientColor2 = color2, Shader.TileMode.CLAMP);
}
Theme.avatar_backgroundPaint.setShader(gradient);
} else {
Theme.avatar_backgroundPaint.setShader(null);
Theme.avatar_backgroundPaint.setColor(ColorUtils.setAlphaComponent(getColor(), alpha));
}
canvas.save(); canvas.save();
canvas.translate(bounds.left, bounds.top); canvas.translate(bounds.left, bounds.top);
if (roundRadius > 0) { if (roundRadius > 0) {

View file

@ -30,7 +30,7 @@ import org.telegram.ui.Cells.GroupCallUserCell;
import java.util.Random; import java.util.Random;
public class AvatarsDarawable { public class AvatarsDrawable {
public final static int STYLE_GROUP_CALL_TOOLTIP = 10; public final static int STYLE_GROUP_CALL_TOOLTIP = 10;
public final static int STYLE_MESSAGE_SEEN = 11; public final static int STYLE_MESSAGE_SEEN = 11;
@ -198,9 +198,9 @@ public class AvatarsDarawable {
overrideSize = size; overrideSize = size;
} }
public void animateFromState(AvatarsDarawable avatarsDarawable, int currentAccount, boolean createAnimator) { public void animateFromState(AvatarsDrawable avatarsDrawable, int currentAccount, boolean createAnimator) {
if (avatarsDarawable.transitionProgressAnimator != null) { if (avatarsDrawable.transitionProgressAnimator != null) {
avatarsDarawable.transitionProgressAnimator.cancel(); avatarsDrawable.transitionProgressAnimator.cancel();
if (transitionInProgress) { if (transitionInProgress) {
transitionInProgress = false; transitionInProgress = false;
swapStates(); swapStates();
@ -209,7 +209,7 @@ public class AvatarsDarawable {
TLObject[] objects = new TLObject[3]; TLObject[] objects = new TLObject[3];
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
objects[i] = currentStates[i].object; objects[i] = currentStates[i].object;
setObject(i, currentAccount, avatarsDarawable.currentStates[i].object); setObject(i, currentAccount, avatarsDrawable.currentStates[i].object);
} }
commitTransition(false); commitTransition(false);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
@ -246,7 +246,7 @@ public class AvatarsDarawable {
Random random = new Random(); Random random = new Random();
public AvatarsDarawable(View parent, boolean inCall) { public AvatarsDrawable(View parent, boolean inCall) {
this.parent = parent; this.parent = parent;
for (int a = 0; a < 3; a++) { for (int a = 0; a < 3; a++) {
currentStates[a] = new DrawingState(); currentStates[a] = new DrawingState();

View file

@ -10,72 +10,72 @@ import org.telegram.tgnet.TLObject;
public class AvatarsImageView extends View { public class AvatarsImageView extends View {
public final AvatarsDarawable avatarsDarawable; public final AvatarsDrawable avatarsDrawable;
public AvatarsImageView(@NonNull Context context, boolean inCall) { public AvatarsImageView(@NonNull Context context, boolean inCall) {
super(context); super(context);
avatarsDarawable = new AvatarsDarawable(this, inCall); avatarsDrawable = new AvatarsDrawable(this, inCall);
} }
@Override @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec);
avatarsDarawable.width = getMeasuredWidth(); avatarsDrawable.width = getMeasuredWidth();
avatarsDarawable.height = getMeasuredHeight(); avatarsDrawable.height = getMeasuredHeight();
} }
@Override @Override
protected void onAttachedToWindow() { protected void onAttachedToWindow() {
super.onAttachedToWindow(); super.onAttachedToWindow();
avatarsDarawable.onAttachedToWindow(); avatarsDrawable.onAttachedToWindow();
} }
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw(Canvas canvas) {
super.onDraw(canvas); super.onDraw(canvas);
avatarsDarawable.onDraw(canvas); avatarsDrawable.onDraw(canvas);
} }
@Override @Override
protected void onDetachedFromWindow() { protected void onDetachedFromWindow() {
super.onDetachedFromWindow(); super.onDetachedFromWindow();
avatarsDarawable.onDetachedFromWindow(); avatarsDrawable.onDetachedFromWindow();
} }
public void setStyle(int style) { public void setStyle(int style) {
avatarsDarawable.setStyle(style); avatarsDrawable.setStyle(style);
} }
public void setDelegate(Runnable delegate) { public void setDelegate(Runnable delegate) {
avatarsDarawable.setDelegate(delegate); avatarsDrawable.setDelegate(delegate);
} }
public void setObject(int a, int currentAccount, TLObject object) { public void setObject(int a, int currentAccount, TLObject object) {
avatarsDarawable.setObject(a, currentAccount, object); avatarsDrawable.setObject(a, currentAccount, object);
} }
public void setAvatarsTextSize(int size) { public void setAvatarsTextSize(int size) {
avatarsDarawable.setAvatarsTextSize(size); avatarsDrawable.setAvatarsTextSize(size);
} }
public void reset() { public void reset() {
avatarsDarawable.reset(); avatarsDrawable.reset();
} }
public void setCount(int usersCount) { public void setCount(int usersCount) {
avatarsDarawable.setCount(usersCount); avatarsDrawable.setCount(usersCount);
} }
public void commitTransition(boolean animated) { public void commitTransition(boolean animated) {
avatarsDarawable.commitTransition(animated); avatarsDrawable.commitTransition(animated);
} }
public void updateAfterTransitionEnd() { public void updateAfterTransitionEnd() {
avatarsDarawable.updateAfterTransitionEnd(); avatarsDrawable.updateAfterTransitionEnd();
} }
public void setCentered(boolean centered) { public void setCentered(boolean centered) {
avatarsDarawable.setCentered(centered); avatarsDrawable.setCentered(centered);
} }
} }

View file

@ -1,6 +1,8 @@
package org.telegram.ui.Components; package org.telegram.ui.Components;
import android.content.Context; import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
@ -12,9 +14,12 @@ import android.view.WindowManager;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.core.content.ContextCompat;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ImageLocation; import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.UserObject; import org.telegram.messenger.UserObject;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
@ -23,7 +28,9 @@ import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.INavigationLayout; import org.telegram.ui.ActionBar.INavigationLayout;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ChatActivity; import org.telegram.ui.ChatActivity;
import org.telegram.ui.DialogsActivity;
import org.telegram.ui.ProfileActivity; import org.telegram.ui.ProfileActivity;
import org.telegram.ui.TopicsFragment;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -41,7 +48,7 @@ public class BackButtonMenu {
int filterId; int filterId;
} }
public static ActionBarPopupWindow show(BaseFragment thisFragment, View backButton, long currentDialogId, Theme.ResourcesProvider resourcesProvider) { public static ActionBarPopupWindow show(BaseFragment thisFragment, View backButton, long currentDialogId, int topicId, Theme.ResourcesProvider resourcesProvider) {
if (thisFragment == null) { if (thisFragment == null) {
return null; return null;
} }
@ -51,7 +58,14 @@ public class BackButtonMenu {
if (parentLayout == null || context == null || fragmentView == null) { if (parentLayout == null || context == null || fragmentView == null) {
return null; return null;
} }
ArrayList<PulledDialog> dialogs = getStackedHistoryDialogs(thisFragment, currentDialogId); ArrayList<PulledDialog> dialogs;
if (topicId != 0) {
new ArrayList<>();
dialogs = getStackedHistoryForTopic(thisFragment, currentDialogId, topicId);
} else {
dialogs = getStackedHistoryDialogs(thisFragment, currentDialogId);
}
if (dialogs.size() <= 0) { if (dialogs.size() <= 0) {
return null; return null;
} }
@ -72,7 +86,11 @@ public class BackButtonMenu {
cell.setMinimumWidth(AndroidUtilities.dp(200)); cell.setMinimumWidth(AndroidUtilities.dp(200));
BackupImageView imageView = new BackupImageView(context); BackupImageView imageView = new BackupImageView(context);
imageView.setRoundRadius(AndroidUtilities.dp(32)); if (chat == null && user == null) {
imageView.setRoundRadius(0);
} else {
imageView.setRoundRadius(chat != null && chat.forum ? AndroidUtilities.dp(8) : AndroidUtilities.dp(16));
}
cell.addView(imageView, LayoutHelper.createFrameRelatively(32, 32, Gravity.START | Gravity.CENTER_VERTICAL, 13, 0, 0, 0)); cell.addView(imageView, LayoutHelper.createFrameRelatively(32, 32, Gravity.START | Gravity.CENTER_VERTICAL, 13, 0, 0, 0));
TextView titleView = new TextView(context); TextView titleView = new TextView(context);
@ -85,6 +103,7 @@ public class BackButtonMenu {
AvatarDrawable avatarDrawable = new AvatarDrawable(); AvatarDrawable avatarDrawable = new AvatarDrawable();
avatarDrawable.setSmallSize(true); avatarDrawable.setSmallSize(true);
Drawable thumb = avatarDrawable; Drawable thumb = avatarDrawable;
boolean addDivider = false;
if (chat != null) { if (chat != null) {
avatarDrawable.setInfo(chat); avatarDrawable.setInfo(chat);
if (chat.photo != null && chat.photo.strippedBitmap != null) { if (chat.photo != null && chat.photo.strippedBitmap != null) {
@ -115,6 +134,13 @@ public class BackButtonMenu {
imageView.setImage(ImageLocation.getForUser(user, ImageLocation.TYPE_SMALL), "50_50", thumb, user); imageView.setImage(ImageLocation.getForUser(user, ImageLocation.TYPE_SMALL), "50_50", thumb, user);
} }
titleView.setText(name); titleView.setText(name);
} else {
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.msg_viewchats).mutate();
imageView.setImageDrawable(drawable);
imageView.setSize(AndroidUtilities.dp(24), AndroidUtilities.dp(24));
imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_actionBarDefaultSubmenuItemIcon, resourcesProvider), PorterDuff.Mode.MULTIPLY));
titleView.setText(LocaleController.getString("AllChats", R.string.AllChats));
addDivider = true;
} }
cell.setBackground(Theme.getSelectorDrawable(Theme.getColor(Theme.key_listSelector, resourcesProvider), false)); cell.setBackground(Theme.getSelectorDrawable(Theme.getColor(Theme.key_listSelector, resourcesProvider), false));
@ -140,13 +166,12 @@ public class BackButtonMenu {
} }
} else { } else {
if (parentLayout != null && parentLayout.getFragmentStack() != null) { if (parentLayout != null && parentLayout.getFragmentStack() != null) {
for (int j = parentLayout.getFragmentStack().size() - 2; j > pDialog.stackIndex; --j) { ArrayList<BaseFragment> fragments = new ArrayList<>(parentLayout.getFragmentStack());
if (j >= 0 && j < parentLayout.getFragmentStack().size()) { for (int j = fragments.size() - 2; j > pDialog.stackIndex; --j) {
parentLayout.removeFragmentFromStack(j); fragments.get(j).removeSelfFromStack();
}
} }
if (pDialog.stackIndex < parentLayout.getFragmentStack().size()) { if (pDialog.stackIndex < parentLayout.getFragmentStack().size()) {
parentLayout.bringToFront(pDialog.stackIndex); // parentLayout.bringToFront(pDialog.stackIndex);
parentLayout.closeLastFragment(true); parentLayout.closeLastFragment(true);
return; return;
} }
@ -156,6 +181,12 @@ public class BackButtonMenu {
goToPulledDialog(thisFragment, pDialog); goToPulledDialog(thisFragment, pDialog);
}); });
layout.addView(cell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48)); layout.addView(cell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
if (addDivider) {
FrameLayout gap = new FrameLayout(context);
gap.setBackgroundColor(Theme.getColor(Theme.key_actionBarDefaultSubmenuSeparator, resourcesProvider));
gap.setTag(R.id.fit_width_tag, 1);
layout.addView(gap, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 8));
}
} }
ActionBarPopupWindow scrimPopupWindow = new ActionBarPopupWindow(layout, LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT); ActionBarPopupWindow scrimPopupWindow = new ActionBarPopupWindow(layout, LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT);
@ -188,6 +219,30 @@ public class BackButtonMenu {
return scrimPopupWindow; return scrimPopupWindow;
} }
private static ArrayList<PulledDialog> getStackedHistoryForTopic(BaseFragment thisFragment, long currentDialogId, int topicId) {
ArrayList<PulledDialog> dialogs = new ArrayList<>();
if (thisFragment.getParentLayout().getFragmentStack().size() > 1 && thisFragment.getParentLayout().getFragmentStack().get(thisFragment.getParentLayout().getFragmentStack().size() - 2) instanceof TopicsFragment) {
PulledDialog pulledDialog = new PulledDialog();
dialogs.add(pulledDialog);
pulledDialog.stackIndex = 0;
pulledDialog.activity = DialogsActivity.class;
pulledDialog = new PulledDialog();
dialogs.add(pulledDialog);
pulledDialog.stackIndex = thisFragment.getParentLayout().getFragmentStack().size() - 2;
pulledDialog.activity = TopicsFragment.class;
pulledDialog.chat = MessagesController.getInstance(thisFragment.getCurrentAccount()).getChat(-currentDialogId);
return dialogs;
} else {
PulledDialog pulledDialog = new PulledDialog();
dialogs.add(pulledDialog);
pulledDialog.stackIndex = -1;
pulledDialog.activity = TopicsFragment.class;
pulledDialog.chat = MessagesController.getInstance(thisFragment.getCurrentAccount()).getChat(-currentDialogId);
return dialogs;
}
}
public static void goToPulledDialog(BaseFragment fragment, PulledDialog dialog) { public static void goToPulledDialog(BaseFragment fragment, PulledDialog dialog) {
if (dialog == null) { if (dialog == null) {
return; return;
@ -206,6 +261,13 @@ public class BackButtonMenu {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putLong("dialog_id", dialog.dialogId); bundle.putLong("dialog_id", dialog.dialogId);
fragment.presentFragment(new ProfileActivity(bundle), true); fragment.presentFragment(new ProfileActivity(bundle), true);
} if (dialog.activity == TopicsFragment.class) {
Bundle bundle = new Bundle();
bundle.putLong("chat_id", dialog.chat.id);
fragment.presentFragment(new TopicsFragment(bundle), true);
} if (dialog.activity == DialogsActivity.class) {
fragment.presentFragment(new DialogsActivity(null), true);
} }
} }

View file

@ -1271,7 +1271,7 @@ public class Bulletin {
super(context, resourcesProvider); super(context, resourcesProvider);
avatarsImageView = new AvatarsImageView(context, false); avatarsImageView = new AvatarsImageView(context, false);
avatarsImageView.setStyle(AvatarsDarawable.STYLE_MESSAGE_SEEN); avatarsImageView.setStyle(AvatarsDrawable.STYLE_MESSAGE_SEEN);
addView(avatarsImageView, LayoutHelper.createFrameRelatively(24 + 12 + 12 + 8, 48, Gravity.START | Gravity.CENTER_VERTICAL, 12, 0, 0, 0)); addView(avatarsImageView, LayoutHelper.createFrameRelatively(24 + 12 + 12 + 8, 48, Gravity.START | Gravity.CENTER_VERTICAL, 12, 0, 0, 0));
textView = new LinkSpanDrawable.LinksTextView(context); textView = new LinkSpanDrawable.LinksTextView(context);

View file

@ -0,0 +1,218 @@
package org.telegram.ui.Components;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.os.Build;
import android.util.StateSet;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewConfiguration;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.ui.ActionBar.Theme;
import java.util.ArrayList;
public class CanvasButton {
Path drawingPath = new Path();
ArrayList<RectF> drawingRects = new ArrayList<>();
int usingRectCount;
boolean buttonPressed;
RippleDrawable selectorDrawable;
private final static int[] pressedState = new int[]{android.R.attr.state_enabled, android.R.attr.state_pressed};
private final View parent;
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Runnable delegate;
private boolean pathCreated;
Runnable longPressRunnable;
Runnable longPressRunnableInner = new Runnable() {
@Override
public void run() {
checkTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0, 0, 0));
parent.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
if (longPressRunnable != null) {
longPressRunnable.run();
}
}
};
private boolean longPressEnabled;
public CanvasButton(View parent) {
this.parent = parent;
paint.setPathEffect(new CornerPathEffect(AndroidUtilities.dp(12)));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
final Paint maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
maskPaint.setFilterBitmap(true);
maskPaint.setPathEffect(new CornerPathEffect(AndroidUtilities.dp(12)));
maskPaint.setColor(0xffffffff);
Drawable maskDrawable = new Drawable() {
@Override
public void draw(Canvas canvas) {
drawInternal(canvas, maskPaint);
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return PixelFormat.TRANSPARENT;
}
};
ColorStateList colorStateList = new ColorStateList(
new int[][]{StateSet.WILD_CARD},
new int[]{Theme.getColor(Theme.key_listSelector) & 0x19ffffff}
);
selectorDrawable = new RippleDrawable(colorStateList, null, maskDrawable);
}
}
public void draw(Canvas canvas) {
drawInternal(canvas, paint);
if (selectorDrawable != null) {
selectorDrawable.draw(canvas);
}
}
private void drawInternal(Canvas canvas, Paint paint) {
if (usingRectCount > 1) {
if (!pathCreated) {
drawingPath.rewind();
int left = 0, top = 0, right = 0, bottom = 0;
for (int i = 0; i < usingRectCount; i++) {
if (i + 1 < usingRectCount) {
float rightCurrent = drawingRects.get(i).right;
float rightNext = drawingRects.get(i + 1).right;
if (Math.abs(rightCurrent - rightNext) < AndroidUtilities.dp(4)) {
drawingRects.get(i + 1).right = drawingRects.get(i).right = Math.max(rightCurrent, rightNext);
}
}
if (i == 0 || drawingRects.get(i).bottom > bottom) {
bottom = (int) drawingRects.get(i).bottom;
}
if (i == 0 || drawingRects.get(i).right > right) {
right = (int) drawingRects.get(i).right;
}
if (i == 0 || drawingRects.get(i).left < left) {
left = (int) drawingRects.get(i).left;
}
if (i == 0 || drawingRects.get(i).top < top) {
top = (int) drawingRects.get(i).top;
}
drawingPath.addRect(drawingRects.get(i), Path.Direction.CCW);
if (selectorDrawable != null) {
selectorDrawable.setBounds(left, top, right, bottom);
}
}
pathCreated = true;
}
canvas.drawPath(drawingPath, paint);
} else if (usingRectCount == 1) {
canvas.drawRoundRect(drawingRects.get(0), AndroidUtilities.dp(10), AndroidUtilities.dp(10), paint);
}
}
public boolean checkTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (contains(x, y)) {
buttonPressed = true;
if (Build.VERSION.SDK_INT >= 21 && selectorDrawable != null) {
selectorDrawable.setHotspot(x, y);
selectorDrawable.setState(pressedState);
}
AndroidUtilities.cancelRunOnUIThread(longPressRunnableInner);
if (longPressEnabled) {
AndroidUtilities.runOnUIThread(longPressRunnableInner, ViewConfiguration.getLongPressTimeout());
}
parent.invalidate();
return true;
}
} else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
if (buttonPressed) {
if (event.getAction() == MotionEvent.ACTION_UP && delegate != null) {
delegate.run();
}
parent.playSoundEffect(SoundEffectConstants.CLICK);
if (Build.VERSION.SDK_INT >= 21 && selectorDrawable != null) {
selectorDrawable.setState(StateSet.NOTHING);
}
buttonPressed = false;
parent.invalidate();
}
AndroidUtilities.cancelRunOnUIThread(longPressRunnableInner);
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (buttonPressed && Build.VERSION.SDK_INT >= 21 && selectorDrawable != null) {
selectorDrawable.setHotspot(x, y);
}
}
return buttonPressed;
}
private boolean contains(int x, int y) {
for (int i = 0; i < usingRectCount; i++) {
if (drawingRects.get(i).contains(x, y)) {
return true;
}
}
return false;
}
public void setColor(int color) {
paint.setColor(color);
if (selectorDrawable != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Theme.setSelectorDrawableColor(selectorDrawable, color, true);
}
}
public void setDelegate(Runnable delegate) {
this.delegate = delegate;
}
public void rewind() {
pathCreated = false;
usingRectCount = 0;
}
public void addRect(RectF rectF) {
usingRectCount++;
if (usingRectCount > drawingRects.size()) {
drawingRects.add(new RectF());
}
RectF rect = drawingRects.get(usingRectCount - 1);
rect.set(rectF);
}
public void setRect(RectF rectF) {
rewind();
addRect(rectF);
}
public void setLongPress(Runnable runnable) {
longPressEnabled = true;
longPressRunnable = runnable;
}
}

View file

@ -0,0 +1,52 @@
package org.telegram.ui.Components;
import org.telegram.messenger.ChatObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBar;
public interface ChatActivityInterface {
default ChatObject.Call getGroupCall() {
return null;
}
default TLRPC.Chat getCurrentChat() {
return null;
}
default TLRPC.User getCurrentUser() {
return null;
}
long getDialogId();
default void scrollToMessageId(int id, int i, boolean b, int i1, boolean b1, int i2) {
}
default boolean shouldShowImport() {
return false;
}
default boolean openedWithLivestream() {
return false;
}
default long getMergeDialogId() {
return 0;
}
default int getTopicId() {
return 0;
}
ChatAvatarContainer getAvatarContainer();
default void checkAndUpdateAvatar() {
}
SizeNotifierFrameLayout getContentView();
ActionBar getActionBar();
}

View file

@ -723,6 +723,8 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
} }
setTypingAnimation(false); setTypingAnimation(false);
if (parentFragment.isTopic && chat != null) { if (parentFragment.isTopic && chat != null) {
int count = parentFragment.getThreadMessage().getRepliesCount();
// newSubtitle = LocaleController.formatPluralString("messages", count, count);
newSubtitle = LocaleController.formatString("TopicProfileStatus", R.string.TopicProfileStatus, chat.title); newSubtitle = LocaleController.formatString("TopicProfileStatus", R.string.TopicProfileStatus, chat.title);
} else if (chat != null) { } else if (chat != null) {
TLRPC.ChatFull info = parentFragment.getCurrentChatInfo(); TLRPC.ChatFull info = parentFragment.getCurrentChatInfo();

View file

@ -62,6 +62,7 @@ public class DialogsItemAnimator extends SimpleItemAnimator {
private final RecyclerListView listView; private final RecyclerListView listView;
public DialogsItemAnimator(RecyclerListView listView) { public DialogsItemAnimator(RecyclerListView listView) {
setSupportsChangeAnimations(false);
this.listView = listView; this.listView = listView;
} }

View file

@ -4,7 +4,6 @@ import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.util.Log;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.BuildVars; import org.telegram.messenger.BuildVars;
@ -18,6 +17,7 @@ import java.util.ArrayList;
public class DrawingInBackgroundThreadDrawable implements NotificationCenter.NotificationCenterDelegate { public class DrawingInBackgroundThreadDrawable implements NotificationCenter.NotificationCenterDelegate {
public final static int THREAD_COUNT = 2;
boolean attachedToWindow; boolean attachedToWindow;
Bitmap backgroundBitmap; Bitmap backgroundBitmap;
@ -26,9 +26,6 @@ public class DrawingInBackgroundThreadDrawable implements NotificationCenter.Not
Bitmap bitmap; Bitmap bitmap;
Canvas bitmapCanvas; Canvas bitmapCanvas;
Bitmap nextRenderingBitmap;
Canvas nextRenderingCanvas;
private boolean bitmapUpdating; private boolean bitmapUpdating;
public int currentLayerNum = 1; public int currentLayerNum = 1;
@ -42,10 +39,11 @@ public class DrawingInBackgroundThreadDrawable implements NotificationCenter.Not
int width; int width;
int padding; int padding;
private static DispatchQueue backgroundQueue; public static DispatchQueuePool queuePool;
private final DispatchQueue backgroundQueue;
boolean error; boolean error;
Runnable bitmapCreateTask = new Runnable() { private final Runnable bitmapCreateTask = new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
@ -74,6 +72,8 @@ public class DrawingInBackgroundThreadDrawable implements NotificationCenter.Not
} }
}; };
boolean needSwapBitmaps;
Runnable uiFrameRunnable = new Runnable() { Runnable uiFrameRunnable = new Runnable() {
@Override @Override
public void run() { public void run() {
@ -89,26 +89,19 @@ public class DrawingInBackgroundThreadDrawable implements NotificationCenter.Not
if (frameGuid != lastFrameId) { if (frameGuid != lastFrameId) {
return; return;
} }
Bitmap bitmapTmp = bitmap; needSwapBitmaps = true;
Canvas bitmapCanvasTmp = bitmapCanvas;
bitmap = nextRenderingBitmap;
bitmapCanvas = nextRenderingCanvas;
nextRenderingBitmap = backgroundBitmap;
nextRenderingCanvas = backgroundCanvas;
backgroundBitmap = bitmapTmp;
backgroundCanvas = bitmapCanvasTmp;
} }
}; };
private boolean reset; private boolean reset;
private int lastFrameId; private int lastFrameId;
public final int threadIndex;
public DrawingInBackgroundThreadDrawable() { public DrawingInBackgroundThreadDrawable() {
if (backgroundQueue == null) { if (queuePool == null) {
backgroundQueue = new DispatchQueue("draw_background_queue"); queuePool = new DispatchQueuePool(THREAD_COUNT);
} }
backgroundQueue = queuePool.getNextQueue();
threadIndex = queuePool.pointer;
} }
public void draw(Canvas canvas, long time, int w, int h, float alpha) { public void draw(Canvas canvas, long time, int w, int h, float alpha) {
@ -121,7 +114,19 @@ public class DrawingInBackgroundThreadDrawable implements NotificationCenter.Not
height = h; height = h;
width = w; width = w;
if ((bitmap == null && nextRenderingBitmap == null) || reset) { if (needSwapBitmaps) {
needSwapBitmaps = false;
Bitmap bitmapTmp = bitmap;
Canvas bitmapCanvasTmp = bitmapCanvas;
bitmap = backgroundBitmap;
bitmapCanvas = backgroundCanvas;
backgroundBitmap = bitmapTmp;
backgroundCanvas = bitmapCanvasTmp;
}
if (bitmap == null || reset) {
reset = false; reset = false;
if (bitmap != null) { if (bitmap != null) {
@ -131,16 +136,16 @@ public class DrawingInBackgroundThreadDrawable implements NotificationCenter.Not
bitmap = null; bitmap = null;
} }
int heightInternal = height + padding; int heightInternal = height + padding;
if (nextRenderingBitmap == null || nextRenderingBitmap.getHeight() != heightInternal || nextRenderingBitmap.getWidth() != width) { if (bitmap == null || bitmap.getHeight() != heightInternal || bitmap.getWidth() != width) {
nextRenderingBitmap = Bitmap.createBitmap(width, heightInternal, Bitmap.Config.ARGB_8888); bitmap = Bitmap.createBitmap(width, heightInternal, Bitmap.Config.ARGB_8888);
nextRenderingCanvas = new Canvas(nextRenderingBitmap); bitmapCanvas = new Canvas(bitmap);
} else { } else {
nextRenderingBitmap.eraseColor(Color.TRANSPARENT); bitmap.eraseColor(Color.TRANSPARENT);
} }
nextRenderingCanvas.save(); bitmapCanvas.save();
nextRenderingCanvas.translate(0, padding); bitmapCanvas.translate(0, padding);
drawInUiThread(nextRenderingCanvas, 1f); drawInUiThread(bitmapCanvas, 1f);
nextRenderingCanvas.restore(); bitmapCanvas.restore();
} }
if (!bitmapUpdating && !paused) { if (!bitmapUpdating && !paused) {
@ -150,11 +155,8 @@ public class DrawingInBackgroundThreadDrawable implements NotificationCenter.Not
backgroundQueue.postRunnable(bitmapCreateTask); backgroundQueue.postRunnable(bitmapCreateTask);
} }
if (bitmap != null || nextRenderingBitmap != null) { if (bitmap != null ) {
Bitmap drawingBitmap = bitmap; Bitmap drawingBitmap = bitmap;
if (drawingBitmap == null) {
drawingBitmap = nextRenderingBitmap;
}
paint.setAlpha((int) (255 * alpha)); paint.setAlpha((int) (255 * alpha));
canvas.save(); canvas.save();
canvas.translate(0, -padding); canvas.translate(0, -padding);
@ -202,11 +204,7 @@ public class DrawingInBackgroundThreadDrawable implements NotificationCenter.Not
if (bitmap != null) { if (bitmap != null) {
bitmaps.add(bitmap); bitmaps.add(bitmap);
} }
if (nextRenderingBitmap != null) {
bitmaps.add(nextRenderingBitmap);
}
bitmap = null; bitmap = null;
nextRenderingBitmap = null;
AndroidUtilities.recycleBitmaps(bitmaps); AndroidUtilities.recycleBitmaps(bitmaps);
attachedToWindow = false; attachedToWindow = false;
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.stopAllHeavyOperations); NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.stopAllHeavyOperations);
@ -261,4 +259,29 @@ public class DrawingInBackgroundThreadDrawable implements NotificationCenter.Not
AndroidUtilities.recycleBitmaps(bitmaps); AndroidUtilities.recycleBitmaps(bitmaps);
} }
} }
public static class DispatchQueuePool {
final int size;
int pointer;
public final DispatchQueue[] pool;
private DispatchQueuePool(int size) {
this.size = size;
pool = new DispatchQueue[size];
}
public DispatchQueue getNextQueue() {
pointer++;
if (pointer > size - 1) {
pointer = 0;
}
DispatchQueue queue = pool[pointer];
if (queue == null) {
queue = pool[pointer] = new DispatchQueue("draw_background_queue_" + pointer);
}
return queue;
}
}
} }

View file

@ -312,11 +312,11 @@ public class EmojiPacksAlert extends BottomSheet implements NotificationCenter.N
} }
drawable.update(time); drawable.update(time);
imageView.backgroundThreadDrawHolder = drawable.getImageReceiver().setDrawInBackgroundThread(imageView.backgroundThreadDrawHolder); imageView.backgroundThreadDrawHolder[threadIndex] = drawable.getImageReceiver().setDrawInBackgroundThread(imageView.backgroundThreadDrawHolder[threadIndex], threadIndex);
imageView.backgroundThreadDrawHolder.time = time; imageView.backgroundThreadDrawHolder[threadIndex].time = time;
drawable.setAlpha(255); drawable.setAlpha(255);
AndroidUtilities.rectTmp2.set(imageView.getLeft() + imageView.getPaddingLeft(), imageView.getPaddingTop(), imageView.getRight() - imageView.getPaddingRight(), imageView.getMeasuredHeight() - imageView.getPaddingBottom()); AndroidUtilities.rectTmp2.set(imageView.getLeft() + imageView.getPaddingLeft(), imageView.getPaddingTop(), imageView.getRight() - imageView.getPaddingRight(), imageView.getMeasuredHeight() - imageView.getPaddingBottom());
imageView.backgroundThreadDrawHolder.setBounds(AndroidUtilities.rectTmp2); imageView.backgroundThreadDrawHolder[threadIndex].setBounds(AndroidUtilities.rectTmp2);
imageView.imageReceiver = drawable.getImageReceiver(); imageView.imageReceiver = drawable.getImageReceiver();
drawInBackgroundViews.add(imageView); drawInBackgroundViews.add(imageView);
} }
@ -350,7 +350,7 @@ public class EmojiPacksAlert extends BottomSheet implements NotificationCenter.N
public void drawInBackground(Canvas canvas) { public void drawInBackground(Canvas canvas) {
for (int i = 0; i < drawInBackgroundViews.size(); i++) { for (int i = 0; i < drawInBackgroundViews.size(); i++) {
EmojiImageView imageView = drawInBackgroundViews.get(i); EmojiImageView imageView = drawInBackgroundViews.get(i);
imageView.imageReceiver.draw(canvas, imageView.backgroundThreadDrawHolder); imageView.imageReceiver.draw(canvas, imageView.backgroundThreadDrawHolder[threadIndex]);
} }
} }
@ -394,7 +394,7 @@ public class EmojiPacksAlert extends BottomSheet implements NotificationCenter.N
super.onFrameReady(); super.onFrameReady();
for (int i = 0; i < drawInBackgroundViews.size(); i++) { for (int i = 0; i < drawInBackgroundViews.size(); i++) {
EmojiImageView imageView = drawInBackgroundViews.get(i); EmojiImageView imageView = drawInBackgroundViews.get(i);
imageView.backgroundThreadDrawHolder.release(); imageView.backgroundThreadDrawHolder[threadIndex].release();
} }
containerView.invalidate(); containerView.invalidate();
} }
@ -1138,7 +1138,7 @@ public class EmojiPacksAlert extends BottomSheet implements NotificationCenter.N
} }
} }
private class EmojiImageView extends View { private class EmojiImageView extends View {
public ImageReceiver.BackgroundThreadDrawHolder backgroundThreadDrawHolder; public ImageReceiver.BackgroundThreadDrawHolder[] backgroundThreadDrawHolder = new ImageReceiver.BackgroundThreadDrawHolder[DrawingInBackgroundThreadDrawable.THREAD_COUNT];
public ImageReceiver imageReceiver; public ImageReceiver imageReceiver;
public EmojiImageView(Context context) { public EmojiImageView(Context context) {

View file

@ -21,7 +21,6 @@ import android.content.DialogInterface;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.DashPathEffect; import android.graphics.DashPathEffect;
import android.graphics.Outline; import android.graphics.Outline;
import android.graphics.Paint; import android.graphics.Paint;
@ -932,7 +931,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
private boolean isRecent; private boolean isRecent;
private AnimatedEmojiSpan span; private AnimatedEmojiSpan span;
private EmojiPack pack; private EmojiPack pack;
private ImageReceiver.BackgroundThreadDrawHolder backgroundThreadDrawHolder; private ImageReceiver.BackgroundThreadDrawHolder[] backgroundThreadDrawHolder = new ImageReceiver.BackgroundThreadDrawHolder[DrawingInBackgroundThreadDrawable.THREAD_COUNT];
float pressedProgress; float pressedProgress;
ValueAnimator backAnimator; ValueAnimator backAnimator;
@ -2829,13 +2828,13 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
} }
drawable.update(time); drawable.update(time);
imageView.backgroundThreadDrawHolder = drawable.getImageReceiver().setDrawInBackgroundThread(imageView.backgroundThreadDrawHolder); imageView.backgroundThreadDrawHolder[threadIndex] = drawable.getImageReceiver().setDrawInBackgroundThread(imageView.backgroundThreadDrawHolder[threadIndex], threadIndex);
imageView.backgroundThreadDrawHolder.time = time; imageView.backgroundThreadDrawHolder[threadIndex].time = time;
imageView.backgroundThreadDrawHolder.overrideAlpha = 1f; imageView.backgroundThreadDrawHolder[threadIndex].overrideAlpha = 1f;
drawable.setAlpha(255); drawable.setAlpha(255);
int topOffset = (int) (imageView.getHeight() * .03f); int topOffset = (int) (imageView.getHeight() * .03f);
AndroidUtilities.rectTmp2.set(imageView.getLeft() + imageView.getPaddingLeft() - startOffset, topOffset, imageView.getRight() - imageView.getPaddingRight() - startOffset, topOffset + imageView.getMeasuredHeight() - imageView.getPaddingTop() - imageView.getPaddingBottom()); AndroidUtilities.rectTmp2.set(imageView.getLeft() + imageView.getPaddingLeft() - startOffset, topOffset, imageView.getRight() - imageView.getPaddingRight() - startOffset, topOffset + imageView.getMeasuredHeight() - imageView.getPaddingTop() - imageView.getPaddingBottom());
imageView.backgroundThreadDrawHolder.setBounds(AndroidUtilities.rectTmp2); imageView.backgroundThreadDrawHolder[threadIndex].setBounds(AndroidUtilities.rectTmp2);
imageView.drawable = drawable; imageView.drawable = drawable;
imageView.imageReceiver = drawable.getImageReceiver(); imageView.imageReceiver = drawable.getImageReceiver();
drawInBackgroundViews.add(imageView); drawInBackgroundViews.add(imageView);
@ -2847,7 +2846,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
for (int i = 0; i < drawInBackgroundViews.size(); i++) { for (int i = 0; i < drawInBackgroundViews.size(); i++) {
ImageViewEmoji imageView = drawInBackgroundViews.get(i); ImageViewEmoji imageView = drawInBackgroundViews.get(i);
if (imageView.drawable != null) { if (imageView.drawable != null) {
imageView.drawable.draw(canvas, imageView.backgroundThreadDrawHolder, false); imageView.drawable.draw(canvas, imageView.backgroundThreadDrawHolder[threadIndex], false);
} }
} }
} }
@ -2914,7 +2913,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
for (int i = 0; i < drawInBackgroundViews.size(); i++) { for (int i = 0; i < drawInBackgroundViews.size(); i++) {
ImageViewEmoji imageView = drawInBackgroundViews.get(i); ImageViewEmoji imageView = drawInBackgroundViews.get(i);
if (imageView.backgroundThreadDrawHolder != null) { if (imageView.backgroundThreadDrawHolder != null) {
imageView.backgroundThreadDrawHolder.release(); imageView.backgroundThreadDrawHolder[threadIndex].release();
} }
} }
emojiGridView.invalidate(); emojiGridView.invalidate();

View file

@ -1,10 +1,10 @@
package org.telegram.ui.Components.Forum; package org.telegram.ui.Components.Forum;
import android.graphics.Paint;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.text.Spanned; import android.text.Spanned;
import android.text.TextPaint;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.style.ImageSpan; import android.text.style.ImageSpan;
@ -71,6 +71,16 @@ public class ForumUtilities {
return combinedDrawable; return combinedDrawable;
} }
public static Drawable createSmallTopicDrawable(String text, int color) {
ForumBubbleDrawable forumBubbleDrawable = new ForumBubbleDrawable(color);
LetterDrawable letterDrawable = new LetterDrawable(null, LetterDrawable.STYLE_SMALL_TOPIC_DRAWABLE);
String title = text.trim().toUpperCase();
letterDrawable.setTitle(title.length() >= 1 ? title.substring(0, 1) : "");
CombinedDrawable combinedDrawable = new CombinedDrawable(forumBubbleDrawable, letterDrawable, 0, 0);
combinedDrawable.setFullsize(true);
return combinedDrawable;
}
public static void openTopic(BaseFragment baseFragment, long chatId, TLRPC.TL_forumTopic topic, int fromMessageId) { public static void openTopic(BaseFragment baseFragment, long chatId, TLRPC.TL_forumTopic topic, int fromMessageId) {
if (baseFragment == null || topic == null) { if (baseFragment == null || topic == null) {
return; return;
@ -78,8 +88,12 @@ public class ForumUtilities {
TLRPC.Chat chatLocal = baseFragment.getMessagesController().getChat(chatId); TLRPC.Chat chatLocal = baseFragment.getMessagesController().getChat(chatId);
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putLong("chat_id", chatId); args.putLong("chat_id", chatId);
if (fromMessageId != 0) { if (fromMessageId != 0) {
args.putInt("message_id", fromMessageId); args.putInt("message_id", fromMessageId);
} else if (topic.read_inbox_max_id == 0) {
//scroll to first message in topic
args.putInt("message_id", topic.id);
} }
args.putInt("unread_count", topic.unread_count); args.putInt("unread_count", topic.unread_count);
args.putBoolean("historyPreloaded", false); args.putBoolean("historyPreloaded", false);
@ -104,11 +118,11 @@ public class ForumUtilities {
baseFragment.presentFragment(chatActivity); baseFragment.presentFragment(chatActivity);
} }
public static CharSequence getTopicSpannedName(TLRPC.ForumTopic topic, TextPaint paint) { public static CharSequence getTopicSpannedName(TLRPC.ForumTopic topic, Paint paint) {
return getTopicSpannedName(topic, paint, null); return getTopicSpannedName(topic, paint, null);
} }
public static CharSequence getTopicSpannedName(TLRPC.ForumTopic topic, TextPaint paint, ForumBubbleDrawable[] drawableToSet) { public static CharSequence getTopicSpannedName(TLRPC.ForumTopic topic, Paint paint, ForumBubbleDrawable[] drawableToSet) {
SpannableStringBuilder sb = new SpannableStringBuilder(); SpannableStringBuilder sb = new SpannableStringBuilder();
if (topic instanceof TLRPC.TL_forumTopic) { if (topic instanceof TLRPC.TL_forumTopic) {
TLRPC.TL_forumTopic forumTopic = (TLRPC.TL_forumTopic) topic; TLRPC.TL_forumTopic forumTopic = (TLRPC.TL_forumTopic) topic;
@ -116,6 +130,7 @@ public class ForumUtilities {
sb.append(" "); sb.append(" ");
AnimatedEmojiSpan span; AnimatedEmojiSpan span;
sb.setSpan(span = new AnimatedEmojiSpan(forumTopic.icon_emoji_id, .95f, paint == null ? null : paint.getFontMetricsInt()), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); sb.setSpan(span = new AnimatedEmojiSpan(forumTopic.icon_emoji_id, .95f, paint == null ? null : paint.getFontMetricsInt()), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
span.top = true;
span.cacheType = AnimatedEmojiDrawable.CACHE_TYPE_EMOJI_STATUS; span.cacheType = AnimatedEmojiDrawable.CACHE_TYPE_EMOJI_STATUS;
} else { } else {
sb.append(" "); sb.append(" ");

View file

@ -0,0 +1,434 @@
package org.telegram.ui.Components.Forum;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextUtils;
import android.view.MotionEvent;
import androidx.core.graphics.ColorUtils;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.R;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.ChatMessageCell;
import org.telegram.ui.Components.AnimatedColor;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.StaticLayoutEx;
public class MessageTopicButton {
private final static float[] lightHueRanges = { 0, 43, 56, 86, 169, 183, 249, 289, 360 };
private final static float[] lightSatValues = { .60f, 1f, .95f, .98f, .80f, .88f, .51f, .55f, .60f };
private final static float[] lightValValues = { .79f, .77f, .60f, .62f, .60f, .61f, .80f, .70f, .79f };
private final static float[] darkHueRanges = { 0, 43, 56, 63, 86, 122, 147, 195, 205, 249, 270, 312, 388, 360 };
private final static float[] darkSatValues = { .64f, .89f, .84f, .87f, .74f, .66f, .81f, .81f, .71f, .51f, .61f, .55f, .62f, .64f };
private final static float[] darkValValues = { .92f, .90f, .82f, .82f, .84f, .84f, .82f, .88f, .96f, .100f, .93f, .88f, .96f, .92f };
private int topicWidth;
private int topicHeight;
private Paint topicPaint;
private Path topicPath;
private Drawable topicArrowDrawable;
private Drawable topicSelectorDrawable;
private Drawable topicIconDrawable;
private Rect topicIconDrawableBounds;
private float[] topicHSV;
private int topicBackgroundColor;
private int topicNameColor;
private int topicArrowColor;
private AnimatedColor topicBackgroundColorAnimated, topicNameColorAnimated;
private boolean topicIconWaiting;
private StaticLayout topicNameLayout;
private RectF topicHitRect;
private boolean topicPressed;
private MessageObject lastMessageObject;
private Context context;
private Theme.ResourcesProvider resourcesProvider;
private final static int[] idleState = new int[]{};
private final static int[] pressedState = new int[]{android.R.attr.state_enabled, android.R.attr.state_pressed};
public MessageTopicButton(Context context, Theme.ResourcesProvider resourcesProvider) {
this.context = context;
this.resourcesProvider = resourcesProvider;
}
protected void onClick() {}
public int set(ChatMessageCell cell, MessageObject messageObject, TLRPC.TL_forumTopic topic, int maxWidth) {
lastMessageObject = messageObject;
if (cell == null || messageObject == null) {
return 0;
}
int iconsz = AndroidUtilities.dp(7) + (int) Theme.chat_topicTextPaint.getTextSize();
float padleft = AndroidUtilities.dp(10) + iconsz;
float padright1 = Theme.chat_topicTextPaint.getTextSize() - AndroidUtilities.dp(8);
float padright = AndroidUtilities.dp(5) + Theme.chat_topicTextPaint.getTextSize();
maxWidth -= padleft + padright;
String title = topic.title == null ? "" : topic.title;
topicNameLayout = StaticLayoutEx.createStaticLayout(title, 0, title.length(), Theme.chat_topicTextPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1f, 0, false, TextUtils.TruncateAt.END, maxWidth, 2, false);
topicHeight = AndroidUtilities.dp(4 + 4.5f) + Math.min(AndroidUtilities.dp(24), topicNameLayout == null ? 0 : topicNameLayout.getHeight());
float textWidth = 0;
int lineCount = topicNameLayout == null ? 0 : topicNameLayout.getLineCount();
if (topicPath == null) {
topicPath = new Path();
} else {
topicPath.rewind();
}
if (topicPaint == null) {
topicPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
int iconColor;
if (topic.icon_emoji_id != 0) {
if (!(topicIconDrawable instanceof AnimatedEmojiDrawable) || topic.icon_emoji_id != ((AnimatedEmojiDrawable) topicIconDrawable).getDocumentId()) {
if (topicIconDrawable instanceof AnimatedEmojiDrawable) {
((AnimatedEmojiDrawable) topicIconDrawable).removeView(cell::invalidateOutbounds);
topicIconDrawable = null;
}
topicIconDrawable = AnimatedEmojiDrawable.make(messageObject.currentAccount, AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, topic.icon_emoji_id);
((AnimatedEmojiDrawable) topicIconDrawable).addView(cell::invalidateOutbounds);
}
topicIconWaiting = false;
iconColor = topicIconDrawable instanceof AnimatedEmojiDrawable ? AnimatedEmojiDrawable.getDominantColor((AnimatedEmojiDrawable) topicIconDrawable) : 0;
if (iconColor == 0) {
topicIconWaiting = true;
iconColor = getThemedColor(messageObject.isOutOwner() ? Theme.key_chat_outReactionButtonText : Theme.key_chat_inReactionButtonText);
}
} else {
iconColor = topic.icon_color;
topicIconDrawable = ForumUtilities.createSmallTopicDrawable(title, topic.icon_color);
}
setupColors(iconColor);
if (topicIconWaiting) {
if (topicNameColorAnimated == null) {
topicNameColorAnimated = new AnimatedColor(cell);
}
if (topicBackgroundColorAnimated == null) {
topicBackgroundColorAnimated = new AnimatedColor(cell);
}
}
if (topicArrowDrawable == null && context != null) {
topicArrowDrawable = context.getResources().getDrawable(R.drawable.msg_mini_topicarrow).mutate();
}
topicArrowDrawable.setColorFilter(new PorterDuffColorFilter(topicArrowColor = ColorUtils.setAlphaComponent(topicNameColor, 140), PorterDuff.Mode.MULTIPLY));
float R = (AndroidUtilities.dp(11) + (int) Theme.chat_topicTextPaint.getTextSize());
int arrowsz = Math.max(1, (int) Theme.chat_topicTextPaint.getTextSize() + AndroidUtilities.dp(0));
if (lineCount == 2) {
topicHeight = AndroidUtilities.dp(15) + 2 * ((int) Theme.chat_topicTextPaint.getTextSize());
float l1w = topicNameLayout.getLineWidth(0) - topicNameLayout.getLineLeft(0);
float l2w = topicNameLayout.getLineWidth(1) - topicNameLayout.getLineLeft(1);
textWidth = Math.max(l1w, l2w);
float r = (AndroidUtilities.dp(11) + (int) Theme.chat_topicTextPaint.getTextSize()) / 1.5f;
boolean same = false;
AndroidUtilities.rectTmp.set(0, 0, R, R);
topicPath.arcTo(AndroidUtilities.rectTmp, 180, 90);
if (Math.abs(l1w - l2w) <= (padright - padright1)) {
l1w = Math.max(l1w, l2w + (padright - padright1));
l2w = Math.max(l2w, l1w - (padright - padright1));
same = true;
}
AndroidUtilities.rectTmp.set(padleft + padright1 + l1w - r, 0, padleft + padright1 + l1w, r);
topicPath.arcTo(AndroidUtilities.rectTmp, 270, 90);
float midly = AndroidUtilities.dp(11) + Theme.chat_topicTextPaint.getTextSize();
float r2 = Math.min(r, Math.abs(l1w - AndroidUtilities.dp(18 - 5) - l2w));
if (!same) {
if (l1w - (padright - padright1) > l2w) {
AndroidUtilities.rectTmp.set(padleft + padright1 + l1w - r2, midly - r2, padleft + padright1 + l1w, midly);
topicPath.arcTo(AndroidUtilities.rectTmp, 0, 90);
AndroidUtilities.rectTmp.set(padleft + padright + l2w, midly, padleft + padright + l2w + r2, midly + r2);
topicPath.arcTo(AndroidUtilities.rectTmp, 270, -90);
} else {
midly = topicHeight - midly;
AndroidUtilities.rectTmp.set(padleft + padright1 + l1w, midly - r2, padleft + padright1 + l1w + r2, midly);
topicPath.arcTo(AndroidUtilities.rectTmp, 180, -90);
AndroidUtilities.rectTmp.set(padleft + padright + l2w - r2, midly, padleft + padright + l2w, midly + r2);
topicPath.arcTo(AndroidUtilities.rectTmp, 270, 90);
}
}
topicArrowDrawable.setBounds(
(int) (padleft + padright + AndroidUtilities.dp(-4) + l2w - arrowsz),
(int) ((topicHeight - AndroidUtilities.dp(11) - Theme.chat_topicTextPaint.getTextSize() + topicHeight) / 2f - arrowsz / 2),
(int) (padleft + padright + AndroidUtilities.dp(-4) + l2w),
(int) ((topicHeight - AndroidUtilities.dp(11) - Theme.chat_topicTextPaint.getTextSize() + topicHeight) / 2f + arrowsz / 2)
);
AndroidUtilities.rectTmp.set(padleft + padright + l2w - r, topicHeight - r, padleft + padright + l2w, topicHeight);
topicPath.arcTo(AndroidUtilities.rectTmp, 0, 90);
AndroidUtilities.rectTmp.set(0, topicHeight - R, R, topicHeight);
topicPath.arcTo(AndroidUtilities.rectTmp, 90, 90);
topicPath.close();
} else if (lineCount == 1) {
topicHeight = AndroidUtilities.dp(11) + (int) Theme.chat_topicTextPaint.getTextSize();
textWidth = topicNameLayout.getLineWidth(0) - topicNameLayout.getLineLeft(0);
AndroidUtilities.rectTmp.set(0, 0, padleft + padright + textWidth, topicHeight);
topicArrowDrawable.setBounds(
(int) (padleft + padright + AndroidUtilities.dp(-4) + textWidth - arrowsz),
(int) (topicHeight / 2f - arrowsz / 2),
(int) (padleft + padright + AndroidUtilities.dp(-4) + textWidth),
(int) (topicHeight / 2f + arrowsz / 2)
);
topicPath.addRoundRect(AndroidUtilities.rectTmp, R, R, Path.Direction.CW);
}
topicWidth = (int) (padleft + padright -AndroidUtilities.dp(1) + textWidth);
int occupingHeight = 0;
if (!messageObject.isAnyKindOfSticker() && messageObject.type != MessageObject.TYPE_ROUND_VIDEO) {
occupingHeight += AndroidUtilities.dp(6) + topicHeight;
if (messageObject.type != MessageObject.TYPE_TEXT) {
occupingHeight += AndroidUtilities.dp(9);
}
}
if (topicSelectorDrawable == null) {
topicSelectorDrawable = Theme.createSelectorDrawable(topicBackgroundColor, Theme.RIPPLE_MASK_ALL);
topicSelectorDrawable.setCallback(cell);
} else {
Theme.setSelectorDrawableColor(topicSelectorDrawable, topicBackgroundColor, true);
}
topicPaint.setColor(topicBackgroundColor);
if (topicIconDrawable != null) {
if (topicIconDrawableBounds == null) {
topicIconDrawableBounds = new Rect();
}
topicIconDrawableBounds.set(
AndroidUtilities.dp(3 + 2f),
AndroidUtilities.dp(2 + (lineCount == 2 ? 3 : 0)),
AndroidUtilities.dp(3 + 2) + iconsz,
AndroidUtilities.dp(2 + (lineCount == 2 ? 3 : 0)) + iconsz
);
topicIconDrawable.setBounds(topicIconDrawableBounds);
}
return occupingHeight;
}
public void onAttached(ChatMessageCell cell) {
if (topicIconDrawable instanceof AnimatedEmojiDrawable && cell != null) {
((AnimatedEmojiDrawable) topicIconDrawable).addView(cell::invalidateOutbounds);
}
}
public void onDetached(ChatMessageCell cell) {
if (topicIconDrawable instanceof AnimatedEmojiDrawable && cell != null) {
((AnimatedEmojiDrawable) topicIconDrawable).removeView(cell::invalidateOutbounds);
}
}
private void setupColors(int iconColor) {
if (lastMessageObject != null && lastMessageObject.shouldDrawWithoutBackground()) {
topicNameColor = getThemedColor(Theme.key_chat_stickerReplyNameText);
} else if (lastMessageObject != null && lastMessageObject.isOutOwner()) {
topicNameColor = getThemedColor(Theme.key_chat_outReactionButtonText);
topicBackgroundColor = ColorUtils.setAlphaComponent(getThemedColor(Theme.key_chat_outReactionButtonBackground), 38);
} else {
if (topicHSV == null) {
topicHSV = new float[3];
}
Color.colorToHSV(iconColor, topicHSV);
float hue = topicHSV[0];
float sat = topicHSV[1];
if (sat <= 0.02f) {
topicNameColor = getThemedColor(Theme.key_chat_inReactionButtonText);
topicBackgroundColor = ColorUtils.setAlphaComponent(getThemedColor(Theme.key_chat_inReactionButtonBackground), 38);
} else {
Color.colorToHSV(getThemedColor(Theme.key_chat_inReactionButtonText), topicHSV);
topicHSV[0] = hue;
float[] hueRanges = Theme.isCurrentThemeDark() ? darkHueRanges : lightHueRanges;
float[] satValues = Theme.isCurrentThemeDark() ? darkSatValues : lightSatValues;
float[] valValues = Theme.isCurrentThemeDark() ? darkValValues : lightValValues;
for (int i = 1; i < hueRanges.length; ++i) {
if (hue <= hueRanges[i]) {
float t = (hue - hueRanges[i - 1]) / (hueRanges[i] - hueRanges[i - 1]);
topicHSV[1] = AndroidUtilities.lerp(satValues[i - 1], satValues[i], t);
topicHSV[2] = AndroidUtilities.lerp(valValues[i - 1], valValues[i], t);
break;
}
}
topicNameColor = Color.HSVToColor(Color.alpha(getThemedColor(Theme.key_chat_inReactionButtonText)), topicHSV);
topicBackgroundColor = Color.HSVToColor(38, topicHSV);
}
}
}
public boolean checkTouchEvent(MotionEvent event) {
if (topicHitRect == null) {
topicPressed = false;
return false;
}
boolean hit = topicHitRect.contains(event.getX(), event.getY());
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (hit) {
if (topicSelectorDrawable != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
topicSelectorDrawable.setHotspot(event.getX() - topicHitRect.left, event.getY() - topicHitRect.top);
}
topicSelectorDrawable.setState(pressedState);
}
topicPressed = true;
} else {
topicPressed = false;
}
return topicPressed;
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (topicPressed != hit) {
if (topicPressed && topicSelectorDrawable != null) {
topicSelectorDrawable.setState(idleState);
}
topicPressed = hit;
}
return topicPressed;
} else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
if (topicPressed) {
topicPressed = false;
if (topicSelectorDrawable != null) {
topicSelectorDrawable.setState(idleState);
}
if (event.getAction() == MotionEvent.ACTION_UP) {
onClick();
return true;
}
}
}
return false;
}
public int width() {
return topicWidth;
}
public int height() {
return topicHeight;
}
public void draw(Canvas canvas, float x, float y, float alpha) {
if (topicIconWaiting && topicIconDrawable instanceof AnimatedEmojiDrawable) {
int iconColor = AnimatedEmojiDrawable.getDominantColor((AnimatedEmojiDrawable) topicIconDrawable);
if (iconColor != 0) {
topicIconWaiting = false;
setupColors(iconColor);
}
}
canvas.save();
if (lastMessageObject != null && lastMessageObject.shouldDrawWithoutBackground()) {
topicPath.offset(x, y);
int oldAlpha1 = -1, oldAlpha2 = -1;
if (alpha < 1) {
oldAlpha1 = getThemedPaint(Theme.key_paint_chatActionBackground).getAlpha();
getThemedPaint(Theme.key_paint_chatActionBackground).setAlpha((int) (oldAlpha1 * alpha));
}
canvas.drawPath(topicPath, getThemedPaint(Theme.key_paint_chatActionBackground));
if (hasGradientService()) {
if (alpha < 1) {
oldAlpha2 = Theme.chat_actionBackgroundGradientDarkenPaint.getAlpha();
Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha((int) (oldAlpha2 * alpha));
}
canvas.drawPath(topicPath, Theme.chat_actionBackgroundGradientDarkenPaint);
}
if (oldAlpha1 >= 0) {
getThemedPaint(Theme.key_paint_chatActionBackground).setAlpha(oldAlpha1);
}
if (oldAlpha2 >= 0) {
Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha(oldAlpha2);
}
topicPath.offset(-x, -y);
canvas.translate(x, y);
} else {
canvas.translate(x, y);
if (topicPath != null && topicPaint != null) {
if (topicBackgroundColorAnimated != null) {
topicPaint.setColor(topicBackgroundColorAnimated.set(topicBackgroundColor));
} else {
topicPaint.setColor(topicBackgroundColor);
}
int wasAlpha = topicPaint.getAlpha();
topicPaint.setAlpha((int) (wasAlpha * alpha));
canvas.drawPath(topicPath, topicPaint);
topicPaint.setAlpha(wasAlpha);
}
}
if (topicHitRect == null) {
topicHitRect = new RectF();
}
topicHitRect.set(x, y, x + topicWidth, y + topicHeight);
if (topicSelectorDrawable != null) {
canvas.save();
canvas.clipPath(topicPath);
AndroidUtilities.rectTmp2.set(0, 0, topicWidth, topicHeight);
topicSelectorDrawable.setBounds(AndroidUtilities.rectTmp2);
topicSelectorDrawable.draw(canvas);
canvas.restore();
}
int nameColor = topicNameColor;
if (topicNameLayout != null) {
canvas.save();
canvas.translate(AndroidUtilities.dp(17) + Theme.chat_topicTextPaint.getTextSize(), AndroidUtilities.dp(4.5f));
if (topicNameColorAnimated != null) {
Theme.chat_topicTextPaint.setColor(nameColor = topicNameColorAnimated.set(topicNameColor));
} else {
Theme.chat_topicTextPaint.setColor(nameColor = topicNameColor);
}
Theme.chat_topicTextPaint.setAlpha((int) (Theme.chat_topicTextPaint.getAlpha() * alpha));
topicNameLayout.draw(canvas);
canvas.restore();
}
if (topicArrowDrawable != null) {
int arrowColor = ColorUtils.setAlphaComponent(nameColor, 140);
if (topicArrowColor != arrowColor) {
topicArrowDrawable.setColorFilter(new PorterDuffColorFilter(topicArrowColor = arrowColor, PorterDuff.Mode.MULTIPLY));
}
topicArrowDrawable.draw(canvas);
}
canvas.restore();
}
public void drawOutbounds(Canvas canvas, float alpha) {
if (topicHitRect != null) {
canvas.save();
canvas.translate(topicHitRect.left, topicHitRect.top);
topicIconDrawable.setAlpha((int) (255 * alpha));
topicIconDrawable.setBounds(topicIconDrawableBounds);
topicIconDrawable.draw(canvas);
canvas.restore();
}
}
public void resetClick() {
if (topicSelectorDrawable != null) {
topicSelectorDrawable.setState(idleState);
}
}
private int getThemedColor(String key) {
Integer color = resourcesProvider != null ? resourcesProvider.getColor(key) : null;
return color != null ? color : Theme.getColor(key);
}
private Paint getThemedPaint(String key) {
Paint paint = resourcesProvider != null ? resourcesProvider.getPaint(key) : null;
return paint != null ? paint : Theme.getThemePaint(key);
}
private boolean hasGradientService() {
return resourcesProvider != null ? resourcesProvider.hasGradientService() : Theme.hasGradientService();
}
}

View file

@ -68,6 +68,7 @@ import org.telegram.messenger.UserObject;
import org.telegram.messenger.voip.VoIPService; import org.telegram.messenger.voip.VoIPService;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.ActionBar.ActionBarMenuItem; import org.telegram.ui.ActionBar.ActionBarMenuItem;
import org.telegram.ui.ActionBar.ActionBarMenuSubItem; import org.telegram.ui.ActionBar.ActionBarMenuSubItem;
import org.telegram.ui.ActionBar.AlertDialog; import org.telegram.ui.ActionBar.AlertDialog;
@ -486,6 +487,7 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
} }
avatars = new AvatarsImageView(context, false); avatars = new AvatarsImageView(context, false);
avatars.setAvatarsTextSize(AndroidUtilities.dp(21));
avatars.setDelegate(() -> updateAvatars(true)); avatars.setDelegate(() -> updateAvatars(true));
avatars.setVisibility(GONE); avatars.setVisibility(GONE);
addView(avatars, LayoutHelper.createFrame(108, 36, Gravity.LEFT | Gravity.TOP)); addView(avatars, LayoutHelper.createFrame(108, 36, Gravity.LEFT | Gravity.TOP));
@ -1973,7 +1975,7 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
frameLayout.invalidate(); frameLayout.invalidate();
} }
updateAvatars(avatars.avatarsDarawable.wasDraw && updateAnimated); updateAvatars(avatars.avatarsDrawable.wasDraw && updateAnimated);
} else { } else {
if (voIPService != null && voIPService.groupCall != null) { if (voIPService != null && voIPService.groupCall != null) {
updateAvatars(currentStyle == STYLE_ACTIVE_GROUP_CALL); updateAvatars(currentStyle == STYLE_ACTIVE_GROUP_CALL);
@ -2044,14 +2046,14 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
private void updateAvatars(boolean animated) { private void updateAvatars(boolean animated) {
if (!animated) { if (!animated) {
if (avatars.avatarsDarawable.transitionProgressAnimator != null) { if (avatars.avatarsDrawable.transitionProgressAnimator != null) {
avatars.avatarsDarawable.transitionProgressAnimator.cancel(); avatars.avatarsDrawable.transitionProgressAnimator.cancel();
avatars.avatarsDarawable.transitionProgressAnimator = null; avatars.avatarsDrawable.transitionProgressAnimator = null;
} }
} }
ChatObject.Call call; ChatObject.Call call;
TLRPC.User userCall; TLRPC.User userCall;
if (avatars.avatarsDarawable.transitionProgressAnimator == null) { if (avatars.avatarsDrawable.transitionProgressAnimator == null) {
int currentAccount; int currentAccount;
if (currentStyle == STYLE_INACTIVE_GROUP_CALL) { if (currentStyle == STYLE_INACTIVE_GROUP_CALL) {
if (chatActivity != null) { if (chatActivity != null) {
@ -2265,41 +2267,4 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
Integer color = resourcesProvider != null ? resourcesProvider.getColor(key) : null; Integer color = resourcesProvider != null ? resourcesProvider.getColor(key) : null;
return color != null ? color : Theme.getColor(key); return color != null ? color : Theme.getColor(key);
} }
public interface ChatActivityInterface {
default ChatObject.Call getGroupCall() {
return null;
}
default TLRPC.Chat getCurrentChat() {
return null;
}
default TLRPC.User getCurrentUser() {
return null;
}
long getDialogId();
default void scrollToMessageId(int id, int i, boolean b, int i1, boolean b1, int i2) {
}
default boolean shouldShowImport() {
return false;
}
default boolean openedWithLivestream() {
return false;
}
default long getMergeDialogId() {
return 0;
}
default int getTopicId() {
return 0;
}
}
} }

View file

@ -674,7 +674,7 @@ public class GroupCallPip implements NotificationCenter.NotificationCenterDelega
} }
private void updateAvatars(boolean animated) { private void updateAvatars(boolean animated) {
if (avatarsImageView.avatarsDarawable.transitionProgressAnimator == null) { if (avatarsImageView.avatarsDrawable.transitionProgressAnimator == null) {
ChatObject.Call call; ChatObject.Call call;
VoIPService voIPService = VoIPService.getSharedInstance(); VoIPService voIPService = VoIPService.getSharedInstance();

View file

@ -280,9 +280,11 @@ public class GroupCallPipAlertView extends LinearLayout implements VoIPService.S
super.onAttachedToWindow(); super.onAttachedToWindow();
VoIPService service = VoIPService.getSharedInstance(); VoIPService service = VoIPService.getSharedInstance();
if (service != null && service.groupCall != null) { if (service != null && service.groupCall != null) {
int color2 = AvatarDrawable.getColorForId(service.getChat().id);
AvatarDrawable avatarDrawable = new AvatarDrawable(); AvatarDrawable avatarDrawable = new AvatarDrawable();
avatarDrawable.setColor(color2); avatarDrawable.setColor(
Theme.getColor(Theme.keys_avatar_background[AvatarDrawable.getColorIndex(service.getChat().id)]),
Theme.getColor(Theme.keys_avatar_background2[AvatarDrawable.getColorIndex(service.getChat().id)])
);
avatarDrawable.setInfo(service.getChat()); avatarDrawable.setInfo(service.getChat());
avatarImageView.setImage(ImageLocation.getForLocal(service.getChat().photo.photo_small), "50_50", avatarDrawable, null); avatarImageView.setImage(ImageLocation.getForLocal(service.getChat().photo.photo_small), "50_50", avatarDrawable, null);

View file

@ -205,6 +205,9 @@ public class HintView extends FrameLayout {
if (!messageObject.isOutOwner() && cell.isDrawNameLayout()) { if (!messageObject.isOutOwner() && cell.isDrawNameLayout()) {
top += AndroidUtilities.dp(20); top += AndroidUtilities.dp(20);
} }
if (!messageObject.shouldDrawWithoutBackground() && cell.isDrawTopic()) {
top += AndroidUtilities.dp(5) + cell.getDrawTopicHeight();
}
} }
if (!isTopArrow && top <= getMeasuredHeight() + AndroidUtilities.dp(10)) { if (!isTopArrow && top <= getMeasuredHeight() + AndroidUtilities.dp(10)) {
return false; return false;

View file

@ -30,6 +30,7 @@ public class LetterDrawable extends Drawable {
public static Paint paint = new Paint(); public static Paint paint = new Paint();
private static TextPaint namePaint; private static TextPaint namePaint;
private static TextPaint namePaintTopic; private static TextPaint namePaintTopic;
private static TextPaint namePaintSmallTopic;
private RectF rect = new RectF(); private RectF rect = new RectF();
private StaticLayout textLayout; private StaticLayout textLayout;
@ -40,6 +41,7 @@ public class LetterDrawable extends Drawable {
public static final int STYLE_DEFAULT = 0; public static final int STYLE_DEFAULT = 0;
public static final int STYLE_TOPIC_DRAWABLE = 1; public static final int STYLE_TOPIC_DRAWABLE = 1;
public static final int STYLE_SMALL_TOPIC_DRAWABLE = 2;
int style; int style;
final TextPaint textPaint; final TextPaint textPaint;
public float scale = 1f; public float scale = 1f;
@ -48,7 +50,6 @@ public class LetterDrawable extends Drawable {
this(null, 0); this(null, 0);
} }
public LetterDrawable(Theme.ResourcesProvider resourcesProvider, int style) { public LetterDrawable(Theme.ResourcesProvider resourcesProvider, int style) {
super(); super();
this.style = style; this.style = style;
@ -60,7 +61,7 @@ public class LetterDrawable extends Drawable {
paint.setColor(Theme.getColor(Theme.key_sharedMedia_linkPlaceholder, resourcesProvider)); paint.setColor(Theme.getColor(Theme.key_sharedMedia_linkPlaceholder, resourcesProvider));
namePaint.setColor(Theme.getColor(Theme.key_sharedMedia_linkPlaceholderText, resourcesProvider)); namePaint.setColor(Theme.getColor(Theme.key_sharedMedia_linkPlaceholderText, resourcesProvider));
textPaint = namePaint; textPaint = namePaint;
} else { } else if (style == STYLE_TOPIC_DRAWABLE) {
if (namePaintTopic == null) { if (namePaintTopic == null) {
namePaintTopic = new TextPaint(Paint.ANTI_ALIAS_FLAG); namePaintTopic = new TextPaint(Paint.ANTI_ALIAS_FLAG);
} }
@ -68,6 +69,14 @@ public class LetterDrawable extends Drawable {
namePaintTopic.setTextSize(AndroidUtilities.dp(13)); namePaintTopic.setTextSize(AndroidUtilities.dp(13));
namePaintTopic.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD)); namePaintTopic.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
textPaint = namePaintTopic; textPaint = namePaintTopic;
} else {
if (namePaintSmallTopic == null) {
namePaintSmallTopic = new TextPaint(Paint.ANTI_ALIAS_FLAG);
}
namePaintSmallTopic.setColor(Color.WHITE);
namePaintSmallTopic.setTextSize(Theme.chat_topicTextPaint.getTextSize() * .75f);
namePaintSmallTopic.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
textPaint = namePaintSmallTopic;
} }
} }

View file

@ -0,0 +1,73 @@
package org.telegram.ui.Components.ListView;
import androidx.recyclerview.widget.DiffUtil;
import org.telegram.ui.Components.RecyclerListView;
import java.util.ArrayList;
public abstract class AdapterWithDiffUtils extends RecyclerListView.SelectionAdapter {
DiffUtilsCallback callback = new DiffUtilsCallback();
public void setItems(ArrayList<? extends Item> oldItems, ArrayList<? extends Item> newItems) {
if (newItems == null) {
newItems = new ArrayList<>();
}
callback.setItems(oldItems, newItems);
DiffUtil.calculateDiff(callback).dispatchUpdatesTo(this);
}
public static class Item {
public final int viewType;
public boolean selectable;
public Item(int viewType, boolean selectable) {
this.viewType = viewType;
this.selectable = selectable;
}
boolean compare(Item item) {
if (viewType != item.viewType) {
return false;
}
if (this.equals(item)) {
return true;
}
return false;
}
}
private class DiffUtilsCallback extends DiffUtil.Callback {
ArrayList<? extends Item> oldItems;
ArrayList<? extends Item> newItems;
public void setItems(ArrayList<? extends Item> oldItems, ArrayList<? extends Item> newItems) {
this.oldItems = oldItems;
this.newItems = newItems;
}
@Override
public int getOldListSize() {
return oldItems.size();
}
@Override
public int getNewListSize() {
return newItems.size();
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return oldItems.get(oldItemPosition).compare(newItems.get(newItemPosition));
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return false;
}
}
}

View file

@ -29,6 +29,8 @@ public class LoadingDrawable extends Drawable {
private long start = -1; private long start = -1;
private LinearGradient gradient; private LinearGradient gradient;
private int gradientColor1, gradientColor2; private int gradientColor1, gradientColor2;
public String colorKey1 = Theme.key_dialogBackground;
public String colorKey2 = Theme.key_dialogBackgroundGray;
private int gradientWidth; private int gradientWidth;
public Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); public Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
@ -46,8 +48,8 @@ public class LoadingDrawable extends Drawable {
return; return;
} }
int gwidth = Math.min(AndroidUtilities.dp(400), bounds.width()); int gwidth = Math.min(AndroidUtilities.dp(400), bounds.width());
int color1 = Theme.getColor(Theme.key_dialogBackground, resourcesProvider); int color1 = Theme.getColor(colorKey1, resourcesProvider);
int color2 = Theme.getColor(Theme.key_dialogBackgroundGray, resourcesProvider); int color2 = Theme.getColor(colorKey2, resourcesProvider);
if (gradient == null || gwidth != gradientWidth || color1 != gradientColor1 || color2 != gradientColor2) { if (gradient == null || gwidth != gradientWidth || color1 != gradientColor1 || color2 != gradientColor2) {
gradientWidth = gwidth; gradientWidth = gwidth;
gradientColor1 = color1; gradientColor1 = color1;

View file

@ -149,6 +149,8 @@ public class MessageContainsEmojiButton extends FrameLayout implements Notificat
mainText = parts[0]; mainText = parts[0];
endText = parts[1]; endText = parts[1];
loadingDrawable = new LoadingDrawable(resourcesProvider); loadingDrawable = new LoadingDrawable(resourcesProvider);
loadingDrawable.colorKey1 = Theme.key_actionBarDefaultSubmenuBackground;
loadingDrawable.colorKey2 = Theme.key_listSelector;
loadingDrawable.paint.setPathEffect(new CornerPathEffect(AndroidUtilities.dp(4))); loadingDrawable.paint.setPathEffect(new CornerPathEffect(AndroidUtilities.dp(4)));
} }
} }

View file

@ -120,6 +120,7 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
} else if (type == TYPE_TO_MANY_COMMUNITIES) { } else if (type == TYPE_TO_MANY_COMMUNITIES) {
loadInactiveChannels(); loadInactiveChannels();
} }
updatePremiumButtonText();
} }
@Override @Override
@ -128,7 +129,6 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
Context context = containerView.getContext(); Context context = containerView.getContext();
premiumButtonView = new PremiumButtonView(context, true); premiumButtonView = new PremiumButtonView(context, true);
updatePremiumButtonText();
if (!hasFixedSize) { if (!hasFixedSize) {
divider = new View(context) { divider = new View(context) {

View file

@ -65,6 +65,7 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati
SvgHelper.SvgDrawable svgIcon; SvgHelper.SvgDrawable svgIcon;
private final int startType; private final int startType;
private final boolean onlySelectedType; private final boolean onlySelectedType;
private boolean forceAbout;
private PremiumPreviewFragment.SubscriptionTier selectedTier; private PremiumPreviewFragment.SubscriptionTier selectedTier;
private int gradientAlpha = 255; private int gradientAlpha = 255;
@ -316,7 +317,7 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati
if (fragment != null && fragment.getVisibleDialog() != null) { if (fragment != null && fragment.getVisibleDialog() != null) {
fragment.getVisibleDialog().dismiss(); fragment.getVisibleDialog().dismiss();
} }
if (onlySelectedType && fragment != null) { if ((onlySelectedType || forceAbout) && fragment != null) {
fragment.presentFragment(new PremiumPreviewFragment(PremiumPreviewFragment.featureTypeToServerString(featureData.type))); fragment.presentFragment(new PremiumPreviewFragment(PremiumPreviewFragment.featureTypeToServerString(featureData.type)));
} else { } else {
PremiumPreviewFragment.buyPremium(fragment, selectedTier, PremiumPreviewFragment.featureTypeToServerString(featureData.type)); PremiumPreviewFragment.buyPremium(fragment, selectedTier, PremiumPreviewFragment.featureTypeToServerString(featureData.type));
@ -414,9 +415,17 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati
containerView.setPadding(backgroundPaddingLeft, backgroundPaddingTop - 1, backgroundPaddingLeft, 0); containerView.setPadding(backgroundPaddingLeft, backgroundPaddingTop - 1, backgroundPaddingLeft, 0);
} }
public PremiumFeatureBottomSheet setForceAbout() {
this.forceAbout = true;
premiumButtonView.clearOverlayText();
setButtonText();
return this;
}
private void setButtonText() { private void setButtonText() {
if (onlySelectedType) { if (forceAbout) {
premiumButtonView.buttonTextView.setText(LocaleController.getString(R.string.AboutTelegramPremium));
} else if (onlySelectedType) {
if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_REACTIONS) { if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_REACTIONS) {
premiumButtonView.buttonTextView.setText(LocaleController.getString(R.string.UnlockPremiumReactions)); premiumButtonView.buttonTextView.setText(LocaleController.getString(R.string.UnlockPremiumReactions));
premiumButtonView.setIcon(R.raw.unlock_icon); premiumButtonView.setIcon(R.raw.unlock_icon);

View file

@ -172,7 +172,7 @@ public class PremiumLockIconView extends ImageView {
int x = (int) (stepW * i); int x = (int) (stepW * i);
int y = (int) (stepH * j); int y = (int) (stepH * j);
int pixel = bitmap.getPixel(x, y); int pixel = bitmap.getPixel(x, y);
if (pixel != Color.TRANSPARENT) { if (Color.alpha(pixel) > 200) {
r += Color.red(pixel); r += Color.red(pixel);
g += Color.green(pixel); g += Color.green(pixel);
b += Color.blue(pixel); b += Color.blue(pixel);

View file

@ -244,8 +244,8 @@ public class VideoScreenPreview extends FrameLayout implements PagerHeaderView,
} }
} }
attachFileName = FileLoader.getAttachFileName(document); attachFileName = FileLoader.getAttachFileName(document);
imageReceiver.setImage(null, null, drawable, null, null, 1); imageReceiver.setImage(null, null, drawable, null, premiumPromo, 1);
FileLoader.getInstance(currentAccount).loadFile(document, null, FileLoader.PRIORITY_HIGH, 0); FileLoader.getInstance(currentAccount).loadFile(document, premiumPromo, FileLoader.PRIORITY_HIGH, 0);
this.document = document; this.document = document;
Utilities.globalQueue.postRunnable(() -> { Utilities.globalQueue.postRunnable(() -> {
File file = FileLoader.getInstance(currentAccount).getPathToAttach(document); File file = FileLoader.getInstance(currentAccount).getPathToAttach(document);
@ -577,7 +577,7 @@ public class VideoScreenPreview extends FrameLayout implements PagerHeaderView,
"&dc=" + document.dc_id + "&dc=" + document.dc_id +
"&size=" + document.size + "&size=" + document.size +
"&mime=" + URLEncoder.encode(document.mime_type, "UTF-8") + "&mime=" + URLEncoder.encode(document.mime_type, "UTF-8") +
"&rid=" + FileLoader.getInstance(currentAccount).getFileReference(document) + "&rid=" + FileLoader.getInstance(currentAccount).getFileReference(MediaDataController.getInstance(currentAccount).getPremiumPromo()) +
"&name=" + URLEncoder.encode(FileLoader.getDocumentFileName(document), "UTF-8") + "&name=" + URLEncoder.encode(FileLoader.getDocumentFileName(document), "UTF-8") +
"&reference=" + Utilities.bytesToHex(document.file_reference != null ? document.file_reference : new byte[0]); "&reference=" + Utilities.bytesToHex(document.file_reference != null ? document.file_reference : new byte[0]);
uri = Uri.parse("tg://" + attachFileName + params); uri = Uri.parse("tg://" + attachFileName + params);

View file

@ -7,10 +7,12 @@ import android.animation.ValueAnimator;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.ColorFilter; import android.graphics.ColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.PixelFormat; import android.graphics.PixelFormat;
import android.graphics.RectF; import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.text.TextPaint; import android.text.TextPaint;
import android.view.View; import android.view.View;

View file

@ -108,8 +108,8 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma
private boolean applyTransformation; private boolean applyTransformation;
private boolean needScale; private boolean needScale;
private final RectF dstRect = new RectF(); private final RectF dstRect = new RectF();
private RectF dstRectBackground; private RectF[] dstRectBackground = new RectF[DrawingInBackgroundThreadDrawable.THREAD_COUNT];
private Paint backgroundPaint; private Paint[] backgroundPaint = new Paint[DrawingInBackgroundThreadDrawable.THREAD_COUNT];
protected static final Handler uiHandler = new Handler(Looper.getMainLooper()); protected static final Handler uiHandler = new Handler(Looper.getMainLooper());
protected volatile boolean isRunning; protected volatile boolean isRunning;
protected volatile boolean isRecycled; protected volatile boolean isRecycled;
@ -175,6 +175,7 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma
if (lottieCacheGenerateQueue == null) { if (lottieCacheGenerateQueue == null) {
createCacheGenQueue(); createCacheGenQueue();
} }
BitmapsCache.incrementTaskCounter();
lottieCacheGenerateQueue.postRunnable(cacheGenerateTask = () -> { lottieCacheGenerateQueue.postRunnable(cacheGenerateTask = () -> {
BitmapsCache bitmapsCacheFinal = bitmapsCache; BitmapsCache bitmapsCacheFinal = bitmapsCache;
if (bitmapsCacheFinal != null) { if (bitmapsCacheFinal != null) {
@ -189,7 +190,10 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma
private Runnable uiRunnableCacheFinished = new Runnable() { private Runnable uiRunnableCacheFinished = new Runnable() {
@Override @Override
public void run() { public void run() {
cacheGenerateTask = null; if (cacheGenerateTask != null) {
BitmapsCache.decrementTaskCounter();
cacheGenerateTask = null;
}
generatingCache = false; generatingCache = false;
decodeFrameFinishedInternal(); decodeFrameFinishedInternal();
} }
@ -205,6 +209,7 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma
protected void checkRunningTasks() { protected void checkRunningTasks() {
if (cacheGenerateTask != null) { if (cacheGenerateTask != null) {
lottieCacheGenerateQueue.cancelRunnable(cacheGenerateTask); lottieCacheGenerateQueue.cancelRunnable(cacheGenerateTask);
BitmapsCache.decrementTaskCounter();
cacheGenerateTask = null; cacheGenerateTask = null;
} }
if (!hasParentView() && nextRenderingBitmap != null && loadFrameTask != null) { if (!hasParentView() && nextRenderingBitmap != null && loadFrameTask != null) {
@ -740,6 +745,7 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma
if (bitmapsCache != null) { if (bitmapsCache != null) {
bitmapsCache.cancelCreate(); bitmapsCache.cancelCreate();
} }
BitmapsCache.decrementTaskCounter();
}, 600); }, 600);
} else if (!mustCancel && cancelCache != null) { } else if (!mustCancel && cancelCache != null) {
AndroidUtilities.cancelRunOnUIThread(cancelCache); AndroidUtilities.cancelRunOnUIThread(cancelCache);
@ -905,10 +911,6 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma
} }
protected boolean scheduleNextGetFrame() { protected boolean scheduleNextGetFrame() {
return scheduleNextGetFrame(false);
}
protected boolean scheduleNextGetFrame(boolean allowGroupedUpdateLocal) {
if (loadFrameTask != null || nextRenderingBitmap != null || !canLoadFrames() || loadingInBackground || destroyWhenDone || !isRunning && (!decodeSingleFrame || decodeSingleFrame && singleFrameDecoded)) { if (loadFrameTask != null || nextRenderingBitmap != null || !canLoadFrames() || loadingInBackground || destroyWhenDone || !isRunning && (!decodeSingleFrame || decodeSingleFrame && singleFrameDecoded)) {
return false; return false;
} }
@ -924,8 +926,8 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma
newReplaceColors = null; newReplaceColors = null;
} }
loadFrameTask = loadFrameRunnable; loadFrameTask = loadFrameRunnable;
if (allowGroupedUpdateLocal && shouldLimitFps) { if (shouldLimitFps) {
DispatchQueuePoolBackground.execute(loadFrameTask); DispatchQueuePoolBackground.execute(loadFrameTask, frameWaitSync != null);
} else { } else {
loadFrameRunnableQueue.execute(loadFrameTask); loadFrameRunnableQueue.execute(loadFrameTask);
} }
@ -976,7 +978,7 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma
if (resetFrame && !isRunning) { if (resetFrame && !isRunning) {
isRunning = true; isRunning = true;
} }
if (scheduleNextGetFrame(false)) { if (scheduleNextGetFrame()) {
if (!async) { if (!async) {
try { try {
frameWaitSync.await(); frameWaitSync.await();
@ -1080,27 +1082,27 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma
} }
} }
} }
scheduleNextGetFrame(true); scheduleNextGetFrame();
} }
@Override @Override
public void draw(Canvas canvas) { public void draw(Canvas canvas) {
drawInternal(canvas, false, 0); drawInternal(canvas, false, 0, 0);
} }
public void drawInBackground(Canvas canvas, float x, float y, float w, float h, int alpha, ColorFilter colorFilter) { public void drawInBackground(Canvas canvas, float x, float y, float w, float h, int alpha, ColorFilter colorFilter, int threadIndex) {
if (dstRectBackground == null) { if (dstRectBackground[threadIndex] == null) {
dstRectBackground = new RectF(); dstRectBackground[threadIndex] = new RectF();
backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); backgroundPaint[threadIndex] = new Paint(Paint.ANTI_ALIAS_FLAG);
backgroundPaint.setFilterBitmap(true); backgroundPaint[threadIndex].setFilterBitmap(true);
} }
backgroundPaint.setAlpha(alpha); backgroundPaint[threadIndex].setAlpha(alpha);
backgroundPaint.setColorFilter(colorFilter); backgroundPaint[threadIndex].setColorFilter(colorFilter);
dstRectBackground.set(x, y, x + w, y + h); dstRectBackground[threadIndex].set(x, y, x + w, y + h);
drawInternal(canvas, true, 0); drawInternal(canvas, true, 0, threadIndex);
} }
public void drawInternal(Canvas canvas, boolean drawInBackground, long time) { public void drawInternal(Canvas canvas, boolean drawInBackground, long time, int threadIndex) {
if (!canLoadFrames() || destroyWhenDone) { if (!canLoadFrames() || destroyWhenDone) {
return; return;
} }
@ -1108,8 +1110,8 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma
updateCurrentFrame(time, false); updateCurrentFrame(time, false);
} }
RectF rect = drawInBackground ? dstRectBackground : dstRect; RectF rect = drawInBackground ? dstRectBackground[threadIndex] : dstRect;
Paint paint = drawInBackground ? backgroundPaint : getPaint(); Paint paint = drawInBackground ? backgroundPaint[threadIndex] : getPaint();
if (paint.getAlpha() == 0) { if (paint.getAlpha() == 0) {
return; return;
@ -1163,7 +1165,7 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma
} }
if (isRunning) { if (isRunning) {
if (renderingBitmap == null && nextRenderingBitmap == null) { if (renderingBitmap == null && nextRenderingBitmap == null) {
scheduleNextGetFrame(true); scheduleNextGetFrame();
} else if (nextRenderingBitmap != null && (renderingBitmap == null || (timeDiff >= timeCheck && !skipFrameUpdate))) { } else if (nextRenderingBitmap != null && (renderingBitmap == null || (timeDiff >= timeCheck && !skipFrameUpdate))) {
if (vibrationPattern != null && currentParentView != null && allowVibration) { if (vibrationPattern != null && currentParentView != null && allowVibration) {
Integer force = vibrationPattern.get(currentFrame - 1); Integer force = vibrationPattern.get(currentFrame - 1);
@ -1322,13 +1324,22 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma
if (lottieCacheGenerateQueue == null) { if (lottieCacheGenerateQueue == null) {
createCacheGenQueue(); createCacheGenQueue();
} }
lottieCacheGenerateQueue.postRunnable(cacheGenerateTask = () -> { if (cacheGenerateTask == null) {
BitmapsCache bitmapsCacheFinal = bitmapsCache; BitmapsCache.incrementTaskCounter();
if (bitmapsCacheFinal != null) { lottieCacheGenerateQueue.postRunnable(cacheGenerateTask = () -> {
bitmapsCacheFinal.createCache(); BitmapsCache bitmapsCacheFinal = bitmapsCache;
} if (bitmapsCacheFinal != null) {
AndroidUtilities.runOnUIThread(onReady); bitmapsCacheFinal.createCache();
}); }
AndroidUtilities.runOnUIThread(() -> {
onReady.run();
if (cacheGenerateTask != null) {
cacheGenerateTask = null;
BitmapsCache.decrementTaskCounter();
}
});
});
}
}); });
} }
}); });

View file

@ -70,7 +70,7 @@ public class ReactedHeaderView extends FrameLayout {
addView(titleView, LayoutHelper.createFrameRelatively(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.START | Gravity.CENTER_VERTICAL, 40, 0, 62, 0)); addView(titleView, LayoutHelper.createFrameRelatively(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.START | Gravity.CENTER_VERTICAL, 40, 0, 62, 0));
avatarsImageView = new AvatarsImageView(context, false); avatarsImageView = new AvatarsImageView(context, false);
avatarsImageView.setStyle(AvatarsDarawable.STYLE_MESSAGE_SEEN); avatarsImageView.setStyle(AvatarsDrawable.STYLE_MESSAGE_SEEN);
addView(avatarsImageView, LayoutHelper.createFrameRelatively(24 + 12 + 12 + 8, LayoutHelper.MATCH_PARENT, Gravity.END | Gravity.CENTER_VERTICAL, 0, 0, 0, 0)); addView(avatarsImageView, LayoutHelper.createFrameRelatively(24 + 12 + 12 + 8, LayoutHelper.MATCH_PARENT, Gravity.END | Gravity.CENTER_VERTICAL, 0, 0, 0, 0));
iconView = new ImageView(context); iconView = new ImageView(context);

View file

@ -8,16 +8,13 @@ import android.content.Context;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.text.TextUtils;
import android.util.LongSparseArray; import android.util.LongSparseArray;
import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
@ -187,6 +184,7 @@ public class ReactedUsersListView extends FrameLayout {
return !customReactionsEmoji.isEmpty() && messageContainsEmojiButton != null ? messageContainsEmojiButton.getMeasuredHeight() + AndroidUtilities.dp(8) : 0; return !customReactionsEmoji.isEmpty() && messageContainsEmojiButton != null ? messageContainsEmojiButton.getMeasuredHeight() + AndroidUtilities.dp(8) : 0;
} }
}; };
loadingView.setColors(Theme.key_actionBarDefaultSubmenuBackground, Theme.key_listSelector, null);
loadingView.setIsSingleCell(true); loadingView.setIsSingleCell(true);
loadingView.setItemsCount(predictiveCount); loadingView.setItemsCount(predictiveCount);

View file

@ -13,7 +13,6 @@ import android.view.ViewConfiguration;
import androidx.core.graphics.ColorUtils; import androidx.core.graphics.ColorUtils;
import androidx.recyclerview.widget.ChatListItemAnimator; import androidx.recyclerview.widget.ChatListItemAnimator;
import org.checkerframework.checker.units.qual.A;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.DocumentObject; import org.telegram.messenger.DocumentObject;
@ -28,7 +27,7 @@ import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.ChatMessageCell; import org.telegram.ui.Cells.ChatMessageCell;
import org.telegram.ui.Components.AnimatedEmojiDrawable; import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AvatarsDarawable; import org.telegram.ui.Components.AvatarsDrawable;
import org.telegram.ui.Components.CounterView; import org.telegram.ui.Components.CounterView;
import java.util.ArrayList; import java.util.ArrayList;
@ -218,12 +217,12 @@ public class ReactionsLayoutInBubble {
button.height = AndroidUtilities.dp(14); button.height = AndroidUtilities.dp(14);
} else { } else {
button.width = (int) (AndroidUtilities.dp(8) + AndroidUtilities.dp(20) + AndroidUtilities.dp(4)); button.width = (int) (AndroidUtilities.dp(8) + AndroidUtilities.dp(20) + AndroidUtilities.dp(4));
if (button.avatarsDarawable != null && button.users.size() > 0) { if (button.avatarsDrawable != null && button.users.size() > 0) {
button.users.size(); button.users.size();
int c1 = 1; int c1 = 1;
int c2 = button.users.size() > 1 ? button.users.size() - 1 : 0; int c2 = button.users.size() > 1 ? button.users.size() - 1 : 0;
button.width += AndroidUtilities.dp(2) + c1 * AndroidUtilities.dp(20) + c2 * AndroidUtilities.dp(20) * 0.8f + AndroidUtilities.dp(1); button.width += AndroidUtilities.dp(2) + c1 * AndroidUtilities.dp(20) + c2 * AndroidUtilities.dp(20) * 0.8f + AndroidUtilities.dp(1);
button.avatarsDarawable.height = AndroidUtilities.dp(26); button.avatarsDrawable.height = AndroidUtilities.dp(26);
} else { } else {
button.width += button.counterDrawable.textPaint.measureText(button.countText) + AndroidUtilities.dp(8); button.width += button.counterDrawable.textPaint.measureText(button.countText) + AndroidUtilities.dp(8);
} }
@ -350,7 +349,7 @@ public class ReactionsLayoutInBubble {
} }
if (lastButton != null) { if (lastButton != null) {
lastDrawingReactionButtonsTmp.remove(button.key); lastDrawingReactionButtonsTmp.remove(button.key);
if (button.x != lastButton.x || button.y != lastButton.y || button.width != lastButton.width || button.count != lastButton.count || button.choosen != lastButton.choosen || button.avatarsDarawable != null || lastButton.avatarsDarawable != null) { if (button.x != lastButton.x || button.y != lastButton.y || button.width != lastButton.width || button.count != lastButton.count || button.choosen != lastButton.choosen || button.avatarsDrawable != null || lastButton.avatarsDrawable != null) {
button.animateFromX = lastButton.x; button.animateFromX = lastButton.x;
button.animateFromY = lastButton.y; button.animateFromY = lastButton.y;
button.animateFromWidth = lastButton.width; button.animateFromWidth = lastButton.width;
@ -363,15 +362,15 @@ public class ReactionsLayoutInBubble {
button.counterDrawable.setCount(lastButton.count, false); button.counterDrawable.setCount(lastButton.count, false);
button.counterDrawable.setCount(button.count, true); button.counterDrawable.setCount(button.count, true);
} }
if (button.avatarsDarawable != null || lastButton.avatarsDarawable != null) { if (button.avatarsDrawable != null || lastButton.avatarsDrawable != null) {
if (button.avatarsDarawable == null) { if (button.avatarsDrawable == null) {
button.setUsers(new ArrayList<>()); button.setUsers(new ArrayList<>());
} }
if (lastButton.avatarsDarawable == null) { if (lastButton.avatarsDrawable == null) {
lastButton.setUsers(new ArrayList<>()); lastButton.setUsers(new ArrayList<>());
} }
if (!equalsUsersList(lastButton.users, button.users)) { if (!equalsUsersList(lastButton.users, button.users)) {
button.avatarsDarawable.animateFromState(lastButton.avatarsDarawable, currentAccount, false); button.avatarsDrawable.animateFromState(lastButton.avatarsDrawable, currentAccount, false);
} }
} }
changed = true; changed = true;
@ -493,7 +492,7 @@ public class ReactionsLayoutInBubble {
int lastDrawnTextColor; int lastDrawnTextColor;
int lastDrawnBackgroundColor; int lastDrawnBackgroundColor;
boolean isSelected; boolean isSelected;
AvatarsDarawable avatarsDarawable; AvatarsDrawable avatarsDrawable;
ArrayList<TLRPC.User> users; ArrayList<TLRPC.User> users;
public ReactionButton(TLRPC.ReactionCount reactionCount, boolean isSmall) { public ReactionButton(TLRPC.ReactionCount reactionCount, boolean isSmall) {
@ -627,12 +626,12 @@ public class ReactionsLayoutInBubble {
canvas.restore(); canvas.restore();
} }
if (avatarsDarawable != null) { if (avatarsDrawable != null) {
canvas.save(); canvas.save();
canvas.translate(AndroidUtilities.dp(10) + AndroidUtilities.dp(20) + AndroidUtilities.dp(2), 0); canvas.translate(AndroidUtilities.dp(10) + AndroidUtilities.dp(20) + AndroidUtilities.dp(2), 0);
avatarsDarawable.setAlpha(alpha); avatarsDrawable.setAlpha(alpha);
avatarsDarawable.setTransitionProgress(progress); avatarsDrawable.setTransitionProgress(progress);
avatarsDarawable.onDraw(canvas); avatarsDrawable.onDraw(canvas);
canvas.restore(); canvas.restore();
} }
} }
@ -688,25 +687,25 @@ public class ReactionsLayoutInBubble {
this.users = users; this.users = users;
if (users != null) { if (users != null) {
Collections.sort(users, usersComparator); Collections.sort(users, usersComparator);
if (avatarsDarawable == null) { if (avatarsDrawable == null) {
avatarsDarawable = new AvatarsDarawable(parentView, false); avatarsDrawable = new AvatarsDrawable(parentView, false);
avatarsDarawable.transitionDuration = ChatListItemAnimator.DEFAULT_DURATION; avatarsDrawable.transitionDuration = ChatListItemAnimator.DEFAULT_DURATION;
avatarsDarawable.transitionInterpolator = ChatListItemAnimator.DEFAULT_INTERPOLATOR; avatarsDrawable.transitionInterpolator = ChatListItemAnimator.DEFAULT_INTERPOLATOR;
avatarsDarawable.setSize(AndroidUtilities.dp(20)); avatarsDrawable.setSize(AndroidUtilities.dp(20));
avatarsDarawable.width = AndroidUtilities.dp(100); avatarsDrawable.width = AndroidUtilities.dp(100);
avatarsDarawable.height = height; avatarsDrawable.height = height;
avatarsDarawable.setAvatarsTextSize(AndroidUtilities.dp(22)); avatarsDrawable.setAvatarsTextSize(AndroidUtilities.dp(22));
if (attached) { if (attached) {
avatarsDarawable.onAttachedToWindow(); avatarsDrawable.onAttachedToWindow();
} }
} }
for (int i = 0; i < users.size(); i++) { for (int i = 0; i < users.size(); i++) {
if (i == 3) { if (i == 3) {
break; break;
} }
avatarsDarawable.setObject(i, currentAccount, users.get(i)); avatarsDrawable.setObject(i, currentAccount, users.get(i));
} }
avatarsDarawable.commitTransition(false); avatarsDrawable.commitTransition(false);
} }
} }
@ -714,8 +713,8 @@ public class ReactionsLayoutInBubble {
if (imageReceiver != null) { if (imageReceiver != null) {
imageReceiver.onAttachedToWindow(); imageReceiver.onAttachedToWindow();
} }
if (avatarsDarawable != null) { if (avatarsDrawable != null) {
avatarsDarawable.onAttachedToWindow(); avatarsDrawable.onAttachedToWindow();
} }
if (animatedEmojiDrawable != null) { if (animatedEmojiDrawable != null) {
animatedEmojiDrawable.addView(parentView); animatedEmojiDrawable.addView(parentView);
@ -726,8 +725,8 @@ public class ReactionsLayoutInBubble {
if (imageReceiver != null) { if (imageReceiver != null) {
imageReceiver.onDetachedFromWindow(); imageReceiver.onDetachedFromWindow();
} }
if (avatarsDarawable != null) { if (avatarsDrawable != null) {
avatarsDarawable.onDetachedFromWindow(); avatarsDrawable.onDetachedFromWindow();
} }
if (animatedEmojiDrawable != null) { if (animatedEmojiDrawable != null) {
animatedEmojiDrawable.removeView(parentView); animatedEmojiDrawable.removeView(parentView);

View file

@ -8,7 +8,7 @@ import org.telegram.ui.Components.AnimatedEmojiSpan;
public class ReactionsUtils { public class ReactionsUtils {
public static final String APPEAR_ANIMATION_FILTER = "30_30_nolimit_pcache"; public static final String APPEAR_ANIMATION_FILTER = "30_30_nolimit";
public static final String SELECT_ANIMATION_FILTER = "60_60_pcache"; public static final String SELECT_ANIMATION_FILTER = "60_60_pcache";
public static final String ACTIVATE_ANIMATION_FILTER = "30_30_pcache"; public static final String ACTIVATE_ANIMATION_FILTER = "30_30_pcache";

View file

@ -56,6 +56,7 @@ import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.AlertDialog; import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.ListView.AdapterWithDiffUtils;
import org.telegram.ui.Components.Premium.PremiumFeatureBottomSheet; import org.telegram.ui.Components.Premium.PremiumFeatureBottomSheet;
import org.telegram.ui.Components.Premium.PremiumLockIconView; import org.telegram.ui.Components.Premium.PremiumLockIconView;
import org.telegram.ui.Components.Reactions.CustomEmojiReactionsWindow; import org.telegram.ui.Components.Reactions.CustomEmojiReactionsWindow;
@ -272,13 +273,12 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
}); });
recyclerListView.setLayoutManager(linearLayoutManager); recyclerListView.setLayoutManager(linearLayoutManager);
recyclerListView.setOverScrollMode(View.OVER_SCROLL_NEVER); recyclerListView.setOverScrollMode(View.OVER_SCROLL_NEVER);
recyclerListView.setAdapter(listAdapter = new RecyclerView.Adapter() { recyclerListView.setAdapter(listAdapter = new AdapterWithDiffUtils() {
int rowCount; @Override
int reactionsStartRow; public boolean isEnabled(RecyclerView.ViewHolder holder) {
int reactionsEndRow; return false;
int premiumUnlockButtonRow; }
int customReactionsEmojiRow;
@NonNull @NonNull
@Override @Override
@ -286,10 +286,10 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
View view; View view;
switch (viewType) { switch (viewType) {
default: default:
case 0: case VIEW_TYPE_REACTION:
view = new ReactionHolderView(context, true); view = new ReactionHolderView(context, true);
break; break;
case 1: case VIEW_TYPE_PREMIUM_BUTTON:
premiumLockContainer = new FrameLayout(context); premiumLockContainer = new FrameLayout(context);
premiumLockIconView = new PremiumLockIconView(context, PremiumLockIconView.TYPE_REACTIONS); premiumLockIconView = new PremiumLockIconView(context, PremiumLockIconView.TYPE_REACTIONS);
premiumLockIconView.setColor(ColorUtils.blendARGB(Theme.getColor(Theme.key_actionBarDefaultSubmenuItemIcon), Theme.getColor(Theme.key_dialogBackground), 0.7f)); premiumLockIconView.setColor(ColorUtils.blendARGB(Theme.getColor(Theme.key_actionBarDefaultSubmenuItemIcon), Theme.getColor(Theme.key_dialogBackground), 0.7f));
@ -305,7 +305,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
}); });
view = premiumLockContainer; view = premiumLockContainer;
break; break;
case 2: case VIEW_TYPE_CUSTOM_EMOJI_BUTTON:
customReactionsContainer = new CustomReactionsContainer(context); customReactionsContainer = new CustomReactionsContainer(context);
customEmojiReactionsIconView = new InternalImageView(context); customEmojiReactionsIconView = new InternalImageView(context);
customEmojiReactionsIconView.setImageResource(R.drawable.msg_reactions_expand); customEmojiReactionsIconView.setImageResource(R.drawable.msg_reactions_expand);
@ -328,45 +328,67 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
@Override @Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (holder.getItemViewType() == 0) { if (holder.getItemViewType() == VIEW_TYPE_REACTION) {
ReactionHolderView h = (ReactionHolderView) holder.itemView; ReactionHolderView h = (ReactionHolderView) holder.itemView;
h.setScaleX(1); h.setScaleX(1);
h.setScaleY(1); h.setScaleY(1);
h.setReaction(visibleReactionsList.get(position), position); h.setReaction(items.get(position).reaction, position);
} }
} }
@Override @Override
public int getItemCount() { public int getItemCount() {
return rowCount; return items.size();
} }
@Override @Override
public int getItemViewType(int position) { public int getItemViewType(int position) {
if (position >= 0 && position < visibleReactionsList.size()) { return items.get(position).viewType;
return 0;
}
if (position == premiumUnlockButtonRow) {
return 1;
}
return 2;
} }
ArrayList<InnerItem> items = new ArrayList<>();
ArrayList<InnerItem> oldItems = new ArrayList<>();
private static final int VIEW_TYPE_REACTION = 0;
private static final int VIEW_TYPE_PREMIUM_BUTTON = 1;
private static final int VIEW_TYPE_CUSTOM_EMOJI_BUTTON = 2;
@Override @Override
public void notifyDataSetChanged() { public void notifyDataSetChanged() {
rowCount = 0; oldItems.clear();
premiumUnlockButtonRow = -1; oldItems.addAll(items);
customReactionsEmojiRow = -1; items.clear();
reactionsStartRow = rowCount; for (int i = 0; i < visibleReactionsList.size(); i++) {
rowCount += visibleReactionsList.size(); items.add(new InnerItem(VIEW_TYPE_REACTION, visibleReactionsList.get(i)));
reactionsEndRow = rowCount; }
if (showUnlockPremiumButton()) { if (showUnlockPremiumButton()) {
premiumUnlockButtonRow = rowCount++; items.add(new InnerItem(VIEW_TYPE_PREMIUM_BUTTON, null));
} }
if (showCustomEmojiReaction()) { if (showCustomEmojiReaction()) {
customReactionsEmojiRow = rowCount++; items.add(new InnerItem(VIEW_TYPE_CUSTOM_EMOJI_BUTTON, null));
} }
super.notifyDataSetChanged(); setItems(oldItems, items);
}
class InnerItem extends AdapterWithDiffUtils.Item {
ReactionsLayoutInBubble.VisibleReaction reaction;
public InnerItem(int viewType, ReactionsLayoutInBubble.VisibleReaction reaction) {
super(viewType, false);
this.reaction = reaction;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
InnerItem innerItem = (InnerItem) o;
if (viewType == innerItem.viewType && viewType == VIEW_TYPE_REACTION) {
return reaction != null && reaction.equals(innerItem.reaction);
}
return viewType == innerItem.viewType;
}
} }
}); });
recyclerListView.addOnScrollListener(new LeftRightShadowsListener()); recyclerListView.addOnScrollListener(new LeftRightShadowsListener());
@ -439,7 +461,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
nextRecentReaction.getLayoutParams().height = size; nextRecentReaction.getLayoutParams().height = size;
bgPaint.setColor(Theme.getColor(Theme.key_actionBarDefaultSubmenuBackground, resourcesProvider)); bgPaint.setColor(Theme.getColor(Theme.key_actionBarDefaultSubmenuBackground, resourcesProvider));
MediaDataController.getInstance(currentAccount).preloadReactions(); MediaDataController.getInstance(currentAccount).preloadDefaultReactions();
} }
private void animatePullingBack() { private void animatePullingBack() {
@ -462,21 +484,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
return; return;
} }
reactionsWindow = new CustomEmojiReactionsWindow(fragment, allReactionsList, selectedReactions, this, resourcesProvider); reactionsWindow = new CustomEmojiReactionsWindow(fragment, allReactionsList, selectedReactions, this, resourcesProvider);
for (int i = 0; i < recyclerListView.getChildCount(); i++) {
View child = recyclerListView.getChildAt(i);
if (child instanceof ReactionHolderView) {
ReactionHolderView holderView = (ReactionHolderView) child;
if (holderView.loopImageView.getImageReceiver().getLottieAnimation() != null) {
holderView.loopImageView.getImageReceiver().moveLottieToFront();
}
if (holderView.loopImageView.animatedEmojiDrawable != null) {
reactionsWindow.getSelectAnimatedEmojiDialog().putAnimatedEmojiToCache(holderView.loopImageView.animatedEmojiDrawable);
}
}
}
if (nextRecentReaction != null && nextRecentReaction.getVisibility() == View.VISIBLE) {
nextRecentReaction.loopImageView.getImageReceiver().moveLottieToFront();
}
reactionsWindow.onDismissListener(() -> { reactionsWindow.onDismissListener(() -> {
reactionsWindow = null; reactionsWindow = null;
}); });
@ -1225,33 +1233,27 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
addView(enterImageView, LayoutHelper.createFrame(34, 34, Gravity.CENTER)); addView(enterImageView, LayoutHelper.createFrame(34, 34, Gravity.CENTER));
addView(pressedBackupImageView, LayoutHelper.createFrame(34, 34, Gravity.CENTER)); addView(pressedBackupImageView, LayoutHelper.createFrame(34, 34, Gravity.CENTER));
addView(loopImageView, LayoutHelper.createFrame(34, 34, Gravity.CENTER)); addView(loopImageView, LayoutHelper.createFrame(34, 34, Gravity.CENTER));
enterImageView.setLayerNum(Integer.MAX_VALUE);
loopImageView.setLayerNum(Integer.MAX_VALUE);
pressedBackupImageView.setLayerNum(Integer.MAX_VALUE);
} }
private void setReaction(ReactionsLayoutInBubble.VisibleReaction react, int position) { private void setReaction(ReactionsLayoutInBubble.VisibleReaction react, int position) {
if (currentReaction != null && currentReaction.equals(react)) { if (currentReaction != null && currentReaction.equals(react)) {
updateImage(react);
return; return;
} }
this.position = position; this.position = position;
resetAnimation(); resetAnimation();
currentReaction = react; currentReaction = react;
selected = selectedReactions.contains(react); selected = selectedReactions.contains(react);
hasEnterAnimation = false;//currentReaction.emojicon != null && (!showCustomEmojiReaction() || allReactionsIsDefault); hasEnterAnimation = currentReaction.emojicon != null && (!showCustomEmojiReaction() || allReactionsIsDefault);
if (currentReaction.emojicon != null) { if (currentReaction.emojicon != null) {
TLRPC.TL_availableReaction defaultReaction = MediaDataController.getInstance(currentAccount).getReactionsMap().get(currentReaction.emojicon); updateImage(react);
if (defaultReaction != null) {
if (recyclerReaction) {
loopImageView.getImageReceiver().setUniqKeyPrefix("r");
}
SvgHelper.SvgDrawable svgThumb = DocumentObject.getSvgThumb(defaultReaction.activate_animation, Theme.key_windowBackgroundGray, 1.0f);
enterImageView.getImageReceiver().setImage(ImageLocation.getForDocument(defaultReaction.appear_animation), ReactionsUtils.APPEAR_ANIMATION_FILTER, null, null, svgThumb, 0, "tgs", react, 0);
pressedBackupImageView.getImageReceiver().setImage(ImageLocation.getForDocument(defaultReaction.select_animation), ReactionsUtils.SELECT_ANIMATION_FILTER, null, null, svgThumb, 0, "tgs", react, 0);
loopImageView.getImageReceiver().setImage(ImageLocation.getForDocument(defaultReaction.select_animation), ReactionsUtils.SELECT_ANIMATION_FILTER, null, null, hasEnterAnimation ? null : svgThumb, 0, "tgs", currentReaction, 0);
loopImageView.setAnimatedEmojiDrawable(null);
pressedBackupImageView.setAnimatedEmojiDrawable(null); pressedBackupImageView.setAnimatedEmojiDrawable(null);
if (enterImageView.getImageReceiver().getLottieAnimation() != null) { if (enterImageView.getImageReceiver().getLottieAnimation() != null) {
enterImageView.getImageReceiver().getLottieAnimation().setCurrentFrame(0, false); enterImageView.getImageReceiver().getLottieAnimation().setCurrentFrame(0, false);
}
} }
} else { } else {
pressedBackupImageView.getImageReceiver().clearImage(); pressedBackupImageView.getImageReceiver().clearImage();
@ -1259,8 +1261,6 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
pressedBackupImageView.setAnimatedEmojiDrawable(new AnimatedEmojiDrawable(AnimatedEmojiDrawable.CACHE_TYPE_ALERT_PREVIEW_LARGE, currentAccount, currentReaction.documentId)); pressedBackupImageView.setAnimatedEmojiDrawable(new AnimatedEmojiDrawable(AnimatedEmojiDrawable.CACHE_TYPE_ALERT_PREVIEW_LARGE, currentAccount, currentReaction.documentId));
loopImageView.setAnimatedEmojiDrawable(new AnimatedEmojiDrawable(AnimatedEmojiDrawable.CACHE_TYPE_ALERT_PREVIEW, currentAccount, currentReaction.documentId)); loopImageView.setAnimatedEmojiDrawable(new AnimatedEmojiDrawable(AnimatedEmojiDrawable.CACHE_TYPE_ALERT_PREVIEW, currentAccount, currentReaction.documentId));
} }
enterImageView.setLayerNum(Integer.MAX_VALUE);
loopImageView.setLayerNum(Integer.MAX_VALUE);
setFocusable(true); setFocusable(true);
shouldSwitchToLoopView = hasEnterAnimation && showCustomEmojiReaction(); shouldSwitchToLoopView = hasEnterAnimation && showCustomEmojiReaction();
if (!hasEnterAnimation) { if (!hasEnterAnimation) {
@ -1281,6 +1281,18 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
} }
} }
private void updateImage(ReactionsLayoutInBubble.VisibleReaction react) {
if (currentReaction.emojicon != null) {
TLRPC.TL_availableReaction defaultReaction = MediaDataController.getInstance(currentAccount).getReactionsMap().get(currentReaction.emojicon);
if (defaultReaction != null) {
SvgHelper.SvgDrawable svgThumb = DocumentObject.getSvgThumb(defaultReaction.activate_animation, Theme.key_windowBackgroundGray, 1.0f);
enterImageView.getImageReceiver().setImage(ImageLocation.getForDocument(defaultReaction.appear_animation), ReactionsUtils.APPEAR_ANIMATION_FILTER, null, null, svgThumb, 0, "tgs", react, 0);
pressedBackupImageView.getImageReceiver().setImage(ImageLocation.getForDocument(defaultReaction.select_animation), ReactionsUtils.SELECT_ANIMATION_FILTER, null, null, svgThumb, 0, "tgs", react, 0);
loopImageView.getImageReceiver().setImage(ImageLocation.getForDocument(defaultReaction.select_animation), ReactionsUtils.SELECT_ANIMATION_FILTER, null, null, hasEnterAnimation ? null : svgThumb, 0, "tgs", currentReaction, 0);
}
}
}
@Override @Override
protected void onAttachedToWindow() { protected void onAttachedToWindow() {
super.onAttachedToWindow(); super.onAttachedToWindow();
@ -1511,8 +1523,6 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
public void play(int delay) { public void play(int delay) {
isEnter = true; isEnter = true;
// cellFlickerDrawable.progress = 0;
// cellFlickerDrawable.repeatEnabled = false;
invalidate(); invalidate();
if (valueAnimator != null) { if (valueAnimator != null) {
valueAnimator.removeAllListeners(); valueAnimator.removeAllListeners();

View file

@ -1899,6 +1899,10 @@ public class RecyclerListView extends RecyclerView {
int emptyViewAnimateToVisibility; int emptyViewAnimateToVisibility;
public void checkIfEmpty() {
checkIfEmpty(updateEmptyViewAnimated());
}
private void checkIfEmpty(boolean animated) { private void checkIfEmpty(boolean animated) {
if (isHidden) { if (isHidden) {
return; return;

View file

@ -434,7 +434,7 @@ public class SearchViewPager extends ViewPagerFixed implements FilteredSearchVie
return false; return false;
} }
for (MessageObject obj : selectedFiles.values()) { for (MessageObject obj : selectedFiles.values()) {
if (obj.getDocument() != null && obj.getDocument().size >= 500 * 1024 * 1024) { if (obj.getDocument() != null && obj.getDocument().size >= 300 * 1024 * 1024) {
return true; return true;
} }
} }

View file

@ -16,7 +16,6 @@ import android.view.MotionEvent;
import android.view.View; import android.view.View;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.ui.ActionBar.Theme;
public class SeekBar { public class SeekBar {
@ -153,6 +152,9 @@ public class SeekBar {
} }
public void setSize(int w, int h) { public void setSize(int w, int h) {
if (width == w && height == h) {
return;
}
width = w; width = w;
height = h; height = h;
setProgress(thumbProgress); setProgress(thumbProgress);

View file

@ -1723,7 +1723,7 @@ public class ShareAlert extends BottomSheet implements NotificationCenter.Notifi
topicsGridView.setScaleY(0.75f + value * 0.25f); topicsGridView.setScaleY(0.75f + value * 0.25f);
topicsGridView.setAlpha(value); topicsGridView.setAlpha(value);
RecyclerListView mainGridView = getMainGridView(); RecyclerListView mainGridView = gridView;
mainGridView.setPivotX(cell.getX() + cell.getWidth() / 2f); mainGridView.setPivotX(cell.getX() + cell.getWidth() / 2f);
mainGridView.setPivotY(cell.getY() + cell.getHeight() / 2f); mainGridView.setPivotY(cell.getY() + cell.getHeight() / 2f);
mainGridView.setScaleX(1f + value * 0.25f); mainGridView.setScaleX(1f + value * 0.25f);
@ -1746,8 +1746,14 @@ public class ShareAlert extends BottomSheet implements NotificationCenter.Notifi
for (int i = 0; i < mainGridView.getChildCount(); i++) { for (int i = 0; i < mainGridView.getChildCount(); i++) {
View v = mainGridView.getChildAt(i); View v = mainGridView.getChildAt(i);
if (v instanceof ShareDialogCell) { if (v instanceof ShareDialogCell) {
v.setTranslationX((v.getX() - cell.getX()) * 0.75f * moveValue); v.setTranslationX((v.getX() - cell.getX()) * 0.5f * moveValue);
v.setTranslationY((v.getY() - cell.getY()) * 0.75f * moveValue); v.setTranslationY((v.getY() - cell.getY()) * 0.5f * moveValue);
if (v != cell) {
v.setAlpha(1f - Math.min(value, 0.5f) / 0.5f);
} else {
v.setAlpha(1f - value);
}
} }
} }
for (int i = 0; i < topicsGridView.getChildCount(); i++) { for (int i = 0; i < topicsGridView.getChildCount(); i++) {

View file

@ -534,8 +534,8 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
public SharedMediaPreloader(BaseFragment fragment) { public SharedMediaPreloader(BaseFragment fragment) {
parentFragment = fragment; parentFragment = fragment;
if (fragment instanceof FragmentContextView.ChatActivityInterface) { if (fragment instanceof ChatActivityInterface) {
FragmentContextView.ChatActivityInterface chatActivity = (FragmentContextView.ChatActivityInterface) fragment; ChatActivityInterface chatActivity = (ChatActivityInterface) fragment;
dialogId = chatActivity.getDialogId(); dialogId = chatActivity.getDialogId();
mergeDialogId = chatActivity.getMergeDialogId(); mergeDialogId = chatActivity.getMergeDialogId();
topicId = chatActivity.getTopicId(); topicId = chatActivity.getTopicId();

View file

@ -46,7 +46,7 @@ import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.ActionBar.BackDrawable; import org.telegram.ui.ActionBar.BackDrawable;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AlertsCreator; import org.telegram.ui.Components.AlertsCreator;
import org.telegram.ui.Components.AvatarsDarawable; import org.telegram.ui.Components.AvatarsDrawable;
import org.telegram.ui.Components.AvatarsImageView; import org.telegram.ui.Components.AvatarsImageView;
import org.telegram.ui.Components.CrossOutDrawable; import org.telegram.ui.Components.CrossOutDrawable;
import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.CubicBezierInterpolator;
@ -326,7 +326,7 @@ public class GroupCallRenderersContainer extends FrameLayout {
}; };
speakingMembersAvatars = new AvatarsImageView(context, true); speakingMembersAvatars = new AvatarsImageView(context, true);
speakingMembersAvatars.setStyle(AvatarsDarawable.STYLE_GROUP_CALL_TOOLTIP); speakingMembersAvatars.setStyle(AvatarsDrawable.STYLE_GROUP_CALL_TOOLTIP);
speakingMembersToast.setClipChildren(false); speakingMembersToast.setClipChildren(false);
speakingMembersToast.setClipToPadding(false); speakingMembersToast.setClipToPadding(false);

View file

@ -3,7 +3,6 @@ package org.telegram.ui.Delegates;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter; import android.graphics.PorterDuffColorFilter;
import android.os.Build; import android.os.Build;
@ -81,7 +80,7 @@ public class ChatActivityMemberRequestsDelegate {
avatarsView = new AvatarsImageView(fragment.getParentActivity(), false) { avatarsView = new AvatarsImageView(fragment.getParentActivity(), false) {
@Override @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = avatarsDarawable.count == 0 ? 0 : (20 * (avatarsDarawable.count - 1) + 24); int width = avatarsDrawable.count == 0 ? 0 : (20 * (avatarsDrawable.count - 1) + 24);
super.onMeasure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(width), MeasureSpec.EXACTLY), heightMeasureSpec); super.onMeasure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(width), MeasureSpec.EXACTLY), heightMeasureSpec);
} }
}; };

View file

@ -86,7 +86,6 @@ import androidx.viewpager.widget.ViewPager;
import org.telegram.messenger.AccountInstance; import org.telegram.messenger.AccountInstance;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BotWebViewVibrationEffect;
import org.telegram.messenger.BuildVars; import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ChatObject; import org.telegram.messenger.ChatObject;
import org.telegram.messenger.ContactsController; import org.telegram.messenger.ContactsController;
@ -168,6 +167,7 @@ import org.telegram.ui.Components.FiltersListBottomSheet;
import org.telegram.ui.Components.FlickerLoadingView; import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.FloatingDebug.FloatingDebugController; import org.telegram.ui.Components.FloatingDebug.FloatingDebugController;
import org.telegram.ui.Components.FloatingDebug.FloatingDebugProvider; import org.telegram.ui.Components.FloatingDebug.FloatingDebugProvider;
import org.telegram.ui.Components.Forum.ForumUtilities;
import org.telegram.ui.Components.FragmentContextView; import org.telegram.ui.Components.FragmentContextView;
import org.telegram.ui.Components.JoinGroupAlert; import org.telegram.ui.Components.JoinGroupAlert;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
@ -3233,7 +3233,25 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
FileLog.e(e); FileLog.e(e);
} }
} }
@Override
public void onButtonClicked(DialogCell dialogCell) {
if (dialogCell.getMessage() != null) {
TLRPC.TL_forumTopic topic = getMessagesController().getTopicsController().findTopic(-dialogCell.getDialogId(), MessageObject.getTopicId(dialogCell.getMessage().messageOwner));
if (topic != null) {
if (onlySelect) {
didSelectResult(dialogCell.getDialogId(), topic.id, false, false);
} else {
ForumUtilities.openTopic(DialogsActivity.this, -dialogCell.getDialogId(), topic, 0);
}
}
}
}
@Override
public void onButtonLongPress(DialogCell dialogCell) {
onItemLongClick(viewPage.listView, dialogCell, viewPage.listView.getChildAdapterPosition(dialogCell), 0, 0, viewPage.dialogsType, viewPage.dialogsAdapter);
}
}; };
viewPage.dialogsAdapter.setForceShowEmptyCell(afterSignup); viewPage.dialogsAdapter.setForceShowEmptyCell(afterSignup);
if (AndroidUtilities.isTablet() && openedDialogId != 0) { if (AndroidUtilities.isTablet() && openedDialogId != 0) {
@ -4292,13 +4310,13 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
public void updateSpeedItem(boolean visibleByPosition) { public void updateSpeedItem(boolean visibleByPosition) {
boolean visibleByDownload = false; boolean visibleByDownload = false;
for (MessageObject obj : getDownloadController().downloadingFiles) { for (MessageObject obj : getDownloadController().downloadingFiles) {
if (obj.getDocument() != null && obj.getDocument().size >= 500 * 1024 * 1024) { if (obj.getDocument() != null && obj.getDocument().size >= 300 * 1024 * 1024) {
visibleByDownload = true; visibleByDownload = true;
break; break;
} }
} }
for (MessageObject obj : getDownloadController().recentDownloadingFiles) { for (MessageObject obj : getDownloadController().recentDownloadingFiles) {
if (obj.getDocument() != null && obj.getDocument().size >= 500 * 1024 * 1024) { if (obj.getDocument() != null && obj.getDocument().size >= 300 * 1024 * 1024) {
visibleByDownload = true; visibleByDownload = true;
break; break;
} }
@ -4341,7 +4359,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
} }
} }
if (index != -1) { if (index != -1) {
FileLoader.getInstance(currentAccount).loadFile(premiumPromo.videos.get(index), null, FileLoader.PRIORITY_HIGH, 0); FileLoader.getInstance(currentAccount).loadFile(premiumPromo.videos.get(index), premiumPromo, FileLoader.PRIORITY_HIGH, 0);
} }
} }
} }
@ -5436,6 +5454,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
return; return;
} }
long dialogId = 0; long dialogId = 0;
int topicId = 0;
int message_id = 0; int message_id = 0;
boolean isGlobalSearch = false; boolean isGlobalSearch = false;
int folderId = 0; int folderId = 0;
@ -5527,6 +5546,10 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
MessageObject messageObject = (MessageObject) obj; MessageObject messageObject = (MessageObject) obj;
dialogId = messageObject.getDialogId(); dialogId = messageObject.getDialogId();
message_id = messageObject.getId(); message_id = messageObject.getId();
TLRPC.Chat chat = getMessagesController().getChat(-dialogId);
if (ChatObject.isForum(chat)) {
topicId = MessageObject.getTopicId(messageObject.messageOwner);
}
searchViewPager.dialogsSearchAdapter.addHashtagsFromMessage(searchViewPager.dialogsSearchAdapter.getLastSearchString()); searchViewPager.dialogsSearchAdapter.addHashtagsFromMessage(searchViewPager.dialogsSearchAdapter.getLastSearchString());
} else if (obj instanceof String) { } else if (obj instanceof String) {
String str = (String) obj; String str = (String) obj;
@ -5640,10 +5663,13 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
slowedReloadAfterDialogClick = true; slowedReloadAfterDialogClick = true;
if (getMessagesController().checkCanOpenChat(args, DialogsActivity.this)) { if (getMessagesController().checkCanOpenChat(args, DialogsActivity.this)) {
TLRPC.Chat chat = getMessagesController().getChat(-dialogId); TLRPC.Chat chat = getMessagesController().getChat(-dialogId);
if (chat != null && chat.forum) { if (chat != null && chat.forum && topicId == 0) {
presentFragment(new TopicsFragment(args)); presentFragment(new TopicsFragment(args));
} else { } else {
ChatActivity chatActivity = new ChatActivity(args); ChatActivity chatActivity = new ChatActivity(args);
if (topicId != 0) {
ForumUtilities.applyTopic(chatActivity, MessagesStorage.TopicKey.of(dialogId, topicId));
}
if (adapter instanceof DialogsAdapter && DialogObject.isUserDialog(dialogId) && (getMessagesController().dialogs_dict.get(dialogId) == null)) { if (adapter instanceof DialogsAdapter && DialogObject.isUserDialog(dialogId) && (getMessagesController().dialogs_dict.get(dialogId) == null)) {
TLRPC.Document sticker = getMediaDataController().getGreetingsSticker(); TLRPC.Document sticker = getMediaDataController().getGreetingsSticker();
if (sticker != null) { if (sticker != null) {
@ -5651,7 +5677,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
} }
} }
presentFragment(chatActivity); presentFragment(chatActivity);
}; }
} }
} }
} }
@ -8208,7 +8234,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
} else { } else {
continue; continue;
} }
if (list == null) { if (list == null || list.getAdapter() == null) {
continue; continue;
} }
int count = list.getChildCount(); int count = list.getChildCount();
@ -8227,7 +8253,12 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
cell.setChecked(false, (mask & MessagesController.UPDATE_MASK_CHAT) != 0); cell.setChecked(false, (mask & MessagesController.UPDATE_MASK_CHAT) != 0);
} else { } else {
if ((mask & MessagesController.UPDATE_MASK_NEW_MESSAGE) != 0) { if ((mask & MessagesController.UPDATE_MASK_NEW_MESSAGE) != 0) {
cell.checkCurrentDialogIndex(dialogsListFrozen); if (cell.checkCurrentDialogIndex(dialogsListFrozen)) {
if (list.getAdapter() != null) {
list.getAdapter().notifyDataSetChanged();
break;
}
}
if (viewPages[c].isDefaultDialogType() && AndroidUtilities.isTablet()) { if (viewPages[c].isDefaultDialogType() && AndroidUtilities.isTablet()) {
cell.setDialogSelected(cell.getDialogId() == openedDialogId); cell.setDialogSelected(cell.getDialogId() == openedDialogId);
} }
@ -8236,7 +8267,12 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
cell.setDialogSelected(cell.getDialogId() == openedDialogId); cell.setDialogSelected(cell.getDialogId() == openedDialogId);
} }
} else { } else {
cell.update(mask, animated); if (cell.update(mask, animated)) {
if (list.getAdapter() != null) {
list.getAdapter().notifyDataSetChanged();
break;
}
}
} }
if (selectedDialogs != null) { if (selectedDialogs != null) {
cell.setChecked(selectedDialogs.contains(cell.getDialogId()), false); cell.setChecked(selectedDialogs.contains(cell.getDialogId()), false);

View file

@ -17,7 +17,6 @@ import android.content.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.EditText; import android.widget.EditText;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.LinearLayout; import android.widget.LinearLayout;
@ -437,6 +436,7 @@ public class LanguageSelectActivity extends BaseFragment implements Notification
); );
showButtonCheck.setOnClickListener(e -> { showButtonCheck.setOnClickListener(e -> {
preferences.edit().putBoolean("translate_button", !getValue()).apply(); preferences.edit().putBoolean("translate_button", !getValue()).apply();
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.updateSearchSettings);
}); });
addView(showButtonCheck, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); addView(showButtonCheck, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

View file

@ -5907,6 +5907,7 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
if (drawerLayoutAdapter != null) { if (drawerLayoutAdapter != null) {
drawerLayoutAdapter.notifyDataSetChanged(); drawerLayoutAdapter.notifyDataSetChanged();
} }
MessagesController.getMainSettings(currentAccount).edit().remove("transcribeButtonPressed").apply();
} else if (id == NotificationCenter.requestPermissions) { } else if (id == NotificationCenter.requestPermissions) {
int type = (int) args[0]; int type = (int) args[0];
String[] permissions = null; String[] permissions = null;

View file

@ -2126,15 +2126,18 @@ public class LoginActivity extends BaseFragment {
for (int i = 0; i < help_countriesList.countries.size(); i++) { for (int i = 0; i < help_countriesList.countries.size(); i++) {
TLRPC.TL_help_country c = help_countriesList.countries.get(i); TLRPC.TL_help_country c = help_countriesList.countries.get(i);
for (int k = 0; k < c.country_codes.size(); k++) { for (int k = 0; k < c.country_codes.size(); k++) {
CountrySelectActivity.Country countryWithCode = new CountrySelectActivity.Country(); TLRPC.TL_help_countryCode countryCode = c.country_codes.get(k);
countryWithCode.name = c.default_name; if (countryCode != null) {
countryWithCode.code = c.country_codes.get(k).country_code; CountrySelectActivity.Country countryWithCode = new CountrySelectActivity.Country();
countryWithCode.shortname = c.iso2; countryWithCode.name = c.default_name;
countryWithCode.code = countryCode.country_code;
countryWithCode.shortname = c.iso2;
countriesArray.add(countryWithCode); countriesArray.add(countryWithCode);
codesMap.put(c.country_codes.get(k).country_code, countryWithCode); codesMap.put(countryCode.country_code, countryWithCode);
if (c.country_codes.get(k).patterns.size() > 0) { if (countryCode.patterns.size() > 0) {
phoneFormatMap.put(c.country_codes.get(k).country_code, c.country_codes.get(k).patterns); phoneFormatMap.put(countryCode.country_code, countryCode.patterns);
}
} }
} }
} }

View file

@ -0,0 +1,141 @@
package org.telegram.ui;
import android.graphics.Rect;
import android.os.Build;
import android.view.MotionEvent;
import android.view.View;
import org.telegram.ui.ActionBar.ActionBarPopupWindow;
import org.telegram.ui.Components.GestureDetector2;
public class LongPressListenerWithMovingGesture implements View.OnTouchListener {
View view;
ActionBarPopupWindow submenu;
Rect rect = new Rect();
boolean subItemClicked;
GestureDetector2 gestureDetector2 = new GestureDetector2(new GestureDetector2.OnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
if (view != null) {
view.setPressed(true);
view.setSelected(true);
if (Build.VERSION.SDK_INT >= 21) {
if (Build.VERSION.SDK_INT == 21 && view.getBackground() != null) {
view.getBackground().setVisible(true, false);
}
view.drawableHotspotChanged(e.getX(), e.getY());
}
}
return true;
}
@Override
public void onUp(MotionEvent e) {
if (view != null) {
view.setPressed(false);
view.setSelected(false);
if (Build.VERSION.SDK_INT == 21 && view.getBackground() != null) {
view.getBackground().setVisible(false, false);
}
}
if (selectedMenuView != null && !subItemClicked) {
selectedMenuView.callOnClick();
subItemClicked = true;
}
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
if (view != null) {
view.callOnClick();
}
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
if (view != null) {
LongPressListenerWithMovingGesture.this.onLongPress();
}
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
});
private int[] location = new int[2];
private View selectedMenuView;
public LongPressListenerWithMovingGesture() {
gestureDetector2.setIsLongpressEnabled(true);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
view = v;
gestureDetector2.onTouchEvent(event);
if (submenu != null && !subItemClicked && event.getAction() == MotionEvent.ACTION_MOVE) {
view.getLocationOnScreen(location);
float x = event.getX() + location[0];
float y = event.getY() + location[1];
submenu.getContentView().getLocationOnScreen(location);
x -= location[0];
y -= location[1];
selectedMenuView = null;
ActionBarPopupWindow.ActionBarPopupWindowLayout popupLayout = (ActionBarPopupWindow.ActionBarPopupWindowLayout) submenu.getContentView();
for (int a = 0; a < popupLayout.getItemsCount(); a++) {
View child = popupLayout.getItemAt(a);
child.getHitRect(rect);
Object tag = child.getTag();
if (child.getVisibility() == View.VISIBLE && child.isClickable()) {
if (!rect.contains((int) x, (int) y)) {
child.setPressed(false);
child.setSelected(false);
if (Build.VERSION.SDK_INT == 21 && child.getBackground() != null) {
child.getBackground().setVisible(false, false);
}
} else {
child.setPressed(true);
child.setSelected(true);
if (Build.VERSION.SDK_INT >= 21) {
if (Build.VERSION.SDK_INT == 21 && child.getBackground() != null) {
child.getBackground().setVisible(true, false);
}
child.drawableHotspotChanged(x, y - child.getTop());
}
selectedMenuView = child;
}
}
}
}
if (event.getAction() == MotionEvent.ACTION_UP && !subItemClicked && selectedMenuView != null) {
selectedMenuView.callOnClick();
subItemClicked = true;
}
return true;
}
public void setSubmenu(ActionBarPopupWindow actionBarPopupWindow) {
submenu = actionBarPopupWindow;
}
public void onLongPress() {
}
}

View file

@ -33,7 +33,7 @@ import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.SimpleTextView; import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AvatarDrawable; import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.AvatarsDarawable; import org.telegram.ui.Components.AvatarsDrawable;
import org.telegram.ui.Components.AvatarsImageView; import org.telegram.ui.Components.AvatarsImageView;
import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.FlickerLoadingView; import org.telegram.ui.Components.FlickerLoadingView;
@ -74,7 +74,7 @@ public class MessageSeenView extends FrameLayout {
addView(titleView, LayoutHelper.createFrame(0, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.CENTER_VERTICAL, 40, 0, 0, 0)); addView(titleView, LayoutHelper.createFrame(0, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.CENTER_VERTICAL, 40, 0, 0, 0));
avatarsImageView = new AvatarsImageView(context, false); avatarsImageView = new AvatarsImageView(context, false);
avatarsImageView.setStyle(AvatarsDarawable.STYLE_MESSAGE_SEEN); avatarsImageView.setStyle(AvatarsDrawable.STYLE_MESSAGE_SEEN);
avatarsImageView.setAvatarsTextSize(AndroidUtilities.dp(22)); avatarsImageView.setAvatarsTextSize(AndroidUtilities.dp(22));
addView(avatarsImageView, LayoutHelper.createFrame(24 + 12 + 12 + 8, LayoutHelper.MATCH_PARENT, Gravity.RIGHT | Gravity.CENTER_VERTICAL, 0, 0, 0, 0)); addView(avatarsImageView, LayoutHelper.createFrame(24 + 12 + 12 + 8, LayoutHelper.MATCH_PARENT, Gravity.RIGHT | Gravity.CENTER_VERTICAL, 0, 0, 0, 0));

View file

@ -3943,6 +3943,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
private Bulletin.Delegate delegate = new Bulletin.Delegate() { private Bulletin.Delegate delegate = new Bulletin.Delegate() {
@Override @Override
public int getBottomOffset(int tag) { public int getBottomOffset(int tag) {
if (captionEditText.getVisibility() == View.GONE) {
return 0;
}
return getHeight() - captionEditText.getTop(); return getHeight() - captionEditText.getTop();
} }
}; };

View file

@ -848,7 +848,7 @@ public class PremiumPreviewFragment extends BaseFragment implements Notification
if (getMediaDataController().getPremiumPromo() != null) { if (getMediaDataController().getPremiumPromo() != null) {
for (TLRPC.Document document : getMediaDataController().getPremiumPromo().videos) { for (TLRPC.Document document : getMediaDataController().getPremiumPromo().videos) {
FileLoader.getInstance(currentAccount).loadFile(document, null, FileLoader.PRIORITY_HIGH, 0); FileLoader.getInstance(currentAccount).loadFile(document, getMediaDataController().getPremiumPromo(), FileLoader.PRIORITY_HIGH, 0);
} }
} }

View file

@ -966,6 +966,7 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio
if (!getUserConfig().isPremium()) { if (!getUserConfig().isPremium()) {
imageView.setVisibility(View.VISIBLE); imageView.setVisibility(View.VISIBLE);
imageView.setImageResource(R.drawable.msg_mini_premiumlock); imageView.setImageResource(R.drawable.msg_mini_premiumlock);
imageView.setTranslationY(AndroidUtilities.dp(1));
imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteValueText), PorterDuff.Mode.MULTIPLY)); imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteValueText), PorterDuff.Mode.MULTIPLY));
} else { } else {
imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayIcon), PorterDuff.Mode.MULTIPLY)); imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayIcon), PorterDuff.Mode.MULTIPLY));

View file

@ -165,6 +165,7 @@ import org.telegram.ui.Components.BackButtonMenu;
import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.Bulletin; import org.telegram.ui.Components.Bulletin;
import org.telegram.ui.Components.BulletinFactory; import org.telegram.ui.Components.BulletinFactory;
import org.telegram.ui.Components.ChatActivityInterface;
import org.telegram.ui.Components.ChatAvatarContainer; import org.telegram.ui.Components.ChatAvatarContainer;
import org.telegram.ui.Components.ChatNotificationsPopupWrapper; import org.telegram.ui.Components.ChatNotificationsPopupWrapper;
import org.telegram.ui.Components.CombinedDrawable; import org.telegram.ui.Components.CombinedDrawable;
@ -179,6 +180,7 @@ import org.telegram.ui.Components.IdenticonDrawable;
import org.telegram.ui.Components.ImageUpdater; import org.telegram.ui.Components.ImageUpdater;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.Premium.GiftPremiumBottomSheet; import org.telegram.ui.Components.Premium.GiftPremiumBottomSheet;
import org.telegram.ui.Components.Premium.PremiumFeatureBottomSheet;
import org.telegram.ui.Components.Premium.PremiumGradient; import org.telegram.ui.Components.Premium.PremiumGradient;
import org.telegram.ui.Components.Premium.PremiumPreviewBottomSheet; import org.telegram.ui.Components.Premium.PremiumPreviewBottomSheet;
import org.telegram.ui.Components.Premium.ProfilePremiumCell; import org.telegram.ui.Components.Premium.ProfilePremiumCell;
@ -523,7 +525,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
private String vcardFirstName; private String vcardFirstName;
private String vcardLastName; private String vcardLastName;
ChatActivity previousTransitionFragment; ChatActivityInterface previousTransitionFragment;
HashSet<Integer> notificationsExceptionTopics = new HashSet<>(); HashSet<Integer> notificationsExceptionTopics = new HashSet<>();
@ -748,12 +750,21 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
int y1 = (int) (v * (1.0f - mediaHeaderAnimationProgress)); int y1 = (int) (v * (1.0f - mediaHeaderAnimationProgress));
if (y1 != 0) { if (y1 != 0) {
if (previousTransitionFragment != null) { if (previousTransitionFragment != null && previousTransitionFragment.getContentView() != null) {
AndroidUtilities.rectTmp2.set(0, 0, getMeasuredWidth(), y1); AndroidUtilities.rectTmp2.set(0, 0, getMeasuredWidth(), y1);
previousTransitionFragment.contentView.drawBlurRect(canvas, getY(), AndroidUtilities.rectTmp2, previousTransitionFragment.getActionBar().blurScrimPaint, true); previousTransitionFragment.getContentView().drawBlurRect(canvas, getY(), AndroidUtilities.rectTmp2, previousTransitionFragment.getActionBar().blurScrimPaint, true);
} }
paint.setColor(currentColor); paint.setColor(currentColor);
canvas.drawRect(0, 0, getMeasuredWidth(), y1, paint); canvas.drawRect(0, 0, getMeasuredWidth(), y1, paint);
if (previousTransitionFragment != null) {
ActionBar actionBar = previousTransitionFragment.getActionBar();
ActionBarMenu menu = actionBar.menu;
int restoreCount = canvas.save();
canvas.translate(actionBar.getX() + menu.getX(), actionBar.getY() + menu.getY());
canvas.saveLayerAlpha(0, 0, menu.getMeasuredWidth(), menu.getMeasuredHeight(), (int) (255 * (1f - animationProgress)), Canvas.ALL_SAVE_FLAG);
menu.draw(canvas);
canvas.restoreToCount(restoreCount);
}
} }
if (y1 != v) { if (y1 != v) {
int color = getThemedColor(Theme.key_windowBackgroundWhite); int color = getThemedColor(Theme.key_windowBackgroundWhite);
@ -1534,6 +1545,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
getNotificationCenter().addObserver(this, NotificationCenter.didReceiveNewMessages); getNotificationCenter().addObserver(this, NotificationCenter.didReceiveNewMessages);
getNotificationCenter().addObserver(this, NotificationCenter.closeChats); getNotificationCenter().addObserver(this, NotificationCenter.closeChats);
getNotificationCenter().addObserver(this, NotificationCenter.topicsDidLoaded); getNotificationCenter().addObserver(this, NotificationCenter.topicsDidLoaded);
getNotificationCenter().addObserver(this, NotificationCenter.updateSearchSettings);
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiLoaded); NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiLoaded);
updateRowsIds(); updateRowsIds();
if (listAdapter != null) { if (listAdapter != null) {
@ -1596,6 +1608,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
getNotificationCenter().removeObserver(this, NotificationCenter.closeChats); getNotificationCenter().removeObserver(this, NotificationCenter.closeChats);
getNotificationCenter().removeObserver(this, NotificationCenter.didReceiveNewMessages); getNotificationCenter().removeObserver(this, NotificationCenter.didReceiveNewMessages);
getNotificationCenter().removeObserver(this, NotificationCenter.topicsDidLoaded); getNotificationCenter().removeObserver(this, NotificationCenter.topicsDidLoaded);
getNotificationCenter().removeObserver(this, NotificationCenter.updateSearchSettings);
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiLoaded); NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiLoaded);
if (avatarsViewPager != null) { if (avatarsViewPager != null) {
avatarsViewPager.onDestroy(); avatarsViewPager.onDestroy();
@ -1668,7 +1681,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
actionBar.setOccupyStatusBar(Build.VERSION.SDK_INT >= 21 && !AndroidUtilities.isTablet() && !inBubbleMode); actionBar.setOccupyStatusBar(Build.VERSION.SDK_INT >= 21 && !AndroidUtilities.isTablet() && !inBubbleMode);
ImageView backButton = actionBar.getBackButton(); ImageView backButton = actionBar.getBackButton();
backButton.setOnLongClickListener(e -> { backButton.setOnLongClickListener(e -> {
ActionBarPopupWindow menu = BackButtonMenu.show(this, backButton, getDialogId(), resourcesProvider); ActionBarPopupWindow menu = BackButtonMenu.show(this, backButton, getDialogId(), getTopicId(), resourcesProvider);
if (menu != null) { if (menu != null) {
menu.setOnDismissListener(() -> dimBehindView(false)); menu.setOnDismissListener(() -> dimBehindView(false));
dimBehindView(backButton, 0.3f); dimBehindView(backButton, 0.3f);
@ -2237,6 +2250,10 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
} }
} }
if (previousTransitionFragment != null) {
nameTextView[0].setRightPadding(nameTextView[0].getMeasuredWidth() - previousTransitionFragment.getAvatarContainer().getTitleTextView().getMeasuredWidth());
}
if (!fragmentOpened && (expandPhoto || openAnimationInProgress && playProfileAnimation == 2)) { if (!fragmentOpened && (expandPhoto || openAnimationInProgress && playProfileAnimation == 2)) {
ignoreLayout = true; ignoreLayout = true;
@ -3392,11 +3409,16 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
return false; return false;
} }
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity(), resourcesProvider); AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity(), resourcesProvider);
builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); builder.setTitle(LocaleController.getString(R.string.ClearSearchAlertTitle));
builder.setMessage(LocaleController.getString("ClearSearch", R.string.ClearSearch)); builder.setMessage(LocaleController.getString(R.string.ClearSearchAlert));
builder.setPositiveButton(LocaleController.getString("ClearButton", R.string.ClearButton), (dialogInterface, i) -> searchAdapter.clearRecent()); builder.setPositiveButton(LocaleController.getString("ClearButton", R.string.ClearButton), (dialogInterface, i) -> searchAdapter.clearRecent());
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
showDialog(builder.create()); AlertDialog dialog = builder.create();
showDialog(dialog);
TextView button = (TextView) dialog.getButton(DialogInterface.BUTTON_POSITIVE);
if (button != null) {
button.setTextColor(Theme.getColor(Theme.key_dialogTextRed2));
}
return true; return true;
}); });
searchListView.setOnScrollListener(new RecyclerView.OnScrollListener() { searchListView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@ -4761,7 +4783,8 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
} }
private void leaveChatPressed() { private void leaveChatPressed() {
AlertsCreator.createClearOrDeleteDialogAlert(ProfileActivity.this, false, currentChat, null, false, false, true, (param) -> { boolean isForum = ChatObject.isForum(currentChat);
AlertsCreator.createClearOrDeleteDialogAlert(ProfileActivity.this, false, currentChat, null, false, isForum, !isForum, (param) -> {
playProfileAnimation = 0; playProfileAnimation = 0;
getNotificationCenter().removeObserver(ProfileActivity.this, NotificationCenter.closeChats); getNotificationCenter().removeObserver(ProfileActivity.this, NotificationCenter.closeChats);
getNotificationCenter().postNotificationName(NotificationCenter.closeChats); getNotificationCenter().postNotificationName(NotificationCenter.closeChats);
@ -5020,6 +5043,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
TLRPC.User user = users.get(a); TLRPC.User user = users.get(a);
getMessagesController().addUserToChat(chatId, user, fwdCount, null, ProfileActivity.this, () -> { getMessagesController().addUserToChat(chatId, user, fwdCount, null, ProfileActivity.this, () -> {
if (++finished[0] == N) { if (++finished[0] == N) {
if (fragmentView == null || getParentActivity() == null) {
return;
}
BulletinFactory.of(ProfileActivity.this).createUsersAddedBulletin(users, currentChat).show(); BulletinFactory.of(ProfileActivity.this).createUsersAddedBulletin(users, currentChat).show();
} }
}); });
@ -5827,6 +5853,13 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
if (isTopic) { if (isTopic) {
updateProfileData(false); updateProfileData(false);
} }
} else if (id == NotificationCenter.updateSearchSettings) {
if (searchAdapter != null) {
searchAdapter.searchArray = searchAdapter.onCreateSearchArray();
searchAdapter.recentSearches.clear();
searchAdapter.updateSearchArray();
searchAdapter.search(searchAdapter.lastSearchString);
}
} }
} }
@ -6133,8 +6166,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
} }
if (parentLayout != null && parentLayout.getFragmentStack().size() >= 2) { if (parentLayout != null && parentLayout.getFragmentStack().size() >= 2) {
BaseFragment fragment = parentLayout.getFragmentStack().get(parentLayout.getFragmentStack().size() - 2); BaseFragment fragment = parentLayout.getFragmentStack().get(parentLayout.getFragmentStack().size() - 2);
if (fragment instanceof ChatActivity) { if (fragment instanceof ChatActivityInterface) {
previousTransitionFragment = (ChatActivity) fragment; previousTransitionFragment = (ChatActivityInterface) fragment;
previousTransitionFragment.getAvatarContainer().getTitleTextView();
} }
} }
if (previousTransitionFragment != null) { if (previousTransitionFragment != null) {
@ -6221,18 +6255,17 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
} }
boolean onlineTextCrosafade = false; boolean onlineTextCrosafade = false;
BaseFragment previousFragment = parentLayout.getFragmentStack().size() > 1 ? parentLayout.getFragmentStack().get(parentLayout.getFragmentStack().size() - 2) : null;
if (previousFragment instanceof ChatActivity) { ChatAvatarContainer avatarContainer = ((ChatActivityInterface) previousTransitionFragment).getAvatarContainer();
ChatAvatarContainer avatarContainer = ((ChatActivity) previousFragment).getAvatarContainer(); if (avatarContainer.getSubtitleTextView().getLeftDrawable() != null || avatarContainer.statusMadeShorter[0]) {
if (avatarContainer.getSubtitleTextView().getLeftDrawable() != null || avatarContainer.statusMadeShorter[0]) { transitionOnlineText = avatarContainer.getSubtitleTextView();
transitionOnlineText = avatarContainer.getSubtitleTextView(); avatarContainer2.invalidate();
avatarContainer2.invalidate(); onlineTextCrosafade = true;
onlineTextCrosafade = true; onlineTextView[0].setAlpha(0f);
onlineTextView[0].setAlpha(0f); onlineTextView[1].setAlpha(0f);
onlineTextView[1].setAlpha(0f); animators.add(ObjectAnimator.ofFloat(onlineTextView[1], View.ALPHA, 1.0f));
animators.add(ObjectAnimator.ofFloat(onlineTextView[1], View.ALPHA, 1.0f));
}
} }
if (!onlineTextCrosafade) { if (!onlineTextCrosafade) {
for (int a = 0; a < 2; a++) { for (int a = 0; a < 2; a++) {
onlineTextView[a].setAlpha(a == 0 ? 1.0f : 0.0f); onlineTextView[a].setAlpha(a == 0 ? 1.0f : 0.0f);
@ -6729,7 +6762,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
} }
if (ChatObject.isChannel(currentChat)) { if (ChatObject.isChannel(currentChat)) {
if (!isTopic && chatInfo != null && currentChat.megagroup && chatInfo.participants != null && !chatInfo.participants.participants.isEmpty()) { if (!isTopic && chatInfo != null && currentChat.megagroup && chatInfo.participants != null && chatInfo.participants.participants != null && !chatInfo.participants.participants.isEmpty()) {
if (!ChatObject.isNotInChat(currentChat) && ChatObject.canAddUsers(currentChat) && chatInfo.participants_count < getMessagesController().maxMegagroupCount) { if (!ChatObject.isNotInChat(currentChat) && ChatObject.canAddUsers(currentChat) && chatInfo.participants_count < getMessagesController().maxMegagroupCount) {
addMemberRow = rowCount++; addMemberRow = rowCount++;
} }
@ -6772,7 +6805,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
lastSectionRow = rowCount++; lastSectionRow = rowCount++;
} }
} else if (chatInfo != null) { } else if (chatInfo != null) {
if (!isTopic && chatInfo.participants != null && !(chatInfo.participants instanceof TLRPC.TL_chatParticipantsForbidden)) { if (!isTopic && chatInfo.participants != null && chatInfo.participants.participants != null && !(chatInfo.participants instanceof TLRPC.TL_chatParticipantsForbidden)) {
if (ChatObject.canAddUsers(currentChat) || currentChat.default_banned_rights == null || !currentChat.default_banned_rights.invite_users) { if (ChatObject.canAddUsers(currentChat) || currentChat.default_banned_rights == null || !currentChat.default_banned_rights.invite_users) {
addMemberRow = rowCount++; addMemberRow = rowCount++;
} }
@ -7766,6 +7799,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
if (otherItem != null) { if (otherItem != null) {
otherItem.setAlpha(progressHalf); otherItem.setAlpha(progressHalf);
} }
if (qrItem != null) {
qrItem.setAlpha(progressHalf);
}
searchItem.setAlpha(progressHalf); searchItem.setAlpha(progressHalf);
topView.invalidate(); topView.invalidate();
fragmentView.invalidate(); fragmentView.invalidate();
@ -8050,7 +8086,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
byte[] data = new byte[1024 * 64]; byte[] data = new byte[1024 * 64];
for (int i = 0; i < files.length; i++) { for (int i = 0; i < files.length; i++) {
if (last && (currentDate - files[i].lastModified()) > 24 * 60 * 60 * 1000) { if ((last || files[i].getName().contains("_mtproto")) && (currentDate - files[i].lastModified()) > 24 * 60 * 60 * 1000) {
continue; continue;
} }
FileInputStream fi = new FileInputStream(files[i]); FileInputStream fi = new FileInputStream(files[i]);
@ -8988,124 +9024,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
} }
} }
private SearchResult[] searchArray = new SearchResult[]{ private SearchResult[] searchArray = onCreateSearchArray();
new SearchResult(500, LocaleController.getString("EditName", R.string.EditName), 0, () -> presentFragment(new ChangeNameActivity(resourcesProvider))),
new SearchResult(501, LocaleController.getString("ChangePhoneNumber", R.string.ChangePhoneNumber), 0, () -> presentFragment(new ActionIntroActivity(ActionIntroActivity.ACTION_TYPE_CHANGE_PHONE_NUMBER))),
new SearchResult(502, LocaleController.getString("AddAnotherAccount", R.string.AddAnotherAccount), 0, () -> {
int freeAccount = -1;
for (int a = 0; a < UserConfig.MAX_ACCOUNT_COUNT; a++) {
if (!UserConfig.getInstance(a).isClientActivated()) {
freeAccount = a;
break;
}
}
if (freeAccount >= 0) {
presentFragment(new LoginActivity(freeAccount));
}
}),
new SearchResult(503, LocaleController.getString("UserBio", R.string.UserBio), 0, () -> {
if (userInfo != null) {
presentFragment(new ChangeBioActivity());
}
}),
new SearchResult(1, LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsSettingsActivity())),
new SearchResult(2, LocaleController.getString("NotificationsPrivateChats", R.string.NotificationsPrivateChats), LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsCustomSettingsActivity(NotificationsController.TYPE_PRIVATE, new ArrayList<>(), true))),
new SearchResult(3, LocaleController.getString("NotificationsGroups", R.string.NotificationsGroups), LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsCustomSettingsActivity(NotificationsController.TYPE_GROUP, new ArrayList<>(), true))),
new SearchResult(4, LocaleController.getString("NotificationsChannels", R.string.NotificationsChannels), LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsCustomSettingsActivity(NotificationsController.TYPE_CHANNEL, new ArrayList<>(), true))),
new SearchResult(5, LocaleController.getString("VoipNotificationSettings", R.string.VoipNotificationSettings), "callsSectionRow", LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsSettingsActivity())),
new SearchResult(6, LocaleController.getString("BadgeNumber", R.string.BadgeNumber), "badgeNumberSection", LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsSettingsActivity())),
new SearchResult(7, LocaleController.getString("InAppNotifications", R.string.InAppNotifications), "inappSectionRow", LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsSettingsActivity())),
new SearchResult(8, LocaleController.getString("ContactJoined", R.string.ContactJoined), "contactJoinedRow", LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsSettingsActivity())),
new SearchResult(9, LocaleController.getString("PinnedMessages", R.string.PinnedMessages), "pinnedMessageRow", LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsSettingsActivity())),
new SearchResult(10, LocaleController.getString("ResetAllNotifications", R.string.ResetAllNotifications), "resetNotificationsRow", LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsSettingsActivity())),
new SearchResult(100, LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacySettingsActivity())),
new SearchResult(101, LocaleController.getString("BlockedUsers", R.string.BlockedUsers), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacyUsersActivity())),
new SearchResult(105, LocaleController.getString("PrivacyPhone", R.string.PrivacyPhone), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacyControlActivity(ContactsController.PRIVACY_RULES_TYPE_PHONE, true))),
new SearchResult(102, LocaleController.getString("PrivacyLastSeen", R.string.PrivacyLastSeen), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacyControlActivity(ContactsController.PRIVACY_RULES_TYPE_LASTSEEN, true))),
new SearchResult(103, LocaleController.getString("PrivacyProfilePhoto", R.string.PrivacyProfilePhoto), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacyControlActivity(ContactsController.PRIVACY_RULES_TYPE_PHOTO, true))),
new SearchResult(104, LocaleController.getString("PrivacyForwards", R.string.PrivacyForwards), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacyControlActivity(ContactsController.PRIVACY_RULES_TYPE_FORWARDS, true))),
new SearchResult(122, LocaleController.getString("PrivacyP2P", R.string.PrivacyP2P), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacyControlActivity(ContactsController.PRIVACY_RULES_TYPE_P2P, true))),
new SearchResult(106, LocaleController.getString("Calls", R.string.Calls), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacyControlActivity(ContactsController.PRIVACY_RULES_TYPE_CALLS, true))),
new SearchResult(107, LocaleController.getString("GroupsAndChannels", R.string.GroupsAndChannels), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacyControlActivity(ContactsController.PRIVACY_RULES_TYPE_INVITE, true))),
new SearchResult(123, LocaleController.getString("PrivacyVoiceMessages", R.string.PrivacyVoiceMessages), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> {
if (!getUserConfig().isPremium()) {
try {
fragmentView.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
} catch (Exception e) {
FileLog.e(e);
}
BulletinFactory.of(ProfileActivity.this).createRestrictVoiceMessagesPremiumBulletin().show();
return;
}
presentFragment(new PrivacyControlActivity(ContactsController.PRIVACY_RULES_TYPE_VOICE_MESSAGES, true));
}),
new SearchResult(108, LocaleController.getString("Passcode", R.string.Passcode), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(PasscodeActivity.determineOpenFragment())),
new SearchResult(109, LocaleController.getString("TwoStepVerification", R.string.TwoStepVerification), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new TwoStepVerificationActivity())),
new SearchResult(110, LocaleController.getString("SessionsTitle", R.string.SessionsTitle), R.drawable.msg_secret, () -> presentFragment(new SessionsActivity(0))),
getMessagesController().autoarchiveAvailable ? new SearchResult(121, LocaleController.getString("ArchiveAndMute", R.string.ArchiveAndMute), "newChatsRow", LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacySettingsActivity())) : null,
new SearchResult(112, LocaleController.getString("DeleteAccountIfAwayFor2", R.string.DeleteAccountIfAwayFor2), "deleteAccountRow", LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacySettingsActivity())),
new SearchResult(113, LocaleController.getString("PrivacyPaymentsClear", R.string.PrivacyPaymentsClear), "paymentsClearRow", LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacySettingsActivity())),
new SearchResult(114, LocaleController.getString("WebSessionsTitle", R.string.WebSessionsTitle), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new SessionsActivity(1))),
new SearchResult(115, LocaleController.getString("SyncContactsDelete", R.string.SyncContactsDelete), "contactsDeleteRow", LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacySettingsActivity())),
new SearchResult(116, LocaleController.getString("SyncContacts", R.string.SyncContacts), "contactsSyncRow", LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacySettingsActivity())),
new SearchResult(117, LocaleController.getString("SuggestContacts", R.string.SuggestContacts), "contactsSuggestRow", LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacySettingsActivity())),
new SearchResult(118, LocaleController.getString("MapPreviewProvider", R.string.MapPreviewProvider), "secretMapRow", LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacySettingsActivity())),
new SearchResult(119, LocaleController.getString("SecretWebPage", R.string.SecretWebPage), "secretWebpageRow", LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacySettingsActivity())),
new SearchResult(120, LocaleController.getString("Devices", R.string.Devices), R.drawable.msg_secret, () -> presentFragment(new SessionsActivity(0))),
new SearchResult(200, LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(201, LocaleController.getString("DataUsage", R.string.DataUsage), "usageSectionRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(202, LocaleController.getString("StorageUsage", R.string.StorageUsage), LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new CacheControlActivity())),
new SearchResult(203, LocaleController.getString("KeepMedia", R.string.KeepMedia), "keepMediaRow", LocaleController.getString("DataSettings", R.string.DataSettings), LocaleController.getString("StorageUsage", R.string.StorageUsage), R.drawable.msg_data, () -> presentFragment(new CacheControlActivity())),
new SearchResult(204, LocaleController.getString("ClearMediaCache", R.string.ClearMediaCache), "cacheRow", LocaleController.getString("DataSettings", R.string.DataSettings), LocaleController.getString("StorageUsage", R.string.StorageUsage), R.drawable.msg_data, () -> presentFragment(new CacheControlActivity())),
new SearchResult(205, LocaleController.getString("LocalDatabase", R.string.LocalDatabase), "databaseRow", LocaleController.getString("DataSettings", R.string.DataSettings), LocaleController.getString("StorageUsage", R.string.StorageUsage), R.drawable.msg_data, () -> presentFragment(new CacheControlActivity())),
new SearchResult(206, LocaleController.getString("NetworkUsage", R.string.NetworkUsage), LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataUsageActivity())),
new SearchResult(207, LocaleController.getString("AutomaticMediaDownload", R.string.AutomaticMediaDownload), "mediaDownloadSectionRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(208, LocaleController.getString("WhenUsingMobileData", R.string.WhenUsingMobileData), LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataAutoDownloadActivity(0))),
new SearchResult(209, LocaleController.getString("WhenConnectedOnWiFi", R.string.WhenConnectedOnWiFi), LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataAutoDownloadActivity(1))),
new SearchResult(210, LocaleController.getString("WhenRoaming", R.string.WhenRoaming), LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataAutoDownloadActivity(2))),
new SearchResult(211, LocaleController.getString("ResetAutomaticMediaDownload", R.string.ResetAutomaticMediaDownload), "resetDownloadRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(212, LocaleController.getString("AutoplayMedia", R.string.AutoplayMedia), "autoplayHeaderRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(213, LocaleController.getString("AutoplayGIF", R.string.AutoplayGIF), "autoplayGifsRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(214, LocaleController.getString("AutoplayVideo", R.string.AutoplayVideo), "autoplayVideoRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(215, LocaleController.getString("Streaming", R.string.Streaming), "streamSectionRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(216, LocaleController.getString("EnableStreaming", R.string.EnableStreaming), "enableStreamRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(217, LocaleController.getString("Calls", R.string.Calls), "callsSectionRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(218, LocaleController.getString("VoipUseLessData", R.string.VoipUseLessData), "useLessDataForCallsRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(219, LocaleController.getString("VoipQuickReplies", R.string.VoipQuickReplies), "quickRepliesRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(220, LocaleController.getString("ProxySettings", R.string.ProxySettings), LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new ProxyListActivity())),
new SearchResult(221, LocaleController.getString("UseProxyForCalls", R.string.UseProxyForCalls), "callsRow", LocaleController.getString("DataSettings", R.string.DataSettings), LocaleController.getString("ProxySettings", R.string.ProxySettings), R.drawable.msg_data, () -> presentFragment(new ProxyListActivity())),
new SearchResult(111, LocaleController.getString("PrivacyDeleteCloudDrafts", R.string.PrivacyDeleteCloudDrafts), "clearDraftsRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(300, LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(301, LocaleController.getString("TextSizeHeader", R.string.TextSizeHeader), "textSizeHeaderRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(302, LocaleController.getString("ChatBackground", R.string.ChatBackground), LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new WallpapersListActivity(WallpapersListActivity.TYPE_ALL))),
new SearchResult(303, LocaleController.getString("SetColor", R.string.SetColor), null, LocaleController.getString("ChatSettings", R.string.ChatSettings), LocaleController.getString("ChatBackground", R.string.ChatBackground), R.drawable.msg_msgbubble3, () -> presentFragment(new WallpapersListActivity(WallpapersListActivity.TYPE_COLOR))),
new SearchResult(304, LocaleController.getString("ResetChatBackgrounds", R.string.ResetChatBackgrounds), "resetRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), LocaleController.getString("ChatBackground", R.string.ChatBackground), R.drawable.msg_msgbubble3, () -> presentFragment(new WallpapersListActivity(WallpapersListActivity.TYPE_ALL))),
new SearchResult(305, LocaleController.getString("AutoNightTheme", R.string.AutoNightTheme), LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_NIGHT))),
new SearchResult(306, LocaleController.getString("ColorTheme", R.string.ColorTheme), "themeHeaderRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(307, LocaleController.getString("ChromeCustomTabs", R.string.ChromeCustomTabs), "customTabsRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(308, LocaleController.getString("DirectShare", R.string.DirectShare), "directShareRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(309, LocaleController.getString("EnableAnimations", R.string.EnableAnimations), "enableAnimationsRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(310, LocaleController.getString("RaiseToSpeak", R.string.RaiseToSpeak), "raiseToSpeakRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(311, LocaleController.getString("SendByEnter", R.string.SendByEnter), "sendByEnterRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(312, LocaleController.getString("SaveToGallerySettings", R.string.SaveToGallerySettings), "saveToGalleryRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(318, LocaleController.getString("DistanceUnits", R.string.DistanceUnits), "distanceRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(313, LocaleController.getString("StickersAndMasks", R.string.StickersAndMasks), LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new StickersActivity(MediaDataController.TYPE_IMAGE, null))),
new SearchResult(314, LocaleController.getString("SuggestStickers", R.string.SuggestStickers), "suggestRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), LocaleController.getString("StickersAndMasks", R.string.StickersAndMasks), R.drawable.msg_msgbubble3, () -> presentFragment(new StickersActivity(MediaDataController.TYPE_IMAGE, null))),
new SearchResult(315, LocaleController.getString("FeaturedStickers", R.string.FeaturedStickers), null, LocaleController.getString("ChatSettings", R.string.ChatSettings), LocaleController.getString("StickersAndMasks", R.string.StickersAndMasks), R.drawable.msg_msgbubble3, () -> presentFragment(new FeaturedStickersActivity())),
new SearchResult(316, LocaleController.getString("Masks", R.string.Masks), null, LocaleController.getString("ChatSettings", R.string.ChatSettings), LocaleController.getString("StickersAndMasks", R.string.StickersAndMasks), R.drawable.msg_msgbubble3, () -> presentFragment(new StickersActivity(MediaDataController.TYPE_MASK, null))),
new SearchResult(317, LocaleController.getString("ArchivedStickers", R.string.ArchivedStickers), null, LocaleController.getString("ChatSettings", R.string.ChatSettings), LocaleController.getString("StickersAndMasks", R.string.StickersAndMasks), R.drawable.msg_msgbubble3, () -> presentFragment(new ArchivedStickersActivity(MediaDataController.TYPE_IMAGE))),
new SearchResult(317, LocaleController.getString("ArchivedMasks", R.string.ArchivedMasks), null, LocaleController.getString("ChatSettings", R.string.ChatSettings), LocaleController.getString("StickersAndMasks", R.string.StickersAndMasks), R.drawable.msg_msgbubble3, () -> presentFragment(new ArchivedStickersActivity(MediaDataController.TYPE_MASK))),
new SearchResult(400, LocaleController.getString("Language", R.string.Language), R.drawable.msg_language, () -> presentFragment(new LanguageSelectActivity())),
new SearchResult(402, LocaleController.getString("AskAQuestion", R.string.AskAQuestion), LocaleController.getString("SettingsHelp", R.string.SettingsHelp), R.drawable.msg_help, () -> showDialog(AlertsCreator.createSupportAlert(ProfileActivity.this, null))),
new SearchResult(403, LocaleController.getString("TelegramFAQ", R.string.TelegramFAQ), LocaleController.getString("SettingsHelp", R.string.SettingsHelp), R.drawable.msg_help, () -> Browser.openUrl(getParentActivity(), LocaleController.getString("TelegramFaqUrl", R.string.TelegramFaqUrl))),
new SearchResult(404, LocaleController.getString("PrivacyPolicy", R.string.PrivacyPolicy), LocaleController.getString("SettingsHelp", R.string.SettingsHelp), R.drawable.msg_help, () -> Browser.openUrl(getParentActivity(), LocaleController.getString("PrivacyPolicyUrl", R.string.PrivacyPolicyUrl))),
};
private ArrayList<MessagesController.FaqSearchResult> faqSearchArray = new ArrayList<>(); private ArrayList<MessagesController.FaqSearchResult> faqSearchArray = new ArrayList<>();
private Context mContext; private Context mContext;
@ -9122,6 +9041,10 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
public SearchAdapter(Context context) { public SearchAdapter(Context context) {
mContext = context; mContext = context;
updateSearchArray();
}
private void updateSearchArray() {
HashMap<Integer, SearchResult> resultHashMap = new HashMap<>(); HashMap<Integer, SearchResult> resultHashMap = new HashMap<>();
for (int a = 0; a < searchArray.length; a++) { for (int a = 0; a < searchArray.length; a++) {
if (searchArray[a] == null) { if (searchArray[a] == null) {
@ -9174,6 +9097,183 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
}); });
} }
private SearchResult[] onCreateSearchArray() {
return new SearchResult[]{
new SearchResult(500, LocaleController.getString("EditName", R.string.EditName), 0, () -> presentFragment(new ChangeNameActivity(resourcesProvider))),
new SearchResult(501, LocaleController.getString("ChangePhoneNumber", R.string.ChangePhoneNumber), 0, () -> presentFragment(new ActionIntroActivity(ActionIntroActivity.ACTION_TYPE_CHANGE_PHONE_NUMBER))),
new SearchResult(502, LocaleController.getString("AddAnotherAccount", R.string.AddAnotherAccount), 0, () -> {
int freeAccount = -1;
for (int a = 0; a < UserConfig.MAX_ACCOUNT_COUNT; a++) {
if (!UserConfig.getInstance(a).isClientActivated()) {
freeAccount = a;
break;
}
}
if (freeAccount >= 0) {
presentFragment(new LoginActivity(freeAccount));
}
}),
new SearchResult(503, LocaleController.getString("UserBio", R.string.UserBio), 0, () -> {
if (userInfo != null) {
presentFragment(new ChangeBioActivity());
}
}),
new SearchResult(504, LocaleController.getString(R.string.AddPhoto), 0, ProfileActivity.this::onWriteButtonClick),
new SearchResult(1, LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsSettingsActivity())),
new SearchResult(2, LocaleController.getString("NotificationsPrivateChats", R.string.NotificationsPrivateChats), LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsCustomSettingsActivity(NotificationsController.TYPE_PRIVATE, new ArrayList<>(), true))),
new SearchResult(3, LocaleController.getString("NotificationsGroups", R.string.NotificationsGroups), LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsCustomSettingsActivity(NotificationsController.TYPE_GROUP, new ArrayList<>(), true))),
new SearchResult(4, LocaleController.getString("NotificationsChannels", R.string.NotificationsChannels), LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsCustomSettingsActivity(NotificationsController.TYPE_CHANNEL, new ArrayList<>(), true))),
new SearchResult(5, LocaleController.getString("VoipNotificationSettings", R.string.VoipNotificationSettings), "callsSectionRow", LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsSettingsActivity())),
new SearchResult(6, LocaleController.getString("BadgeNumber", R.string.BadgeNumber), "badgeNumberSection", LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsSettingsActivity())),
new SearchResult(7, LocaleController.getString("InAppNotifications", R.string.InAppNotifications), "inappSectionRow", LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsSettingsActivity())),
new SearchResult(8, LocaleController.getString("ContactJoined", R.string.ContactJoined), "contactJoinedRow", LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsSettingsActivity())),
new SearchResult(9, LocaleController.getString("PinnedMessages", R.string.PinnedMessages), "pinnedMessageRow", LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsSettingsActivity())),
new SearchResult(10, LocaleController.getString("ResetAllNotifications", R.string.ResetAllNotifications), "resetNotificationsRow", LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsSettingsActivity())),
new SearchResult(11, LocaleController.getString(R.string.NotificationsService), "notificationsServiceRow", LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsSettingsActivity())),
new SearchResult(12, LocaleController.getString(R.string.NotificationsServiceConnection), "notificationsServiceConnectionRow", LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsSettingsActivity())),
new SearchResult(13, LocaleController.getString(R.string.RepeatNotifications), "repeatRow", LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.msg_notifications, () -> presentFragment(new NotificationsSettingsActivity())),
new SearchResult(100, LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacySettingsActivity())),
new SearchResult(101, LocaleController.getString("BlockedUsers", R.string.BlockedUsers), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacyUsersActivity())),
new SearchResult(105, LocaleController.getString("PrivacyPhone", R.string.PrivacyPhone), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacyControlActivity(ContactsController.PRIVACY_RULES_TYPE_PHONE, true))),
new SearchResult(102, LocaleController.getString("PrivacyLastSeen", R.string.PrivacyLastSeen), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacyControlActivity(ContactsController.PRIVACY_RULES_TYPE_LASTSEEN, true))),
new SearchResult(103, LocaleController.getString("PrivacyProfilePhoto", R.string.PrivacyProfilePhoto), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacyControlActivity(ContactsController.PRIVACY_RULES_TYPE_PHOTO, true))),
new SearchResult(104, LocaleController.getString("PrivacyForwards", R.string.PrivacyForwards), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacyControlActivity(ContactsController.PRIVACY_RULES_TYPE_FORWARDS, true))),
new SearchResult(122, LocaleController.getString("PrivacyP2P", R.string.PrivacyP2P), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacyControlActivity(ContactsController.PRIVACY_RULES_TYPE_P2P, true))),
new SearchResult(106, LocaleController.getString("Calls", R.string.Calls), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacyControlActivity(ContactsController.PRIVACY_RULES_TYPE_CALLS, true))),
new SearchResult(107, LocaleController.getString("GroupsAndChannels", R.string.GroupsAndChannels), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacyControlActivity(ContactsController.PRIVACY_RULES_TYPE_INVITE, true))),
new SearchResult(123, LocaleController.getString("PrivacyVoiceMessages", R.string.PrivacyVoiceMessages), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> {
if (!getUserConfig().isPremium()) {
try {
fragmentView.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
} catch (Exception e) {
FileLog.e(e);
}
BulletinFactory.of(ProfileActivity.this).createRestrictVoiceMessagesPremiumBulletin().show();
return;
}
presentFragment(new PrivacyControlActivity(ContactsController.PRIVACY_RULES_TYPE_VOICE_MESSAGES, true));
}),
new SearchResult(108, LocaleController.getString("Passcode", R.string.Passcode), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(PasscodeActivity.determineOpenFragment())),
new SearchResult(109, LocaleController.getString("TwoStepVerification", R.string.TwoStepVerification), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new TwoStepVerificationActivity())),
new SearchResult(110, LocaleController.getString("SessionsTitle", R.string.SessionsTitle), R.drawable.msg_secret, () -> presentFragment(new SessionsActivity(0))),
getMessagesController().autoarchiveAvailable ? new SearchResult(121, LocaleController.getString("ArchiveAndMute", R.string.ArchiveAndMute), "newChatsRow", LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacySettingsActivity())) : null,
new SearchResult(112, LocaleController.getString("DeleteAccountIfAwayFor2", R.string.DeleteAccountIfAwayFor2), "deleteAccountRow", LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacySettingsActivity())),
new SearchResult(113, LocaleController.getString("PrivacyPaymentsClear", R.string.PrivacyPaymentsClear), "paymentsClearRow", LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacySettingsActivity())),
new SearchResult(114, LocaleController.getString("WebSessionsTitle", R.string.WebSessionsTitle), LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new SessionsActivity(1))),
new SearchResult(115, LocaleController.getString("SyncContactsDelete", R.string.SyncContactsDelete), "contactsDeleteRow", LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacySettingsActivity())),
new SearchResult(116, LocaleController.getString("SyncContacts", R.string.SyncContacts), "contactsSyncRow", LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacySettingsActivity())),
new SearchResult(117, LocaleController.getString("SuggestContacts", R.string.SuggestContacts), "contactsSuggestRow", LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacySettingsActivity())),
new SearchResult(118, LocaleController.getString("MapPreviewProvider", R.string.MapPreviewProvider), "secretMapRow", LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacySettingsActivity())),
new SearchResult(119, LocaleController.getString("SecretWebPage", R.string.SecretWebPage), "secretWebpageRow", LocaleController.getString("PrivacySettings", R.string.PrivacySettings), R.drawable.msg_secret, () -> presentFragment(new PrivacySettingsActivity())),
new SearchResult(120, LocaleController.getString(R.string.Devices), R.drawable.msg_devices, () -> presentFragment(new SessionsActivity(0))),
new SearchResult(121, LocaleController.getString(R.string.TerminateAllSessions), "terminateAllSessionsRow", LocaleController.getString(R.string.Devices), R.drawable.msg_devices, () -> presentFragment(new SessionsActivity(0))),
new SearchResult(122, LocaleController.getString(R.string.LinkDesktopDevice), LocaleController.getString(R.string.Devices), R.drawable.msg_devices, () -> presentFragment(new SessionsActivity(0).setHighlightLinkDesktopDevice())),
new SearchResult(200, LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(201, LocaleController.getString("DataUsage", R.string.DataUsage), "usageSectionRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(202, LocaleController.getString("StorageUsage", R.string.StorageUsage), LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new CacheControlActivity())),
new SearchResult(203, LocaleController.getString("KeepMedia", R.string.KeepMedia), "keepMediaRow", LocaleController.getString("DataSettings", R.string.DataSettings), LocaleController.getString("StorageUsage", R.string.StorageUsage), R.drawable.msg_data, () -> presentFragment(new CacheControlActivity())),
new SearchResult(204, LocaleController.getString("ClearMediaCache", R.string.ClearMediaCache), "cacheRow", LocaleController.getString("DataSettings", R.string.DataSettings), LocaleController.getString("StorageUsage", R.string.StorageUsage), R.drawable.msg_data, () -> presentFragment(new CacheControlActivity())),
new SearchResult(205, LocaleController.getString("LocalDatabase", R.string.LocalDatabase), "databaseRow", LocaleController.getString("DataSettings", R.string.DataSettings), LocaleController.getString("StorageUsage", R.string.StorageUsage), R.drawable.msg_data, () -> presentFragment(new CacheControlActivity())),
new SearchResult(206, LocaleController.getString("NetworkUsage", R.string.NetworkUsage), LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataUsageActivity())),
new SearchResult(207, LocaleController.getString("AutomaticMediaDownload", R.string.AutomaticMediaDownload), "mediaDownloadSectionRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(208, LocaleController.getString("WhenUsingMobileData", R.string.WhenUsingMobileData), LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataAutoDownloadActivity(0))),
new SearchResult(209, LocaleController.getString("WhenConnectedOnWiFi", R.string.WhenConnectedOnWiFi), LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataAutoDownloadActivity(1))),
new SearchResult(210, LocaleController.getString("WhenRoaming", R.string.WhenRoaming), LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataAutoDownloadActivity(2))),
new SearchResult(211, LocaleController.getString("ResetAutomaticMediaDownload", R.string.ResetAutomaticMediaDownload), "resetDownloadRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(212, LocaleController.getString("AutoplayMedia", R.string.AutoplayMedia), "autoplayHeaderRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(213, LocaleController.getString("AutoplayGIF", R.string.AutoplayGIF), "autoplayGifsRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(214, LocaleController.getString("AutoplayVideo", R.string.AutoplayVideo), "autoplayVideoRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(215, LocaleController.getString("Streaming", R.string.Streaming), "streamSectionRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(216, LocaleController.getString("EnableStreaming", R.string.EnableStreaming), "enableStreamRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(217, LocaleController.getString("Calls", R.string.Calls), "callsSectionRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(218, LocaleController.getString("VoipUseLessData", R.string.VoipUseLessData), "useLessDataForCallsRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(219, LocaleController.getString("VoipQuickReplies", R.string.VoipQuickReplies), "quickRepliesRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(220, LocaleController.getString("ProxySettings", R.string.ProxySettings), LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new ProxyListActivity())),
new SearchResult(221, LocaleController.getString("UseProxyForCalls", R.string.UseProxyForCalls), "callsRow", LocaleController.getString("DataSettings", R.string.DataSettings), LocaleController.getString("ProxySettings", R.string.ProxySettings), R.drawable.msg_data, () -> presentFragment(new ProxyListActivity())),
new SearchResult(111, LocaleController.getString("PrivacyDeleteCloudDrafts", R.string.PrivacyDeleteCloudDrafts), "clearDraftsRow", LocaleController.getString("DataSettings", R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(222, LocaleController.getString(R.string.SaveToGallery), "saveToGallerySectionRow", LocaleController.getString(R.string.DataSettings), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(223, LocaleController.getString(R.string.SaveToGalleryPrivate), "saveToGalleryPeerRow", LocaleController.getString(R.string.DataSettings), LocaleController.getString(R.string.SaveToGallery), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(224, LocaleController.getString(R.string.SaveToGalleryGroups), "saveToGalleryGroupsRow", LocaleController.getString(R.string.DataSettings), LocaleController.getString(R.string.SaveToGallery), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(225, LocaleController.getString(R.string.SaveToGalleryChannels), "saveToGalleryChannelsRow", LocaleController.getString(R.string.DataSettings), LocaleController.getString(R.string.SaveToGallery), R.drawable.msg_data, () -> presentFragment(new DataSettingsActivity())),
new SearchResult(300, LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(301, LocaleController.getString("TextSizeHeader", R.string.TextSizeHeader), "textSizeHeaderRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(302, LocaleController.getString(R.string.ChangeChatBackground), LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new WallpapersListActivity(WallpapersListActivity.TYPE_ALL))),
new SearchResult(303, LocaleController.getString("SetColor", R.string.SetColor), null, LocaleController.getString("ChatSettings", R.string.ChatSettings), LocaleController.getString("ChatBackground", R.string.ChatBackground), R.drawable.msg_msgbubble3, () -> presentFragment(new WallpapersListActivity(WallpapersListActivity.TYPE_COLOR))),
new SearchResult(304, LocaleController.getString("ResetChatBackgrounds", R.string.ResetChatBackgrounds), "resetRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), LocaleController.getString("ChatBackground", R.string.ChatBackground), R.drawable.msg_msgbubble3, () -> presentFragment(new WallpapersListActivity(WallpapersListActivity.TYPE_ALL))),
new SearchResult(306, LocaleController.getString("ColorTheme", R.string.ColorTheme), "themeHeaderRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(319, LocaleController.getString(R.string.BrowseThemes), null, LocaleController.getString(R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_THEMES_BROWSER))),
new SearchResult(320, LocaleController.getString(R.string.CreateNewTheme), "createNewThemeRow", LocaleController.getString(R.string.ChatSettings), LocaleController.getString(R.string.BrowseThemes), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_THEMES_BROWSER))),
new SearchResult(321, LocaleController.getString(R.string.BubbleRadius), "bubbleRadiusHeaderRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(322, LocaleController.getString(R.string.ChatList), "chatListHeaderRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(323, LocaleController.getString(R.string.ChatListSwipeGesture), "swipeGestureHeaderRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(324, LocaleController.getString(R.string.AppIcon), "appIconHeaderRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(305, LocaleController.getString("AutoNightTheme", R.string.AutoNightTheme), LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_NIGHT))),
new SearchResult(307, LocaleController.getString("ChromeCustomTabs", R.string.ChromeCustomTabs), "customTabsRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(308, LocaleController.getString("DirectShare", R.string.DirectShare), "directShareRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(309, LocaleController.getString("EnableAnimations", R.string.EnableAnimations), "enableAnimationsRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(310, LocaleController.getString("RaiseToSpeak", R.string.RaiseToSpeak), "raiseToSpeakRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(325, LocaleController.getString(R.string.MicrophoneForVoiceMessages), "bluetoothScoRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(311, LocaleController.getString("SendByEnter", R.string.SendByEnter), "sendByEnterRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
SharedConfig.canBlurChat() ? new SearchResult(326, LocaleController.getString(R.string.BlurInChat), "chatBlurRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))) : null,
new SearchResult(318, LocaleController.getString("DistanceUnits", R.string.DistanceUnits), "distanceRow", LocaleController.getString("ChatSettings", R.string.ChatSettings), R.drawable.msg_msgbubble3, () -> presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC))),
new SearchResult(600, LocaleController.getString(R.string.StickersName), R.drawable.msg_sticker, () -> presentFragment(new StickersActivity(MediaDataController.TYPE_IMAGE, null))),
new SearchResult(601, LocaleController.getString("SuggestStickers", R.string.SuggestStickers), "suggestRow", LocaleController.getString(R.string.StickersName), R.drawable.msg_sticker, () -> presentFragment(new StickersActivity(MediaDataController.TYPE_IMAGE, null))),
new SearchResult(602, LocaleController.getString("FeaturedStickers", R.string.FeaturedStickers), "featuredStickersHeaderRow", LocaleController.getString(R.string.StickersName), R.drawable.msg_sticker, () -> presentFragment(new StickersActivity(MediaDataController.TYPE_IMAGE, null))),
new SearchResult(603, LocaleController.getString("Masks", R.string.Masks), null, LocaleController.getString(R.string.StickersName), R.drawable.msg_sticker, () -> presentFragment(new StickersActivity(MediaDataController.TYPE_MASK, null))),
new SearchResult(604, LocaleController.getString("ArchivedStickers", R.string.ArchivedStickers), null, LocaleController.getString(R.string.StickersName), R.drawable.msg_sticker, () -> presentFragment(new ArchivedStickersActivity(MediaDataController.TYPE_IMAGE))),
new SearchResult(605, LocaleController.getString("ArchivedMasks", R.string.ArchivedMasks), null, LocaleController.getString(R.string.StickersName), R.drawable.msg_sticker, () -> presentFragment(new ArchivedStickersActivity(MediaDataController.TYPE_MASK))),
new SearchResult(606, LocaleController.getString(R.string.LargeEmoji), "largeEmojiRow", LocaleController.getString(R.string.StickersName), R.drawable.msg_sticker, () -> presentFragment(new StickersActivity(MediaDataController.TYPE_IMAGE, null))),
new SearchResult(607, LocaleController.getString(R.string.LoopAnimatedStickers), "loopRow", LocaleController.getString(R.string.StickersName), R.drawable.msg_sticker, () -> presentFragment(new StickersActivity(MediaDataController.TYPE_IMAGE, null))),
new SearchResult(608, LocaleController.getString(R.string.Emoji), null, LocaleController.getString(R.string.StickersName), R.drawable.input_smile, () -> presentFragment(new StickersActivity(MediaDataController.TYPE_EMOJIPACKS, null))),
new SearchResult(609, LocaleController.getString(R.string.SuggestAnimatedEmoji), "suggestAnimatedEmojiRow", LocaleController.getString(R.string.StickersName), LocaleController.getString(R.string.Emoji), R.drawable.input_smile, () -> presentFragment(new StickersActivity(MediaDataController.TYPE_EMOJIPACKS, null))),
new SearchResult(610, LocaleController.getString(R.string.FeaturedEmojiPacks), "featuredStickersHeaderRow", LocaleController.getString(R.string.StickersName), LocaleController.getString(R.string.Emoji), R.drawable.input_smile, () -> presentFragment(new StickersActivity(MediaDataController.TYPE_EMOJIPACKS, null))),
new SearchResult(611, LocaleController.getString(R.string.DoubleTapSetting), null, LocaleController.getString(R.string.StickersName), R.drawable.msg_sticker, () -> presentFragment(new ReactionsDoubleTapManageActivity())),
new SearchResult(700, LocaleController.getString(R.string.Filters), null, R.drawable.msg_folder, () -> presentFragment(new FiltersSetupActivity())),
new SearchResult(701, LocaleController.getString(R.string.CreateNewFilter), "createFilterRow", LocaleController.getString(R.string.Filters), R.drawable.msg_folder, () -> presentFragment(new FiltersSetupActivity())),
isPremiumFeatureAvailable(-1) ? new SearchResult(800, LocaleController.getString(R.string.TelegramPremium), R.drawable.msg_settings_premium, () -> presentFragment(new PremiumPreviewFragment("settings"))) : null,
isPremiumFeatureAvailable(PremiumPreviewFragment.PREMIUM_FEATURE_LIMITS) ? new SearchResult(801, LocaleController.getString(R.string.PremiumPreviewLimits), LocaleController.getString(R.string.TelegramPremium), R.drawable.msg_settings_premium, () -> showDialog(new PremiumFeatureBottomSheet(ProfileActivity.this, PremiumPreviewFragment.PREMIUM_FEATURE_LIMITS, false).setForceAbout())) : null,
isPremiumFeatureAvailable(PremiumPreviewFragment.PREMIUM_FEATURE_ANIMATED_EMOJI) ? new SearchResult(802, LocaleController.getString(R.string.PremiumPreviewEmoji), LocaleController.getString(R.string.TelegramPremium), R.drawable.msg_settings_premium, () -> showDialog(new PremiumFeatureBottomSheet(ProfileActivity.this, PremiumPreviewFragment.PREMIUM_FEATURE_ANIMATED_EMOJI, false).setForceAbout())) : null,
isPremiumFeatureAvailable(PremiumPreviewFragment.PREMIUM_FEATURE_UPLOAD_LIMIT) ? new SearchResult(803, LocaleController.getString(R.string.PremiumPreviewUploads), LocaleController.getString(R.string.TelegramPremium), R.drawable.msg_settings_premium, () -> showDialog(new PremiumFeatureBottomSheet(ProfileActivity.this, PremiumPreviewFragment.PREMIUM_FEATURE_UPLOAD_LIMIT, false).setForceAbout())) : null,
isPremiumFeatureAvailable(PremiumPreviewFragment.PREMIUM_FEATURE_DOWNLOAD_SPEED) ? new SearchResult(804, LocaleController.getString(R.string.PremiumPreviewDownloadSpeed), LocaleController.getString(R.string.TelegramPremium), R.drawable.msg_settings_premium, () -> showDialog(new PremiumFeatureBottomSheet(ProfileActivity.this, PremiumPreviewFragment.PREMIUM_FEATURE_DOWNLOAD_SPEED, false).setForceAbout())) : null,
isPremiumFeatureAvailable(PremiumPreviewFragment.PREMIUM_FEATURE_VOICE_TO_TEXT) ? new SearchResult(805, LocaleController.getString(R.string.PremiumPreviewVoiceToText), LocaleController.getString(R.string.TelegramPremium), R.drawable.msg_settings_premium, () -> showDialog(new PremiumFeatureBottomSheet(ProfileActivity.this, PremiumPreviewFragment.PREMIUM_FEATURE_VOICE_TO_TEXT, false).setForceAbout())) : null,
isPremiumFeatureAvailable(PremiumPreviewFragment.PREMIUM_FEATURE_ADS) ? new SearchResult(806, LocaleController.getString(R.string.PremiumPreviewNoAds), LocaleController.getString(R.string.TelegramPremium), R.drawable.msg_settings_premium, () -> showDialog(new PremiumFeatureBottomSheet(ProfileActivity.this, PremiumPreviewFragment.PREMIUM_FEATURE_ADS, false).setForceAbout())) : null,
isPremiumFeatureAvailable(PremiumPreviewFragment.PREMIUM_FEATURE_REACTIONS) ? new SearchResult(807, LocaleController.getString(R.string.PremiumPreviewReactions), LocaleController.getString(R.string.TelegramPremium), R.drawable.msg_settings_premium, () -> showDialog(new PremiumFeatureBottomSheet(ProfileActivity.this, PremiumPreviewFragment.PREMIUM_FEATURE_REACTIONS, false).setForceAbout())) : null,
isPremiumFeatureAvailable(PremiumPreviewFragment.PREMIUM_FEATURE_STICKERS) ? new SearchResult(808, LocaleController.getString(R.string.PremiumPreviewStickers), LocaleController.getString(R.string.TelegramPremium), R.drawable.msg_settings_premium, () -> showDialog(new PremiumFeatureBottomSheet(ProfileActivity.this, PremiumPreviewFragment.PREMIUM_FEATURE_STICKERS, false).setForceAbout())) : null,
isPremiumFeatureAvailable(PremiumPreviewFragment.PREMIUM_FEATURE_ADVANCED_CHAT_MANAGEMENT) ? new SearchResult(809, LocaleController.getString(R.string.PremiumPreviewAdvancedChatManagement), LocaleController.getString(R.string.TelegramPremium), R.drawable.msg_settings_premium, () -> showDialog(new PremiumFeatureBottomSheet(ProfileActivity.this, PremiumPreviewFragment.PREMIUM_FEATURE_ADVANCED_CHAT_MANAGEMENT, false).setForceAbout())) : null,
isPremiumFeatureAvailable(PremiumPreviewFragment.PREMIUM_FEATURE_PROFILE_BADGE) ? new SearchResult(810, LocaleController.getString(R.string.PremiumPreviewProfileBadge), LocaleController.getString(R.string.TelegramPremium), R.drawable.msg_settings_premium, () -> showDialog(new PremiumFeatureBottomSheet(ProfileActivity.this, PremiumPreviewFragment.PREMIUM_FEATURE_PROFILE_BADGE, false).setForceAbout())) : null,
isPremiumFeatureAvailable(PremiumPreviewFragment.PREMIUM_FEATURE_ANIMATED_AVATARS) ? new SearchResult(811, LocaleController.getString(R.string.PremiumPreviewAnimatedProfiles), LocaleController.getString(R.string.TelegramPremium), R.drawable.msg_settings_premium, () -> showDialog(new PremiumFeatureBottomSheet(ProfileActivity.this, PremiumPreviewFragment.PREMIUM_FEATURE_ANIMATED_AVATARS, false).setForceAbout())) : null,
isPremiumFeatureAvailable(PremiumPreviewFragment.PREMIUM_FEATURE_APPLICATION_ICONS) ? new SearchResult(812, LocaleController.getString(R.string.PremiumPreviewAppIcon), LocaleController.getString(R.string.TelegramPremium), R.drawable.msg_settings_premium, () -> showDialog(new PremiumFeatureBottomSheet(ProfileActivity.this, PremiumPreviewFragment.PREMIUM_FEATURE_APPLICATION_ICONS, false).setForceAbout())) : null,
isPremiumFeatureAvailable(PremiumPreviewFragment.PREMIUM_FEATURE_EMOJI_STATUS) ? new SearchResult(813, LocaleController.getString(R.string.PremiumPreviewEmojiStatus), LocaleController.getString(R.string.TelegramPremium), R.drawable.msg_settings_premium, () -> showDialog(new PremiumFeatureBottomSheet(ProfileActivity.this, PremiumPreviewFragment.PREMIUM_FEATURE_EMOJI_STATUS, false).setForceAbout())) : null,
new SearchResult(400, LocaleController.getString("Language", R.string.Language), R.drawable.msg_language, () -> presentFragment(new LanguageSelectActivity())),
new SearchResult(405, LocaleController.getString(R.string.ShowTranslateButton), LocaleController.getString(R.string.Language), R.drawable.msg_language, () -> presentFragment(new LanguageSelectActivity())),
MessagesController.getGlobalMainSettings().getBoolean("translate_button", false) ? new SearchResult(406, LocaleController.getString(R.string.DoNotTranslate), LocaleController.getString(R.string.Language), R.drawable.msg_language, () -> presentFragment(new LanguageSelectActivity())) : null,
new SearchResult(402, LocaleController.getString("AskAQuestion", R.string.AskAQuestion), LocaleController.getString("SettingsHelp", R.string.SettingsHelp), R.drawable.msg_help, () -> showDialog(AlertsCreator.createSupportAlert(ProfileActivity.this, null))),
new SearchResult(403, LocaleController.getString("TelegramFAQ", R.string.TelegramFAQ), LocaleController.getString("SettingsHelp", R.string.SettingsHelp), R.drawable.msg_help, () -> Browser.openUrl(getParentActivity(), LocaleController.getString("TelegramFaqUrl", R.string.TelegramFaqUrl))),
new SearchResult(404, LocaleController.getString("PrivacyPolicy", R.string.PrivacyPolicy), LocaleController.getString("SettingsHelp", R.string.SettingsHelp), R.drawable.msg_help, () -> Browser.openUrl(getParentActivity(), LocaleController.getString("PrivacyPolicyUrl", R.string.PrivacyPolicyUrl))),
};
}
private boolean isPremiumFeatureAvailable(int feature) {
if (getMessagesController().premiumLocked && !getUserConfig().isPremium()) {
return false;
}
if (feature == -1) {
return true;
}
return getMessagesController().premiumFeaturesTypesToPosition.get(feature, -1) != -1;
}
private void loadFaqWebPage() { private void loadFaqWebPage() {
faqWebPage = getMessagesController().faqWebPage; faqWebPage = getMessagesController().faqWebPage;
if (faqWebPage != null) { if (faqWebPage != null) {
@ -9446,7 +9546,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
if (result.guid == 502) { if (result.guid == 502) {
int freeAccount = -1; int freeAccount = -1;
for (int b = 0; b < UserConfig.MAX_ACCOUNT_COUNT; b++) { for (int b = 0; b < UserConfig.MAX_ACCOUNT_COUNT; b++) {
if (!UserConfig.getInstance(a).isClientActivated()) { if (!UserConfig.getInstance(b).isClientActivated()) {
freeAccount = b; freeAccount = b;
break; break;
} }

View file

@ -2255,7 +2255,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati
public int position; public int position;
public TLRPC.Document document; public TLRPC.Document document;
public AnimatedEmojiSpan span; public AnimatedEmojiSpan span;
public ImageReceiver.BackgroundThreadDrawHolder backgroundThreadDrawHolder; public ImageReceiver.BackgroundThreadDrawHolder[] backgroundThreadDrawHolder = new ImageReceiver.BackgroundThreadDrawHolder[DrawingInBackgroundThreadDrawable.THREAD_COUNT];
public ImageReceiver imageReceiver; public ImageReceiver imageReceiver;
public ImageReceiver imageReceiverToDraw; public ImageReceiver imageReceiverToDraw;
public boolean isDefaultReaction; public boolean isDefaultReaction;
@ -3283,8 +3283,8 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati
} else { } else {
imageReceiver.setRoundRadius(0); imageReceiver.setRoundRadius(0);
} }
imageView.backgroundThreadDrawHolder = imageReceiver.setDrawInBackgroundThread(imageView.backgroundThreadDrawHolder); imageView.backgroundThreadDrawHolder[threadIndex] = imageReceiver.setDrawInBackgroundThread(imageView.backgroundThreadDrawHolder[threadIndex], threadIndex);
imageView.backgroundThreadDrawHolder.time = time; imageView.backgroundThreadDrawHolder[threadIndex].time = time;
imageView.imageReceiverToDraw = imageReceiver; imageView.imageReceiverToDraw = imageReceiver;
imageView.update(time); imageView.update(time);
@ -3302,7 +3302,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati
); );
} }
AndroidUtilities.rectTmp2.offset(imageView.getLeft() + (int) imageView.getTranslationX() - startOffset, topOffset); AndroidUtilities.rectTmp2.offset(imageView.getLeft() + (int) imageView.getTranslationX() - startOffset, topOffset);
imageView.backgroundThreadDrawHolder.setBounds(AndroidUtilities.rectTmp2); imageView.backgroundThreadDrawHolder[threadIndex].setBounds(AndroidUtilities.rectTmp2);
imageView.skewAlpha = 1f; imageView.skewAlpha = 1f;
imageView.skewIndex = i; imageView.skewIndex = i;
@ -3326,7 +3326,7 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati
} }
} else if (imageView.imageReceiverToDraw != null) { } else if (imageView.imageReceiverToDraw != null) {
// imageView.drawable.setColorFilter(premiumStarColorFilter); // imageView.drawable.setColorFilter(premiumStarColorFilter);
imageView.imageReceiverToDraw.draw(canvas, imageView.backgroundThreadDrawHolder); imageView.imageReceiverToDraw.draw(canvas, imageView.backgroundThreadDrawHolder[threadIndex]);
} }
} }
} }
@ -3445,8 +3445,8 @@ public class SelectAnimatedEmojiDialog extends FrameLayout implements Notificati
super.onFrameReady(); super.onFrameReady();
for (int i = 0; i < drawInBackgroundViews.size(); i++) { for (int i = 0; i < drawInBackgroundViews.size(); i++) {
ImageViewEmoji imageView = drawInBackgroundViews.get(i); ImageViewEmoji imageView = drawInBackgroundViews.get(i);
if (imageView.backgroundThreadDrawHolder != null) { if (imageView.backgroundThreadDrawHolder[threadIndex] != null) {
imageView.backgroundThreadDrawHolder.release(); imageView.backgroundThreadDrawHolder[threadIndex].release();
} }
} }
emojiGridView.invalidate(); emojiGridView.invalidate();

View file

@ -13,6 +13,7 @@ import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.graphics.Canvas;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
@ -73,6 +74,7 @@ import org.telegram.ui.Components.LinkSpanDrawable;
import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.URLSpanNoUnderline; import org.telegram.ui.Components.URLSpanNoUnderline;
import org.telegram.ui.Components.UndoView; import org.telegram.ui.Components.UndoView;
import org.telegram.ui.Components.voip.CellFlickerDrawable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Objects; import java.util.Objects;
@ -116,10 +118,18 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
private int repeatLoad = 0; private int repeatLoad = 0;
private boolean highlightLinkDesktopDevice;
private boolean fragmentOpened;
public SessionsActivity(int type) { public SessionsActivity(int type) {
currentType = type; currentType = type;
} }
public SessionsActivity setHighlightLinkDesktopDevice() {
this.highlightLinkDesktopDevice = true;
return this;
}
@Override @Override
public boolean onFragmentCreate() { public boolean onFragmentCreate() {
super.onFragmentCreate(); super.onFragmentCreate();
@ -135,6 +145,21 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.newSessionReceived); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.newSessionReceived);
} }
@Override
public void onTransitionAnimationEnd(boolean isOpen, boolean backward) {
super.onTransitionAnimationEnd(isOpen, backward);
if (isOpen && !backward) {
fragmentOpened = true;
for (int i = 0; i < listView.getChildCount(); i++) {
View ch = listView.getChildAt(i);
if (ch instanceof ScanQRCodeView) {
((ScanQRCodeView) ch).buttonTextView.invalidate();
}
}
}
}
@Override @Override
public View createView(Context context) { public View createView(Context context) {
globalFlickerLoadingView = new FlickerLoadingView(context); globalFlickerLoadingView = new FlickerLoadingView(context);
@ -902,12 +927,17 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
BackupImageView imageView; BackupImageView imageView;
TextView textView; TextView textView;
TextView buttonTextView;
CellFlickerDrawable flickerDrawable = new CellFlickerDrawable();
public ScanQRCodeView(@NonNull Context context) { public ScanQRCodeView(@NonNull Context context) {
super(context); super(context);
imageView = new BackupImageView(context); imageView = new BackupImageView(context);
addView(imageView, LayoutHelper.createFrame(120, 120, Gravity.CENTER_HORIZONTAL, 0, 16, 0, 0)); addView(imageView, LayoutHelper.createFrame(120, 120, Gravity.CENTER_HORIZONTAL, 0, 16, 0, 0));
flickerDrawable.repeatEnabled = false;
flickerDrawable.animationSpeedScale = 1.2f;
imageView.setOnClickListener(new OnClickListener() { imageView.setOnClickListener(new OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
@ -964,7 +994,19 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
textView.setText(spanned); textView.setText(spanned);
TextView buttonTextView = new TextView(context); buttonTextView = new TextView(context) {
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
if (flickerDrawable.progress <= 1f && highlightLinkDesktopDevice && fragmentOpened) {
AndroidUtilities.rectTmp.set(0, 0, getWidth(), getHeight());
flickerDrawable.setParentWidth(getMeasuredWidth());
flickerDrawable.draw(canvas, AndroidUtilities.rectTmp, AndroidUtilities.dp(8), null);
invalidate();
}
}
};
buttonTextView.setPadding(AndroidUtilities.dp(34), 0, AndroidUtilities.dp(34), 0); buttonTextView.setPadding(AndroidUtilities.dp(34), 0, AndroidUtilities.dp(34), 0);
buttonTextView.setGravity(Gravity.CENTER); buttonTextView.setGravity(Gravity.CENTER);
buttonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); buttonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);

View file

@ -39,6 +39,7 @@ import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils; import androidx.core.graphics.ColorUtils;
import androidx.recyclerview.widget.DefaultItemAnimator; import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -75,6 +76,7 @@ import org.telegram.ui.Components.AlertsCreator;
import org.telegram.ui.Components.AnimatedEmojiDrawable; import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.Bulletin; import org.telegram.ui.Components.Bulletin;
import org.telegram.ui.Components.BulletinFactory; import org.telegram.ui.Components.BulletinFactory;
import org.telegram.ui.Components.ChatActivityInterface;
import org.telegram.ui.Components.ChatAvatarContainer; import org.telegram.ui.Components.ChatAvatarContainer;
import org.telegram.ui.Components.ChatNotificationsPopupWrapper; import org.telegram.ui.Components.ChatNotificationsPopupWrapper;
import org.telegram.ui.Components.ColoredImageSpan; import org.telegram.ui.Components.ColoredImageSpan;
@ -87,6 +89,7 @@ import org.telegram.ui.Components.FragmentContextView;
import org.telegram.ui.Components.InviteMembersBottomSheet; import org.telegram.ui.Components.InviteMembersBottomSheet;
import org.telegram.ui.Components.JoinGroupAlert; import org.telegram.ui.Components.JoinGroupAlert;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.ListView.AdapterWithDiffUtils;
import org.telegram.ui.Components.NumberTextView; import org.telegram.ui.Components.NumberTextView;
import org.telegram.ui.Components.RLottieImageView; import org.telegram.ui.Components.RLottieImageView;
import org.telegram.ui.Components.RadialProgressView; import org.telegram.ui.Components.RadialProgressView;
@ -100,12 +103,11 @@ import org.telegram.ui.Delegates.ChatActivityMemberRequestsDelegate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Objects;
public class TopicsFragment extends BaseFragment implements NotificationCenter.NotificationCenterDelegate, FragmentContextView.ChatActivityInterface { public class TopicsFragment extends BaseFragment implements NotificationCenter.NotificationCenterDelegate, ChatActivityInterface {
final long chatId; final long chatId;
ArrayList<TLRPC.TL_forumTopic> forumTopics = new ArrayList<>(); ArrayList<Item> forumTopics = new ArrayList<>();
SizeNotifierFrameLayout contentView; SizeNotifierFrameLayout contentView;
ChatAvatarContainer avatarContainer; ChatAvatarContainer avatarContainer;
@ -124,6 +126,9 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
LinearLayoutManager layoutManager; LinearLayoutManager layoutManager;
boolean animatedUpdateEnabled = true; boolean animatedUpdateEnabled = true;
private final static int VIEW_TYPE_TOPIC = 0;
private final static int VIEW_TYPE_LOADING_CELL = 1;
private static final int toggle_id = 1; private static final int toggle_id = 1;
private static final int add_member_id = 2; private static final int add_member_id = 2;
private static final int create_topic_id = 3; private static final int create_topic_id = 3;
@ -141,6 +146,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
boolean canShowCreateTopic; boolean canShowCreateTopic;
private UnreadCounterTextView bottomOverlayChatText; private UnreadCounterTextView bottomOverlayChatText;
private RecyclerListView recyclerListView; private RecyclerListView recyclerListView;
private ItemTouchHelper itemTouchHelper;
private ActionBarMenuSubItem createTopicSubmenu; private ActionBarMenuSubItem createTopicSubmenu;
private ActionBarMenuSubItem addMemberSubMenu; private ActionBarMenuSubItem addMemberSubMenu;
private ActionBarMenuSubItem deleteChatSubmenu; private ActionBarMenuSubItem deleteChatSubmenu;
@ -149,6 +155,8 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
private float searchAnimation2Progress = 0f; private float searchAnimation2Progress = 0f;
HashSet<Integer> selectedTopics = new HashSet<>(); HashSet<Integer> selectedTopics = new HashSet<>();
private boolean reordering;
private boolean ignoreDiffUtil;
private NumberTextView selectedDialogsCountTextView; private NumberTextView selectedDialogsCountTextView;
private ActionBarMenuItem pinItem; private ActionBarMenuItem pinItem;
private ActionBarMenuItem unpinItem; private ActionBarMenuItem unpinItem;
@ -181,7 +189,6 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
DialogsActivity dialogsActivity; DialogsActivity dialogsActivity;
private boolean updateAnimated; private boolean updateAnimated;
private long lastAnimatedDuration;
private int transitionAnimationIndex; private int transitionAnimationIndex;
private int transitionAnimationGlobalIndex; private int transitionAnimationGlobalIndex;
@ -418,6 +425,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
case delete_chat_id: case delete_chat_id:
TLRPC.Chat chatLocal = getMessagesController().getChat(chatId); TLRPC.Chat chatLocal = getMessagesController().getChat(chatId);
AlertsCreator.createClearOrDeleteDialogAlert(TopicsFragment.this, false, chatLocal, null, false, true, false, (param) -> { AlertsCreator.createClearOrDeleteDialogAlert(TopicsFragment.this, false, chatLocal, null, false, true, false, (param) -> {
getNotificationCenter().removeObserver(TopicsFragment.this, NotificationCenter.closeChats);
getNotificationCenter().postNotificationName(NotificationCenter.closeChats); getNotificationCenter().postNotificationName(NotificationCenter.closeChats);
finishFragment(); finishFragment();
getNotificationCenter().postNotificationName(NotificationCenter.needDeleteDialog, -chatLocal.id, null, chatLocal, param); getNotificationCenter().postNotificationName(NotificationCenter.needDeleteDialog, -chatLocal.id, null, chatLocal, param);
@ -433,7 +441,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
if (selectedTopics.size() > 0) { if (selectedTopics.size() > 0) {
scrollToTop = true; scrollToTop = true;
updateAnimated = true; updateAnimated = true;
topicsController.pinTopic(chatId, selectedTopics.iterator().next(), id == pin_id); topicsController.pinTopic(chatId, selectedTopics.iterator().next(), id == pin_id, TopicsFragment.this);
} }
clearSelectedTopics(); clearSelectedTopics();
break; break;
@ -473,12 +481,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
actionBar.setOnClickListener(v -> { actionBar.setOnClickListener(v -> {
Bundle args = new Bundle(); openProfile(false);
args.putLong("chat_id", chatId);
ProfileActivity fragment = new ProfileActivity(args, avatarContainer.getSharedMediaPreloader());
// fragment.setChatInfo(parentFragment.getCurrentChatInfo());
// fragment.setPlayProfileAnimation(byAvatar ? 2 : 1);
presentFragment(fragment);
}); });
ActionBarMenu menu = actionBar.createMenu(); ActionBarMenu menu = actionBar.createMenu();
@ -522,14 +525,71 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
avatarContainer.setOccupyStatusBar(!AndroidUtilities.isTablet()); avatarContainer.setOccupyStatusBar(!AndroidUtilities.isTablet());
actionBar.addView(avatarContainer, 0, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, !inPreviewMode ? 56 : 0, 0, 86, 0)); actionBar.addView(avatarContainer, 0, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, !inPreviewMode ? 56 : 0, 0, 86, 0));
avatarContainer.getAvatarImageView().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openProfile(true);
}
});
recyclerListView = new RecyclerListView(context) { recyclerListView = new RecyclerListView(context) {
@Override @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) { protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b); super.onLayout(changed, l, t, r, b);
checkForLoadMore(); checkForLoadMore();
} }
@Override
protected boolean emptyViewIsVisible() {
return super.emptyViewIsVisible();
}
};
DefaultItemAnimator defaultItemAnimator = new DefaultItemAnimator() {
Runnable finishRunnable;
int scrollAnimationIndex;
@Override
public void checkIsRunning() {
if (scrollAnimationIndex == -1) {
scrollAnimationIndex = getNotificationCenter().setAnimationInProgress(scrollAnimationIndex, null, false);
if (finishRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(finishRunnable);
finishRunnable = null;
}
}
}
@Override
protected void onAllAnimationsDone() {
super.onAllAnimationsDone();
if (finishRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(finishRunnable);
finishRunnable = null;
}
AndroidUtilities.runOnUIThread(finishRunnable = () -> {
finishRunnable = null;
if (scrollAnimationIndex != -1) {
getNotificationCenter().onAnimationFinish(scrollAnimationIndex);
scrollAnimationIndex = -1;
}
});
}
@Override
public void endAnimations() {
super.endAnimations();
if (finishRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(finishRunnable);
}
AndroidUtilities.runOnUIThread(finishRunnable = () -> {
finishRunnable = null;
if (scrollAnimationIndex != -1) {
getNotificationCenter().onAnimationFinish(scrollAnimationIndex);
scrollAnimationIndex = -1;
}
});
}
}; };
DefaultItemAnimator defaultItemAnimator = new DefaultItemAnimator();
defaultItemAnimator.setSupportsChangeAnimations(false); defaultItemAnimator.setSupportsChangeAnimations(false);
defaultItemAnimator.setDelayAnimations(false); defaultItemAnimator.setDelayAnimations(false);
recyclerListView.setItemAnimator(itemAnimator = defaultItemAnimator); recyclerListView.setItemAnimator(itemAnimator = defaultItemAnimator);
@ -541,7 +601,8 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
} }
}); });
recyclerListView.setAnimateEmptyView(true, RecyclerListView.EMPTY_VIEW_ANIMATION_TYPE_ALPHA); recyclerListView.setAnimateEmptyView(true, RecyclerListView.EMPTY_VIEW_ANIMATION_TYPE_ALPHA);
recyclerListView.setItemsEnterAnimator(itemsEnterAnimator = new RecyclerItemsEnterAnimator(recyclerListView, true)); itemsEnterAnimator = new RecyclerItemsEnterAnimator(recyclerListView, true);
recyclerListView.setItemsEnterAnimator(itemsEnterAnimator);
recyclerListView.setOnItemClickListener((view, position) -> { recyclerListView.setOnItemClickListener((view, position) -> {
TLRPC.TL_forumTopic topic = null; TLRPC.TL_forumTopic topic = null;
if (view instanceof TopicDialogCell) { if (view instanceof TopicDialogCell) {
@ -619,6 +680,8 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
} }
} }
}); });
itemTouchHelper = new ItemTouchHelper(new TouchHelperCallback());
itemTouchHelper.attachToRecyclerView(recyclerListView);
contentView.addView(recyclerListView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); contentView.addView(recyclerListView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
((ViewGroup.MarginLayoutParams) recyclerListView.getLayoutParams()).topMargin = -AndroidUtilities.dp(100); ((ViewGroup.MarginLayoutParams) recyclerListView.getLayoutParams()).topMargin = -AndroidUtilities.dp(100);
@ -800,6 +863,15 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
return fragmentView; return fragmentView;
} }
private void openProfile(boolean byAvatar) {
Bundle args = new Bundle();
args.putLong("chat_id", chatId);
ProfileActivity fragment = new ProfileActivity(args, avatarContainer.getSharedMediaPreloader());
fragment.setChatInfo(chatFull);
fragment.setPlayProfileAnimation(fragmentView.getMeasuredHeight() > fragmentView.getMeasuredWidth() && byAvatar ? 2 : 1);
presentFragment(fragment);
}
public void switchToChat(boolean removeFragment) { public void switchToChat(boolean removeFragment) {
removeFragmentOnTransitionEnd = removeFragment; removeFragmentOnTransitionEnd = removeFragment;
@ -949,7 +1021,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
pinItem.setOnClickListener(e -> { pinItem.setOnClickListener(e -> {
scrollToTop = true; scrollToTop = true;
updateAnimated = true; updateAnimated = true;
topicsController.pinTopic(chatId, topic.id, !topic.pinned); topicsController.pinTopic(chatId, topic.id, !topic.pinned, TopicsFragment.this);
finishPreviewFragment(); finishPreviewFragment();
}); });
@ -1022,6 +1094,9 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
if (topicsEmptyView != null && forumTopics.size() == 0) { if (topicsEmptyView != null && forumTopics.size() == 0) {
topicsEmptyView.showProgress(loadingTopics, fragmentBeginToShow); topicsEmptyView.showProgress(loadingTopics, fragmentBeginToShow);
} }
if (recyclerListView != null) {
recyclerListView.checkIfEmpty();
}
updateCreateTopicButton(true); updateCreateTopicButton(true);
} }
@ -1126,6 +1201,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
selectedTopics.clear(); selectedTopics.clear();
actionBar.hideActionMode(); actionBar.hideActionMode();
AndroidUtilities.updateVisibleRows(recyclerListView); AndroidUtilities.updateVisibleRows(recyclerListView);
updateReordering();
} }
private void toggleSelection(View view) { private void toggleSelection(View view) {
@ -1155,7 +1231,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
} else { } else {
readCount++; readCount++;
} }
if (ChatObject.canManageTopic(currentAccount, currentChat, topic)) { if (ChatObject.canManageTopics(currentChat)) {
if (topic.pinned) { if (topic.pinned) {
canUnpinCount++; canUnpinCount++;
} else { } else {
@ -1221,9 +1297,32 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
deleteItem.setVisibility(canDeleteCount == selectedTopics.size() ? View.VISIBLE : View.GONE); deleteItem.setVisibility(canDeleteCount == selectedTopics.size() ? View.VISIBLE : View.GONE);
otherItem.checkHideMenuItem(); otherItem.checkHideMenuItem();
updateReordering();
} }
} }
public void updateReordering() {
boolean canReorderPins = ChatObject.canManageTopics(getCurrentChat());
boolean newReordering = canReorderPins && !selectedTopics.isEmpty();
if (reordering != newReordering) {
reordering = newReordering;
adapter.notifyItemRangeChanged(0, adapter.getItemCount());
}
}
public void sendReorder() {
ArrayList<Integer> newOrder = new ArrayList<>();
for (int i = 0; i < forumTopics.size(); ++i) {
TLRPC.TL_forumTopic topic = forumTopics.get(i).topic;
if (topic != null && topic.pinned) {
newOrder.add(topic.id);
}
}
getMessagesController().getTopicsController().reorderPinnedTopics(chatId, newOrder);
ignoreDiffUtil = true;
}
private void chekActionMode() { private void chekActionMode() {
if (actionBar.actionModeIsExist(null)) { if (actionBar.actionModeIsExist(null)) {
return; return;
@ -1248,6 +1347,62 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
restartTopic = otherItem.addSubItem(restart_topic_id, R.drawable.msg_topic_restart, LocaleController.getString("RestartTopic", R.string.RestartTopic)); restartTopic = otherItem.addSubItem(restart_topic_id, R.drawable.msg_topic_restart, LocaleController.getString("RestartTopic", R.string.RestartTopic));
} }
public class TouchHelperCallback extends ItemTouchHelper.Callback {
@Override
public boolean isLongPressDragEnabled() {
return !selectedTopics.isEmpty();
}
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
int position = viewHolder.getAdapterPosition();
if (position < 0 || position >= forumTopics.size() || forumTopics.get(position).topic == null || !forumTopics.get(position).topic.pinned) {
return makeMovementFlags(0, 0);
}
return makeMovementFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN, 0);
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
if (source.getItemViewType() != target.getItemViewType()) {
return false;
}
int position = target.getAdapterPosition();
if (position < 0 || position >= forumTopics.size() || forumTopics.get(position).topic == null || !forumTopics.get(position).topic.pinned) {
return false;
}
adapter.swapElements(source.getAdapterPosition(), target.getAdapterPosition());
return true;
}
@Override
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (actionState == ItemTouchHelper.ACTION_STATE_IDLE) {
sendReorder();
} else {
recyclerListView.cancelClickRunnables(false);
viewHolder.itemView.setPressed(true);
}
super.onSelectedChanged(viewHolder, actionState);
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
}
@Override
public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
viewHolder.itemView.setPressed(false);
}
}
private void updateChatInfo() { private void updateChatInfo() {
updateChatInfo(false); updateChatInfo(false);
} }
@ -1262,6 +1417,11 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
if (!opnendForSelect) { if (!opnendForSelect) {
if (chatLocal != null) { if (chatLocal != null) {
avatarContainer.setTitle(chatLocal.title); avatarContainer.setTitle(chatLocal.title);
Drawable rightIcon = null;
if (getMessagesController().isDialogMuted(-chatId, 0)) {
rightIcon = getThemedDrawable(Theme.key_drawable_muteIconDrawable);
}
avatarContainer.setTitleIcons(null, rightIcon);
} }
updateSubtitle(); updateSubtitle();
} else { } else {
@ -1369,6 +1529,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.groupCallUpdated); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.groupCallUpdated);
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.notificationsSettingsUpdated); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.notificationsSettingsUpdated);
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.chatSwithcedToForum); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.chatSwithcedToForum);
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.closeChats);
updateTopicsList(false, false); updateTopicsList(false, false);
SelectAnimatedEmojiDialog.preload(currentAccount); SelectAnimatedEmojiDialog.preload(currentAccount);
@ -1406,6 +1567,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.groupCallUpdated); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.groupCallUpdated);
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.notificationsSettingsUpdated); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.notificationsSettingsUpdated);
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.chatSwithcedToForum); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.chatSwithcedToForum);
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.closeChats);
TLRPC.Chat chatLocal = getMessagesController().getChat(chatId); TLRPC.Chat chatLocal = getMessagesController().getChat(chatId);
if (ChatObject.isChannel(chatLocal)) { if (ChatObject.isChannel(chatLocal)) {
@ -1416,43 +1578,40 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
private void updateTopicsList(boolean animated, boolean enalbeEnterAnimation) { private void updateTopicsList(boolean animated, boolean enalbeEnterAnimation) {
if (!animated && (updateAnimated || itemAnimator != null && (System.currentTimeMillis() - lastAnimatedDuration) < itemAnimator.getMoveDuration())) { if (!animated && updateAnimated) {
animated = true; animated = true;
} }
if (animated) {
lastAnimatedDuration = System.currentTimeMillis();
}
updateAnimated = false; updateAnimated = false;
ArrayList<TLRPC.TL_forumTopic> topics = topicsController.getTopics(chatId); ArrayList<TLRPC.TL_forumTopic> topics = topicsController.getTopics(chatId);
if (topics != null) { if (topics != null) {
int oldCount = forumTopics.size(); int oldCount = forumTopics.size();
ArrayList<Item> oldItems = new ArrayList<>(forumTopics);
forumTopics.clear(); forumTopics.clear();
for (int i = 0; i < topics.size(); i++) { for (int i = 0; i < topics.size(); i++) {
if (excludeTopics != null && excludeTopics.contains(topics.get(i).id)) { if (excludeTopics != null && excludeTopics.contains(topics.get(i).id)) {
continue; continue;
} }
forumTopics.add(topics.get(i)); forumTopics.add(new Item(VIEW_TYPE_TOPIC, topics.get(i)));
} }
if (forumTopics.size() == 1 && forumTopics.get(0).id == 1) { if (forumTopics.size() == 1 && forumTopics.get(0).topic.id == 1) {
forumTopics.clear(); forumTopics.clear();
} else if (!forumTopics.isEmpty() && !topicsController.endIsReached(chatId)) {
forumTopics.add(new Item(VIEW_TYPE_LOADING_CELL, null));
} }
for (int i = forumTopics.size() - 1; i >= 0; --i) { int newCount = forumTopics.size();
if (forumTopics.get(i).pinned) { if (fragmentBeginToShow && enalbeEnterAnimation && newCount > oldCount) {
forumTopics.add(0, forumTopics.remove(i)); itemsEnterAnimator.showItemsAnimated(oldCount + 4);
} animated = false;
} }
if (recyclerListView != null && recyclerListView.getItemAnimator() != (animated ? itemAnimator : null)) { if (recyclerListView != null && recyclerListView.getItemAnimator() != (animated ? itemAnimator : null)) {
recyclerListView.setItemAnimator(animated ? itemAnimator : null); recyclerListView.setItemAnimator(animated ? itemAnimator : null);
} }
if (adapter != null) { if (adapter != null) {
adapter.notifyDataSetChanged(true); adapter.setItems(oldItems, forumTopics);
}
int newCount = forumTopics.size();
if (fragmentBeginToShow && enalbeEnterAnimation && newCount > oldCount) {
itemsEnterAnimator.showItemsAnimated(oldCount + 1);
} }
if (scrollToTop && layoutManager != null) { if (scrollToTop && layoutManager != null) {
@ -1484,6 +1643,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
if (args.length > 1 && (Boolean) args[1]) { if (args.length > 1 && (Boolean) args[1]) {
checkForLoadMore(); checkForLoadMore();
} }
checkLoading();
} }
} else if (id == NotificationCenter.updateInterfaces) { } else if (id == NotificationCenter.updateInterfaces) {
int mask = (Integer) args[0]; int mask = (Integer) args[0];
@ -1491,7 +1651,12 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
updateChatInfo(); updateChatInfo();
} }
if ((mask & MessagesController.UPDATE_MASK_SELECT_DIALOG) > 0) { if ((mask & MessagesController.UPDATE_MASK_SELECT_DIALOG) > 0) {
updateTopicsList(false, false); getMessagesController().getTopicsController().sortTopics(chatId, false);
boolean wasOnTop = !recyclerListView.canScrollVertically(-1);
updateTopicsList(true, false);
if (wasOnTop) {
layoutManager.scrollToPosition(0);
}
} }
} else if (id == NotificationCenter.dialogsNeedReload) { } else if (id == NotificationCenter.dialogsNeedReload) {
updateTopicsList(false, false); updateTopicsList(false, false);
@ -1500,13 +1665,16 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
if (this.chatId == chatId) { if (this.chatId == chatId) {
groupCall = getMessagesController().getGroupCall(chatId, false); groupCall = getMessagesController().getGroupCall(chatId, false);
if (fragmentContextView != null) { if (fragmentContextView != null) {
fragmentContextView.checkCall(true); fragmentContextView.checkCall(!fragmentBeginToShow);
} }
} }
} else if (id == NotificationCenter.notificationsSettingsUpdated) { } else if (id == NotificationCenter.notificationsSettingsUpdated) {
updateTopicsList(false, false); updateTopicsList(false, false);
updateChatInfo(true);
} else if (id == NotificationCenter.chatSwithcedToForum) { } else if (id == NotificationCenter.chatSwithcedToForum) {
} else if (id == NotificationCenter.closeChats) {
removeSelfFromStack();
} }
} }
@ -1544,40 +1712,57 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
this.dialogsActivity = dialogsActivity; this.dialogsActivity = dialogsActivity;
} }
private class Adapter extends RecyclerListView.SelectionAdapter { private class Adapter extends AdapterWithDiffUtils {
@Override
public int getItemViewType(int position) {
return forumTopics.get(position).viewType;
}
@NonNull @NonNull
@Override @Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
TopicDialogCell dialogCell = new TopicDialogCell(null, parent.getContext(), true, false); if (viewType == VIEW_TYPE_TOPIC) {
return new RecyclerListView.Holder(dialogCell); TopicDialogCell dialogCell = new TopicDialogCell(null, parent.getContext(), true, false);
return new RecyclerListView.Holder(dialogCell);
} else {
FlickerLoadingView flickerLoadingView = new FlickerLoadingView(parent.getContext());
flickerLoadingView.setViewType(FlickerLoadingView.TOPIC_CELL_TYPE);
flickerLoadingView.setIsSingleCell(true);
flickerLoadingView.showDate(true);
return new RecyclerListView.Holder(flickerLoadingView);
}
} }
@Override @Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
TLRPC.TL_forumTopic topic = forumTopics.get(position); if (holder.getItemViewType() == VIEW_TYPE_TOPIC) {
TLRPC.TL_forumTopic nextTopic = null; TLRPC.TL_forumTopic topic = forumTopics.get(position).topic;
if (position + 1 < forumTopics.size()) { TLRPC.TL_forumTopic nextTopic = null;
nextTopic = forumTopics.get(position + 1); if (position + 1 < forumTopics.size()) {
nextTopic = forumTopics.get(position + 1).topic;
}
TopicDialogCell dialogCell = (TopicDialogCell) holder.itemView;
TLRPC.Message tlMessage = topic.topMessage;
int oldId = dialogCell.forumTopic == null ? 0 : dialogCell.forumTopic.id;
int newId = topic.id;
boolean animated = oldId == newId && dialogCell.position == position && animatedUpdateEnabled;
if (tlMessage != null) {
MessageObject messageObject = new MessageObject(currentAccount, tlMessage, false, false);
dialogCell.setForumTopic(topic, -chatId, messageObject, animated);
dialogCell.drawDivider = position != forumTopics.size() - 1;
dialogCell.fullSeparator = topic.pinned && (nextTopic == null || !nextTopic.pinned);
dialogCell.setPinForced(topic.pinned);
dialogCell.position = position;
}
dialogCell.setTopicIcon(topic);
dialogCell.setChecked(selectedTopics.contains(newId), animated);
dialogCell.onReorderStateChanged(reordering, true);
} }
TopicDialogCell dialogCell = (TopicDialogCell) holder.itemView;
TLRPC.Message tlMessage = topic.topMessage;
int oldId = dialogCell.forumTopic == null ? 0 : dialogCell.forumTopic.id;
int newId = topic.id;
boolean animated = oldId == newId && dialogCell.position == position && animatedUpdateEnabled;
if (tlMessage != null) {
MessageObject messageObject = new MessageObject(currentAccount, tlMessage, false, false);
dialogCell.setForumTopic(topic, -chatId, messageObject, animated);
dialogCell.drawDivider = position != forumTopics.size() - 1;
dialogCell.fullSeparator = topic.pinned && (nextTopic == null || !nextTopic.pinned);
dialogCell.setPinForced(topic.pinned);
dialogCell.position = position;
}
dialogCell.setTopicIcon(topic);
dialogCell.setChecked(selectedTopics.contains(newId), animated);
} }
@Override @Override
@ -1587,52 +1772,15 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
@Override @Override
public boolean isEnabled(RecyclerView.ViewHolder holder) { public boolean isEnabled(RecyclerView.ViewHolder holder) {
return true; return holder.getItemViewType() == VIEW_TYPE_TOPIC;
} }
private ArrayList<Integer> hashes = new ArrayList<>(); public void swapElements(int from, int to) {
forumTopics.add(to, forumTopics.remove(from));
@Override if (recyclerListView.getItemAnimator() != itemAnimator) {
public void notifyDataSetChanged() { recyclerListView.setItemAnimator(itemAnimator);
hashes.clear();
for (int i = 0; i < forumTopics.size(); ++i) {
hashes.add(forumTopics.get(i).id);
}
super.notifyDataSetChanged();
}
public void notifyDataSetChanged(boolean diff) {
final ArrayList<Integer> oldHashes = new ArrayList<>(hashes);
hashes.clear();
for (int i = 0; i < forumTopics.size(); ++i) {
hashes.add(forumTopics.get(i).id);
}
if (diff) {
DiffUtil.calculateDiff(new DiffUtil.Callback() {
@Override
public int getOldListSize() {
return oldHashes.size();
}
@Override
public int getNewListSize() {
return hashes.size();
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return Objects.equals(hashes.get(newItemPosition), oldHashes.get(oldItemPosition));
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return false;
}
}).dispatchUpdatesTo(this);
} else {
super.notifyDataSetChanged();
} }
notifyItemMoved(from, to);
} }
} }
@ -1648,8 +1796,10 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
chekBoxPaddingTop = 24; chekBoxPaddingTop = 24;
heightDefault = 64; heightDefault = 64;
heightThreeLines = 76; heightThreeLines = 76;
forbidVerified = true;
} }
private TLRPC.TL_forumTopic currentTopic;
private AnimatedEmojiDrawable animatedEmojiDrawable; private AnimatedEmojiDrawable animatedEmojiDrawable;
private Drawable forumIcon; private Drawable forumIcon;
boolean attached; boolean attached;
@ -1730,6 +1880,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
} }
public void setTopicIcon(TLRPC.TL_forumTopic topic) { public void setTopicIcon(TLRPC.TL_forumTopic topic) {
currentTopic = topic;
closed = topic != null && topic.closed; closed = topic != null && topic.closed;
if (topic != null && topic.icon_emoji_id != 0) { if (topic != null && topic.icon_emoji_id != 0) {
setForumIcon(null); setForumIcon(null);
@ -1959,9 +2110,9 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
String searchTrimmed = searchString.trim().toLowerCase(); String searchTrimmed = searchString.trim().toLowerCase();
ArrayList<TLRPC.TL_forumTopic> topics = new ArrayList<>(); ArrayList<TLRPC.TL_forumTopic> topics = new ArrayList<>();
for (int i = 0; i < forumTopics.size(); i++) { for (int i = 0; i < forumTopics.size(); i++) {
if (forumTopics.get(i).title.toLowerCase().contains(searchTrimmed)) { if (forumTopics.get(i).topic != null && forumTopics.get(i).topic.title.toLowerCase().contains(searchTrimmed)) {
topics.add(forumTopics.get(i)); topics.add(forumTopics.get(i).topic);
forumTopics.get(i).searchQuery = searchTrimmed; forumTopics.get(i).topic.searchQuery = searchTrimmed;
} }
} }
@ -2345,4 +2496,36 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
} }
} }
} }
private class Item extends AdapterWithDiffUtils.Item {
TLRPC.TL_forumTopic topic;
public Item(int viewType, TLRPC.TL_forumTopic topic) {
super(viewType, true);
this.topic = topic;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Item item = (Item) o;
if (viewType == item.viewType && viewType == VIEW_TYPE_TOPIC) {
return topic.id == item.topic.id;
}
return false;
}
}
@Override
public ChatAvatarContainer getAvatarContainer() {
return avatarContainer;
}
@Override
public SizeNotifierFrameLayout getContentView() {
return contentView;
}
} }

View file

@ -10,7 +10,6 @@ import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DefaultItemAnimator; import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -26,6 +25,7 @@ import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.ShadowSectionCell; import org.telegram.ui.Cells.ShadowSectionCell;
import org.telegram.ui.Cells.TextCell; import org.telegram.ui.Cells.TextCell;
import org.telegram.ui.Cells.TopicExceptionCell; import org.telegram.ui.Cells.TopicExceptionCell;
import org.telegram.ui.Components.ListView.AdapterWithDiffUtils;
import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.RecyclerListView;
import java.util.ArrayList; import java.util.ArrayList;
@ -100,7 +100,7 @@ public class TopicsNotifySettingsFragments extends BaseFragment {
} }
if (items.get(position).viewType == VIEW_TYPE_TOPIC) { if (items.get(position).viewType == VIEW_TYPE_TOPIC) {
TLRPC.TL_forumTopic topic = (TLRPC.TL_forumTopic) items.get(position).object; TLRPC.TL_forumTopic topic = (TLRPC.TL_forumTopic) items.get(position).topic;
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putLong("dialog_id", dialogId); bundle.putLong("dialog_id", dialogId);
bundle.putInt("topic_id", topic.id); bundle.putInt("topic_id", topic.id);
@ -199,32 +199,7 @@ public class TopicsNotifySettingsFragments extends BaseFragment {
items.add(new Item(VIEW_TYPE_DIVIDER, null)); items.add(new Item(VIEW_TYPE_DIVIDER, null));
if (adapter != null) { if (adapter != null) {
if (!animated) { adapter.setItems(oldItems, items);
adapter.notifyDataSetChanged();
} else {
ArrayList<Item> finalOldItems = oldItems;
DiffUtil.calculateDiff(new DiffUtil.Callback() {
@Override
public int getOldListSize() {
return finalOldItems.size();
}
@Override
public int getNewListSize() {
return items.size();
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return items.get(newItemPosition).compare(finalOldItems.get(oldItemPosition));
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return false;
}
}).dispatchUpdatesTo(adapter);
}
} }
} }
@ -232,7 +207,7 @@ public class TopicsNotifySettingsFragments extends BaseFragment {
exceptionsTopics = notificationsExceptionTopics; exceptionsTopics = notificationsExceptionTopics;
} }
private class Adapter extends RecyclerListView.SelectionAdapter { private class Adapter extends AdapterWithDiffUtils {
@NonNull @NonNull
@Override @Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
@ -268,8 +243,8 @@ public class TopicsNotifySettingsFragments extends BaseFragment {
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (items.get(position).viewType == VIEW_TYPE_TOPIC) { if (items.get(position).viewType == VIEW_TYPE_TOPIC) {
TopicExceptionCell cell = (TopicExceptionCell) holder.itemView; TopicExceptionCell cell = (TopicExceptionCell) holder.itemView;
cell.setTopic(dialogId, (TLRPC.TL_forumTopic) items.get(position).object); cell.setTopic(dialogId, items.get(position).topic);
cell.drawDivider = !(position != items.size() - 1 && items.get(position +1).viewType != VIEW_TYPE_TOPIC); cell.drawDivider = !(position != items.size() - 1 && items.get(position + 1).viewType != VIEW_TYPE_TOPIC);
} }
} }
@ -289,23 +264,26 @@ public class TopicsNotifySettingsFragments extends BaseFragment {
} }
} }
private class Item { private class Item extends AdapterWithDiffUtils.Item {
final int viewType; final TLRPC.TL_forumTopic topic;
final TLRPC.TL_forumTopic object;
private Item(int viewType, TLRPC.TL_forumTopic object) { private Item(int viewType, TLRPC.TL_forumTopic object) {
this.viewType = viewType; super(viewType, false);
this.object = object; this.topic = object;
} }
boolean compare(Item item) { @Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Item item = (Item) o;
if (viewType != item.viewType) { if (viewType != item.viewType) {
return false; return false;
} }
if (object != null && item.object != null && object.id == item.object.id) { if (topic != null && item.topic != null) {
return true; return topic.id == item.topic.id;
} }
return false; return true;
} }
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 786 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -1662,8 +1662,10 @@
<string name="UsernamePlaceholder">Your Username</string> <string name="UsernamePlaceholder">Your Username</string>
<string name="UsernameLinkPlaceholder">username</string> <string name="UsernameLinkPlaceholder">username</string>
<string name="UsernameInUse">Sorry, this username is already taken.</string> <string name="UsernameInUse">Sorry, this username is already taken.</string>
<string name="UsernameInUsePurchase">This link is already taken.\nHowever, it is currently available for purchase. **Learn more…**</string>
<string name="UsernameInvalid">Sorry, this username is invalid.</string> <string name="UsernameInvalid">Sorry, this username is invalid.</string>
<string name="UsernameInvalidShort">A username must have at least 5 characters.</string> <string name="UsernameInvalidShort">A username must have at least 5 characters.</string>
<string name="UsernameInvalidShortPurchase">A username must have at least 5 characters.\nHowever, it is currently available for purchase. **Learn more…**</string>
<string name="UsernameInvalidLong">The username must not exceed 32 characters.</string> <string name="UsernameInvalidLong">The username must not exceed 32 characters.</string>
<string name="UsernameInvalidStartNumber">Sorry, a username can\'t start with a number.</string> <string name="UsernameInvalidStartNumber">Sorry, a username can\'t start with a number.</string>
<string name="UsernameHelp">You can choose a username on **Telegram**. If you do, other people will be able to find you by this username and contact you without knowing your phone number.\n\nYou can use **az**, **09** and underscores. Minimum length is **5** characters.</string> <string name="UsernameHelp">You can choose a username on **Telegram**. If you do, other people will be able to find you by this username and contact you without knowing your phone number.\n\nYou can use **az**, **09** and underscores. Minimum length is **5** characters.</string>
@ -3454,6 +3456,7 @@
<string name="TooManyCommunitiesHintEdit">Sorry, you are a member of too many groups and channels. For technical reasons, you need to leave some first before changing this setting in your groups.</string> <string name="TooManyCommunitiesHintEdit">Sorry, you are a member of too many groups and channels. For technical reasons, you need to leave some first before changing this setting in your groups.</string>
<string name="UserChannelTooMuchJoin">Sorry, the target user is a member of too many groups and channels. Please ask them to leave some first.</string> <string name="UserChannelTooMuchJoin">Sorry, the target user is a member of too many groups and channels. Please ask them to leave some first.</string>
<!--Alert messages--> <!--Alert messages-->
<string name="LimitReachedPinnedTopics">Sorry, you can\'t pin more than %d topics to the top.</string>
<string name="DeleteAllMessagesAlert">Warning! This will **delete all messages** in this chat for **both** participants.</string> <string name="DeleteAllMessagesAlert">Warning! This will **delete all messages** in this chat for **both** participants.</string>
<string name="DeleteAllMessagesChannelAlert">Warning! This will **delete all messages** in this channel.</string> <string name="DeleteAllMessagesChannelAlert">Warning! This will **delete all messages** in this channel.</string>
<string name="DeleteAllMessagesSavedAlert">Warning! This will **delete all messages** in this chat.</string> <string name="DeleteAllMessagesSavedAlert">Warning! This will **delete all messages** in this chat.</string>
@ -5696,6 +5699,7 @@
<string name="RestartTopic">Reopen topic</string> <string name="RestartTopic">Reopen topic</string>
<string name="CloseTopics">Close topics</string> <string name="CloseTopics">Close topics</string>
<string name="RestartTopics">Reopen topics</string> <string name="RestartTopics">Reopen topics</string>
<string name="OpenAllTopics">All Topics</string>
<string name="TopicViewAsTopics">View as topics</string> <string name="TopicViewAsTopics">View as topics</string>
<string name="DeleteSelectedTopics">Are you sure you want delete these topics?</string> <string name="DeleteSelectedTopics">Are you sure you want delete these topics?</string>
<string name="DeleteSelectedTopic">Are you sure you want delete %s?</string> <string name="DeleteSelectedTopic">Are you sure you want delete %s?</string>
@ -5776,4 +5780,5 @@
<string name="ChannelCaptionLimitPremiumPromo_few">Make the caption shorter or subscribe to *Telegram Premium* to double the limit to **%1$s** characters.</string> <string name="ChannelCaptionLimitPremiumPromo_few">Make the caption shorter or subscribe to *Telegram Premium* to double the limit to **%1$s** characters.</string>
<string name="ChannelCaptionLimitPremiumPromo_many">Make the caption shorter or subscribe to *Telegram Premium* to double the limit to **%1$s** characters.</string> <string name="ChannelCaptionLimitPremiumPromo_many">Make the caption shorter or subscribe to *Telegram Premium* to double the limit to **%1$s** characters.</string>
<string name="ChannelCaptionLimitPremiumPromo_other">Make the caption shorter or subscribe to *Telegram Premium* to double the limit to **%1$s** characters.</string> <string name="ChannelCaptionLimitPremiumPromo_other">Make the caption shorter or subscribe to *Telegram Premium* to double the limit to **%1$s** characters.</string>
<string name="AllChats">All Chats</string>
</resources> </resources>

View file

@ -13,8 +13,8 @@
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true # org.gradle.parallel=true
#Sat Mar 12 05:53:50 MSK 2016 #Sat Mar 12 05:53:50 MSK 2016
APP_VERSION_NAME=9.1.2 APP_VERSION_NAME=9.1.3
APP_VERSION_CODE=2902 APP_VERSION_CODE=2917
APP_PACKAGE=org.telegram.messenger APP_PACKAGE=org.telegram.messenger
RELEASE_KEY_PASSWORD=TelegramAndroidPswd RELEASE_KEY_PASSWORD=TelegramAndroidPswd
RELEASE_KEY_ALIAS=tmessages RELEASE_KEY_ALIAS=tmessages