Update to 8.2.1 (2462)

This commit is contained in:
xaxtix 2021-11-05 13:06:49 +03:00
parent 09f95ec069
commit 1d379b9a7b
141 changed files with 11475 additions and 5394 deletions

View File

@ -26,11 +26,11 @@ dependencies {
compileOnly 'org.checkerframework:checker-compat-qual:2.5.0'
implementation 'com.google.firebase:firebase-messaging:22.0.0'
implementation 'com.google.firebase:firebase-config:21.0.1'
implementation 'com.google.firebase:firebase-datatransport:18.0.1'
implementation 'com.google.firebase:firebase-datatransport:18.1.0'
implementation 'com.google.firebase:firebase-appindexing:20.0.0'
implementation 'com.google.android.gms:play-services-maps:17.0.1'
implementation 'com.google.android.gms:play-services-auth:19.2.0'
implementation 'com.google.android.gms:play-services-vision:16.2.0'
implementation 'com.google.android.gms:play-services-vision:20.1.3'
implementation 'com.google.android.gms:play-services-wearable:17.1.0'
implementation 'com.google.android.gms:play-services-location:18.0.0'
implementation 'com.google.android.gms:play-services-wallet:18.1.3'
@ -299,7 +299,7 @@ android {
}
}
defaultConfig.versionCode = 2432
defaultConfig.versionCode = 2462
applicationVariants.all { variant ->
variant.outputs.all { output ->
@ -317,8 +317,8 @@ android {
defaultConfig {
minSdkVersion 16
targetSdkVersion 29
versionName "8.1.2"
targetSdkVersion 30
versionName "8.2.1"
vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi']

View File

@ -37,7 +37,7 @@ import java.util.List;
*/
public class ChildHelper {
private static final boolean DEBUG = BuildVars.DEBUG_VERSION;
private static final boolean DEBUG = false;//BuildVars.DEBUG_VERSION;
private static final String TAG = "ChildrenHelper";

View File

@ -46,7 +46,7 @@ public class LinearLayoutManager extends RecyclerView.LayoutManager implements
private static final String TAG = "LinearLayoutManager";
static final boolean DEBUG = BuildVars.DEBUG_VERSION;
static final boolean DEBUG = false;
public static final int HORIZONTAL = RecyclerView.HORIZONTAL;

View File

@ -89,6 +89,10 @@ public class AccountInstance {
return MessagesController.getNotificationsSettings(currentAccount);
}
public MemberRequestsController getMemberRequestsController() {
return MemberRequestsController.getInstance(currentAccount);
}
public int getCurrentAccount() {
return currentAccount;
}

View File

@ -529,10 +529,12 @@ public class AndroidUtilities {
if (context == null || AndroidUtilities.statusBarHeight > 0) {
return;
}
AndroidUtilities.statusBarHeight = getStatusBarHeight(context);
}
public static int getStatusBarHeight(Context context) {
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
AndroidUtilities.statusBarHeight = context.getResources().getDimensionPixelSize(resourceId);
}
return resourceId > 0 ? context.getResources().getDimensionPixelSize(resourceId) : 0;
}
public static int getThumbForNameOrMime(String name, String mime, boolean media) {
@ -2282,8 +2284,8 @@ public class AndroidUtilities {
}
}
private static File getAlbumDir(boolean secretChat) { //TODO scoped storage
if (secretChat || Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
private static File getAlbumDir(boolean secretChat) {
if (secretChat || !BuildVars.NO_SCOPED_STORAGE || (Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
return FileLoader.getDirectory(FileLoader.MEDIA_DIR_CACHE);
}
File storageDir = null;

View File

@ -75,4 +75,8 @@ public class BaseController {
protected final FileRefController getFileRefController() {
return parentAccountInstance.getFileRefController();
}
protected final MemberRequestsController getMemberRequestsController() {
return parentAccountInstance.getMemberRequestsController();
}
}

View File

@ -10,17 +10,18 @@ package org.telegram.messenger;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
public class BuildVars {
public static boolean DEBUG_VERSION = false;
public static boolean DEBUG_PRIVATE_VERSION = false;
public static boolean LOGS_ENABLED = false;
public static boolean DEBUG_PRIVATE_VERSION = false;
public static boolean USE_CLOUD_STRINGS = true;
public static boolean CHECK_UPDATES = true;
public static boolean NO_SCOPED_STORAGE = true/* || Build.VERSION.SDK_INT <= 28*/;
public static int BUILD_VERSION = 2432;
public static String BUILD_VERSION_STRING = "8.1.2";
public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29;
public static int BUILD_VERSION = 2462;
public static String BUILD_VERSION_STRING = "8.2.1";
public static int APP_ID = 4;
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";
public static String SMS_HASH = isStandaloneApp() ? "w0lkcmTZkKh" : (DEBUG_VERSION ? "O2P2z+/jBpJ" : "oLeq9AcOZkT");

View File

@ -1490,6 +1490,10 @@ public class ChatObject {
return (chat instanceof TLRPC.TL_channel || chat instanceof TLRPC.TL_channelForbidden) && chat.megagroup;
}
public static boolean isChannelAndNotMegaGroup(TLRPC.Chat chat) {
return isChannel(chat) && !isMegagroup(chat);
}
public static boolean isMegagroup(int currentAccount, long chatId) {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(chatId);
return ChatObject.isChannel(chat) && chat.megagroup;
@ -1569,6 +1573,11 @@ public class ChatObject {
return chat instanceof TLRPC.TL_channel || chat instanceof TLRPC.TL_channelForbidden;
}
public static boolean isChannelAndNotMegaGroup(long chatId, int currentAccount) {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(chatId);
return isChannelAndNotMegaGroup(chat);
}
public static boolean isCanWriteToChannel(long chatId, int currentAccount) {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(chatId);
return ChatObject.canSendMessages(chat) || chat.megagroup;

View File

@ -3,62 +3,63 @@ package org.telegram.messenger;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.TextUtils;
import android.util.LongSparseArray;
import com.google.android.exoplayer2.util.Log;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.RequestDelegate;
import org.telegram.tgnet.ResultCallback;
import org.telegram.tgnet.SerializedData;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ChatTheme;
import org.telegram.ui.ActionBar.EmojiThemes;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
public class ChatThemeController extends BaseController {
private static final long reloadTimeoutMs = 2 * 60 * 60 * 1000;
private static volatile DispatchQueue chatThemeQueue = new DispatchQueue("stageQueue");
public static volatile DispatchQueue chatThemeQueue = new DispatchQueue("chatThemeQueue");
private static final HashMap<Long, Bitmap> themeIdWallpaperMap = new HashMap<>();
//private static final HashMap<Long, Bitmap> themeIdWallpaperMap = new HashMap<>();
private static final HashMap<Long, Bitmap> themeIdWallpaperThumbMap = new HashMap<>();
private static List<ChatTheme> allChatThemes;
private static volatile int themesHash;
private static List<EmojiThemes> allChatThemes;
private static volatile long themesHash;
private static volatile long lastReloadTimeMs;
public static void init() {
SharedPreferences preferences = getSharedPreferences();
themesHash = 0;
lastReloadTimeMs = 0;
if (!BuildVars.DEBUG_VERSION) {
preferences.getInt("hash", 0);
try {
themesHash = preferences.getLong("hash", 0);
lastReloadTimeMs = preferences.getLong("lastReload", 0);
} catch (Exception e) {
FileLog.e(e);
}
allChatThemes = getAllChatThemesFromPrefs();
Emoji.preloadEmoji("");
preloadSticker("");
if (!allChatThemes.isEmpty()) {
for (ChatTheme chatTheme : allChatThemes) {
Emoji.preloadEmoji(chatTheme.getEmoticon());
for (EmojiThemes chatTheme : allChatThemes) {
preloadSticker(chatTheme.getEmoticon());
}
} else {
Emoji.preloadEmoji("\uD83E\uDD81");
Emoji.preloadEmoji("");
Emoji.preloadEmoji("\uD83D\uDC8E");
Emoji.preloadEmoji("\uD83D\uDC68\u200D\uD83C\uDFEB");
Emoji.preloadEmoji("\uD83C\uDF37");
Emoji.preloadEmoji("\uD83D\uDD2E");
Emoji.preloadEmoji("\uD83C\uDF84");
Emoji.preloadEmoji("\uD83C\uDFAE");
}
}
public static void requestAllChatThemes(final ResultCallback<List<ChatTheme>> callback, boolean withDefault) {
private static void preloadSticker(String emojicon) {
ImageReceiver imageReceiver = new ImageReceiver();
TLRPC.Document document = MediaDataController.getInstance(UserConfig.selectedAccount).getEmojiAnimatedSticker(emojicon);
imageReceiver.setImage(ImageLocation.getForDocument(document), "50_50", null, null, null, 0);
Emoji.preloadEmoji(emojicon);
}
public static void requestAllChatThemes(final ResultCallback<List<EmojiThemes>> callback, boolean withDefault) {
if (themesHash == 0 || lastReloadTimeMs == 0) {
init();
}
@ -69,30 +70,30 @@ public class ChatThemeController extends BaseController {
request.hash = themesHash;
ConnectionsManager.getInstance(UserConfig.selectedAccount).sendRequest(request, (response, error) -> chatThemeQueue.postRunnable(() -> {
boolean isError = false;
final List<ChatTheme> chatThemes;
if (response instanceof TLRPC.TL_account_chatThemes) {
TLRPC.TL_account_chatThemes resp = (TLRPC.TL_account_chatThemes) response;
final List<EmojiThemes> chatThemes;
if (response instanceof TLRPC.TL_account_themes) {
TLRPC.TL_account_themes resp = (TLRPC.TL_account_themes) response;
themesHash = resp.hash;
lastReloadTimeMs = System.currentTimeMillis();
SharedPreferences.Editor editor = getSharedPreferences().edit();
editor.clear();
editor.putInt("hash", themesHash);
editor.putLong("hash", themesHash);
editor.putLong("lastReload", lastReloadTimeMs);
editor.putInt("count", resp.themes.size());
chatThemes = new ArrayList<>(resp.themes.size());
for (int i = 0; i < resp.themes.size(); ++i) {
TLRPC.TL_chatTheme tlChatTheme = resp.themes.get(i);
TLRPC.TL_theme tlChatTheme = resp.themes.get(i);
Emoji.preloadEmoji(tlChatTheme.emoticon);
SerializedData data = new SerializedData(tlChatTheme.getObjectSize());
tlChatTheme.serializeToStream(data);
editor.putString("theme_" + i, Utilities.bytesToHex(data.toByteArray()));
ChatTheme chatTheme = new ChatTheme(tlChatTheme, false);
EmojiThemes chatTheme = new EmojiThemes(tlChatTheme, false);
chatTheme.preloadWallpaper();
chatThemes.add(chatTheme);
}
editor.apply();
} else if (response instanceof TLRPC.TL_account_chatThemesNotModified) {
} else if (response instanceof TLRPC.TL_account_themesNotModified) {
chatThemes = getAllChatThemesFromPrefs();
} else {
chatThemes = null;
@ -100,10 +101,10 @@ public class ChatThemeController extends BaseController {
AndroidUtilities.runOnUIThread(() -> callback.onError(error));
}
if (!isError) {
if (withDefault && !chatThemes.get(0).isDefault) {
chatThemes.add(0, ChatTheme.getDefault());
if (withDefault && !chatThemes.get(0).showAsDefaultStub) {
chatThemes.add(0, EmojiThemes.createChatThemesDefault());
}
for (ChatTheme theme : chatThemes) {
for (EmojiThemes theme : chatThemes) {
theme.initColors();
}
AndroidUtilities.runOnUIThread(() -> {
@ -113,11 +114,11 @@ public class ChatThemeController extends BaseController {
}
}));
} else {
List<ChatTheme> chatThemes = new ArrayList<>(allChatThemes);
if (withDefault && !chatThemes.get(0).isDefault) {
chatThemes.add(0, ChatTheme.getDefault());
List<EmojiThemes> chatThemes = new ArrayList<>(allChatThemes);
if (withDefault && !chatThemes.get(0).showAsDefaultStub) {
chatThemes.add(0, EmojiThemes.createChatThemesDefault());
}
for (ChatTheme theme : chatThemes) {
for (EmojiThemes theme : chatThemes) {
theme.initColors();
}
callback.onComplete(chatThemes);
@ -131,17 +132,17 @@ public class ChatThemeController extends BaseController {
return ApplicationLoader.applicationContext.getSharedPreferences("chatthemeconfig_emoji", Context.MODE_PRIVATE);
}
private static List<ChatTheme> getAllChatThemesFromPrefs() {
private static List<EmojiThemes> getAllChatThemesFromPrefs() {
SharedPreferences preferences = getSharedPreferences();
int count = preferences.getInt("count", 0);
List<ChatTheme> themes = new ArrayList<>(count);
List<EmojiThemes> themes = new ArrayList<>(count);
for (int i = 0; i < count; ++i) {
String value = preferences.getString("theme_" + i, "");
SerializedData serializedData = new SerializedData(Utilities.hexToBytes(value));
try {
TLRPC.TL_chatTheme chatTheme = TLRPC.TL_chatTheme.TLdeserialize(serializedData, serializedData.readInt32(true), true);
TLRPC.TL_theme chatTheme = TLRPC.Theme.TLdeserialize(serializedData, serializedData.readInt32(true), true);
if (chatTheme != null) {
themes.add(new ChatTheme(chatTheme, false));
themes.add(new EmojiThemes(chatTheme, false));
}
} catch (Throwable e) {
FileLog.e(e);
@ -150,15 +151,15 @@ public class ChatThemeController extends BaseController {
return themes;
}
public static void requestChatTheme(final String emoticon, final ResultCallback<ChatTheme> callback) {
public static void requestChatTheme(final String emoticon, final ResultCallback<EmojiThemes> callback) {
if (TextUtils.isEmpty(emoticon)) {
callback.onComplete(null);
return;
}
requestAllChatThemes(new ResultCallback<List<ChatTheme>>() {
requestAllChatThemes(new ResultCallback<List<EmojiThemes>>() {
@Override
public void onComplete(List<ChatTheme> result) {
for (ChatTheme theme : result) {
public void onComplete(List<EmojiThemes> result) {
for (EmojiThemes theme : result) {
if (emoticon.equals(theme.getEmoticon())) {
theme.initColors();
callback.onComplete(theme);
@ -221,14 +222,14 @@ public class ChatThemeController extends BaseController {
}
}
public ChatTheme getDialogTheme(long dialogId) {
public EmojiThemes getDialogTheme(long dialogId) {
String emoticon = dialogEmoticonsMap.get(dialogId);
if (emoticon == null) {
emoticon = getEmojiSharedPreferences().getString("chatTheme_" + currentAccount + "_" + dialogId, null);
dialogEmoticonsMap.put(dialogId, emoticon);
}
if (emoticon != null) {
for (ChatTheme theme : allChatThemes) {
for (EmojiThemes theme : allChatThemes) {
if (emoticon.equals(theme.getEmoticon())) {
return theme;
}
@ -238,26 +239,30 @@ public class ChatThemeController extends BaseController {
}
public static void preloadAllWallpaperImages(boolean isDark) {
for (ChatTheme chatTheme : allChatThemes) {
long themeId = chatTheme.getTlTheme(isDark).id;
if (themeIdWallpaperMap.containsKey(themeId)) {
for (EmojiThemes chatTheme : allChatThemes) {
TLRPC.TL_theme theme = chatTheme.getTlTheme(isDark ? 1 : 0);
if (theme == null) {
continue;
}
chatTheme.loadWallpaper(isDark, result -> {
if (result != null) {
themeIdWallpaperMap.put(result.first, result.second);
}
});
long themeId = theme.id;
if (getPatternFile(themeId).exists()) {
continue;
}
chatTheme.loadWallpaper(isDark ? 1 : 0, null);
}
}
public static void preloadAllWallpaperThumbs(boolean isDark) {
for (ChatTheme chatTheme : allChatThemes) {
long themeId = chatTheme.getTlTheme(isDark).id;
for (EmojiThemes chatTheme : allChatThemes) {
TLRPC.TL_theme theme = chatTheme.getTlTheme(isDark ? 1 : 0);
if (theme == null) {
continue;
}
long themeId = theme.id;
if (themeIdWallpaperThumbMap.containsKey(themeId)) {
continue;
}
chatTheme.loadWallpaperThumb(isDark, result -> {
chatTheme.loadWallpaperThumb(isDark ? 1 : 0, result -> {
if (result != null) {
themeIdWallpaperThumbMap.put(result.first, result.second);
}
@ -266,15 +271,52 @@ public class ChatThemeController extends BaseController {
}
public static void clearWallpaperImages() {
themeIdWallpaperMap.clear();
}
public static void clearWallpaperThumbImages() {
themeIdWallpaperThumbMap.clear();
}
public static Bitmap getWallpaperBitmap(long themeId) {
return themeIdWallpaperMap.get(themeId);
public static void getWallpaperBitmap(long themeId, ResultCallback<Bitmap> callback) {
if (themesHash == 0) {
callback.onComplete(null);
return;
}
File file = getPatternFile(themeId);
chatThemeQueue.postRunnable(() -> {
Bitmap bitmap = null;
try {
if (file.exists()) {
bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
}
} catch (Exception e) {
FileLog.e(e);
}
if (callback != null) {
Bitmap finalBitmap = bitmap;
AndroidUtilities.runOnUIThread(() -> {
callback.onComplete(finalBitmap);
});
}
});
}
private static File getPatternFile(long themeId) {
return new File(ApplicationLoader.getFilesDirFixed(), String.format(Locale.US, "%d_%d.jpg", themeId, themesHash));
}
public static void saveWallpaperBitmap(Bitmap bitmap, long themeId) {
File file = getPatternFile(themeId);
chatThemeQueue.postRunnable(() -> {
try {
FileOutputStream stream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 87, stream);
stream.close();
} catch (Exception e) {
FileLog.e(e);
}
});
}
public static Bitmap getWallpaperThumbBitmap(long themeId) {

View File

@ -742,7 +742,7 @@ public class FileRefController extends BaseController {
} else if (response instanceof TLRPC.TL_account_wallPapers) {
TLRPC.TL_account_wallPapers accountWallPapers = (TLRPC.TL_account_wallPapers) response;
for (int i = 0, size10 = accountWallPapers.wallpapers.size(); i < size10; i++) {
result = getFileReference(((TLRPC.TL_wallPaper) accountWallPapers.wallpapers.get(i)).document, requester.location, needReplacement, locationReplacement);
result = getFileReference(((TLRPC.WallPaper) accountWallPapers.wallpapers.get(i)).document, requester.location, needReplacement, locationReplacement);
if (result != null) {
break;
}

View File

@ -743,6 +743,10 @@ public class GcmPushListenerService extends FirebaseMessagingService {
messageText = LocaleController.formatString("NotificationGroupAddSelfMega", R.string.NotificationGroupAddSelfMega, args[0], args[1]);
break;
}
case "CHAT_REQ_JOINED": {
messageText = LocaleController.formatString("UserAcceptedToGroupPushWithGroup", R.string.UserAcceptedToGroupPushWithGroup, args[0], args[1]);
break;
}
case "CHAT_MESSAGE_FWDS": {
messageText = LocaleController.formatString("NotificationGroupForwardedFew", R.string.NotificationGroupForwardedFew, args[0], args[1], LocaleController.formatPluralString("messages", Utilities.parseInt(args[2])));
localMessage = true;

View File

@ -14,6 +14,8 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
@ -30,6 +32,8 @@ import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.SparseArray;
import com.google.android.exoplayer2.util.Log;
import org.json.JSONArray;
import org.json.JSONObject;
import org.telegram.messenger.secretmedia.EncryptedFileInputStream;
@ -73,9 +77,18 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
import java.util.zip.GZIPInputStream;
/**
* image filter types
* suffixes:
* f - image is wallpaper
* isc - ignore cache for small images
* b - need blur image
* g - autoplay
*/
public class ImageLoader {
private HashMap<String, Integer> bitmapUseCounts = new HashMap<>();
private LruCache<BitmapDrawable> smallImagesMemCache;
private LruCache<BitmapDrawable> memCache;
private LruCache<BitmapDrawable> wallpaperMemCache;
private LruCache<RLottieDrawable> lottieMemCache;
@ -118,9 +131,23 @@ public class ImageLoader {
public static final String AUTOPLAY_FILTER = "g";
public void moveToFront(String key) {
if (key == null) {
return;
}
BitmapDrawable drawable = memCache.get(key);
if (drawable != null) {
memCache.moveToFront(key);
}
drawable = smallImagesMemCache.get(key);
if (drawable != null) {
smallImagesMemCache.moveToFront(key);
}
}
public void putThumbsToCache(ArrayList<MessageThumb> updateMessageThumbs) {
for (int i = 0; i < updateMessageThumbs.size(); i++) {
putImageToCache(updateMessageThumbs.get(i).drawable, updateMessageThumbs.get(i).key);
putImageToCache(updateMessageThumbs.get(i).drawable, updateMessageThumbs.get(i).key, true);
}
}
@ -1433,6 +1460,8 @@ public class ImageLoader {
if (cacheImage.key.endsWith("_f")) {
wallpaperMemCache.put(cacheImage.key, bitmapDrawable);
incrementUseCount = false;
} else if (!cacheImage.key.endsWith("_isc") && bitmapDrawable.getBitmap().getWidth() <= 80 * AndroidUtilities.density && bitmapDrawable.getBitmap().getHeight() <= 80 * AndroidUtilities.density) {
smallImagesMemCache.put(cacheImage.key, bitmapDrawable);
} else {
memCache.put(cacheImage.key, bitmapDrawable);
}
@ -1469,7 +1498,10 @@ public class ImageLoader {
private BitmapDrawable getFromMemCache(String key) {
BitmapDrawable drawable = memCache.get(key);
if (drawable == null) {
return wallpaperMemCache.get(key);
drawable = smallImagesMemCache.get(key);
}
if (drawable == null) {
drawable = wallpaperMemCache.get(key);
}
return drawable;
}
@ -1698,7 +1730,30 @@ public class ImageLoader {
}
int cacheSize = Math.min(maxSize, memoryClass / 7) * 1024 * 1024;
memCache = new LruCache<BitmapDrawable>(cacheSize) {
int commonCacheSize = (int) (cacheSize * 0.8f);
int smallImagesCacheSize = (int) (cacheSize * 0.2f);
memCache = new LruCache<BitmapDrawable>(commonCacheSize) {
@Override
protected int sizeOf(String key, BitmapDrawable value) {
return value.getBitmap().getByteCount();
}
@Override
protected void entryRemoved(boolean evicted, String key, final BitmapDrawable oldValue, BitmapDrawable newValue) {
if (ignoreRemoval != null && ignoreRemoval.equals(key)) {
return;
}
final Integer count = bitmapUseCounts.get(key);
if (count == null || count == 0) {
Bitmap b = oldValue.getBitmap();
if (!b.isRecycled()) {
b.recycle();
}
}
}
};
smallImagesMemCache = new LruCache<BitmapDrawable>(smallImagesCacheSize) {
@Override
protected int sizeOf(String key, BitmapDrawable value) {
return value.getBitmap().getByteCount();
@ -2104,10 +2159,15 @@ public class ImageLoader {
}
private void performReplace(String oldKey, String newKey) {
BitmapDrawable b = memCache.get(oldKey);
LruCache<BitmapDrawable> currentCache = memCache;
BitmapDrawable b = currentCache.get(oldKey);
if (b == null) {
currentCache = smallImagesMemCache;
b = currentCache.get(oldKey);
}
replacedBitmaps.put(oldKey, newKey);
if (b != null) {
BitmapDrawable oldBitmap = memCache.get(newKey);
BitmapDrawable oldBitmap = currentCache.get(newKey);
boolean dontChange = false;
if (oldBitmap != null && oldBitmap.getBitmap() != null && b.getBitmap() != null) {
Bitmap oldBitmapObject = oldBitmap.getBitmap();
@ -2118,11 +2178,11 @@ public class ImageLoader {
}
if (!dontChange) {
ignoreRemoval = oldKey;
memCache.remove(oldKey);
memCache.put(newKey, b);
currentCache.remove(oldKey);
currentCache.put(newKey, b);
ignoreRemoval = null;
} else {
memCache.remove(oldKey);
currentCache.remove(oldKey);
}
}
Integer val = bitmapUseCounts.get(oldKey);
@ -2158,6 +2218,7 @@ public class ImageLoader {
public void removeImage(String key) {
bitmapUseCounts.remove(key);
memCache.remove(key);
smallImagesMemCache.remove(key);
}
public boolean isInMemCache(String key, boolean animated) {
@ -2169,6 +2230,7 @@ public class ImageLoader {
}
public void clearMemory() {
smallImagesMemCache.evictAll();
memCache.evictAll();
lottieMemCache.evictAll();
}
@ -2195,6 +2257,14 @@ public class ImageLoader {
if (imageReceiver == null) {
return;
}
ArrayList<Runnable> runnables = imageReceiver.getLoadingOperations();
if (!runnables.isEmpty()) {
for (int i = 0; i < runnables.size(); i++) {
imageLoadQueue.cancelRunnable(runnables.get(i));
}
runnables.clear();
}
imageReceiver.addLoadingImageRunnable(null);
imageLoadQueue.postRunnable(() -> {
for (int a = 0; a < 3; a++) {
int type;
@ -2222,17 +2292,6 @@ public class ImageLoader {
});
}
public BitmapDrawable getAnyImageFromMemory(String key) {
BitmapDrawable drawable = memCache.get(key);
if (drawable == null) {
ArrayList<String> filters = memCache.getFilterKeys(key);
if (filters != null && !filters.isEmpty()) {
return memCache.get(key + "@" + filters.get(0));
}
}
return drawable;
}
public BitmapDrawable getImageFromMemory(TLObject fileLocation, String httpUrl, String filter) {
if (fileLocation == null && httpUrl == null) {
return null;
@ -2262,18 +2321,25 @@ public class ImageLoader {
}
private void replaceImageInCacheInternal(final String oldKey, final String newKey, final ImageLocation newLocation) {
ArrayList<String> arr = memCache.getFilterKeys(oldKey);
if (arr != null) {
for (int a = 0; a < arr.size(); a++) {
String filter = arr.get(a);
String oldK = oldKey + "@" + filter;
String newK = newKey + "@" + filter;
performReplace(oldK, newK);
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.didReplacedPhotoInMemCache, oldK, newK, newLocation);
for (int i = 0; i < 2; i++) {
ArrayList<String> arr;
if (i == 0) {
arr = memCache.getFilterKeys(oldKey);
} else {
arr = smallImagesMemCache.getFilterKeys(oldKey);
}
if (arr != null) {
for (int a = 0; a < arr.size(); a++) {
String filter = arr.get(a);
String oldK = oldKey + "@" + filter;
String newK = newKey + "@" + filter;
performReplace(oldK, newK);
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.didReplacedPhotoInMemCache, oldK, newK, newLocation);
}
} else {
performReplace(oldKey, newKey);
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.didReplacedPhotoInMemCache, oldKey, newKey, newLocation);
}
} else {
performReplace(oldKey, newKey);
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.didReplacedPhotoInMemCache, oldKey, newKey, newLocation);
}
}
@ -2285,8 +2351,12 @@ public class ImageLoader {
}
}
public void putImageToCache(BitmapDrawable bitmap, String key) {
memCache.put(key, bitmap);
public void putImageToCache(BitmapDrawable bitmap, String key, boolean smallImage) {
if (smallImage) {
smallImagesMemCache.put(key, bitmap);
} else {
memCache.put(key, bitmap);
}
}
private void generateThumb(int mediaType, File originalPath, ThumbGenerateInfo info) {
@ -2332,7 +2402,7 @@ public class ImageLoader {
final boolean shouldGenerateQualityThumb = imageReceiver.isShouldGenerateQualityThumb();
final int currentAccount = imageReceiver.getCurrentAccount();
final boolean currentKeyQuality = type == ImageReceiver.TYPE_IMAGE && imageReceiver.isCurrentKeyQuality();
imageLoadQueue.postRunnable(() -> {
final Runnable loadOperationRunnable = () -> {
boolean added = false;
if (thumb != 2) {
CacheImage alreadyLoadingUrl = imageLoadingByUrl.get(url);
@ -2633,7 +2703,9 @@ public class ImageLoader {
}
}
}
});
};
imageLoadQueue.postRunnable(loadOperationRunnable);
imageReceiver.addLoadingImageRunnable(loadOperationRunnable);
}
public void preloadArtwork(String athumbUrl) {
@ -2684,7 +2756,14 @@ public class ImageLoader {
drawable = memCache.get(mediaKey);
if (drawable != null) {
memCache.moveToFront(mediaKey);
} else {
}
if (drawable == null) {
drawable = smallImagesMemCache.get(mediaKey);
if (drawable != null) {
smallImagesMemCache.moveToFront(mediaKey);
}
}
if (drawable == null) {
drawable = wallpaperMemCache.get(mediaKey);
if (drawable != null) {
wallpaperMemCache.moveToFront(mediaKey);
@ -2710,7 +2789,14 @@ public class ImageLoader {
drawable = memCache.get(imageKey);
if (drawable != null) {
memCache.moveToFront(imageKey);
} else {
}
if (drawable == null) {
drawable = smallImagesMemCache.get(imageKey);
if (drawable != null) {
smallImagesMemCache.moveToFront(imageKey);
}
}
if (drawable == null) {
drawable = wallpaperMemCache.get(imageKey);
if (drawable != null) {
wallpaperMemCache.moveToFront(imageKey);
@ -2737,7 +2823,14 @@ public class ImageLoader {
drawable = memCache.get(thumbKey);
if (drawable != null) {
memCache.moveToFront(thumbKey);
} else {
}
if (drawable == null) {
drawable = smallImagesMemCache.get(thumbKey);
if (drawable != null) {
smallImagesMemCache.moveToFront(thumbKey);
}
}
if (drawable == null) {
drawable = wallpaperMemCache.get(thumbKey);
if (drawable != null) {
wallpaperMemCache.moveToFront(thumbKey);
@ -3657,7 +3750,7 @@ public class ImageLoader {
Point point = ChatMessageCell.getMessageSize(w, h);
String key = String.format(Locale.US, "%s_false@%d_%d_b", ImageLocation.getStippedKey(message, message, size), (int) (point.x / AndroidUtilities.density), (int) (point.y / AndroidUtilities.density));
if (!getInstance().memCache.contains(key)) {
if (!getInstance().isInMemCache(key, false)) {
Bitmap b = getStrippedPhotoBitmap(size.bytes, null);
if (b != null) {
Utilities.blurBitmap(b, 3, 1, b.getWidth(), b.getHeight(), b.getRowBytes());

View File

@ -36,6 +36,8 @@ import org.telegram.ui.Components.RecyclableDrawable;
import androidx.annotation.Keep;
import java.util.ArrayList;
public class ImageReceiver implements NotificationCenter.NotificationCenterDelegate {
public interface ImageReceiverDelegate {
@ -248,7 +250,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
private boolean forcePreview;
private boolean forceCrossfade;
private int[] roundRadius = new int[4];
private boolean isRoundRect;
private boolean isRoundRect = true;
private Paint roundPaint;
private RectF roundRect = new RectF();
@ -273,6 +275,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
private float pressedProgress;
private int animateFromIsPressed;
private String uniqKeyPrefix;
private ArrayList<Runnable> loadingOperations = new ArrayList<>();
public ImageReceiver() {
this(null);
@ -1016,7 +1019,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (isRoundRect) {
try {
canvas.drawRoundRect(roundRect, roundRadius[0], roundRadius[0], roundPaint);
if (roundRadius[0] == 0) {
canvas.drawRect(roundRect, roundPaint);
} else {
canvas.drawRoundRect(roundRect, roundRadius[0], roundRadius[0], roundPaint);
}
} catch (Exception e) {
onBitmapException(bitmapDrawable);
FileLog.e(e);
@ -1111,7 +1118,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (isRoundRect) {
try {
canvas.drawRoundRect(roundRect, roundRadius[0], roundRadius[0], roundPaint);
if (roundRadius[0] == 0) {
canvas.drawRect(roundRect, roundPaint);
} else {
canvas.drawRoundRect(roundRect, roundRadius[0], roundRadius[0], roundPaint);
}
} catch (Exception e) {
onBitmapException(bitmapDrawable);
FileLog.e(e);
@ -2059,7 +2070,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
updateDrawableRadius(drawable);
if (isVisible && (!memCache && !forcePreview || forceCrossfade)) {
if (isVisible && (!memCache && !forcePreview || forceCrossfade) && crossfadeDuration != 0) {
boolean allowCorssfade = true;
if (currentMediaDrawable instanceof AnimatedFileDrawable && ((AnimatedFileDrawable) currentMediaDrawable).hasBitmap()) {
allowCorssfade = false;
@ -2319,4 +2330,17 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
public String getUniqKeyPrefix() {
return uniqKeyPrefix;
}
public void addLoadingImageRunnable(Runnable loadOperationRunnable) {
loadingOperations.add(loadOperationRunnable);
}
public ArrayList<Runnable> getLoadingOperations() {
return loadingOperations;
}
public void moveImageToFront() {
ImageLoader.getInstance().moveToFront(currentImageKey);
ImageLoader.getInstance().moveToFront(currentThumbKey);
}
}

View File

@ -1711,6 +1711,11 @@ public class LocaleController {
}
public static String formatSectionDate(long date) {
return formatYearMont(date, false);
}
public static String formatYearMont(long date, boolean alwaysShowYear) {
try {
date *= 1000;
Calendar rightNow = Calendar.getInstance();
@ -1733,7 +1738,7 @@ public class LocaleController {
LocaleController.getString("November", R.string.November),
LocaleController.getString("December", R.string.December)
};
if (year == dateYear) {
if (year == dateYear && !alwaysShowYear) {
return months[month];
} else {
return months[month] + " " + dateYear;

View File

@ -2091,10 +2091,10 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
if (!playlistEndReached[0]) {
loadingPlaylist = true;
AccountInstance.getInstance(playingMessageObject.currentAccount).getMediaDataController().loadMedia(playingMessageObject.getDialogId(), 50, playlistMaxId[0], MediaDataController.MEDIA_MUSIC, 1, playlistClassGuid);
AccountInstance.getInstance(playingMessageObject.currentAccount).getMediaDataController().loadMedia(playingMessageObject.getDialogId(), 50, playlistMaxId[0], 0, MediaDataController.MEDIA_MUSIC, 1, playlistClassGuid, 0);
} else if (playlistMergeDialogId != 0 && !playlistEndReached[1]) {
loadingPlaylist = true;
AccountInstance.getInstance(playingMessageObject.currentAccount).getMediaDataController().loadMedia(playlistMergeDialogId, 50, playlistMaxId[0], MediaDataController.MEDIA_MUSIC, 1, playlistClassGuid);
AccountInstance.getInstance(playingMessageObject.currentAccount).getMediaDataController().loadMedia(playlistMergeDialogId, 50, playlistMaxId[0], 0, MediaDataController.MEDIA_MUSIC, 1, playlistClassGuid, 0);
}
}
@ -4030,7 +4030,18 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
public static String getStickerExt(Uri uri) {
InputStream inputStream = null;
try {
inputStream = ApplicationLoader.applicationContext.getContentResolver().openInputStream(uri);
try {
inputStream = ApplicationLoader.applicationContext.getContentResolver().openInputStream(uri);
} catch (Exception e) {
inputStream = null;
}
if (inputStream == null) {
File file = new File(uri.getPath());
if (file.exists()) {
inputStream = new FileInputStream(file);
}
}
byte[] header = new byte[12];
if (inputStream.read(header, 0, 12) == 12) {
if (header[0] == (byte) 0x89 && header[1] == (byte) 0x50 && header[2] == (byte) 0x4E && header[3] == (byte) 0x47 && header[4] == (byte) 0x0D && header[5] == (byte) 0x0A && header[6] == (byte) 0x1A && header[7] == (byte) 0x0A) {

View File

@ -32,6 +32,7 @@ import android.text.Spanned;
import android.text.SpannedString;
import android.text.TextUtils;
import android.text.style.CharacterStyle;
import android.util.Log;
import android.util.SparseArray;
import org.telegram.SQLite.SQLiteCursor;
@ -47,6 +48,7 @@ import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.Bulletin;
import org.telegram.ui.Components.SharedMediaLayout;
import org.telegram.ui.Components.StickerSetBulletinLayout;
import org.telegram.ui.Components.StickersArchiveAlert;
import org.telegram.ui.Components.TextStyleSpan;
@ -73,14 +75,13 @@ import androidx.core.content.pm.ShortcutInfoCompat;
import androidx.core.content.pm.ShortcutManagerCompat;
import androidx.core.graphics.drawable.IconCompat;
import com.google.android.exoplayer2.util.Log;
@SuppressWarnings("unchecked")
public class MediaDataController extends BaseController {
public static String SHORTCUT_CATEGORY = "org.telegram.messenger.SHORTCUT_SHARE";
private static volatile MediaDataController[] Instance = new MediaDataController[UserConfig.MAX_ACCOUNT_COUNT];
public static MediaDataController getInstance(int num) {
MediaDataController localInstance = Instance[num];
if (localInstance == null) {
@ -1866,7 +1867,9 @@ public class MediaDataController extends BaseController {
}
}
/** @param toggle 0 - remove, 1 - archive, 2 - add */
/**
* @param toggle 0 - remove, 1 - archive, 2 - add
*/
public void toggleStickerSet(Context context, TLObject stickerSetObject, int toggle, BaseFragment baseFragment, boolean showSettings, boolean showTooltip) {
TLRPC.StickerSet stickerSet;
TLRPC.TL_messages_stickerSet messages_stickerSet;
@ -1970,7 +1973,9 @@ public class MediaDataController extends BaseController {
}
}
/** @param toggle 0 - uninstall, 1 - archive, 2 - unarchive */
/**
* @param toggle 0 - uninstall, 1 - archive, 2 - unarchive
*/
public void toggleStickerSets(ArrayList<TLRPC.StickerSet> stickerSetList, int type, int toggle, BaseFragment baseFragment, boolean showSettings) {
int stickerSetListSize = stickerSetList.size();
ArrayList<TLRPC.InputStickerSet> inputStickerSets = new ArrayList<>(stickerSetListSize);
@ -2325,22 +2330,35 @@ public class MediaDataController extends BaseController {
public final static int MEDIA_URL = 3;
public final static int MEDIA_MUSIC = 4;
public final static int MEDIA_GIF = 5;
public final static int MEDIA_TYPES_COUNT = 6;
public final static int MEDIA_PHOTOS_ONLY = 6;
public final static int MEDIA_VIDEOS_ONLY = 7;
public final static int MEDIA_TYPES_COUNT = 8;
public void loadMedia(long dialogId, int count, int max_id, int type, int fromCache, int classGuid) {
public void loadMedia(long dialogId, int count, int max_id, int min_id, int type, int fromCache, int classGuid, int requestIndex) {
boolean isChannel = DialogObject.isChatDialog(dialogId) && ChatObject.isChannel(-dialogId, currentAccount);
if (BuildVars.LOGS_ENABLED) {
FileLog.d("load media did " + dialogId + " count = " + count + " max_id " + max_id + " type = " + type + " cache = " + fromCache + " classGuid = " + classGuid);
}
if (fromCache != 0 || DialogObject.isEncryptedDialog(dialogId)) {
loadMediaDatabase(dialogId, count, max_id, type, classGuid, isChannel, fromCache);
if ((fromCache != 0 || DialogObject.isEncryptedDialog(dialogId))) {
loadMediaDatabase(dialogId, count, max_id, min_id, type, classGuid, isChannel, fromCache, requestIndex);
} else {
TLRPC.TL_messages_search req = new TLRPC.TL_messages_search();
req.limit = count;
req.offset_id = max_id;
if (min_id != 0) {
req.offset_id = min_id;
req.add_offset = -count;
} else {
req.offset_id = max_id;
}
if (type == MEDIA_PHOTOVIDEO) {
req.filter = new TLRPC.TL_inputMessagesFilterPhotoVideo();
} else if (type == MEDIA_PHOTOS_ONLY) {
req.filter = new TLRPC.TL_inputMessagesFilterPhotos();
} else if (type == MEDIA_VIDEOS_ONLY) {
req.filter = new TLRPC.TL_inputMessagesFilterVideo();
} else if (type == MEDIA_FILE) {
req.filter = new TLRPC.TL_inputMessagesFilterDocument();
} else if (type == MEDIA_AUDIO) {
@ -2361,7 +2379,14 @@ public class MediaDataController extends BaseController {
if (error == null) {
TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
getMessagesController().removeDeletedMessagesFromArray(dialogId, res.messages);
processLoadedMedia(res, dialogId, count, max_id, type, 0, classGuid, isChannel, res.messages.size() == 0);
boolean topReached;
if (min_id != 0) {
topReached = res.messages.size() <= 1;
} else {
topReached = res.messages.size() == 0;
}
processLoadedMedia(res, dialogId, count, max_id, min_id, type, 0, classGuid, isChannel, topReached, requestIndex);
}
});
getConnectionsManager().bindRequestToGuid(reqId, classGuid);
@ -2371,9 +2396,9 @@ public class MediaDataController extends BaseController {
public void getMediaCounts(long dialogId, int classGuid) {
getMessagesStorage().getStorageQueue().postRunnable(() -> {
try {
int[] counts = new int[]{-1, -1, -1, -1, -1, -1};
int[] countsFinal = new int[]{-1, -1, -1, -1, -1, -1};
int[] old = new int[]{0, 0, 0, 0, 0, 0};
int[] counts = new int[]{-1, -1, -1, -1, -1, -1, -1, -1};
int[] countsFinal = new int[]{-1, -1, -1, -1, -1, -1, -1, -1};
int[] old = new int[]{0, 0, 0, 0, 0, 0, 0, 0};
SQLiteCursor cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT type, count, old FROM media_counts_v2 WHERE uid = %d", dialogId));
while (cursor.next()) {
int type = cursor.intValue(0);
@ -2386,7 +2411,7 @@ public class MediaDataController extends BaseController {
if (DialogObject.isEncryptedDialog(dialogId)) {
for (int a = 0; a < counts.length; a++) {
if (counts[a] == -1) {
cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT COUNT(mid) FROM media_v3 WHERE uid = %d AND type = %d LIMIT 1", dialogId, a));
cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT COUNT(mid) FROM media_v4 WHERE uid = %d AND type = %d LIMIT 1", dialogId, a));
if (cursor.next()) {
counts[a] = cursor.intValue(0);
} else {
@ -2417,6 +2442,10 @@ public class MediaDataController extends BaseController {
req.filters.add(new TLRPC.TL_inputMessagesFilterUrl());
} else if (a == MEDIA_MUSIC) {
req.filters.add(new TLRPC.TL_inputMessagesFilterMusic());
} else if (a == MEDIA_PHOTOS_ONLY) {
req.filters.add(new TLRPC.TL_inputMessagesFilterPhotos());
} else if (a == MEDIA_VIDEOS_ONLY) {
req.filters.add(new TLRPC.TL_inputMessagesFilterVideo());
} else {
req.filters.add(new TLRPC.TL_inputMessagesFilterGif());
}
@ -2429,7 +2458,11 @@ public class MediaDataController extends BaseController {
}
if (!req.filters.isEmpty()) {
int reqId = getConnectionsManager().sendRequest(req, (response, error) -> {
Arrays.fill(counts, 0);
for (int i = 0; i < counts.length; i++) {
if (counts[i] < 0) {
counts[i] = 0;
}
}
if (response != null) {
TLRPC.Vector res = (TLRPC.Vector) response;
for (int a = 0, N = res.objects.size(); a < N; a++) {
@ -2447,6 +2480,10 @@ public class MediaDataController extends BaseController {
type = MEDIA_MUSIC;
} else if (searchCounter.filter instanceof TLRPC.TL_inputMessagesFilterGif) {
type = MEDIA_GIF;
} else if (searchCounter.filter instanceof TLRPC.TL_inputMessagesFilterPhotos) {
type = MEDIA_PHOTOS_ONLY;
} else if (searchCounter.filter instanceof TLRPC.TL_inputMessagesFilterVideo) {
type = MEDIA_VIDEOS_ONLY;
} else {
continue;
}
@ -2568,20 +2605,20 @@ public class MediaDataController extends BaseController {
}
}
private void processLoadedMedia(TLRPC.messages_Messages res, long dialogId, int count, int max_id, int type, int fromCache, int classGuid, boolean isChannel, boolean topReached) {
private void processLoadedMedia(TLRPC.messages_Messages res, long dialogId, int count, int max_id, int min_id, int type, int fromCache, int classGuid, boolean isChannel, boolean topReached, int requestIndex) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("process load media did " + dialogId + " count = " + count + " max_id " + max_id + " type = " + type + " cache = " + fromCache + " classGuid = " + classGuid);
FileLog.d("process load media did " + dialogId + " count = " + count + " max_id=" + max_id + " min_id=" + min_id + " type = " + type + " cache = " + fromCache + " classGuid = " + classGuid);
}
if (fromCache != 0 && res.messages.isEmpty() && !DialogObject.isEncryptedDialog(dialogId)) {
if (fromCache != 0 && ((res.messages.isEmpty() && min_id == 0) || (res.messages.size() <= 1 && min_id != 0)) && !DialogObject.isEncryptedDialog(dialogId)) {
if (fromCache == 2) {
return;
}
loadMedia(dialogId, count, max_id, type, 0, classGuid);
loadMedia(dialogId, count, max_id, min_id, type, 0, classGuid, requestIndex);
} else {
if (fromCache == 0) {
ImageLoader.saveMessagesThumbs(res.messages);
getMessagesStorage().putUsersAndChats(res.users, res.chats, true, true);
putMediaDatabase(dialogId, type, res.messages, max_id, topReached);
putMediaDatabase(dialogId, type, res.messages, max_id, min_id, topReached);
}
Utilities.searchQueue.postRunnable(() -> {
@ -2602,7 +2639,7 @@ public class MediaDataController extends BaseController {
int totalCount = res.count;
getMessagesController().putUsers(res.users, fromCache != 0);
getMessagesController().putChats(res.chats, fromCache != 0);
getNotificationCenter().postNotificationName(NotificationCenter.mediaDidLoad, dialogId, totalCount, objects, classGuid, type, topReached);
getNotificationCenter().postNotificationName(NotificationCenter.mediaDidLoad, dialogId, totalCount, objects, classGuid, type, topReached, min_id != 0, requestIndex);
});
});
}
@ -2653,7 +2690,7 @@ public class MediaDataController extends BaseController {
}
cursor.dispose();
if (count == -1 && DialogObject.isEncryptedDialog(dialogId)) {
cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT COUNT(mid) FROM media_v3 WHERE uid = %d AND type = %d LIMIT 1", dialogId, type));
cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT COUNT(mid) FROM media_v4 WHERE uid = %d AND type = %d LIMIT 1", dialogId, type));
if (cursor.next()) {
count = cursor.intValue(0);
}
@ -2670,7 +2707,7 @@ public class MediaDataController extends BaseController {
});
}
private void loadMediaDatabase(long uid, int count, int max_id, int type, int classGuid, boolean isChannel, int fromCache) {
private void loadMediaDatabase(long uid, int count, int max_id, int min_id, int type, int classGuid, boolean isChannel, int fromCache, int requestIndex) {
Runnable runnable = new Runnable() {
@Override
public void run() {
@ -2684,40 +2721,62 @@ public class MediaDataController extends BaseController {
SQLiteCursor cursor;
SQLiteDatabase database = getMessagesStorage().getDatabase();
boolean isEnd = false;
boolean reverseMessages = false;
if (!DialogObject.isEncryptedDialog(uid)) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT start FROM media_holes_v2 WHERE uid = %d AND type = %d AND start IN (0, 1)", uid, type));
if (cursor.next()) {
isEnd = cursor.intValue(0) == 1;
} else {
cursor.dispose();
cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid) FROM media_v3 WHERE uid = %d AND type = %d AND mid > 0", uid, type));
if (min_id == 0) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT start FROM media_holes_v2 WHERE uid = %d AND type = %d AND start IN (0, 1)", uid, type));
if (cursor.next()) {
int mid = cursor.intValue(0);
if (mid != 0) {
SQLitePreparedStatement state = database.executeFast("REPLACE INTO media_holes_v2 VALUES(?, ?, ?, ?)");
state.requery();
state.bindLong(1, uid);
state.bindInteger(2, type);
state.bindInteger(3, 0);
state.bindInteger(4, mid);
state.step();
state.dispose();
isEnd = cursor.intValue(0) == 1;
} else {
cursor.dispose();
cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid) FROM media_v4 WHERE uid = %d AND type = %d AND mid > 0", uid, type));
if (cursor.next()) {
int mid = cursor.intValue(0);
if (mid != 0) {
SQLitePreparedStatement state = database.executeFast("REPLACE INTO media_holes_v2 VALUES(?, ?, ?, ?)");
state.requery();
state.bindLong(1, uid);
state.bindInteger(2, type);
state.bindInteger(3, 0);
state.bindInteger(4, mid);
state.step();
state.dispose();
}
}
}
cursor.dispose();
}
cursor.dispose();
int holeMessageId = 0;
if (max_id != 0) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT end FROM media_holes_v2 WHERE uid = %d AND type = %d AND end <= %d ORDER BY end DESC LIMIT 1", uid, type, max_id));
int startHole = 0;
cursor = database.queryFinalized(String.format(Locale.US, "SELECT start, end FROM media_holes_v2 WHERE uid = %d AND type = %d AND start <= %d ORDER BY end DESC LIMIT 1", uid, type, max_id));
if (cursor.next()) {
holeMessageId = cursor.intValue(0);
startHole = cursor.intValue(0);
holeMessageId = cursor.intValue(1);
}
cursor.dispose();
if (holeMessageId > 1) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v3 WHERE uid = %d AND mid > 0 AND mid < %d AND mid >= %d AND type = %d ORDER BY date DESC, mid DESC LIMIT %d", uid, max_id, holeMessageId, type, countToLoad));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v4 WHERE uid = %d AND mid > 0 AND mid < %d AND mid >= %d AND type = %d ORDER BY date DESC, mid DESC LIMIT %d", uid, max_id, holeMessageId, type, countToLoad));
isEnd = false;
} else {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v3 WHERE uid = %d AND mid > 0 AND mid < %d AND type = %d ORDER BY date DESC, mid DESC LIMIT %d", uid, max_id, type, countToLoad));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v4 WHERE uid = %d AND mid > 0 AND mid < %d AND type = %d ORDER BY date DESC, mid DESC LIMIT %d", uid, max_id, type, countToLoad));
}
} else if (min_id != 0) {
int startHole = 0;
cursor = database.queryFinalized(String.format(Locale.US, "SELECT start, end FROM media_holes_v2 WHERE uid = %d AND type = %d AND end >= %d ORDER BY end ASC LIMIT 1", uid, type, min_id));
if (cursor.next()) {
startHole = cursor.intValue(0);
holeMessageId = cursor.intValue(1);
}
cursor.dispose();
reverseMessages = true;
if (startHole > 1) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v4 WHERE uid = %d AND mid > 0 AND mid >= %d AND mid <= %d AND type = %d ORDER BY date ASC, mid ASC LIMIT %d", uid, min_id, startHole, type, countToLoad));
} else {
isEnd = true;
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v4 WHERE uid = %d AND mid > 0 AND mid >= %d AND type = %d ORDER BY date ASC, mid ASC LIMIT %d", uid, min_id, type, countToLoad));
}
} else {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT max(end) FROM media_holes_v2 WHERE uid = %d AND type = %d", uid, type));
@ -2726,17 +2785,19 @@ public class MediaDataController extends BaseController {
}
cursor.dispose();
if (holeMessageId > 1) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v3 WHERE uid = %d AND mid >= %d AND type = %d ORDER BY date DESC, mid DESC LIMIT %d", uid, holeMessageId, type, countToLoad));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v4 WHERE uid = %d AND mid >= %d AND type = %d ORDER BY date DESC, mid DESC LIMIT %d", uid, holeMessageId, type, countToLoad));
} else {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v3 WHERE uid = %d AND mid > 0 AND type = %d ORDER BY date DESC, mid DESC LIMIT %d", uid, type, countToLoad));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v4 WHERE uid = %d AND mid > 0 AND type = %d ORDER BY date DESC, mid DESC LIMIT %d", uid, type, countToLoad));
}
}
} else {
isEnd = true;
if (max_id != 0) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid, r.random_id FROM media_v3 as m LEFT JOIN randoms_v2 as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid > %d AND type = %d ORDER BY m.mid ASC LIMIT %d", uid, max_id, type, countToLoad));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid, r.random_id FROM media_v4 as m LEFT JOIN randoms_v2 as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid > %d AND type = %d ORDER BY m.mid ASC LIMIT %d", uid, max_id, type, countToLoad));
} else if (min_id != 0) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid, r.random_id FROM media_v4 as m LEFT JOIN randoms_v2 as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid < %d AND type = %d ORDER BY m.mid DESC LIMIT %d", uid, min_id, type, countToLoad));
} else {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid, r.random_id FROM media_v3 as m LEFT JOIN randoms_v2 as r ON r.mid = m.mid WHERE m.uid = %d AND type = %d ORDER BY m.mid ASC LIMIT %d", uid, type, countToLoad));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid, r.random_id FROM media_v4 as m LEFT JOIN randoms_v2 as r ON r.mid = m.mid WHERE m.uid = %d AND type = %d ORDER BY m.mid ASC LIMIT %d", uid, type, countToLoad));
}
}
@ -2751,7 +2812,12 @@ public class MediaDataController extends BaseController {
if (DialogObject.isEncryptedDialog(uid)) {
message.random_id = cursor.longValue(2);
}
res.messages.add(message);
if (reverseMessages) {
res.messages.add(0, message);
} else {
res.messages.add(message);
}
MessagesStorage.addUsersAndChatsFromMessage(message, usersToLoad, chatsToLoad);
}
}
@ -2763,10 +2829,14 @@ public class MediaDataController extends BaseController {
if (!chatsToLoad.isEmpty()) {
getMessagesStorage().getChatsInternal(TextUtils.join(",", chatsToLoad), res.chats);
}
if (res.messages.size() > count) {
if (res.messages.size() > count && min_id == 0) {
res.messages.remove(res.messages.size() - 1);
} else {
topReached = isEnd;
if (min_id != 0) {
topReached = false;
} else {
topReached = isEnd;
}
}
} catch (Exception e) {
res.messages.clear();
@ -2776,7 +2846,7 @@ public class MediaDataController extends BaseController {
} finally {
Runnable task = this;
AndroidUtilities.runOnUIThread(() -> getMessagesStorage().completeTaskForGuid(task, classGuid));
processLoadedMedia(res, uid, count, max_id, type, fromCache, classGuid, isChannel, topReached);
processLoadedMedia(res, uid, count, max_id, min_id, type, fromCache, classGuid, isChannel, topReached, requestIndex);
}
}
};
@ -2785,17 +2855,17 @@ public class MediaDataController extends BaseController {
messagesStorage.bindTaskToGuid(runnable, classGuid);
}
private void putMediaDatabase(long uid, int type, ArrayList<TLRPC.Message> messages, int max_id, boolean topReached) {
private void putMediaDatabase(long uid, int type, ArrayList<TLRPC.Message> messages, int max_id, int min_id, boolean topReached) {
getMessagesStorage().getStorageQueue().postRunnable(() -> {
try {
if (messages.isEmpty() || topReached) {
if (min_id == 0 && (messages.isEmpty() || topReached)) {
getMessagesStorage().doneHolesInMedia(uid, max_id, type);
if (messages.isEmpty()) {
return;
}
}
getMessagesStorage().getDatabase().beginTransaction();
SQLitePreparedStatement state2 = getMessagesStorage().getDatabase().executeFast("REPLACE INTO media_v3 VALUES(?, ?, ?, ?, ?)");
SQLitePreparedStatement state2 = getMessagesStorage().getDatabase().executeFast("REPLACE INTO media_v4 VALUES(?, ?, ?, ?, ?)");
for (TLRPC.Message message : messages) {
if (canAddMessageToMedia(message)) {
state2.requery();
@ -2811,9 +2881,11 @@ public class MediaDataController extends BaseController {
}
}
state2.dispose();
if (!topReached || max_id != 0) {
int minId = topReached ? 1 : messages.get(messages.size() - 1).id;
if (max_id != 0) {
if (!topReached || max_id != 0 || min_id != 0) {
int minId = (topReached && min_id == 0) ? 1 : messages.get(messages.size() - 1).id;
if (min_id != 0) {
getMessagesStorage().closeHolesInMedia(uid, minId, messages.get(0).id, type);
} else if (max_id != 0) {
getMessagesStorage().closeHolesInMedia(uid, minId, max_id, type);
} else {
getMessagesStorage().closeHolesInMedia(uid, minId, Integer.MAX_VALUE, type);
@ -2836,15 +2908,15 @@ public class MediaDataController extends BaseController {
SQLiteCursor cursor;
if (a == 0) {
if (!DialogObject.isEncryptedDialog(dialogId)) {
cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v3 WHERE uid = %d AND mid < %d AND type = %d ORDER BY date DESC, mid DESC LIMIT 1000", dialogId, maxId, MEDIA_MUSIC));
cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v4 WHERE uid = %d AND mid < %d AND type = %d ORDER BY date DESC, mid DESC LIMIT 1000", dialogId, maxId, MEDIA_MUSIC));
} else {
cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v3 WHERE uid = %d AND mid > %d AND type = %d ORDER BY date DESC, mid DESC LIMIT 1000", dialogId, maxId, MEDIA_MUSIC));
cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v4 WHERE uid = %d AND mid > %d AND type = %d ORDER BY date DESC, mid DESC LIMIT 1000", dialogId, maxId, MEDIA_MUSIC));
}
} else {
if (!DialogObject.isEncryptedDialog(dialogId)) {
cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v3 WHERE uid = %d AND mid > %d AND type = %d ORDER BY date DESC, mid DESC LIMIT 1000", dialogId, minId, MEDIA_MUSIC));
cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v4 WHERE uid = %d AND mid > %d AND type = %d ORDER BY date DESC, mid DESC LIMIT 1000", dialogId, minId, MEDIA_MUSIC));
} else {
cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v3 WHERE uid = %d AND mid < %d AND type = %d ORDER BY date DESC, mid DESC LIMIT 1000", dialogId, minId, MEDIA_MUSIC));
cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v4 WHERE uid = %d AND mid < %d AND type = %d ORDER BY date DESC, mid DESC LIMIT 1000", dialogId, minId, MEDIA_MUSIC));
}
}
@ -3804,7 +3876,7 @@ public class MediaDataController extends BaseController {
}
}
if (!ok) {
getMessagesStorage().updatePinnedMessages(dialogId, req.id, false, -1, 0, false, null);
getMessagesStorage().updatePinnedMessages(dialogId, req.id, false, -1, 0, false, null);
}
});
}
@ -4006,8 +4078,7 @@ public class MediaDataController extends BaseController {
if (messageObject.messageOwner.reply_to.reply_to_peer_id.channel_id != 0) {
channelId = messageObject.messageOwner.reply_to.reply_to_peer_id.channel_id;
}
} else
if (messageObject.messageOwner.peer_id.channel_id != 0) {
} else if (messageObject.messageOwner.peer_id.channel_id != 0) {
channelId = messageObject.messageOwner.peer_id.channel_id;
}
@ -4164,9 +4235,9 @@ public class MediaDataController extends BaseController {
getMessagesStorage().getDatabase().beginTransaction();
SQLitePreparedStatement state;
if (scheduled) {
state = getMessagesStorage().getDatabase().executeFast("UPDATE scheduled_messages_v2 SET replydata = ? WHERE mid = ? AND uid = ?");
state = getMessagesStorage().getDatabase().executeFast("UPDATE scheduled_messages_v2 SET replydata = ?, reply_to_message_id = ? WHERE mid = ? AND uid = ?");
} else {
state = getMessagesStorage().getDatabase().executeFast("UPDATE messages_v2 SET replydata = ? WHERE mid = ? AND uid = ?");
state = getMessagesStorage().getDatabase().executeFast("UPDATE messages_v2 SET replydata = ?, reply_to_message_id = ? WHERE mid = ? AND uid = ?");
}
for (int a = 0; a < result.size(); a++) {
TLRPC.Message message = result.get(a);
@ -4183,8 +4254,9 @@ public class MediaDataController extends BaseController {
MessageObject messageObject = messageObjects.get(b);
state.requery();
state.bindByteBuffer(1, data);
state.bindInteger(2, messageObject.getId());
state.bindLong(3, messageObject.getDialogId());
state.bindInteger(2, message.id);
state.bindInteger(3, messageObject.getId());
state.bindLong(4, messageObject.getDialogId());
state.step();
}
data.reuse();

View File

@ -0,0 +1,79 @@
package org.telegram.messenger;
import android.text.TextUtils;
import android.util.LongSparseArray;
import androidx.annotation.Nullable;
import org.telegram.tgnet.RequestDelegate;
import org.telegram.tgnet.TLRPC;
public class MemberRequestsController extends BaseController {
private static final MemberRequestsController[] instances = new MemberRequestsController[UserConfig.MAX_ACCOUNT_COUNT];
public static MemberRequestsController getInstance(int accountNum) {
MemberRequestsController local = instances[accountNum];
if (local == null) {
synchronized (MemberRequestsController.class) {
local = instances[accountNum];
if (local == null) {
local = new MemberRequestsController(accountNum);
instances[accountNum] = local;
}
}
}
return local;
}
private final LongSparseArray<TLRPC.TL_messages_chatInviteImporters> firstImportersCache = new LongSparseArray<>();
public MemberRequestsController(int accountNum) {
super(accountNum);
}
@Nullable
public TLRPC.TL_messages_chatInviteImporters getCachedImporters(long chatId) {
return firstImportersCache.get(chatId);
}
public int getImporters(final long chatId, final String query, TLRPC.TL_chatInviteImporter lastImporter, LongSparseArray<TLRPC.User> users, RequestDelegate onComplete) {
boolean isEmptyQuery = TextUtils.isEmpty(query);
TLRPC.TL_messages_getChatInviteImporters req = new TLRPC.TL_messages_getChatInviteImporters();
req.peer = MessagesController.getInstance(currentAccount).getInputPeer(-chatId);
req.requested = true;
req.limit = 30;
if (!isEmptyQuery) {
req.q = query;
req.flags |= 4;
}
if (lastImporter == null) {
req.offset_user = new TLRPC.TL_inputUserEmpty();
} else {
req.offset_user = getMessagesController().getInputUser(users.get(lastImporter.user_id));
req.offset_date = lastImporter.date;
}
return getConnectionsManager().sendRequest(req, (response, error) -> {
AndroidUtilities.runOnUIThread(() -> {
if (error == null) {
TLRPC.TL_messages_chatInviteImporters importers = (TLRPC.TL_messages_chatInviteImporters) response;
firstImportersCache.put(chatId, importers);
}
onComplete.run(response, error);
});
});
}
public void onPendingRequestsUpdated(TLRPC.TL_updatePendingJoinRequests update) {
long peerId = MessageObject.getPeerId(update.peer);
firstImportersCache.put(-peerId, null);
TLRPC.ChatFull chatFull = getMessagesController().getChatFull(-peerId);
if (chatFull != null) {
chatFull.requests_pending = update.requests_pending;
chatFull.recent_requesters = update.recent_requesters;
chatFull.flags |= 131072;
getMessagesStorage().updateChatInfo(chatFull, false);
getNotificationCenter().postNotificationName(NotificationCenter.chatInfoDidLoad, chatFull, 0, false, false);
}
}
}

View File

@ -124,6 +124,7 @@ public class MessageObject {
public long loadedFileSize;
public byte[] sponsoredId;
public int sponsoredChannelPost;
public String botStartParam;
public boolean animateComments;
@ -186,6 +187,9 @@ public class MessageObject {
public String messageTrimmedToHighlight;
public int parentWidth;
public ImageLocation mediaThumb;
public ImageLocation mediaSmallThumb;
static final String[] excludeWords = new String[] {
" vs. ",
" vs ",
@ -1832,6 +1836,11 @@ public class MessageObject {
}
messageText = replaceWithLink(LocaleController.formatString("ActionTTLChanged", R.string.ActionTTLChanged, time), "un1", fromUser);
}
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionParticipantJoinByRequest) {
TLRPC.TL_channelAdminLogEventActionParticipantJoinByRequest action = (TLRPC.TL_channelAdminLogEventActionParticipantJoinByRequest) event.action;
messageText = replaceWithLink(LocaleController.getString("JoinedViaInviteLinkApproved", R.string.JoinedViaInviteLinkApproved), "un1", fromUser);
messageText = replaceWithLink(messageText, "un2", action.invite);
messageText = replaceWithLink(messageText, "un3", MessagesController.getInstance(currentAccount).getUser(action.approved_by));
} else {
messageText = "unsupported " + event.action;
}
@ -2961,6 +2970,15 @@ public class MessageObject {
? LocaleController.formatString("ChatThemeChangedYou", R.string.ChatThemeChangedYou, emoticon)
: LocaleController.formatString("ChatThemeChangedTo", R.string.ChatThemeChangedTo, userName, emoticon);
}
} else if (messageOwner.action instanceof TLRPC.TL_messageActionChatJoinedByRequest) {
if (UserObject.isUserSelf(fromUser)) {
boolean isChannel = ChatObject.isChannelAndNotMegaGroup(messageOwner.peer_id.channel_id, currentAccount);
messageText = isChannel
? LocaleController.getString("RequestToJoinChannelApproved", R.string.RequestToJoinChannelApproved)
: LocaleController.getString("RequestToJoinGroupApproved", R.string.RequestToJoinGroupApproved);
} else {
messageText = replaceWithLink(LocaleController.getString("UserAcceptedToGroupAction", R.string.UserAcceptedToGroupAction), "un1", fromObject);
}
}
}
} else {
@ -4280,13 +4298,13 @@ public class MessageObject {
if (useManualParse) {
addLinks(isOutOwner(), messageText, true, true);
} else {
if (messageText instanceof Spannable && messageText.length() < 1000) {
try {
AndroidUtilities.addLinks((Spannable) messageText, Linkify.PHONE_NUMBERS);
} catch (Throwable e) {
FileLog.e(e);
}
}
// if (messageText instanceof Spannable && messageText.length() < 1000) {
// try {
// AndroidUtilities.addLinks((Spannable) messageText, Linkify.PHONE_NUMBERS);
// } catch (Throwable e) {
// FileLog.e(e);
// }
// }
}
if (isYouTubeVideo() || replyMessageObject != null && replyMessageObject.isYouTubeVideo()) {
addUrlsByPattern(isOutOwner(), messageText, false, 3, Integer.MAX_VALUE, false);
@ -5776,6 +5794,9 @@ public class MessageObject {
if (message == null) {
return false;
}
if (ChatObject.isChannelAndNotMegaGroup(chat) && message.action instanceof TLRPC.TL_messageActionChatJoinedByRequest) {
return false;
}
if (message.id < 0) {
return true;
}
@ -6119,6 +6140,21 @@ public class MessageObject {
}
}
public void createMediaThumbs() {
if (isVideo()) {
TLRPC.Document document = getDocument();
TLRPC.PhotoSize thumb = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 50);
TLRPC.PhotoSize qualityThumb = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 320);
mediaThumb = ImageLocation.getForDocument(qualityThumb, document);
mediaSmallThumb = ImageLocation.getForDocument(thumb, document);
} else if (messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && messageOwner.media.photo != null && !photoThumbs.isEmpty()) {
TLRPC.PhotoSize currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(photoThumbs, 50);
TLRPC.PhotoSize currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(photoThumbs, 320, false, currentPhotoObjectThumb, false);
mediaThumb = ImageLocation.getForObject(currentPhotoObject, photoThumbsObject);
mediaSmallThumb = ImageLocation.getForObject(currentPhotoObjectThumb, photoThumbsObject);
}
}
public boolean hasHighlightedWords() {
return highlightedWords != null && !highlightedWords.isEmpty();
}

View File

@ -2703,6 +2703,9 @@ public class MessagesController extends BaseController implements NotificationCe
}
public TLRPC.User getUser(Long id) {
if (id == 0) {
return UserConfig.getInstance(currentAccount).getCurrentUser();
}
return users.get(id);
}
@ -10875,62 +10878,69 @@ public class MessagesController extends BaseController implements NotificationCe
req.participant = getInputPeer(getUserConfig().getClientUserId());
getConnectionsManager().sendRequest(req, (response, error) -> {
TLRPC.TL_channels_channelParticipant res = (TLRPC.TL_channels_channelParticipant) response;
if (res != null && res.participant instanceof TLRPC.TL_channelParticipantSelf && res.participant.inviter_id != getUserConfig().getClientUserId()) {
if (chat.megagroup && getMessagesStorage().isMigratedChat(chat.id)) {
return;
}
AndroidUtilities.runOnUIThread(() -> {
putUsers(res.users, false);
putChats(res.chats, false);
});
getMessagesStorage().putUsersAndChats(res.users, res.chats, true, true);
if (res != null && res.participant instanceof TLRPC.TL_channelParticipantSelf) {
TLRPC.TL_channelParticipantSelf selfParticipant = (TLRPC.TL_channelParticipantSelf) res.participant;
if (selfParticipant.inviter_id != getUserConfig().getClientUserId() || selfParticipant.via_invite) {
if (chat.megagroup && getMessagesStorage().isMigratedChat(chat.id)) {
return;
}
AndroidUtilities.runOnUIThread(() -> {
putUsers(res.users, false);
putChats(res.chats, false);
});
getMessagesStorage().putUsersAndChats(res.users, res.chats, true, true);
ArrayList<MessageObject> pushMessages;
if (createMessage && Math.abs(getConnectionsManager().getCurrentTime() - res.participant.date) < 24 * 60 * 60 && !getMessagesStorage().hasInviteMeMessage(chatId)) {
TLRPC.TL_messageService message = new TLRPC.TL_messageService();
message.media_unread = true;
message.unread = true;
message.flags = TLRPC.MESSAGE_FLAG_HAS_FROM_ID;
message.post = true;
message.local_id = message.id = getUserConfig().getNewMessageId();
message.date = res.participant.date;
message.action = new TLRPC.TL_messageActionChatAddUser();
message.from_id = new TLRPC.TL_peerUser();
message.from_id.user_id = res.participant.inviter_id;
message.action.users.add(getUserConfig().getClientUserId());
message.peer_id = new TLRPC.TL_peerChannel();
message.peer_id.channel_id = chatId;
message.dialog_id = -chatId;
getUserConfig().saveConfig(false);
ArrayList<MessageObject> pushMessages;
if (createMessage && Math.abs(getConnectionsManager().getCurrentTime() - res.participant.date) < 24 * 60 * 60 && !getMessagesStorage().hasInviteMeMessage(chatId)) {
TLRPC.TL_messageService message = new TLRPC.TL_messageService();
message.media_unread = true;
message.unread = true;
message.flags = TLRPC.MESSAGE_FLAG_HAS_FROM_ID;
message.post = true;
message.local_id = message.id = getUserConfig().getNewMessageId();
message.date = res.participant.date;
if (selfParticipant.inviter_id != getUserConfig().getClientUserId()) {
message.action = new TLRPC.TL_messageActionChatAddUser();
} else if (selfParticipant.via_invite) {
message.action = new TLRPC.TL_messageActionChatJoinedByRequest();
}
message.from_id = new TLRPC.TL_peerUser();
message.from_id.user_id = res.participant.inviter_id;
message.action.users.add(getUserConfig().getClientUserId());
message.peer_id = new TLRPC.TL_peerChannel();
message.peer_id.channel_id = chatId;
message.dialog_id = -chatId;
getUserConfig().saveConfig(false);
pushMessages = new ArrayList<>();
ArrayList<TLRPC.Message> messagesArr = new ArrayList<>();
pushMessages = new ArrayList<>();
ArrayList<TLRPC.Message> messagesArr = new ArrayList<>();
ConcurrentHashMap<Long, TLRPC.User> usersDict = new ConcurrentHashMap<>();
for (int a = 0; a < res.users.size(); a++) {
TLRPC.User user = res.users.get(a);
usersDict.put(user.id, user);
ConcurrentHashMap<Long, TLRPC.User> usersDict = new ConcurrentHashMap<>();
for (int a = 0; a < res.users.size(); a++) {
TLRPC.User user = res.users.get(a);
usersDict.put(user.id, user);
}
messagesArr.add(message);
MessageObject obj = new MessageObject(currentAccount, message, usersDict, true, false);
pushMessages.add(obj);
getMessagesStorage().getStorageQueue().postRunnable(() -> AndroidUtilities.runOnUIThread(() -> getNotificationsController().processNewMessages(pushMessages, true, false, null)));
getMessagesStorage().putMessages(messagesArr, true, true, false, 0, false);
} else {
pushMessages = null;
}
messagesArr.add(message);
MessageObject obj = new MessageObject(currentAccount, message, usersDict, true, false);
pushMessages.add(obj);
getMessagesStorage().getStorageQueue().postRunnable(() -> AndroidUtilities.runOnUIThread(() -> getNotificationsController().processNewMessages(pushMessages, true, false, null)));
getMessagesStorage().putMessages(messagesArr, true, true, false, 0, false);
} else {
pushMessages = null;
getMessagesStorage().saveChatInviter(chatId, res.participant.inviter_id);
AndroidUtilities.runOnUIThread(() -> {
gettingChatInviters.delete(chatId);
if (pushMessages != null) {
updateInterfaceWithMessages(-chatId, pushMessages, false);
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
}
getNotificationCenter().postNotificationName(NotificationCenter.didLoadChatInviter, chatId, res.participant.inviter_id);
});
}
getMessagesStorage().saveChatInviter(chatId, res.participant.inviter_id);
AndroidUtilities.runOnUIThread(() -> {
gettingChatInviters.delete(chatId);
if (pushMessages != null) {
updateInterfaceWithMessages(-chatId, pushMessages, false);
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
}
getNotificationCenter().postNotificationName(NotificationCenter.didLoadChatInviter, chatId, res.participant.inviter_id);
});
}
});
}
@ -12728,6 +12738,11 @@ public class MessagesController extends BaseController implements NotificationCe
updatesOnMainThread = new ArrayList<>();
}
updatesOnMainThread.add(baseUpdate);
} else if (baseUpdate instanceof TLRPC.TL_updatePendingJoinRequests) {
if (updatesOnMainThread == null) {
updatesOnMainThread = new ArrayList<>();
}
updatesOnMainThread.add(baseUpdate);
}
}
if (messages != null) {
@ -13387,6 +13402,9 @@ public class MessagesController extends BaseController implements NotificationCe
getNotificationCenter().postNotificationName(NotificationCenter.userInfoDidLoad, peerId, userFull);
getMessagesStorage().updateUserInfo(userFull, false);
}
} else if (baseUpdate instanceof TLRPC.TL_updatePendingJoinRequests) {
TLRPC.TL_updatePendingJoinRequests update = (TLRPC.TL_updatePendingJoinRequests) baseUpdate;
getMemberRequestsController().onPendingRequestsUpdated(update);
}
}
if (editor != null) {
@ -13814,6 +13832,7 @@ public class MessagesController extends BaseController implements NotificationCe
MessageObject messageObject = new MessageObject(currentAccount, message, usersDict, chatsDict, true, true);
messageObject.sponsoredId = sponsoredMessage.random_id;
messageObject.botStartParam = sponsoredMessage.start_param;
messageObject.sponsoredChannelPost = sponsoredMessage.channel_post;
result.add(messageObject);
}
}
@ -14577,6 +14596,16 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
public int getChatPendingRequestsOnClosed(long chatId) {
return mainPreferences.getInt("chatPendingRequests" + chatId, 0);
}
public void setChatPendingRequestsOnClose(long chatId, int count) {
mainPreferences.edit()
.putInt("chatPendingRequests" + chatId, count)
.apply();
}
public interface MessagesLoadedCallback {
void onMessagesLoaded(boolean fromCache);
void onError();

View File

@ -48,8 +48,6 @@ import java.util.concurrent.atomic.AtomicLong;
import androidx.annotation.UiThread;
import androidx.collection.LongSparseArray;
import com.google.android.exoplayer2.util.Log;
public class MessagesStorage extends BaseController {
public interface IntCallback {
@ -100,7 +98,7 @@ public class MessagesStorage extends BaseController {
private CountDownLatch openSync = new CountDownLatch(1);
private static volatile MessagesStorage[] Instance = new MessagesStorage[UserConfig.MAX_ACCOUNT_COUNT];
private final static int LAST_DB_VERSION = 84;
private final static int LAST_DB_VERSION = 86;
private boolean databaseMigrationInProgress;
public static MessagesStorage getInstance(int num) {
@ -296,11 +294,12 @@ public class MessagesStorage extends BaseController {
database.executeFast("CREATE TABLE media_holes_v2(uid INTEGER, type INTEGER, start INTEGER, end INTEGER, PRIMARY KEY(uid, type, start));").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS uid_end_media_holes_v2 ON media_holes_v2(uid, type, end);").stepThis().dispose();
database.executeFast("CREATE TABLE scheduled_messages_v2(mid INTEGER, uid INTEGER, send_state INTEGER, date INTEGER, data BLOB, ttl INTEGER, replydata BLOB, PRIMARY KEY(mid, uid))").stepThis().dispose();
database.executeFast("CREATE TABLE scheduled_messages_v2(mid INTEGER, uid INTEGER, send_state INTEGER, date INTEGER, data BLOB, ttl INTEGER, replydata BLOB, reply_to_message_id INTEGER, PRIMARY KEY(mid, uid))").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS send_state_idx_scheduled_messages_v2 ON scheduled_messages_v2(mid, send_state, date);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS uid_date_idx_scheduled_messages_v2 ON scheduled_messages_v2(uid, date);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS reply_to_idx_scheduled_messages_v2 ON scheduled_messages_v2(mid, reply_to_message_id);").stepThis().dispose();
database.executeFast("CREATE TABLE messages_v2(mid INTEGER, uid INTEGER, read_state INTEGER, send_state INTEGER, date INTEGER, data BLOB, out INTEGER, ttl INTEGER, media INTEGER, replydata BLOB, imp INTEGER, mention INTEGER, forwards INTEGER, replies_data BLOB, thread_reply_id INTEGER, is_channel INTEGER, PRIMARY KEY(mid, uid))").stepThis().dispose();
database.executeFast("CREATE TABLE messages_v2(mid INTEGER, uid INTEGER, read_state INTEGER, send_state INTEGER, date INTEGER, data BLOB, out INTEGER, ttl INTEGER, media INTEGER, replydata BLOB, imp INTEGER, mention INTEGER, forwards INTEGER, replies_data BLOB, thread_reply_id INTEGER, is_channel INTEGER, reply_to_message_id INTEGER, PRIMARY KEY(mid, uid))").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS uid_mid_read_out_idx_messages_v2 ON messages_v2(uid, mid, read_state, out);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS uid_date_mid_idx_messages_v2 ON messages_v2(uid, date, mid);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS mid_out_idx_messages_v2 ON messages_v2(mid, out);").stepThis().dispose();
@ -308,6 +307,7 @@ public class MessagesStorage extends BaseController {
database.executeFast("CREATE INDEX IF NOT EXISTS send_state_idx_messages_v2 ON messages_v2(mid, send_state, date);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS uid_mention_idx_messages_v2 ON messages_v2(uid, mention, read_state);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS is_channel_idx_messages_v2 ON messages_v2(mid, is_channel);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS reply_to_idx_messages_v2 ON messages_v2(mid, reply_to_message_id);").stepThis().dispose();
database.executeFast("CREATE TABLE download_queue(uid INTEGER, type INTEGER, date INTEGER, data BLOB, parent TEXT, PRIMARY KEY (uid, type));").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS type_date_idx_download_queue ON download_queue(type, date);").stepThis().dispose();
@ -341,8 +341,8 @@ public class MessagesStorage extends BaseController {
database.executeFast("CREATE TABLE params(id INTEGER PRIMARY KEY, seq INTEGER, pts INTEGER, date INTEGER, qts INTEGER, lsv INTEGER, sg INTEGER, pbytes BLOB)").stepThis().dispose();
database.executeFast("INSERT INTO params VALUES(1, 0, 0, 0, 0, 0, 0, NULL)").stepThis().dispose();
database.executeFast("CREATE TABLE media_v3(mid INTEGER, uid INTEGER, date INTEGER, type INTEGER, data BLOB, PRIMARY KEY(mid, uid))").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS uid_mid_type_date_idx_media_v3 ON media_v3(uid, mid, type, date);").stepThis().dispose();
database.executeFast("CREATE TABLE media_v4(mid INTEGER, uid INTEGER, date INTEGER, type INTEGER, data BLOB, PRIMARY KEY(mid, uid, type))").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS uid_mid_type_date_idx_media_v3 ON media_v4(uid, mid, type, date);").stepThis().dispose();
database.executeFast("CREATE TABLE bot_keyboard(uid INTEGER PRIMARY KEY, mid INTEGER, info BLOB)").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS bot_keyboard_idx_mid_v2 ON bot_keyboard(mid, uid);").stepThis().dispose();
@ -445,6 +445,9 @@ public class MessagesStorage extends BaseController {
try {
updateDbToLastVersion(version);
} catch (Exception e) {
if (BuildVars.DEBUG_PRIVATE_VERSION) {
throw e;
}
FileLog.e(e);
throw new RuntimeException("malformed");
}
@ -452,7 +455,9 @@ public class MessagesStorage extends BaseController {
}
} catch (Exception e) {
FileLog.e(e);
if (BuildVars.DEBUG_PRIVATE_VERSION) {
throw new RuntimeException(e);
}
if (openTries < 3 && e.getMessage() != null && e.getMessage().contains("malformed")) {
if (openTries == 2) {
cleanupInternal(true);
@ -1465,9 +1470,62 @@ public class MessagesStorage extends BaseController {
version = 84;
}
if (version == 84) {
database.executeFast("CREATE TABLE IF NOT EXISTS media_v4(mid INTEGER, uid INTEGER, date INTEGER, type INTEGER, data BLOB, PRIMARY KEY(mid, uid, type))").stepThis().dispose();
database.beginTransaction();
SQLiteCursor cursor;
try {
cursor = database.queryFinalized("SELECT mid, uid, date, type, data FROM media_v3 WHERE 1");
} catch (Exception e) {
cursor = null;
FileLog.e(e);
}
if (cursor != null) {
SQLitePreparedStatement statement = database.executeFast("REPLACE INTO media_v4 VALUES(?, ?, ?, ?, ?)");
while (cursor.next()) {
NativeByteBuffer data = cursor.byteBufferValue(4);
if (data == null) {
continue;
}
int mid = cursor.intValue(0);
long uid = cursor.longValue(1);
int lowerId = (int) uid;
if (lowerId == 0) {
int highId = (int) (uid >> 32);
uid = DialogObject.makeEncryptedDialogId(highId);
}
int date = cursor.intValue(2);
int type = cursor.intValue(3);
statement.requery();
statement.bindInteger(1, mid);
statement.bindLong(2, uid);
statement.bindInteger(3, date);
statement.bindInteger(4, type);
statement.bindByteBuffer(5, data);
statement.step();
data.reuse();
}
cursor.dispose();
statement.dispose();
}
database.commitTransaction();
database.executeFast("DROP TABLE IF EXISTS media_v3;").stepThis().dispose();
database.executeFast("PRAGMA user_version = 85").stepThis().dispose();
version = 85;
}
if (version == 85) {
executeNoException("ALTER TABLE messages_v2 ADD COLUMN reply_to_message_id INTEGER default 0");
executeNoException("ALTER TABLE scheduled_messages_v2 ADD COLUMN reply_to_message_id INTEGER default 0");
database.executeFast("CREATE INDEX IF NOT EXISTS reply_to_idx_messages_v2 ON messages_v2(mid, reply_to_message_id);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS reply_to_idx_scheduled_messages_v2 ON scheduled_messages_v2(mid, reply_to_message_id);").stepThis().dispose();
executeNoException("UPDATE messages_v2 SET replydata = NULL");
executeNoException("UPDATE scheduled_messages_v2 SET replydata = NULL");
database.executeFast("PRAGMA user_version = 86").stepThis().dispose();
version = 86;
}
FileLog.d("MessagesStorage db migration finished");
AndroidUtilities.runOnUIThread(() -> {
@ -3697,7 +3755,7 @@ public class MessagesStorage extends BaseController {
database.executeFast("DELETE FROM messages_holes WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM bot_keyboard WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media_counts_v2 WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media_v3 WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media_v4 WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media_holes_v2 WHERE uid = " + did).stepThis().dispose();
getMediaDataController().clearBotKeyboard(did, null);
@ -3718,7 +3776,7 @@ public class MessagesStorage extends BaseController {
database.executeFast("DELETE FROM messages_v2 WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM bot_keyboard WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media_counts_v2 WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media_v3 WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media_v4 WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM messages_holes WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media_holes_v2 WHERE uid = " + did).stepThis().dispose();
getMediaDataController().clearBotKeyboard(did, null);
@ -3850,7 +3908,7 @@ public class MessagesStorage extends BaseController {
database.executeFast("DELETE FROM messages_v2 WHERE uid IN " + ids).stepThis().dispose();
database.executeFast("DELETE FROM polls_v2 WHERE 1").stepThis().dispose();
database.executeFast("DELETE FROM bot_keyboard WHERE uid IN " + ids).stepThis().dispose();
database.executeFast("DELETE FROM media_v3 WHERE uid IN " + ids).stepThis().dispose();
database.executeFast("DELETE FROM media_v4 WHERE uid IN " + ids).stepThis().dispose();
database.executeFast("DELETE FROM messages_holes WHERE uid IN " + ids).stepThis().dispose();
database.executeFast("DELETE FROM media_holes_v2 WHERE uid IN " + ids).stepThis().dispose();
database.commitTransaction();
@ -4019,7 +4077,7 @@ public class MessagesStorage extends BaseController {
cursor.dispose();
deleteFromDownloadQueue(idsToDelete, true);
if (!messages.isEmpty()) {
SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages_v2 VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?)");
SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages_v2 VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, 0)");
for (int a = 0; a < messages.size(); a++) {
TLRPC.Message message = messages.get(a);
@ -8423,7 +8481,7 @@ public class MessagesStorage extends BaseController {
database.beginTransaction();
SQLitePreparedStatement state = database.executeFast("UPDATE messages_v2 SET data = ? WHERE mid = ? AND uid = ?");
SQLitePreparedStatement state2 = database.executeFast("UPDATE media_v3 SET data = ? WHERE mid = ? AND uid = ?");
SQLitePreparedStatement state2 = database.executeFast("UPDATE media_v4 SET data = ? WHERE mid = ? AND uid = ?");
for (int a = 0; a < messages.size(); a++) {
TLRPC.Message message = messages.get(a);
NativeByteBuffer data = new NativeByteBuffer(message.getObjectSize());
@ -8477,7 +8535,7 @@ public class MessagesStorage extends BaseController {
database.executeFast("DELETE FROM messages_v2 WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM bot_keyboard WHERE uid = " + did).stepThis().dispose();
database.executeFast("UPDATE media_counts_v2 SET old = 1 WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media_v3 WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media_v4 WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM messages_holes WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media_holes_v2 WHERE uid = " + did).stepThis().dispose();
getMediaDataController().clearBotKeyboard(did, null);
@ -8747,7 +8805,7 @@ public class MessagesStorage extends BaseController {
database.beginTransaction();
}
SQLitePreparedStatement state_messages = database.executeFast("REPLACE INTO scheduled_messages_v2 VALUES(?, ?, ?, ?, ?, ?, NULL)");
SQLitePreparedStatement state_messages = database.executeFast("REPLACE INTO scheduled_messages_v2 VALUES(?, ?, ?, ?, ?, ?, NULL, 0)");
SQLitePreparedStatement state_randoms = database.executeFast("REPLACE INTO randoms_v2 VALUES(?, ?, ?)");
ArrayList<Long> dialogsToUpdate = new ArrayList<>();
@ -8835,7 +8893,7 @@ public class MessagesStorage extends BaseController {
LongSparseArray<ArrayList<Integer>> dialogMessagesIdsMap = new LongSparseArray<>();
LongSparseArray<ArrayList<Integer>> dialogMentionsIdsMap = new LongSparseArray<>();
SQLitePreparedStatement state_messages = database.executeFast("REPLACE INTO messages_v2 VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?)");
SQLitePreparedStatement state_messages = database.executeFast("REPLACE INTO messages_v2 VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, 0)");
SQLitePreparedStatement state_media = null;
SQLitePreparedStatement state_randoms = database.executeFast("REPLACE INTO randoms_v2 VALUES(?, ?, ?)");
SQLitePreparedStatement state_download = database.executeFast("REPLACE INTO download_queue VALUES(?, ?, ?, ?, ?)");
@ -8938,7 +8996,7 @@ public class MessagesStorage extends BaseController {
SparseIntArray mediaTypes = dialogMediaTypes.get(dialogId);
ArrayList<Integer> messagesMediaIdsMap = dialogMessagesMediaIdsMap.get(dialogId);
SparseIntArray mediaTypesChange = null;
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid, type FROM media_v3 WHERE mid IN(%s) AND uid = %d", messageMediaIds.toString(), dialogId));
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid, type FROM media_v4 WHERE mid IN(%s) AND uid = %d", messageMediaIds.toString(), dialogId));
while (cursor.next()) {
int mid = cursor.intValue(0);
int type = cursor.intValue(1);
@ -9120,7 +9178,7 @@ public class MessagesStorage extends BaseController {
if (MediaDataController.canAddMessageToMedia(message)) {
if (state_media == null) {
state_media = database.executeFast("REPLACE INTO media_v3 VALUES(?, ?, ?, ?, ?)");
state_media = database.executeFast("REPLACE INTO media_v4 VALUES(?, ?, ?, ?, ?)");
}
state_media.requery();
state_media.bindInteger(1, messageId);
@ -9561,14 +9619,14 @@ public class MessagesStorage extends BaseController {
}
try {
state = database.executeFast("UPDATE media_v3 SET mid = ? WHERE mid = ? AND uid = ?");
state = database.executeFast("UPDATE media_v4 SET mid = ? WHERE mid = ? AND uid = ?");
state.bindInteger(1, newId);
state.bindInteger(2, oldMessageId);
state.bindLong(3, did);
state.step();
} catch (Exception e) {
try {
database.executeFast(String.format(Locale.US, "DELETE FROM media_v3 WHERE mid = %d AND uid = %d", oldMessageId, did)).stepThis().dispose();
database.executeFast(String.format(Locale.US, "DELETE FROM media_v4 WHERE mid = %d AND uid = %d", oldMessageId, did)).stepThis().dispose();
} catch (Exception e2) {
FileLog.e(e2);
}
@ -9947,6 +10005,38 @@ public class MessagesStorage extends BaseController {
FileLog.e(e);
}
cursor.dispose();
getMessagesStorage().getDatabase().beginTransaction();
SQLitePreparedStatement state;
for (int i = 0; i < 2; i++) {
if (i == 0) {
if (dialogId != 0) {
state = getMessagesStorage().getDatabase().executeFast("UPDATE messages_v2 SET replydata = ? WHERE reply_to_message_id IN(?) AND uid = ?");
} else {
state = getMessagesStorage().getDatabase().executeFast("UPDATE messages_v2 SET replydata = ? WHERE reply_to_message_id IN(?) AND is_channel = 0");
}
} else {
if (dialogId != 0) {
state = getMessagesStorage().getDatabase().executeFast("UPDATE scheduled_messages_v2 SET replydata = ? WHERE reply_to_message_id IN(?) AND uid = ?");
} else {
state = getMessagesStorage().getDatabase().executeFast("UPDATE scheduled_messages_v2 SET replydata = ? WHERE reply_to_message_id IN(?)");
}
}
TLRPC.TL_messageEmpty emptyMessage = new TLRPC.TL_messageEmpty();
NativeByteBuffer data = new NativeByteBuffer(emptyMessage.getObjectSize());
emptyMessage.serializeToStream(data);
state.requery();
state.bindByteBuffer(1, data);
state.bindString(2, ids);
if (dialogId != 0) {
state.bindLong(3, dialogId);
}
state.step();
state.dispose();
getMessagesStorage().getDatabase().commitTransaction();
}
deleteFromDownloadQueue(idsToDelete, true);
AndroidUtilities.runOnUIThread(() -> getFileLoader().cancelLoadFiles(namesToDelete));
getFileLoader().deleteFiles(filesToDelete, 0);
@ -9965,7 +10055,7 @@ public class MessagesStorage extends BaseController {
cursor.dispose();
dialogsIds.add(did);
SQLitePreparedStatement state = database.executeFast("UPDATE dialogs SET unread_count = ?, unread_count_i = ? WHERE did = ?");
state = database.executeFast("UPDATE dialogs SET unread_count = ?, unread_count_i = ? WHERE did = ?");
state.requery();
state.bindInteger(1, Math.max(0, old_unread_count - counts[0]));
state.bindInteger(2, Math.max(0, old_mentions_count - counts[1]));
@ -9996,7 +10086,7 @@ public class MessagesStorage extends BaseController {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT count FROM chat_pinned_count WHERE uid = %d", did));
if (cursor.next()) {
int count = cursor.intValue(0);
SQLitePreparedStatement state = database.executeFast("UPDATE chat_pinned_count SET count = ? WHERE uid = ?");
state = database.executeFast("UPDATE chat_pinned_count SET count = ? WHERE uid = ?");
state.requery();
state.bindInteger(1, Math.max(0, count - updatedCount));
state.bindLong(2, did);
@ -10009,7 +10099,7 @@ public class MessagesStorage extends BaseController {
database.executeFast(String.format(Locale.US, "DELETE FROM polls_v2 WHERE mid IN(%s) AND uid = %d", ids, did)).stepThis().dispose();
database.executeFast(String.format(Locale.US, "DELETE FROM bot_keyboard WHERE mid IN(%s) AND uid = %d", ids, did)).stepThis().dispose();
if (temp.isEmpty()) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT uid, type FROM media_v3 WHERE mid IN(%s) AND uid = %d", ids, did));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT uid, type FROM media_v4 WHERE mid IN(%s) AND uid = %d", ids, did));
SparseArray<LongSparseArray<Integer>> mediaCounts = null;
while (cursor.next()) {
long uid = cursor.longValue(0);
@ -10034,7 +10124,7 @@ public class MessagesStorage extends BaseController {
}
cursor.dispose();
if (mediaCounts != null) {
SQLitePreparedStatement state = database.executeFast("REPLACE INTO media_counts_v2 VALUES(?, ?, ?, ?)");
state = database.executeFast("REPLACE INTO media_counts_v2 VALUES(?, ?, ?, ?)");
for (int c = 0, N3 = mediaCounts.size(); c < N3; c++) {
int type = mediaCounts.keyAt(c);
LongSparseArray<Integer> value = mediaCounts.valueAt(c);
@ -10062,7 +10152,7 @@ public class MessagesStorage extends BaseController {
state.dispose();
}
}
database.executeFast(String.format(Locale.US, "DELETE FROM media_v3 WHERE mid IN(%s) AND uid = %d", ids, did)).stepThis().dispose();
database.executeFast(String.format(Locale.US, "DELETE FROM media_v4 WHERE mid IN(%s) AND uid = %d", ids, did)).stepThis().dispose();
}
database.executeFast(String.format(Locale.US, "DELETE FROM messages_seq WHERE mid IN(%s)", ids)).stepThis().dispose();
if (!temp.isEmpty()) {
@ -10346,7 +10436,7 @@ public class MessagesStorage extends BaseController {
}
database.executeFast(String.format(Locale.US, "DELETE FROM messages_v2 WHERE uid = %d AND mid <= %d", -channelId, mid)).stepThis().dispose();
database.executeFast(String.format(Locale.US, "DELETE FROM media_v3 WHERE uid = %d AND mid <= %d", -channelId, mid)).stepThis().dispose();
database.executeFast(String.format(Locale.US, "DELETE FROM media_v4 WHERE uid = %d AND mid <= %d", -channelId, mid)).stepThis().dispose();
database.executeFast(String.format(Locale.US, "UPDATE media_counts_v2 SET old = 1 WHERE uid = %d", -channelId)).stepThis().dispose();
updateWidgets(dialogsIds);
return dialogsIds;
@ -10600,8 +10690,8 @@ public class MessagesStorage extends BaseController {
database.beginTransaction();
SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages_v2 VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?)");
SQLitePreparedStatement state2 = database.executeFast("REPLACE INTO media_v3 VALUES(?, ?, ?, ?, ?)");
SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages_v2 VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, 0)");
SQLitePreparedStatement state2 = database.executeFast("REPLACE INTO media_v4 VALUES(?, ?, ?, ?, ?)");
if (message.dialog_id == 0) {
MessageObject.getDialogId(message);
}
@ -10693,7 +10783,7 @@ public class MessagesStorage extends BaseController {
try {
if (scheduled) {
database.executeFast(String.format(Locale.US, "DELETE FROM scheduled_messages_v2 WHERE uid = %d AND mid > 0", dialogId)).stepThis().dispose();
SQLitePreparedStatement state_messages = database.executeFast("REPLACE INTO scheduled_messages_v2 VALUES(?, ?, ?, ?, ?, ?, NULL)");
SQLitePreparedStatement state_messages = database.executeFast("REPLACE INTO scheduled_messages_v2 VALUES(?, ?, ?, ?, ?, ?, NULL, 0)");
int count = messages.messages.size();
for (int a = 0; a < count; a++) {
TLRPC.Message message = messages.messages.get(a);
@ -10758,8 +10848,8 @@ public class MessagesStorage extends BaseController {
ArrayList<String> namesToDelete = new ArrayList<>();
ArrayList<Pair<Long, Integer>> idsToDelete = new ArrayList<>();
SQLitePreparedStatement state_messages = database.executeFast("REPLACE INTO messages_v2 VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?)");
SQLitePreparedStatement state_media = database.executeFast("REPLACE INTO media_v3 VALUES(?, ?, ?, ?, ?)");
SQLitePreparedStatement state_messages = database.executeFast("REPLACE INTO messages_v2 VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, 0)");
SQLitePreparedStatement state_media = database.executeFast("REPLACE INTO media_v4 VALUES(?, ?, ?, ?, ?)");
SQLitePreparedStatement state_polls = null;
SQLitePreparedStatement state_webpage = null;
SQLitePreparedStatement state_tasks = null;
@ -10923,7 +11013,7 @@ public class MessagesStorage extends BaseController {
state_media.step();
} else if (message instanceof TLRPC.TL_messageService && message.action instanceof TLRPC.TL_messageActionHistoryClear) {
try {
database.executeFast(String.format(Locale.US, "DELETE FROM media_v3 WHERE mid = %d AND uid = %d", message.id, dialogId)).stepThis().dispose();
database.executeFast(String.format(Locale.US, "DELETE FROM media_v4 WHERE mid = %d AND uid = %d", message.id, dialogId)).stepThis().dispose();
database.executeFast("DELETE FROM media_counts_v2 WHERE uid = " + dialogId).stepThis().dispose();
} catch (Exception e2) {
FileLog.e(e2);
@ -11413,9 +11503,9 @@ public class MessagesStorage extends BaseController {
}
if (!dialogs.dialogs.isEmpty()) {
SQLitePreparedStatement state_messages = database.executeFast("REPLACE INTO messages_v2 VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?)");
SQLitePreparedStatement state_messages = database.executeFast("REPLACE INTO messages_v2 VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, 0)");
SQLitePreparedStatement state_dialogs = database.executeFast("REPLACE INTO dialogs VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
SQLitePreparedStatement state_media = database.executeFast("REPLACE INTO media_v3 VALUES(?, ?, ?, ?, ?)");
SQLitePreparedStatement state_media = database.executeFast("REPLACE INTO media_v4 VALUES(?, ?, ?, ?, ?)");
SQLitePreparedStatement state_settings = database.executeFast("REPLACE INTO dialog_settings VALUES(?, ?)");
SQLitePreparedStatement state_holes = database.executeFast("REPLACE INTO messages_holes VALUES(?, ?, ?)");
SQLitePreparedStatement state_media_holes = database.executeFast("REPLACE INTO media_holes_v2 VALUES(?, ?, ?, ?)");

View File

@ -158,7 +158,7 @@ public class MusicBrowserService extends MediaBrowserService implements Notifica
try {
ArrayList<Long> usersToLoad = new ArrayList<>();
ArrayList<Long> chatsToLoad = new ArrayList<>();
SQLiteCursor cursor = messagesStorage.getDatabase().queryFinalized(String.format(Locale.US, "SELECT DISTINCT uid FROM media_v3 WHERE uid != 0 AND mid > 0 AND type = %d", MediaDataController.MEDIA_MUSIC));
SQLiteCursor cursor = messagesStorage.getDatabase().queryFinalized(String.format(Locale.US, "SELECT DISTINCT uid FROM media_v4 WHERE uid != 0 AND mid > 0 AND type = %d", MediaDataController.MEDIA_MUSIC));
while (cursor.next()) {
long dialogId = cursor.longValue(0);
if (DialogObject.isEncryptedDialog(dialogId)) {
@ -174,7 +174,7 @@ public class MusicBrowserService extends MediaBrowserService implements Notifica
cursor.dispose();
if (!dialogs.isEmpty()) {
String ids = TextUtils.join(",", dialogs);
cursor = messagesStorage.getDatabase().queryFinalized(String.format(Locale.US, "SELECT uid, data, mid FROM media_v3 WHERE uid IN (%s) AND mid > 0 AND type = %d ORDER BY date DESC, mid DESC", ids, MediaDataController.MEDIA_MUSIC));
cursor = messagesStorage.getDatabase().queryFinalized(String.format(Locale.US, "SELECT uid, data, mid FROM media_v4 WHERE uid IN (%s) AND mid > 0 AND type = %d ORDER BY date DESC, mid DESC", ids, MediaDataController.MEDIA_MUSIC));
while (cursor.next()) {
NativeByteBuffer data = cursor.byteBufferValue(1);
if (data != null) {

View File

@ -223,6 +223,7 @@ public class NotificationCenter {
public static final int appUpdateAvailable = totalEvents++;
public static final int onDatabaseMigration = totalEvents++;
public static final int onEmojiInteractionsReceived = totalEvents++;
public static final int emojiPreviewThemesChanged = totalEvents++;
private SparseArray<ArrayList<NotificationCenterDelegate>> observers = new SparseArray<>();
private SparseArray<ArrayList<NotificationCenterDelegate>> removeAfterBroadcast = new SparseArray<>();

View File

@ -1760,6 +1760,8 @@ public class NotificationsController extends BaseController {
: LocaleController.formatString("ChangedChatThemeTo", R.string.ChatThemeChangedTo, name, emoticon);
}
return msg;
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatJoinedByRequest) {
return messageObject.messageText.toString();
}
} else {
if (messageObject.isMediaEmpty()) {
@ -2334,6 +2336,8 @@ public class NotificationsController extends BaseController {
? LocaleController.formatString("ChangedChatThemeYou", R.string.ChatThemeChangedYou, emoticon)
: LocaleController.formatString("ChangedChatThemeTo", R.string.ChatThemeChangedTo, name, emoticon);
}
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatJoinedByRequest) {
msg = messageObject.messageText.toString();
}
} else if (ChatObject.isChannel(chat) && !chat.megagroup) {
if (messageObject.isMediaEmpty()) {
@ -4125,8 +4129,9 @@ public class NotificationsController extends BaseController {
}
}
boolean needAddPerson = !(lastMessageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatJoinedByRequest);
NotificationCompat.MessagingStyle messagingStyle;
if (selfPerson != null) {
if (selfPerson != null && needAddPerson) {
messagingStyle = new NotificationCompat.MessagingStyle(selfPerson);
} else {
messagingStyle = new NotificationCompat.MessagingStyle("");

View File

@ -1614,7 +1614,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
AndroidUtilities.runOnUIThread(() -> {
if (bitmapFinal[0] != null && keyFinal[0] != null) {
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(bitmapFinal[0]), keyFinal[0]);
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(bitmapFinal[0]), keyFinal[0], false);
}
sendMessage((TLRPC.TL_document) finalDocument, null, null, peer, replyToMsg, replyToTopMsg, null, null, null, null, notify, scheduleDate, 0, parentObject, sendAnimationData);
});
@ -6717,7 +6717,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
AndroidUtilities.runOnUIThread(() -> {
if (finalDocument != null) {
if (precahcedThumb[0] != null && precachedKey[0] != null) {
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(precahcedThumb[0]), precachedKey[0]);
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(precahcedThumb[0]), precachedKey[0], false);
}
accountInstance.getSendMessagesHelper().sendMessage(finalDocument, null, finalPathFinal, dialogId, replyToMsg, replyToTopMsg, result.send_message.message, result.send_message.entities, result.send_message.reply_markup, params, notify, scheduleDate, 0, result, null);
} else if (finalPhoto != null) {
@ -7395,7 +7395,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
AndroidUtilities.runOnUIThread(() -> {
if (thumbFinal != null && thumbKeyFinal != null) {
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(thumbFinal), thumbKeyFinal);
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(thumbFinal), thumbKeyFinal, false);
}
if (editingMessageObject != null) {
accountInstance.getSendMessagesHelper().editMessage(editingMessageObject, null, videoEditedInfo, videoFinal, finalPath, params, false, parentFinal);
@ -7592,7 +7592,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
AndroidUtilities.runOnUIThread(() -> {
if (bitmapFinal[0] != null && keyFinal[0] != null) {
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(bitmapFinal[0]), keyFinal[0]);
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(bitmapFinal[0]), keyFinal[0], false);
}
if (editingMessageObject != null) {
accountInstance.getSendMessagesHelper().editMessage(editingMessageObject, photoFinal, null, null, null, params, false, parentFinal);
@ -8035,7 +8035,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
AndroidUtilities.runOnUIThread(() -> {
if (thumbFinal != null && thumbKeyFinal != null) {
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(thumbFinal), thumbKeyFinal);
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(thumbFinal), thumbKeyFinal, false);
}
if (editingMessageObject != null) {
accountInstance.getSendMessagesHelper().editMessage(editingMessageObject, null, videoEditedInfo, videoFinal, finalPath, params, false, parentFinal);

View File

@ -23,6 +23,7 @@ import android.util.SparseArray;
import org.json.JSONObject;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.SerializedData;
import org.telegram.ui.Components.SharedMediaLayout;
import org.telegram.ui.Components.SwipeGestureSettingsView;
import org.telegram.tgnet.TLRPC;
@ -133,6 +134,8 @@ public class SharedConfig {
private static int chatSwipeAction;
public static int distanceSystemType;
public static int mediaColumnsCount = 3;
public static int fastScrollHintCount = 3;
static {
loadConfig();
@ -370,6 +373,9 @@ public class SharedConfig {
messageSeenHintCount = preferences.getInt("messageSeenCount", 3);
emojiInteractionsHintCount = preferences.getInt("emojiInteractionsHintCount", 3);
dayNightThemeSwitchHintCount = preferences.getInt("dayNightThemeSwitchHintCount", 3);
mediaColumnsCount = preferences.getInt("mediaColumnsCount", 3);
fastScrollHintCount = preferences.getInt("fastScrollHintCount", 3);
preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
showNotificationsForAllAccounts = preferences.getBoolean("AllAccounts", true);
@ -1141,4 +1147,18 @@ public class SharedConfig {
return devicePerformanceClass;
}
public static void setMediaColumnsCount(int count) {
if (mediaColumnsCount != count) {
mediaColumnsCount = count;
ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).edit().putInt("mediaColumnsCount", mediaColumnsCount).apply();
}
}
public static void setFastScrollHintCount(int count) {
if (fastScrollHintCount != count) {
fastScrollHintCount = count;
ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).edit().putInt("fastScrollHintCount", fastScrollHintCount).apply();
}
}
}

View File

@ -33,6 +33,7 @@ public class Utilities {
public static volatile DispatchQueue cacheClearQueue = new DispatchQueue("cacheClearQueue");
public static volatile DispatchQueue searchQueue = new DispatchQueue("searchQueue");
public static volatile DispatchQueue phoneBookQueue = new DispatchQueue("phoneBookQueue");
public static volatile DispatchQueue themeQueue = new DispatchQueue("themeQueue");
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();

View File

@ -430,7 +430,7 @@ public class CameraController implements MediaRecorder.OnInfoListener {
outputStream.getFD().sync();
outputStream.close();
if (scaled != null) {
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(scaled), key);
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(scaled), key, false);
}
if (callback != null) {
callback.run();
@ -446,7 +446,7 @@ public class CameraController implements MediaRecorder.OnInfoListener {
outputStream.getFD().sync();
outputStream.close();
if (bitmap != null) {
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(bitmap), key);
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(bitmap), key, false);
}
} catch (Exception e) {
FileLog.e(e);
@ -726,7 +726,7 @@ public class CameraController implements MediaRecorder.OnInfoListener {
if (onVideoTakeCallback != null) {
String path = cacheFile.getAbsolutePath();
if (bitmapFinal != null) {
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(bitmapFinal), Utilities.MD5(path));
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(bitmapFinal), Utilities.MD5(path), false);
}
onVideoTakeCallback.onFinishVideoRecording(path, durationFinal);
onVideoTakeCallback = null;

File diff suppressed because it is too large Load Diff

View File

@ -50,6 +50,7 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils;
import org.telegram.messenger.AndroidUtilities;
@ -165,6 +166,7 @@ public class ActionBarMenuItem extends FrameLayout {
private int notificationIndex = -1;
private float transitionOffset;
private View showSubMenuFrom;
private final Theme.ResourcesProvider resourcesProvider;
public ActionBarMenuItem(Context context, ActionBarMenu menu, int backgroundColor, int iconColor) {
@ -584,7 +586,7 @@ public class ActionBarMenuItem extends FrameLayout {
yOffset = offset;
}
public void toggleSubMenu() {
public void toggleSubMenu(View topView, View fromView) {
if (popupLayout == null || parentMenu != null && parentMenu.isActionMode && parentMenu.parentActionBar != null && !parentMenu.parentActionBar.isActionModeShowed()) {
return;
}
@ -596,48 +598,76 @@ public class ActionBarMenuItem extends FrameLayout {
popupWindow.dismiss();
return;
}
showSubMenuFrom = fromView;
if (subMenuDelegate != null) {
subMenuDelegate.onShowSubMenu();
}
if (popupWindow == null) {
popupWindow = new ActionBarPopupWindow(popupLayout, LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT);
if (animationEnabled && Build.VERSION.SDK_INT >= 19) {
popupWindow.setAnimationStyle(0);
} else {
popupWindow.setAnimationStyle(R.style.PopupAnimation);
}
if (!animationEnabled) {
popupWindow.setAnimationEnabled(animationEnabled);
}
popupWindow.setOutsideTouchable(true);
popupWindow.setClippingEnabled(true);
if (layoutInScreen) {
popupWindow.setLayoutInScreen(true);
}
popupWindow.setInputMethodMode(ActionBarPopupWindow.INPUT_METHOD_NOT_NEEDED);
popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED);
popupWindow.getContentView().setFocusableInTouchMode(true);
popupWindow.getContentView().setOnKeyListener((v, keyCode, event) -> {
if (keyCode == KeyEvent.KEYCODE_MENU && event.getRepeatCount() == 0 && event.getAction() == KeyEvent.ACTION_UP && popupWindow != null && popupWindow.isShowing()) {
popupWindow.dismiss();
return true;
}
return false;
});
popupWindow.setOnDismissListener(() -> {
onDismiss();
if (subMenuDelegate != null) {
subMenuDelegate.onHideSubMenu();
}
});
if (popupLayout.getParent() != null) {
((ViewGroup) popupLayout.getParent()).removeView(popupLayout);
}
if (measurePopup) {
popupLayout.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.x - AndroidUtilities.dp(40), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.y, MeasureSpec.AT_MOST));
ViewGroup container = popupLayout;
if (topView != null) {
LinearLayout linearLayout = new LinearLayout(getContext()) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
popupLayout.measure(widthMeasureSpec, heightMeasureSpec);
topView.getLayoutParams().width = popupLayout.getMeasuredWidth() - AndroidUtilities.dp(16);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
};
linearLayout.setOrientation(LinearLayout.VERTICAL);
FrameLayout frameLayout = new FrameLayout(getContext());
frameLayout.setAlpha(0f);
frameLayout.animate().alpha(1f).setDuration(100).start();
Drawable drawable = ContextCompat.getDrawable(getContext(), R.drawable.popup_fixed_alert2).mutate();
drawable.setColorFilter(new PorterDuffColorFilter(popupLayout.getBackgroundColor(), PorterDuff.Mode.MULTIPLY));
frameLayout.setBackground(drawable);
frameLayout.addView(topView);
linearLayout.addView(frameLayout, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
linearLayout.addView(popupLayout, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, 0, 0, -AndroidUtilities.dp(4), 0, 0));
container = linearLayout;
}
popupWindow = new ActionBarPopupWindow(container, LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT);
if (animationEnabled && Build.VERSION.SDK_INT >= 19) {
popupWindow.setAnimationStyle(0);
} else {
popupWindow.setAnimationStyle(R.style.PopupAnimation);
}
if (!animationEnabled) {
popupWindow.setAnimationEnabled(animationEnabled);
}
popupWindow.setOutsideTouchable(true);
popupWindow.setClippingEnabled(true);
if (layoutInScreen) {
popupWindow.setLayoutInScreen(true);
}
popupWindow.setInputMethodMode(ActionBarPopupWindow.INPUT_METHOD_NOT_NEEDED);
popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED);
container.setFocusableInTouchMode(true);
container.setOnKeyListener((v, keyCode, event) -> {
if (keyCode == KeyEvent.KEYCODE_MENU && event.getRepeatCount() == 0 && event.getAction() == KeyEvent.ACTION_UP && popupWindow != null && popupWindow.isShowing()) {
popupWindow.dismiss();
return true;
}
return false;
});
popupWindow.setOnDismissListener(() -> {
onDismiss();
if (subMenuDelegate != null) {
subMenuDelegate.onHideSubMenu();
}
});
// if (measurePopup) {
container.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.x - AndroidUtilities.dp(40), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.y, MeasureSpec.AT_MOST));
measurePopup = false;
}
//}
processedPopupClick = false;
popupWindow.setFocusable(true);
if (popupLayout.getMeasuredWidth() == 0) {
if (container.getMeasuredWidth() == 0) {
updateOrShowPopup(true, true);
} else {
updateOrShowPopup(true, false);
@ -645,6 +675,9 @@ public class ActionBarMenuItem extends FrameLayout {
popupLayout.updateRadialSelectors();
popupWindow.startAnimation();
}
public void toggleSubMenu() {
toggleSubMenu(null, null);
}
public void openSearch(boolean openKeyboard) {
if (searchContainer == null || searchContainer.getVisibility() == VISIBLE || parentMenu == null) {
@ -728,6 +761,8 @@ public class ActionBarMenuItem extends FrameLayout {
if (openKeyboard) {
AndroidUtilities.hideKeyboard(searchField);
}
parentMenu.requestLayout();
requestLayout();
return false;
} else {
searchContainer.setVisibility(VISIBLE);
@ -1496,15 +1531,15 @@ public class ActionBarMenuItem extends FrameLayout {
if (show) {
popupLayout.scrollToTop();
}
View fromView = showSubMenuFrom == null ? this : showSubMenuFrom;
if (parentMenu != null) {
View parent = parentMenu.parentActionBar;
if (subMenuOpenSide == 0) {
if (show) {
popupWindow.showAsDropDown(parent, getLeft() + parentMenu.getLeft() + getMeasuredWidth() - popupLayout.getMeasuredWidth() + (int) getTranslationX(), offsetY);
popupWindow.showAsDropDown(parent, fromView.getLeft() + parentMenu.getLeft() + fromView.getMeasuredWidth() - popupWindow.getContentView().getMeasuredWidth() + (int) getTranslationX(), offsetY);
}
if (update) {
popupWindow.update(parent, getLeft() + parentMenu.getLeft() + getMeasuredWidth() - popupLayout.getMeasuredWidth() + (int) getTranslationX(), offsetY, -1, -1);
popupWindow.update(parent, fromView.getLeft() + parentMenu.getLeft() + fromView.getMeasuredWidth() - popupWindow.getContentView().getMeasuredWidth() + (int) getTranslationX(), offsetY, -1, -1);
}
} else {
if (show) {
@ -1523,10 +1558,10 @@ public class ActionBarMenuItem extends FrameLayout {
if (getParent() != null) {
View parent = (View) getParent();
if (show) {
popupWindow.showAsDropDown(parent, getLeft() + getMeasuredWidth() - popupLayout.getMeasuredWidth() + additionalXOffset, offsetY);
popupWindow.showAsDropDown(parent, getLeft() + getMeasuredWidth() - popupWindow.getContentView().getMeasuredWidth() + additionalXOffset, offsetY);
}
if (update) {
popupWindow.update(parent, getLeft() + getMeasuredWidth() - popupLayout.getMeasuredWidth() + additionalXOffset, offsetY, -1, -1);
popupWindow.update(parent, getLeft() + getMeasuredWidth() - popupWindow.getContentView().getMeasuredWidth() + additionalXOffset, offsetY, -1, -1);
}
}
} else if (subMenuOpenSide == 1) {
@ -1538,10 +1573,10 @@ public class ActionBarMenuItem extends FrameLayout {
}
} else {
if (show) {
popupWindow.showAsDropDown(this, getMeasuredWidth() - popupLayout.getMeasuredWidth() + additionalXOffset, offsetY);
popupWindow.showAsDropDown(this, getMeasuredWidth() - popupWindow.getContentView().getMeasuredWidth() + additionalXOffset, offsetY);
}
if (update) {
popupWindow.update(this, getMeasuredWidth() - popupLayout.getMeasuredWidth() + additionalXOffset, offsetY, -1, -1);
popupWindow.update(this, getMeasuredWidth() - popupWindow.getContentView().getMeasuredWidth() + additionalXOffset, offsetY, -1, -1);
}
}
}

View File

@ -234,4 +234,8 @@ public class ActionBarMenuSubItem extends FrameLayout {
Integer color = resourcesProvider != null ? resourcesProvider.getColor(key) : null;
return color != null ? color : Theme.getColor(key);
}
public CheckBox2 getCheckView() {
return checkView;
}
}

View File

@ -278,7 +278,7 @@ public class ActionBarPopupWindow extends PopupWindow {
if (animationEnabled) {
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(
ObjectAnimator.ofFloat(child, View.ALPHA, 0.0f, 1.0f),
ObjectAnimator.ofFloat(child, View.ALPHA, 0f, child.isEnabled() ? 1f : 0.5f),
ObjectAnimator.ofFloat(child, View.TRANSLATION_Y, AndroidUtilities.dp(shownFromBotton ? 6 : -6), 0));
animatorSet.setDuration(180);
animatorSet.addListener(new AnimatorListenerAdapter() {
@ -547,7 +547,18 @@ public class ActionBarPopupWindow extends PopupWindow {
if (windowAnimatorSet != null) {
return;
}
ActionBarPopupWindowLayout content = (ActionBarPopupWindowLayout) getContentView();
ViewGroup viewGroup = (ViewGroup) getContentView();
ActionBarPopupWindowLayout content = null;
if (viewGroup instanceof ActionBarPopupWindowLayout) {
content = (ActionBarPopupWindowLayout) viewGroup;
} else {
for (int i = 0; i < viewGroup.getChildCount(); i++) {
if (viewGroup.getChildAt(i) instanceof ActionBarPopupWindowLayout) {
content = (ActionBarPopupWindowLayout) viewGroup.getChildAt(i);
}
}
}
content.setTranslationY(0);
content.setAlpha(1.0f);
content.setPivotX(content.getMeasuredWidth());
@ -578,11 +589,21 @@ public class ActionBarPopupWindow extends PopupWindow {
@Override
public void onAnimationEnd(Animator animation) {
windowAnimatorSet = null;
ActionBarPopupWindowLayout content = (ActionBarPopupWindowLayout) getContentView();
ViewGroup viewGroup = (ViewGroup) getContentView();
ActionBarPopupWindowLayout content = null;
if (viewGroup instanceof ActionBarPopupWindowLayout) {
content = (ActionBarPopupWindowLayout) viewGroup;
} else {
for (int i = 0; i < viewGroup.getChildCount(); i++) {
if (viewGroup.getChildAt(i) instanceof ActionBarPopupWindowLayout) {
content = (ActionBarPopupWindowLayout) viewGroup.getChildAt(i);
}
}
}
int count = content.getItemsCount();
for (int a = 0; a < count; a++) {
View child = content.getItemAt(a);
child.setAlpha(1.0f);
child.setAlpha(child.isEnabled() ? 1f : 0.5f);
}
}
});

View File

@ -713,5 +713,4 @@ public abstract class BaseFragment {
public Theme.ResourcesProvider getResourceProvider() {
return null;
}
}

View File

@ -1111,6 +1111,10 @@ public class BottomSheet extends Dialog {
onHideListener = listener;
}
protected int getTargetOpenTranslationY() {
return 0;
}
private void startOpenAnimation() {
if (dismissed) {
return;

View File

@ -1,300 +0,0 @@
package org.telegram.ui.ActionBar;
import android.app.Activity;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.util.Pair;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.ChatThemeController;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLoader;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.ResultCallback;
import org.telegram.tgnet.TLRPC;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class ChatTheme {
public final boolean isDefault;
private final TLRPC.TL_chatTheme chatThemeObject;
private HashMap<String, Integer> lightCurrentColors;
private HashMap<String, Integer> darkCurrentColors;
private String darkWallpaperLink;
private String lightWallpaperLink;
public ChatTheme(TLRPC.TL_chatTheme chatThemeObject, boolean isDefault) {
this.chatThemeObject = chatThemeObject;
this.isDefault = isDefault;
}
public void initColors() {
getCurrentColors(0, false);
getCurrentColors(0, true);
}
public String getEmoticon() {
return chatThemeObject.emoticon;
}
public TLRPC.TL_theme getTlTheme(boolean isDark) {
return isDark ? ((TLRPC.TL_theme) chatThemeObject.dark_theme) : ((TLRPC.TL_theme) chatThemeObject.theme);
}
public TLRPC.WallPaper getWallpaper(boolean isDark) {
return getTlTheme(isDark).settings.wallpaper;
}
public String getWallpaperLink(boolean isDark) {
return isDark ? darkWallpaperLink : lightWallpaperLink;
}
public HashMap<String, Integer> getCurrentColors(int currentAccount, boolean isDark) {
HashMap<String, Integer> currentColors = isDark ? darkCurrentColors : lightCurrentColors;
if (currentColors != null) {
return currentColors;
}
TLRPC.TL_theme tlTheme = getTlTheme(isDark);
Theme.ThemeInfo baseTheme = Theme.getTheme(Theme.getBaseThemeKey(tlTheme.settings));
Theme.ThemeInfo themeInfo = new Theme.ThemeInfo(baseTheme);
Theme.ThemeAccent accent = themeInfo.createNewAccent(tlTheme, currentAccount, true);
themeInfo.setCurrentAccentId(accent.id);
HashMap<String, Integer> currentColorsNoAccent = new HashMap<>();
String[] wallpaperLink = new String[1];
if (themeInfo.pathToFile != null) {
currentColorsNoAccent.putAll(Theme.getThemeFileValues(new File(themeInfo.pathToFile), null, wallpaperLink));
} else if (themeInfo.assetName != null) {
currentColorsNoAccent.putAll(Theme.getThemeFileValues(null, themeInfo.assetName, wallpaperLink));
}
if (isDark) {
darkWallpaperLink = wallpaperLink[0];
} else {
lightWallpaperLink = wallpaperLink[0];
}
currentColors = new HashMap<>(currentColorsNoAccent);
accent.fillAccentColors(currentColorsNoAccent, currentColors);
if (!isDark) {
currentColors.put(Theme.key_chat_messageTextOut, Theme.MSG_OUT_COLOR_BLACK);
}
HashMap<String, String> fallbackKeys = Theme.getFallbackKeys();
for (Map.Entry<String, String> fallbackEntry : fallbackKeys.entrySet()) {
String colorKey = fallbackEntry.getKey();
if (!currentColors.containsKey(colorKey)) {
Integer color = currentColors.get(fallbackEntry.getValue());
currentColors.put(colorKey, color);
}
}
HashMap<String, Integer> defaultColors = Theme.getDefaultColors();
for (Map.Entry<String, Integer> entry : defaultColors.entrySet()) {
if (!currentColors.containsKey(entry.getKey())) {
currentColors.put(entry.getKey(), entry.getValue());
}
}
if (isDark) {
darkCurrentColors = currentColors;
} else {
lightCurrentColors = currentColors;
}
return currentColors;
}
public void loadWallpaper(boolean isDark, ResultCallback<Pair<Long, Bitmap>> callback) {
final TLRPC.WallPaper wallPaper = getWallpaper(isDark);
if (wallPaper == null && callback != null) {
callback.onComplete(null);
return;
}
long themeId = getTlTheme(isDark).id;
Bitmap cachedBitmap = ChatThemeController.getWallpaperBitmap(themeId);
if (cachedBitmap != null && callback != null) {
callback.onComplete(new Pair<>(themeId, cachedBitmap));
return;
}
ImageLocation imageLocation = ImageLocation.getForDocument(wallPaper.document);
ImageReceiver imageReceiver = new ImageReceiver();
String imageFilter;
if (SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_LOW) {
int w = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y);
int h = Math.max(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y);
imageFilter = (int) (w / AndroidUtilities.density) + "_" + (int) (h / AndroidUtilities.density) + "_f";
} else {
imageFilter = (int) (1080 / AndroidUtilities.density) + "_" + (int) (1920 / AndroidUtilities.density) + "_f";
}
imageReceiver.setImage(imageLocation, imageFilter, null, ".jpg", wallPaper, 1);
imageReceiver.setDelegate((receiver, set, thumb, memCache) -> {
ImageReceiver.BitmapHolder holder = receiver.getBitmapSafe();
if (!set || holder == null) {
return;
}
Bitmap bitmap = holder.bitmap;
if (bitmap == null && (holder.drawable instanceof BitmapDrawable)) {
bitmap = ((BitmapDrawable) holder.drawable).getBitmap();
}
if (callback != null) {
callback.onComplete(new Pair<>(themeId, bitmap));
}
});
ImageLoader.getInstance().loadImageForImageReceiver(imageReceiver);
}
public void loadWallpaperThumb(boolean isDark, ResultCallback<Pair<Long, Bitmap>> callback) {
final TLRPC.WallPaper wallpaper = getWallpaper(isDark);
if (wallpaper == null) {
if (callback != null) {
callback.onComplete(null);
}
return;
}
long themeId = getTlTheme(isDark).id;
Bitmap bitmap = ChatThemeController.getWallpaperThumbBitmap(themeId);
File file = getWallpaperThumbFile(themeId);
if (bitmap == null && file.exists() && file.length() > 0) {
try {
bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
} catch (Exception e) {
FileLog.e(e);
}
}
if (bitmap != null) {
if (callback != null) {
callback.onComplete(new Pair<>(themeId, bitmap));
}
return;
}
final TLRPC.PhotoSize thumbSize = FileLoader.getClosestPhotoSizeWithSize(wallpaper.document.thumbs, 120);
ImageLocation imageLocation = ImageLocation.getForDocument(thumbSize, wallpaper.document);
ImageReceiver imageReceiver = new ImageReceiver();
imageReceiver.setImage(imageLocation, "120_80", null, null, null, 1);
imageReceiver.setDelegate((receiver, set, thumb, memCache) -> {
ImageReceiver.BitmapHolder holder = receiver.getBitmapSafe();
if (!set || holder == null) {
return;
}
Bitmap resultBitmap = holder.bitmap;
if (resultBitmap == null && (holder.drawable instanceof BitmapDrawable)) {
resultBitmap = ((BitmapDrawable) holder.drawable).getBitmap();
}
if (resultBitmap != null) {
if (callback != null) {
callback.onComplete(new Pair<>(themeId, resultBitmap));
}
final Bitmap saveBitmap = resultBitmap;
Utilities.globalQueue.postRunnable(() -> {
try (FileOutputStream outputStream = new FileOutputStream(file)) {
saveBitmap.compress(Bitmap.CompressFormat.PNG, 87, outputStream);
} catch (Exception e) {
FileLog.e(e);
}
});
} else {
if (callback != null) {
callback.onComplete(null);
}
}
});
ImageLoader.getInstance().loadImageForImageReceiver(imageReceiver);
}
public void preloadWallpaper() {
loadWallpaperThumb(false, null);
loadWallpaperThumb(true, null);
loadWallpaper(false, null);
loadWallpaper(true, null);
}
private File getWallpaperThumbFile(long themeId) {
return new File(ApplicationLoader.getFilesDirFixed(), "wallpaper_thumb_" + themeId + ".png");
}
public static Theme.ThemeInfo getDefaultThemeInfo(boolean isDark) {
Theme.ThemeInfo themeInfo = isDark ? Theme.getCurrentNightTheme() : Theme.getCurrentTheme();
if (isDark != themeInfo.isDark()) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("themeconfig", Activity.MODE_PRIVATE);
String lastThemeName = isDark
? preferences.getString("lastNightTheme", "Dark Blue")
: preferences.getString("lastDayTheme", "Blue");
themeInfo = Theme.getTheme(lastThemeName);
if (themeInfo == null) {
themeInfo = Theme.getTheme(isDark ? "Dark Blue" : "Blue");
}
}
return new Theme.ThemeInfo(themeInfo);
}
public static ChatTheme getDefault() {
Theme.ThemeInfo darkThemeInfo = getDefaultThemeInfo(true);
fillTlTheme(darkThemeInfo);
Theme.ThemeInfo lightThemeInfo = getDefaultThemeInfo(false);
fillTlTheme(lightThemeInfo);
TLRPC.TL_chatTheme tlChatTheme = new TLRPC.TL_chatTheme();
tlChatTheme.emoticon = "";
tlChatTheme.dark_theme = darkThemeInfo.info;
tlChatTheme.theme = lightThemeInfo.info;
ChatTheme chatTheme = new ChatTheme(tlChatTheme, true);
chatTheme.darkCurrentColors = getCurrentColors(darkThemeInfo);
chatTheme.lightCurrentColors = getCurrentColors(lightThemeInfo);
return chatTheme;
}
private static void fillTlTheme(Theme.ThemeInfo themeInfo) {
if (themeInfo.info == null) {
themeInfo.info = new TLRPC.TL_theme();
}
if (themeInfo.info.settings == null) {
themeInfo.info.settings = new TLRPC.TL_themeSettings();
}
ArrayList<Integer> messageColors = new ArrayList<>();
Theme.ThemeAccent accent = themeInfo.getAccent(false);
if (accent != null) {
if (accent.myMessagesAccentColor != 0) {
messageColors.add(accent.myMessagesAccentColor);
}
if (accent.myMessagesGradientAccentColor1 != 0) {
messageColors.add(accent.myMessagesGradientAccentColor1);
}
if (accent.myMessagesGradientAccentColor2 != 0) {
messageColors.add(accent.myMessagesGradientAccentColor2);
}
if (accent.myMessagesGradientAccentColor3 != 0) {
messageColors.add(accent.myMessagesGradientAccentColor3);
}
}
themeInfo.info.settings.message_colors = messageColors;
}
private static HashMap<String, Integer> getCurrentColors(Theme.ThemeInfo themeInfo) {
HashMap<String, Integer> currentColorsNoAccent = new HashMap<>();
if (themeInfo.pathToFile != null) {
currentColorsNoAccent.putAll(Theme.getThemeFileValues(new File(themeInfo.pathToFile), null, null));
} else if (themeInfo.assetName != null) {
currentColorsNoAccent.putAll(Theme.getThemeFileValues(null, themeInfo.assetName, null));
}
HashMap<String, Integer> currentColors = new HashMap<>(currentColorsNoAccent);
Theme.ThemeAccent themeAccent = themeInfo.getAccent(false);
if (themeAccent != null) {
themeAccent.fillAccentColors(currentColorsNoAccent, currentColors);
}
return currentColors;
}
}

View File

@ -25,10 +25,6 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Build;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.view.DisplayCutout;
import android.view.Gravity;
import android.view.MotionEvent;
@ -40,6 +36,10 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.FileLog;
@ -91,6 +91,8 @@ public class DrawerLayoutContainer extends FrameLayout {
private PreviewForegroundDrawable previewForegroundDrawable;
private boolean drawCurrentPreviewFragmentAbove;
private float startY;
private boolean keyboardVisibility;
private int imeHeight;
public DrawerLayoutContainer(Context context) {
super(context);
@ -102,6 +104,15 @@ public class DrawerLayoutContainer extends FrameLayout {
if (Build.VERSION.SDK_INT >= 21) {
setFitsSystemWindows(true);
setOnApplyWindowInsetsListener((v, insets) -> {
if (Build.VERSION.SDK_INT >= 30) {
boolean newKeyboardVisibility = insets.isVisible(WindowInsets.Type.ime());
int imeHeight = insets.getInsets(WindowInsets.Type.ime()).bottom;
if (keyboardVisibility != newKeyboardVisibility || this.imeHeight != imeHeight) {
keyboardVisibility = newKeyboardVisibility;
this.imeHeight = imeHeight;
requestLayout();
}
}
final DrawerLayoutContainer drawerLayoutContainer = (DrawerLayoutContainer) v;
if (AndroidUtilities.statusBarHeight != insets.getSystemWindowInsetTop()) {
drawerLayoutContainer.requestLayout();

View File

@ -0,0 +1,510 @@
package org.telegram.ui.ActionBar;
import android.app.Activity;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.util.Pair;
import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.ChatThemeController;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLoader;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.ResultCallback;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.ChatThemeBottomSheet;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class EmojiThemes {
public boolean showAsDefaultStub;
String emoji;
int currentIndex = 0;
ArrayList<ThemeItem> items = new ArrayList<>();
private EmojiThemes() {
}
public EmojiThemes(TLRPC.TL_theme chatThemeObject, boolean isDefault) {
this.showAsDefaultStub = isDefault;
this.emoji = chatThemeObject.emoticon;
if (!isDefault) {
ThemeItem lightTheme = new ThemeItem();
lightTheme.tlTheme = chatThemeObject;
lightTheme.settingsIndex = 0;
items.add(lightTheme);
ThemeItem darkTheme = new ThemeItem();
darkTheme.tlTheme = chatThemeObject;
darkTheme.settingsIndex = 1;
items.add(darkTheme);
}
}
public static EmojiThemes createPreviewFullTheme(TLRPC.TL_theme tl_theme) {
EmojiThemes chatTheme = new EmojiThemes();
chatTheme.emoji = tl_theme.emoticon;
for (int i = 0; i < tl_theme.settings.size(); i++) {
ThemeItem theme = new ThemeItem();
theme.tlTheme = tl_theme;
theme.settingsIndex = i;
chatTheme.items.add(theme);
}
return chatTheme;
}
public static EmojiThemes createChatThemesDefault() {
EmojiThemes themeItem = new EmojiThemes();
themeItem.emoji = "";
themeItem.showAsDefaultStub = true;
ThemeItem lightTheme = new ThemeItem();
lightTheme.themeInfo = getDefaultThemeInfo(true);
themeItem.items.add(lightTheme);
ThemeItem darkTheme = new ThemeItem();
darkTheme.themeInfo = getDefaultThemeInfo(false);
themeItem.items.add(darkTheme);
return themeItem;
}
public static EmojiThemes createPreviewCustom() {
EmojiThemes themeItem = new EmojiThemes();
themeItem.emoji = "\uD83C\uDFA8";
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("themeconfig", Activity.MODE_PRIVATE);
String lastDayCustomTheme = preferences.getString("lastDayCustomTheme", null);
int dayAccentId = preferences.getInt("lastDayCustomThemeAccentId", -1);
if (lastDayCustomTheme == null || Theme.getTheme(lastDayCustomTheme) == null) {
lastDayCustomTheme = preferences.getString("lastDayTheme", "Blue");
Theme.ThemeInfo themeInfo = Theme.getTheme(lastDayCustomTheme);
if (themeInfo == null) {
lastDayCustomTheme = "Blue";
}
preferences.edit().putString("lastDayCustomTheme", lastDayCustomTheme).apply();
}
String lastDarkCustomTheme = preferences.getString("lastDarkCustomTheme", null);
int darkAccentId = preferences.getInt("lastDarkCustomThemeAccentId", -1);
if (lastDarkCustomTheme == null || Theme.getTheme(lastDarkCustomTheme) == null) {
lastDarkCustomTheme = preferences.getString("lastDarkTheme", "Dark Blue");
Theme.ThemeInfo themeInfo = Theme.getTheme(lastDarkCustomTheme);
if (themeInfo == null) {
lastDarkCustomTheme = "Dark Blue";
}
preferences.edit().putString("lastDarkCustomTheme", lastDarkCustomTheme).apply();
}
ThemeItem lightTheme = new ThemeItem();
lightTheme.themeInfo = Theme.getTheme(lastDayCustomTheme);
lightTheme.accentId = dayAccentId;
themeItem.items.add(lightTheme);
themeItem.items.add(null);
ThemeItem darkTheme = new ThemeItem();
darkTheme.themeInfo = Theme.getTheme(lastDarkCustomTheme);
darkTheme.accentId = darkAccentId;
themeItem.items.add(darkTheme);
themeItem.items.add(null);
return themeItem;
}
public static EmojiThemes createHomePreviewTheme() {
EmojiThemes themeItem = new EmojiThemes();
themeItem.emoji = "\uD83C\uDFE0";
ThemeItem blue = new ThemeItem();
blue.themeInfo = Theme.getTheme("Blue");
blue.accentId = 99;
themeItem.items.add(blue);
ThemeItem day = new ThemeItem();
day.themeInfo = Theme.getTheme("Day");
day.accentId = 9;
themeItem.items.add(day);
ThemeItem night = new ThemeItem();
night.themeInfo = Theme.getTheme("Night");
night.accentId = 0;
themeItem.items.add(night);
ThemeItem nightBlue = new ThemeItem();
nightBlue.themeInfo = Theme.getTheme("Dark Blue");
nightBlue.accentId = 0;
themeItem.items.add(nightBlue);
return themeItem;
}
public void initColors() {
getCurrentColors(0, 0);
getCurrentColors(0, 1);
}
public String getEmoticon() {
return emoji;
}
public TLRPC.TL_theme getTlTheme(int index) {
return items.get(index).tlTheme;
}
public TLRPC.WallPaper getWallpaper(int index) {
int settingsIndex = items.get(index).settingsIndex;
if (settingsIndex >= 0) {
return getTlTheme(index).settings.get(settingsIndex).wallpaper;
}
return null;
}
public String getWallpaperLink(int index) {
return items.get(index).wallpaperLink;
}
public int getSettingsIndex(int index) {
return items.get(index).settingsIndex;
}
public HashMap<String, Integer> getCurrentColors(int currentAccount, int index) {
HashMap<String, Integer> currentColors = items.get(index).currentColors;
if (currentColors != null) {
return currentColors;
}
Theme.ThemeInfo themeInfo = getThemeInfo(index);
Theme.ThemeAccent accent = null;
if (themeInfo == null) {
int settingsIndex = getSettingsIndex(index);
TLRPC.TL_theme tlTheme = getTlTheme(index);
Theme.ThemeInfo baseTheme = Theme.getTheme(Theme.getBaseThemeKey(tlTheme.settings.get(settingsIndex)));
themeInfo = new Theme.ThemeInfo(baseTheme);
accent = themeInfo.createNewAccent(tlTheme, currentAccount, true, settingsIndex);
themeInfo.setCurrentAccentId(accent.id);
} else {
if (themeInfo.themeAccentsMap != null) {
accent = themeInfo.themeAccentsMap.get(items.get(index).accentId);
}
}
HashMap<String, Integer> currentColorsNoAccent = new HashMap<>();
String[] wallpaperLink = new String[1];
if (themeInfo.pathToFile != null) {
currentColorsNoAccent.putAll(Theme.getThemeFileValues(new File(themeInfo.pathToFile), null, wallpaperLink));
} else if (themeInfo.assetName != null) {
currentColorsNoAccent.putAll(Theme.getThemeFileValues(null, themeInfo.assetName, wallpaperLink));
}
items.get(index).wallpaperLink = wallpaperLink[0];
currentColors = new HashMap<>(currentColorsNoAccent);
if (accent != null) {
accent.fillAccentColors(currentColorsNoAccent, currentColors);
}
HashMap<String, String> fallbackKeys = Theme.getFallbackKeys();
for (Map.Entry<String, String> fallbackEntry : fallbackKeys.entrySet()) {
String colorKey = fallbackEntry.getKey();
if (!currentColors.containsKey(colorKey)) {
Integer color = currentColors.get(fallbackEntry.getValue());
currentColors.put(colorKey, color);
}
}
HashMap<String, Integer> defaultColors = Theme.getDefaultColors();
for (Map.Entry<String, Integer> entry : defaultColors.entrySet()) {
if (!currentColors.containsKey(entry.getKey())) {
currentColors.put(entry.getKey(), entry.getValue());
}
}
items.get(index).currentColors = currentColors;
return currentColors;
}
public Theme.ThemeInfo getThemeInfo(int index) {
return items.get(index).themeInfo;
}
public void loadWallpaper(int index, ResultCallback<Pair<Long, Bitmap>> callback) {
final TLRPC.WallPaper wallPaper = getWallpaper(index);
if (wallPaper == null) {
if (callback != null) {
callback.onComplete(null);
}
return;
}
long themeId = getTlTheme(index).id;
ChatThemeController.getWallpaperBitmap(themeId, cachedBitmap -> {
if (cachedBitmap != null && callback != null) {
callback.onComplete(new Pair<>(themeId, cachedBitmap));
return;
}
ImageLocation imageLocation = ImageLocation.getForDocument(wallPaper.document);
ImageReceiver imageReceiver = new ImageReceiver();
String imageFilter;
if (SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_LOW) {
int w = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y);
int h = Math.max(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y);
imageFilter = (int) (w / AndroidUtilities.density) + "_" + (int) (h / AndroidUtilities.density) + "_f";
} else {
imageFilter = (int) (1080 / AndroidUtilities.density) + "_" + (int) (1920 / AndroidUtilities.density) + "_f";
}
imageReceiver.setImage(imageLocation, imageFilter, null, ".jpg", wallPaper, 1);
imageReceiver.setDelegate((receiver, set, thumb, memCache) -> {
ImageReceiver.BitmapHolder holder = receiver.getBitmapSafe();
if (!set || holder == null) {
return;
}
Bitmap bitmap = holder.bitmap;
if (bitmap == null && (holder.drawable instanceof BitmapDrawable)) {
bitmap = ((BitmapDrawable) holder.drawable).getBitmap();
}
if (callback != null) {
callback.onComplete(new Pair<>(themeId, bitmap));
}
ChatThemeController.saveWallpaperBitmap(bitmap, themeId);
});
ImageLoader.getInstance().loadImageForImageReceiver(imageReceiver);
});
}
public void loadWallpaperThumb(int index, ResultCallback<Pair<Long, Bitmap>> callback) {
final TLRPC.WallPaper wallpaper = getWallpaper(index);
if (wallpaper == null) {
if (callback != null) {
callback.onComplete(null);
}
return;
}
long themeId = getTlTheme(index).id;
Bitmap bitmap = ChatThemeController.getWallpaperThumbBitmap(themeId);
File file = getWallpaperThumbFile(themeId);
if (bitmap == null && file.exists() && file.length() > 0) {
try {
bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
} catch (Exception e) {
FileLog.e(e);
}
}
if (bitmap != null) {
if (callback != null) {
callback.onComplete(new Pair<>(themeId, bitmap));
}
return;
}
final TLRPC.PhotoSize thumbSize = FileLoader.getClosestPhotoSizeWithSize(wallpaper.document.thumbs, 120);
ImageLocation imageLocation = ImageLocation.getForDocument(thumbSize, wallpaper.document);
ImageReceiver imageReceiver = new ImageReceiver();
imageReceiver.setImage(imageLocation, "120_80", null, null, null, 1);
imageReceiver.setDelegate((receiver, set, thumb, memCache) -> {
ImageReceiver.BitmapHolder holder = receiver.getBitmapSafe();
if (!set || holder == null) {
return;
}
Bitmap resultBitmap = holder.bitmap;
if (resultBitmap == null && (holder.drawable instanceof BitmapDrawable)) {
resultBitmap = ((BitmapDrawable) holder.drawable).getBitmap();
}
if (resultBitmap != null) {
if (callback != null) {
callback.onComplete(new Pair<>(themeId, resultBitmap));
}
final Bitmap saveBitmap = resultBitmap;
Utilities.globalQueue.postRunnable(() -> {
try (FileOutputStream outputStream = new FileOutputStream(file)) {
saveBitmap.compress(Bitmap.CompressFormat.PNG, 87, outputStream);
} catch (Exception e) {
FileLog.e(e);
}
});
} else {
if (callback != null) {
callback.onComplete(null);
}
}
});
ImageLoader.getInstance().loadImageForImageReceiver(imageReceiver);
}
public void preloadWallpaper() {
loadWallpaperThumb(0, null);
loadWallpaperThumb(1, null);
loadWallpaper(0, null);
loadWallpaper(1, null);
}
private File getWallpaperThumbFile(long themeId) {
return new File(ApplicationLoader.getFilesDirFixed(), "wallpaper_thumb_" + themeId + ".png");
}
public static Theme.ThemeInfo getDefaultThemeInfo(boolean isDark) {
Theme.ThemeInfo themeInfo = isDark ? Theme.getCurrentNightTheme() : Theme.getCurrentTheme();
if (isDark != themeInfo.isDark()) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("themeconfig", Activity.MODE_PRIVATE);
String lastThemeName = isDark
? preferences.getString("lastDarkTheme", "Dark Blue")
: preferences.getString("lastDayTheme", "Blue");
themeInfo = Theme.getTheme(lastThemeName);
if (themeInfo == null) {
themeInfo = Theme.getTheme(isDark ? "Dark Blue" : "Blue");
}
}
return new Theme.ThemeInfo(themeInfo);
}
public static void fillTlTheme(Theme.ThemeInfo themeInfo) {
if (themeInfo.info == null) {
themeInfo.info = new TLRPC.TL_theme();
}
}
public static HashMap<String, Integer> getCurrentColors(Theme.ThemeInfo themeInfo) {
HashMap<String, Integer> currentColorsNoAccent = new HashMap<>();
if (themeInfo.pathToFile != null) {
currentColorsNoAccent.putAll(Theme.getThemeFileValues(new File(themeInfo.pathToFile), null, null));
} else if (themeInfo.assetName != null) {
currentColorsNoAccent.putAll(Theme.getThemeFileValues(null, themeInfo.assetName, null));
}
HashMap<String, Integer> currentColors = new HashMap<>(currentColorsNoAccent);
Theme.ThemeAccent themeAccent = themeInfo.getAccent(false);
if (themeAccent != null) {
themeAccent.fillAccentColors(currentColorsNoAccent, currentColors);
}
return currentColors;
}
public int getAccentId(int themeIndex) {
return items.get(themeIndex).accentId;
}
public void loadPreviewColors(int currentAccount) {
for (int i = 0; i < items.size(); i++) {
if (items.get(i) == null) {
continue;
}
HashMap<String, Integer> colorsMap = getCurrentColors(currentAccount, i);
Integer color = colorsMap.get(Theme.key_chat_inBubble);
if (color == null) {
color = Theme.getDefaultColor(Theme.key_chat_inBubble);
}
items.get(i).inBubbleColor = color;
color = colorsMap.get(Theme.key_chat_outBubble);
if (color == null) {
color = Theme.getDefaultColor(Theme.key_chat_outBubble);
}
items.get(i).outBubbleColor = color;
color = colorsMap.get(Theme.key_featuredStickers_addButton);
if (color == null) {
color = Theme.getDefaultColor(Theme.key_featuredStickers_addButton);
}
items.get(i).outLineColor = color;
color = colorsMap.get(Theme.key_chat_wallpaper);
if (color == null) {
items.get(i).patternBgColor = 0;
} else {
items.get(i).patternBgColor = color;
}
color = colorsMap.get(Theme.key_chat_wallpaper_gradient_to1);
if (color == null) {
items.get(i).patternBgGradientColor1 = 0;
} else {
items.get(i).patternBgGradientColor1 = color;
}
color = colorsMap.get(Theme.key_chat_wallpaper_gradient_to2);
if (color == null) {
items.get(i).patternBgGradientColor2 = 0;
} else {
items.get(i).patternBgGradientColor2 = color;
}
color = colorsMap.get(Theme.key_chat_wallpaper_gradient_to3);
if (color == null) {
items.get(i).patternBgGradientColor3 = 0;
} else {
items.get(i).patternBgGradientColor3 = color;
}
if (items.get(i).themeInfo != null && items.get(i).themeInfo.getKey().equals("Blue")) {
int accentId = items.get(i).accentId >= 0 ? items.get(i).accentId : items.get(i).themeInfo.currentAccentId;
if (accentId == 99) {
items.get(i).patternBgColor = 0xffdbddbb;
items.get(i).patternBgGradientColor1 = 0xff6ba587;
items.get(i).patternBgGradientColor2 = 0xffd5d88d;
items.get(i).patternBgGradientColor3 = 0xff88b884;
}
}
}
}
public ThemeItem getThemeItem(int index) {
return items.get(index);
}
public static void saveCustomTheme(Theme.ThemeInfo themeInfo, int accentId) {
if (themeInfo == null) {
return;
}
if (accentId >= 0 && themeInfo.themeAccentsMap != null) {
Theme.ThemeAccent accent = themeInfo.themeAccentsMap.get(accentId);
if (accent == null || accent.isDefault) {
return;
}
}
if (themeInfo.getKey().equals("Blue") && accentId == 99) {
return;
}
if (themeInfo.getKey().equals("Day") && accentId == 9) {
return;
}
if (themeInfo.getKey().equals("Night") && accentId == 0) {
return;
}
if (themeInfo.getKey().equals("Dark Blue") && accentId == 0) {
return;
}
boolean dark = themeInfo.isDark();
String key = dark ? "lastDarkCustomTheme" : "lastDayCustomTheme";
String accentKey = dark ? "lastDarkCustomThemeAccentId" : "lastDayCustomThemeAccentId";
ApplicationLoader.applicationContext.getSharedPreferences("themeconfig", Activity.MODE_PRIVATE).edit()
.putString(key, themeInfo.getKey())
.putInt(accentKey, accentId)
.apply();
}
public static class ThemeItem {
public Theme.ThemeInfo themeInfo;
TLRPC.TL_theme tlTheme;
int settingsIndex;
public int accentId = -1;
public HashMap<String, Integer> currentColors;
private String wallpaperLink;
public int inBubbleColor;
public int outBubbleColor;
public int outLineColor;
public int patternBgColor;
public int patternBgGradientColor1;
public int patternBgGradientColor2;
public int patternBgGradientColor3;
}
}

View File

@ -66,6 +66,8 @@ import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.Bitmaps;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ChatThemeController;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLocation;
@ -85,6 +87,7 @@ import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Cells.ThemesHorizontalListCell;
import org.telegram.ui.Components.AudioVisualizerDrawable;
import org.telegram.ui.Components.BackgroundGradientDrawable;
import org.telegram.ui.Components.ChatThemeBottomSheet;
import org.telegram.ui.Components.ChoosingStickerStatusDrawable;
import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.FragmentContextViewWavesDrawable;
@ -105,7 +108,6 @@ import org.telegram.ui.RoundVideoProgressShadow;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
@ -118,6 +120,7 @@ import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
@ -127,8 +130,6 @@ import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.core.graphics.ColorUtils;
import com.google.android.exoplayer2.util.Log;
public class Theme {
public static final String DEFAULT_BACKGROUND_SLUG = "d";
@ -205,6 +206,8 @@ public class Theme {
private Bitmap crosfadeFromBitmap;
private Shader crosfadeFromBitmapShader;
PathDrawParams pathDrawCacheParams;
public MessageDrawable(int type, boolean out, boolean selected) {
this(type, out, selected, null);
}
@ -619,6 +622,17 @@ public class Theme {
return buffer;
}
public void drawCached(Canvas canvas, PathDrawParams patchDrawCacheParams) {
this.pathDrawCacheParams = patchDrawCacheParams;
if (crossfadeFromDrawable != null) {
crossfadeFromDrawable.pathDrawCacheParams = patchDrawCacheParams;
}
draw(canvas);
this.pathDrawCacheParams = null;
if (crossfadeFromDrawable != null) {
crossfadeFromDrawable.pathDrawCacheParams = null;
}
}
@Override
public void draw(Canvas canvas) {
if (crossfadeFromDrawable != null) {
@ -663,119 +677,138 @@ public class Theme {
}
int top = Math.max(bounds.top, 0);
path.reset();
if (isOut) {
if (drawFullBubble || currentType == TYPE_PREVIEW || paintToUse != null || topY + bounds.bottom - rad < currentBackgroundHeight) {
if (currentType == TYPE_MEDIA) {
path.moveTo(bounds.right - dp(8) - rad, bounds.bottom - padding);
} else {
path.moveTo(bounds.right - dp(2.6f), bounds.bottom - padding);
}
path.lineTo(bounds.left + padding + rad, bounds.bottom - padding);
rect.set(bounds.left + padding, bounds.bottom - padding - rad * 2, bounds.left + padding + rad * 2, bounds.bottom - padding);
path.arcTo(rect, 90, 90, false);
} else {
path.moveTo(bounds.right - dp(8), top - topY + currentBackgroundHeight);
path.lineTo(bounds.left + padding, top - topY + currentBackgroundHeight);
}
if (drawFullBubble || currentType == TYPE_PREVIEW || paintToUse != null || topY + rad * 2 >= 0) {
path.lineTo(bounds.left + padding, bounds.top + padding + rad);
rect.set(bounds.left + padding, bounds.top + padding, bounds.left + padding + rad * 2, bounds.top + padding + rad * 2);
path.arcTo(rect, 180, 90, false);
int radToUse = isTopNear ? nearRad : rad;
if (currentType == TYPE_MEDIA) {
path.lineTo(bounds.right - padding - radToUse, bounds.top + padding);
rect.set(bounds.right - padding - radToUse * 2, bounds.top + padding, bounds.right - padding, bounds.top + padding + radToUse * 2);
} else {
path.lineTo(bounds.right - dp(8) - radToUse, bounds.top + padding);
rect.set(bounds.right - dp(8) - radToUse * 2, bounds.top + padding, bounds.right - dp(8), bounds.top + padding + radToUse * 2);
}
path.arcTo(rect, 270, 90, false);
} else {
path.lineTo(bounds.left + padding, top - topY - dp(2));
if (currentType == TYPE_MEDIA) {
path.lineTo(bounds.right - padding, top - topY - dp(2));
} else {
path.lineTo(bounds.right - dp(8), top - topY - dp(2));
}
}
if (currentType == TYPE_MEDIA) {
if (paintToUse != null || topY + bounds.bottom - rad < currentBackgroundHeight) {
int radToUse = isBottomNear ? nearRad : rad;
path.lineTo(bounds.right - padding, bounds.bottom - padding - radToUse);
rect.set(bounds.right - padding - radToUse * 2, bounds.bottom - padding - radToUse * 2, bounds.right - padding, bounds.bottom - padding);
path.arcTo(rect, 0, 90, false);
} else {
path.lineTo(bounds.right - padding, top - topY + currentBackgroundHeight);
}
} else {
if (drawFullBubble || currentType == TYPE_PREVIEW || paintToUse != null || topY + bounds.bottom - smallRad * 2 < currentBackgroundHeight) {
path.lineTo(bounds.right - dp(8), bounds.bottom - padding - smallRad - dp(3));
rect.set(bounds.right - dp(8), bounds.bottom - padding - smallRad * 2 - dp(9), bounds.right - dp(7) + smallRad * 2, bounds.bottom - padding - dp(1));
path.arcTo(rect, 180, -83, false);
} else {
path.lineTo(bounds.right - dp(8), top - topY + currentBackgroundHeight);
}
}
boolean drawFullBottom, drawFullTop;
if (pathDrawCacheParams != null && bounds.height() < currentBackgroundHeight) {
drawFullBottom = true;
drawFullTop = true;
} else {
if (drawFullBubble || currentType == TYPE_PREVIEW || paintToUse != null || topY + bounds.bottom - rad < currentBackgroundHeight) {
if (currentType == TYPE_MEDIA) {
path.moveTo(bounds.left + dp(8) + rad, bounds.bottom - padding);
} else {
path.moveTo(bounds.left + dp(2.6f), bounds.bottom - padding);
}
path.lineTo(bounds.right - padding - rad, bounds.bottom - padding);
rect.set(bounds.right - padding - rad * 2, bounds.bottom - padding - rad * 2, bounds.right - padding, bounds.bottom - padding);
path.arcTo(rect, 90, -90, false);
} else {
path.moveTo(bounds.left + dp(8), top - topY + currentBackgroundHeight);
path.lineTo(bounds.right - padding, top - topY + currentBackgroundHeight);
}
if (drawFullBubble || currentType == TYPE_PREVIEW || paintToUse != null || topY + rad * 2 >= 0) {
path.lineTo(bounds.right - padding, bounds.top + padding + rad);
rect.set(bounds.right - padding - rad * 2, bounds.top + padding, bounds.right - padding, bounds.top + padding + rad * 2);
path.arcTo(rect, 0, -90, false);
int radToUse = isTopNear ? nearRad : rad;
if (currentType == TYPE_MEDIA) {
path.lineTo(bounds.left + padding + radToUse, bounds.top + padding);
rect.set(bounds.left + padding, bounds.top + padding, bounds.left + padding + radToUse * 2, bounds.top + padding + radToUse * 2);
} else {
path.lineTo(bounds.left + dp(8) + radToUse, bounds.top + padding);
rect.set(bounds.left + dp(8), bounds.top + padding, bounds.left + dp(8) + radToUse * 2, bounds.top + padding + radToUse * 2);
}
path.arcTo(rect, 270, -90, false);
} else {
path.lineTo(bounds.right - padding, top - topY - dp(2));
if (currentType == TYPE_MEDIA) {
path.lineTo(bounds.left + padding, top - topY - dp(2));
} else {
path.lineTo(bounds.left + dp(8), top - topY - dp(2));
}
}
if (currentType == TYPE_MEDIA) {
if (paintToUse != null || topY + bounds.bottom - rad < currentBackgroundHeight) {
int radToUse = isBottomNear ? nearRad : rad;
path.lineTo(bounds.left + padding, bounds.bottom - padding - radToUse);
rect.set(bounds.left + padding, bounds.bottom - padding - radToUse * 2, bounds.left + padding + radToUse * 2, bounds.bottom - padding);
path.arcTo(rect, 180, -90, false);
drawFullBottom = currentType == TYPE_MEDIA ? topY + bounds.bottom - smallRad * 2 < currentBackgroundHeight : topY + bounds.bottom - rad < currentBackgroundHeight;
drawFullTop = topY + rad * 2 >= 0;
}
Path path;
boolean invalidatePath;
if (pathDrawCacheParams != null) {
path = pathDrawCacheParams.path;
invalidatePath = pathDrawCacheParams.invalidatePath(bounds, drawFullBottom, drawFullTop);
} else {
path = this.path;
invalidatePath = true;
}
if (invalidatePath) {
path.reset();
if (isOut) {
if (drawFullBubble || currentType == TYPE_PREVIEW || paintToUse != null || drawFullBottom) {
if (currentType == TYPE_MEDIA) {
path.moveTo(bounds.right - dp(8) - rad, bounds.bottom - padding);
} else {
path.moveTo(bounds.right - dp(2.6f), bounds.bottom - padding);
}
path.lineTo(bounds.left + padding + rad, bounds.bottom - padding);
rect.set(bounds.left + padding, bounds.bottom - padding - rad * 2, bounds.left + padding + rad * 2, bounds.bottom - padding);
path.arcTo(rect, 90, 90, false);
} else {
path.moveTo(bounds.right - dp(8), top - topY + currentBackgroundHeight);
path.lineTo(bounds.left + padding, top - topY + currentBackgroundHeight);
}
} else {
if (drawFullBubble || currentType == TYPE_PREVIEW || paintToUse != null || topY + bounds.bottom - smallRad * 2 < currentBackgroundHeight) {
path.lineTo(bounds.left + dp(8), bounds.bottom - padding - smallRad - dp(3));
rect.set(bounds.left + dp(7) - smallRad * 2, bounds.bottom - padding - smallRad * 2 - dp(9), bounds.left + dp(8), bounds.bottom - padding - dp(1));
path.arcTo(rect, 0, 83, false);
if (drawFullBubble || currentType == TYPE_PREVIEW || paintToUse != null || drawFullTop) {
path.lineTo(bounds.left + padding, bounds.top + padding + rad);
rect.set(bounds.left + padding, bounds.top + padding, bounds.left + padding + rad * 2, bounds.top + padding + rad * 2);
path.arcTo(rect, 180, 90, false);
int radToUse = isTopNear ? nearRad : rad;
if (currentType == TYPE_MEDIA) {
path.lineTo(bounds.right - padding - radToUse, bounds.top + padding);
rect.set(bounds.right - padding - radToUse * 2, bounds.top + padding, bounds.right - padding, bounds.top + padding + radToUse * 2);
} else {
path.lineTo(bounds.right - dp(8) - radToUse, bounds.top + padding);
rect.set(bounds.right - dp(8) - radToUse * 2, bounds.top + padding, bounds.right - dp(8), bounds.top + padding + radToUse * 2);
}
path.arcTo(rect, 270, 90, false);
} else {
path.lineTo(bounds.left + dp(8), top - topY + currentBackgroundHeight);
path.lineTo(bounds.left + padding, top - topY - dp(2));
if (currentType == TYPE_MEDIA) {
path.lineTo(bounds.right - padding, top - topY - dp(2));
} else {
path.lineTo(bounds.right - dp(8), top - topY - dp(2));
}
}
if (currentType == TYPE_MEDIA) {
if (paintToUse != null || drawFullBottom) {
int radToUse = isBottomNear ? nearRad : rad;
path.lineTo(bounds.right - padding, bounds.bottom - padding - radToUse);
rect.set(bounds.right - padding - radToUse * 2, bounds.bottom - padding - radToUse * 2, bounds.right - padding, bounds.bottom - padding);
path.arcTo(rect, 0, 90, false);
} else {
path.lineTo(bounds.right - padding, top - topY + currentBackgroundHeight);
}
} else {
if (drawFullBubble || currentType == TYPE_PREVIEW || paintToUse != null || drawFullBottom) {
path.lineTo(bounds.right - dp(8), bounds.bottom - padding - smallRad - dp(3));
rect.set(bounds.right - dp(8), bounds.bottom - padding - smallRad * 2 - dp(9), bounds.right - dp(7) + smallRad * 2, bounds.bottom - padding - dp(1));
path.arcTo(rect, 180, -83, false);
} else {
path.lineTo(bounds.right - dp(8), top - topY + currentBackgroundHeight);
}
}
} else {
if (drawFullBubble || currentType == TYPE_PREVIEW || paintToUse != null || drawFullBottom) {
if (currentType == TYPE_MEDIA) {
path.moveTo(bounds.left + dp(8) + rad, bounds.bottom - padding);
} else {
path.moveTo(bounds.left + dp(2.6f), bounds.bottom - padding);
}
path.lineTo(bounds.right - padding - rad, bounds.bottom - padding);
rect.set(bounds.right - padding - rad * 2, bounds.bottom - padding - rad * 2, bounds.right - padding, bounds.bottom - padding);
path.arcTo(rect, 90, -90, false);
} else {
path.moveTo(bounds.left + dp(8), top - topY + currentBackgroundHeight);
path.lineTo(bounds.right - padding, top - topY + currentBackgroundHeight);
}
if (drawFullBubble || currentType == TYPE_PREVIEW || paintToUse != null || drawFullTop) {
path.lineTo(bounds.right - padding, bounds.top + padding + rad);
rect.set(bounds.right - padding - rad * 2, bounds.top + padding, bounds.right - padding, bounds.top + padding + rad * 2);
path.arcTo(rect, 0, -90, false);
int radToUse = isTopNear ? nearRad : rad;
if (currentType == TYPE_MEDIA) {
path.lineTo(bounds.left + padding + radToUse, bounds.top + padding);
rect.set(bounds.left + padding, bounds.top + padding, bounds.left + padding + radToUse * 2, bounds.top + padding + radToUse * 2);
} else {
path.lineTo(bounds.left + dp(8) + radToUse, bounds.top + padding);
rect.set(bounds.left + dp(8), bounds.top + padding, bounds.left + dp(8) + radToUse * 2, bounds.top + padding + radToUse * 2);
}
path.arcTo(rect, 270, -90, false);
} else {
path.lineTo(bounds.right - padding, top - topY - dp(2));
if (currentType == TYPE_MEDIA) {
path.lineTo(bounds.left + padding, top - topY - dp(2));
} else {
path.lineTo(bounds.left + dp(8), top - topY - dp(2));
}
}
if (currentType == TYPE_MEDIA) {
if (paintToUse != null || drawFullBottom) {
int radToUse = isBottomNear ? nearRad : rad;
path.lineTo(bounds.left + padding, bounds.bottom - padding - radToUse);
rect.set(bounds.left + padding, bounds.bottom - padding - radToUse * 2, bounds.left + padding + radToUse * 2, bounds.bottom - padding);
path.arcTo(rect, 180, -90, false);
} else {
path.lineTo(bounds.left + padding, top - topY + currentBackgroundHeight);
}
} else {
if (drawFullBubble || currentType == TYPE_PREVIEW || paintToUse != null || drawFullBottom) {
path.lineTo(bounds.left + dp(8), bounds.bottom - padding - smallRad - dp(3));
rect.set(bounds.left + dp(7) - smallRad * 2, bounds.bottom - padding - smallRad * 2 - dp(9), bounds.left + dp(8), bounds.bottom - padding - dp(1));
path.arcTo(rect, 0, 83, false);
} else {
path.lineTo(bounds.left + dp(8), top - topY + currentBackgroundHeight);
}
}
}
path.close();
}
path.close();
canvas.drawPath(path, p);
if (gradientShader != null && isSelected && paintToUse == null) {
@ -832,6 +865,21 @@ public class Theme {
crossfadeFromDrawable.setBounds(left, top, right, bottom);
}
}
public static class PathDrawParams {
Path path = new Path();
Rect lastRect = new Rect();
boolean lastDrawFullTop;
boolean lastDrawFullBottom;
public boolean invalidatePath(Rect bounds, boolean drawFullBottom, boolean drawFullTop) {
boolean invalidate = lastRect.isEmpty() || lastRect.top != bounds.top || lastRect.bottom != bounds.bottom || lastRect.right != bounds.right || lastRect.left != bounds.left || lastDrawFullTop != drawFullTop || lastDrawFullBottom != drawFullBottom || !drawFullTop || !drawFullBottom;
lastDrawFullTop = drawFullTop;
lastDrawFullBottom = drawFullBottom;
lastRect.set(bounds);
return invalidate;
}
}
}
public static class PatternsLoader implements NotificationCenter.NotificationCenterDelegate {
@ -1007,7 +1055,7 @@ public class Theme {
}
ThemeInfo themeInfo = accent.parentTheme;
HashMap<String, Integer> values = getThemeFileValues(null, themeInfo.assetName, null);
checkIsDark(values, themeInfo);
int backgroundAccent = accent.accentColor;
int backgroundColor = (int) accent.backgroundOverrideColor;
@ -1167,6 +1215,7 @@ public class Theme {
public TLRPC.InputFile uploadedFile;
public OverrideWallpaperInfo overrideWallpaper;
public boolean isDefault;
ThemeAccent() {
@ -1470,7 +1519,6 @@ public class Theme {
if (id < 100) {
return !TextUtils.isEmpty(patternSlug) ? new File(ApplicationLoader.getFilesDirFixed(), String.format(Locale.US, "%s_%d_%s_v5.jpg", parentTheme.getKey(), id, patternSlug)) : null;
} else {
// return !TextUtils.isEmpty(patternSlug) ? new File(ApplicationLoader.getFilesDirFixed(), String.format(Locale.US, "%s_%d_%s_v4.jpg", parentTheme.getKey(), id, patternSlug)) : null;
return !TextUtils.isEmpty(patternSlug) ? new File(ApplicationLoader.getFilesDirFixed(), String.format(Locale.US, "%s_%d_%s_v8_dubug.jpg", parentTheme.getKey(), id, patternSlug)) : null;
}
}
@ -1743,6 +1791,11 @@ public class Theme {
private String newPathToWallpaper;
public OverrideWallpaperInfo overrideWallpaper;
private int isDark = UNKNOWN;
private final static int DARK= 1;
private final static int LIGHT = 0;
private final static int UNKNOWN = -1;
ThemeInfo() {
@ -2004,7 +2057,20 @@ public class Theme {
}
public boolean isDark() {
return "Dark Blue".equals(name) || "Night".equals(name);
if (isDark != UNKNOWN) {
return isDark == DARK;
}
if ("Dark Blue".equals(name) || "Night".equals(name)) {
isDark = DARK;
} else if ("Blue".equals(name) || "Arctic Blue".equals(name) || "Day".equals(name)) {
isDark = LIGHT;
}
if (isDark == UNKNOWN) {
String[] wallpaperLink = new String[1];
HashMap<String, Integer> colors = getThemeFileValues(new File(pathToFile), null, wallpaperLink);
checkIsDark(colors, this);
}
return isDark == DARK;
}
public boolean isLight() {
@ -2070,6 +2136,7 @@ public class Theme {
themeAccents = new ArrayList<>();
themeAccentsMap = new SparseArray<>();
accentsByThemeId = new LongSparseArray<>();
for (int a = 0; a < accent.length; a++) {
ThemeAccent themeAccent = new ThemeAccent();
themeAccent.id = ids != null ? ids[a] : a;
@ -2147,7 +2214,7 @@ public class Theme {
previewParsed = false;
saveOtherThemes(true);
if (this == currentTheme && previousTheme == null) {
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.needSetDayNightTheme, this, this == currentNightTheme, null, -1);
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.needSetDayNightTheme, this, this == currentNightTheme, null, -1, fallbackKeys);
}
}
@ -2254,20 +2321,24 @@ public class Theme {
}
public ThemeAccent createNewAccent(TLRPC.TL_theme info, int account) {
return createNewAccent(info, account, false);
return createNewAccent(info, account, false, 0);
}
public ThemeAccent createNewAccent(TLRPC.TL_theme info, int account, boolean ignoreThemeInfoId) {
public ThemeAccent createNewAccent(TLRPC.TL_theme info, int account, boolean ignoreThemeInfoId, int settingsIndex) {
if (info == null) {
return null;
}
TLRPC.ThemeSettings settings = null;
if (settingsIndex < info.settings.size()) {
settings = info.settings.get(settingsIndex);
}
if (ignoreThemeInfoId) {
ThemeAccent themeAccent = chatAccentsByThemeId.get(info.id);
if (themeAccent != null) {
return themeAccent;
}
int id = ++lastChatThemeId;
themeAccent = createNewAccent(info.settings);
themeAccent = createNewAccent(settings);
themeAccent.id = id;
themeAccent.info = info;
themeAccent.account = account;
@ -2279,7 +2350,7 @@ public class Theme {
return themeAccent;
}
int id = ++lastAccentId;
themeAccent = createNewAccent(info.settings);
themeAccent = createNewAccent(settings);
themeAccent.id = id;
themeAccent.info = info;
themeAccent.account = account;
@ -2524,6 +2595,7 @@ public class Theme {
private static long[] remoteThemesHash = new long[UserConfig.MAX_ACCOUNT_COUNT];
public static ArrayList<ThemeInfo> themes;
public static final ArrayList<ChatThemeBottomSheet.ChatThemeItem> defaultEmojiThemes = new ArrayList<>();
private static ArrayList<ThemeInfo> otherThemes;
private static HashMap<String, ThemeInfo> themesDict;
private static ThemeInfo currentTheme;
@ -3637,6 +3709,8 @@ public class Theme {
public static final String key_drawable_shareIcon = "drawableShareIcon";
public static final String key_drawable_muteIconDrawable = "drawableMuteIcon";
public static final String key_drawable_lockIconDrawable = "drawableLockIcon";
public static final String key_drawable_chat_pollHintDrawableOut = "drawable_chat_pollHintDrawableOut";
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, String> defaultChatDrawableColorKeys = new HashMap<>();
@ -5002,6 +5076,9 @@ public class Theme {
accent.info = (TLRPC.TL_theme) TLRPC.Theme.TLdeserialize(data, data.readInt32(true), true);
}
}
if (accent.info != null) {
accent.isDefault = accent.info.isDefault;
}
info.themeAccentsMap.put(accent.id, accent);
if (accent.info != null) {
info.accentsByThemeId.put(accent.info.id, accent);
@ -5009,11 +5086,12 @@ public class Theme {
newAccents.add(accent);
info.lastAccentId = Math.max(info.lastAccentId, accent.id);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
} catch (Throwable e) {
FileLog.e(e);
throw new RuntimeException(e);
}
} else {
String key = "accent_for_" + info.assetName;
@ -5120,6 +5198,7 @@ public class Theme {
autoNightLastSunCheckDay = preferences.getInt("autoNightLastSunCheckDay", -1);
} catch (Exception e) {
FileLog.e(e);
throw new RuntimeException(e);
}
if (applyingTheme == null) {
applyingTheme = defaultTheme;
@ -5163,6 +5242,35 @@ public class Theme {
}
applyTheme(applyingTheme, false, false, switchToTheme == 2);
AndroidUtilities.runOnUIThread(Theme::checkAutoNightThemeConditions);
preferences = ApplicationLoader.applicationContext.getSharedPreferences("emojithemes_config", Context.MODE_PRIVATE);
int count = preferences.getInt("count", 0);
ArrayList<ChatThemeBottomSheet.ChatThemeItem> previewItems = new ArrayList<>();
previewItems.add(new ChatThemeBottomSheet.ChatThemeItem(EmojiThemes.createHomePreviewTheme()));
for (int i = 0; i < count; ++i) {
String value = preferences.getString("theme_" + i, "");
SerializedData serializedData = new SerializedData(Utilities.hexToBytes(value));
try {
TLRPC.TL_theme theme = TLRPC.Theme.TLdeserialize(serializedData, serializedData.readInt32(true), true);
previewItems.add(new ChatThemeBottomSheet.ChatThemeItem(EmojiThemes.createPreviewFullTheme(theme)));
ChatThemeController.chatThemeQueue.postRunnable(new Runnable() {
@Override
public void run() {
for (int i = 0; i < previewItems.size(); i++) {
previewItems.get(i).chatTheme.loadPreviewColors(0);
}
AndroidUtilities.runOnUIThread(() -> {
defaultEmojiThemes.clear();
defaultEmojiThemes.addAll(previewItems);
NotificationCenter.getInstance(0).postNotificationName(NotificationCenter.emojiPreviewThemesChanged);
});
}
});
} catch (Throwable e) {
FileLog.e(e);
}
}
}
private static Method StateListDrawable_getStateDrawableMethod;
@ -5890,7 +5998,8 @@ public class Theme {
themeInfo.account = UserConfig.selectedAccount;
String[] wallpaperLink = new String[1];
getThemeFileValues(new File(themeInfo.pathToFile), null, wallpaperLink);
HashMap<String, Integer> colors = getThemeFileValues(new File(themeInfo.pathToFile), null, wallpaperLink);
checkIsDark(colors, themeInfo);
if (!TextUtils.isEmpty(wallpaperLink[0])) {
String link = wallpaperLink[0];
@ -6964,13 +7073,17 @@ public class Theme {
boolean changed = false;
if (response instanceof TLRPC.TL_theme) {
TLRPC.TL_theme theme = (TLRPC.TL_theme) response;
if (accent != null && theme.settings != null) {
if (!ThemeInfo.accentEquals(accent, theme.settings)) {
TLRPC.ThemeSettings settings = null;
if (theme.settings.size() > 0) {
settings = theme.settings.get(0);
}
if (accent != null && settings != null) {
if (!ThemeInfo.accentEquals(accent, settings)) {
File file = accent.getPathToWallpaper();
if (file != null) {
file.delete();
}
ThemeInfo.fillAccentValues(accent, theme.settings);
ThemeInfo.fillAccentValues(accent, settings);
if (currentTheme == themeInfo && currentTheme.currentAccentId == accent.id) {
refreshThemeColors();
createChatResources(ApplicationLoader.applicationContext, false);
@ -6979,7 +7092,7 @@ public class Theme {
PatternsLoader.createLoader(true);
changed = true;
}
accent.patternMotion = theme.settings.wallpaper != null && theme.settings.wallpaper.settings != null && theme.settings.wallpaper.settings.motion;
accent.patternMotion = settings.wallpaper != null && settings.wallpaper.settings != null && settings.wallpaper.settings.motion;
} else if (theme.document != null && theme.document.id != info.document.id) {
if (accent != null) {
accent.info = theme;
@ -6999,7 +7112,7 @@ public class Theme {
}
public static void loadRemoteThemes(final int currentAccount, boolean force) {
if (loadingRemoteThemes[currentAccount] || !force && Math.abs(System.currentTimeMillis() / 1000 - lastLoadingThemesTime[currentAccount]) < 60 * 60 || !UserConfig.getInstance(currentAccount).isClientActivated()) {
if (loadingRemoteThemes[currentAccount]) {
return;
}
loadingRemoteThemes[currentAccount] = true;
@ -7012,6 +7125,7 @@ public class Theme {
TLRPC.TL_account_themes res = (TLRPC.TL_account_themes) response;
remoteThemesHash[currentAccount] = res.hash;
lastLoadingThemesTime[currentAccount] = (int) (System.currentTimeMillis() / 1000);
ArrayList<TLRPC.TL_theme> emojiPreviewThemes = new ArrayList<>();
ArrayList<Object> oldServerThemes = new ArrayList<>();
for (int a = 0, N = themes.size(); a < N; a++) {
ThemeInfo info = themes.get(a);
@ -7034,36 +7148,47 @@ public class Theme {
continue;
}
TLRPC.TL_theme theme = (TLRPC.TL_theme) t;
if (theme.settings != null) {
String key = getBaseThemeKey(theme.settings);
if (key == null) {
continue;
}
ThemeInfo info = themesDict.get(key);
if (info == null || info.themeAccents == null) {
continue;
}
ThemeAccent accent = info.accentsByThemeId.get(theme.id);
if (accent != null) {
if (!ThemeInfo.accentEquals(accent, theme.settings)) {
File file = accent.getPathToWallpaper();
if (file != null) {
file.delete();
if (theme.isDefault) {
//TODO new emoji themes
continue;
//emojiPreviewThemes.add(theme);
}
if (theme.settings != null && theme.settings.size() > 0) {
for (int i = 0; i < theme.settings.size(); i++) {
TLRPC.ThemeSettings settings = theme.settings.get(i);
if (settings != null) {
String key = getBaseThemeKey(settings);
if (key == null) {
continue;
}
ThemeInfo.fillAccentValues(accent, theme.settings);
loadPatterns = true;
added = true;
if (currentTheme == info && currentTheme.currentAccentId == accent.id) {
refreshThemeColors();
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.needSetDayNightTheme, currentTheme, currentNightTheme == currentTheme, null, -1);
ThemeInfo info = themesDict.get(key);
if (info == null || info.themeAccents == null) {
continue;
}
}
accent.patternMotion = theme.settings.wallpaper != null && theme.settings.wallpaper.settings != null && theme.settings.wallpaper.settings.motion;
oldServerThemes.remove(accent);
} else {
accent = info.createNewAccent(theme, currentAccount);
if (!TextUtils.isEmpty(accent.patternSlug)) {
loadPatterns = true;
ThemeAccent accent = info.accentsByThemeId.get(theme.id);
if (accent != null) {
if (!ThemeInfo.accentEquals(accent, settings)) {
File file = accent.getPathToWallpaper();
if (file != null) {
file.delete();
}
ThemeInfo.fillAccentValues(accent, settings);
loadPatterns = true;
added = true;
if (currentTheme == info && currentTheme.currentAccentId == accent.id) {
refreshThemeColors();
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.needSetDayNightTheme, currentTheme, currentNightTheme == currentTheme, null, -1);
}
}
accent.patternMotion = settings.wallpaper != null && settings.wallpaper.settings != null && settings.wallpaper.settings.motion;
oldServerThemes.remove(accent);
} else {
accent = info.createNewAccent(theme, currentAccount);
if (!TextUtils.isEmpty(accent.patternSlug)) {
loadPatterns = true;
}
}
accent.isDefault = theme.isDefault;
}
}
} else {
@ -7123,10 +7248,52 @@ public class Theme {
if (loadPatterns) {
PatternsLoader.createLoader(true);
}
generateEmojiPreviewThemes(emojiPreviewThemes, currentAccount);
}
}));
}
private static void generateEmojiPreviewThemes(final ArrayList<TLRPC.TL_theme> emojiPreviewThemes, int currentAccount) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("emojithemes_config", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("count", emojiPreviewThemes.size());
for (int i = 0; i < emojiPreviewThemes.size(); ++i) {
TLRPC.TL_theme tlChatTheme = emojiPreviewThemes.get(i);
SerializedData data = new SerializedData(tlChatTheme.getObjectSize());
tlChatTheme.serializeToStream(data);
editor.putString("theme_" + i, Utilities.bytesToHex(data.toByteArray()));
EmojiThemes chatTheme = new EmojiThemes(tlChatTheme, false);
}
editor.apply();
if (!emojiPreviewThemes.isEmpty()) {
final ArrayList<ChatThemeBottomSheet.ChatThemeItem> previewItems = new ArrayList<>();
previewItems.add(new ChatThemeBottomSheet.ChatThemeItem(EmojiThemes.createHomePreviewTheme()));
for (int i = 0; i < emojiPreviewThemes.size(); i++) {
TLRPC.TL_theme theme = emojiPreviewThemes.get(i);
EmojiThemes chatTheme = EmojiThemes.createPreviewFullTheme(theme);
ChatThemeBottomSheet.ChatThemeItem item = new ChatThemeBottomSheet.ChatThemeItem(chatTheme);
previewItems.add(item);
}
ChatThemeController.chatThemeQueue.postRunnable(new Runnable() {
@Override
public void run() {
for (int i = 0; i < previewItems.size(); i++) {
previewItems.get(i).chatTheme.loadPreviewColors(currentAccount);
}
AndroidUtilities.runOnUIThread(() -> {
defaultEmojiThemes.clear();
defaultEmojiThemes.addAll(previewItems);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.emojiPreviewThemesChanged);
});
}
});
} else {
defaultEmojiThemes.clear();
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.emojiPreviewThemesChanged);
}
}
public static String getBaseThemeKey(TLRPC.ThemeSettings settings) {
if (settings.base_theme instanceof TLRPC.TL_baseThemeClassic) {
return "Blue";
@ -7178,9 +7345,13 @@ public class Theme {
if (info == null) {
return;
}
if (info.settings != null) {
TLRPC.ThemeSettings settings = null;
if (info.settings.size() > 0) {
settings = info.settings.get(0);
}
if (settings != null) {
if (theme == null) {
String key = getBaseThemeKey(info.settings);
String key = getBaseThemeKey(settings);
if (key == null) {
return;
}
@ -7199,19 +7370,21 @@ public class Theme {
accent.info = info;
accent.account = account;
theme.accentsByThemeId.put(info.id, accent);
if (!ThemeInfo.accentEquals(accent, info.settings)) {
if (!ThemeInfo.accentEquals(accent, settings)) {
File file = accent.getPathToWallpaper();
if (file != null) {
file.delete();
}
ThemeInfo.fillAccentValues(accent, info.settings);
ThemeInfo.fillAccentValues(accent, settings);
if (currentTheme == theme && currentTheme.currentAccentId == accent.id) {
refreshThemeColors();
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.needSetDayNightTheme, currentTheme, currentNightTheme == currentTheme, null, -1);
}
PatternsLoader.createLoader(true);
}
accent.patternMotion = info.settings.wallpaper != null && info.settings.wallpaper.settings != null && info.settings.wallpaper.settings.motion;
accent.patternMotion = settings.wallpaper != null && settings.wallpaper.settings != null && settings.wallpaper.settings.motion;
theme.previewParsed = false;
} else {
String key;
@ -7278,6 +7451,7 @@ public class Theme {
try {
String[] wallpaperLink = new String[1];
HashMap<String, Integer> colors = getThemeFileValues(new File(pathToFile), null, wallpaperLink);
checkIsDark(colors, accent.parentTheme);
Integer wallpaperFileOffset = colors.get("wallpaperFileOffset");
Bitmap bitmap = Bitmaps.createBitmap(560, 678, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
@ -7556,6 +7730,21 @@ public class Theme {
return null;
}
private static void checkIsDark(HashMap<String, Integer> colors, Theme.ThemeInfo info) {
if (info == null || colors == null) {
return;
}
if (info.isDark == ThemeInfo.UNKNOWN) {
int averageBackgroundColor = getPreviewColor(colors, key_windowBackgroundWhite);
averageBackgroundColor = ColorUtils.blendARGB(averageBackgroundColor, getPreviewColor(colors, key_windowBackgroundWhite), 0.5f);
if (ColorUtils.calculateLuminance(averageBackgroundColor) < 0.5f) {
info.isDark = ThemeInfo.DARK;
} else {
info.isDark = ThemeInfo.LIGHT;
}
}
}
public static HashMap<String, Integer> getThemeFileValues(File file, String assetName, String[] wallpaperLink) {
FileInputStream stream = null;
HashMap<String, Integer> stringMap = new HashMap<>();
@ -8321,6 +8510,8 @@ public class Theme {
addChatDrawable(key_drawable_shareIcon, chat_shareIconDrawable, key_chat_serviceIcon);
addChatDrawable(key_drawable_muteIconDrawable, chat_muteIconDrawable, key_chat_muteIcon);
addChatDrawable(key_drawable_lockIconDrawable, chat_lockIconDrawable, key_chat_lockIcon);
addChatDrawable(key_drawable_chat_pollHintDrawableOut, chat_pollHintDrawable[1], key_chat_outPreviewInstantText);
addChatDrawable(key_drawable_chat_pollHintDrawableIn, chat_pollHintDrawable[0], key_chat_inPreviewInstantText);
applyChatTheme(fontsOnly, false);
}
@ -8654,7 +8845,8 @@ public class Theme {
}
Drawable drawable = wallpaperOverride != null ? wallpaperOverride : currentWallpaper;
if (drawable instanceof MotionBackgroundDrawable) {
boolean drawServiceGradient = drawable instanceof MotionBackgroundDrawable && SharedConfig.getDevicePerformanceClass() != SharedConfig.PERFORMANCE_CLASS_LOW;
if (drawServiceGradient) {
Bitmap newBitmap = ((MotionBackgroundDrawable) drawable).getBitmap();
if (serviceBitmap != newBitmap) {
serviceBitmap = newBitmap;
@ -9140,8 +9332,12 @@ public class Theme {
if (accent != null) {
wallpaperFile = accent.getPathToWallpaper();
wallpaperMotion = accent.patternMotion;
if (accent.info != null && accent.info.settings != null && accent.info.settings.wallpaper != null) {
wallpaperDocument = accent.info.settings.wallpaper.document;
TLRPC.ThemeSettings settings = null;
if (accent.info != null && accent.info.settings.size() > 0) {
settings = accent.info.settings.get(0);
}
if (accent.info != null && settings != null && settings.wallpaper != null) {
wallpaperDocument = settings.wallpaper.document;
}
} else {
wallpaperFile = null;
@ -9156,7 +9352,7 @@ public class Theme {
}
TLRPC.Document finalWallpaperDocument = wallpaperDocument;
Utilities.searchQueue.postRunnable(wallpaperLoadTask = () -> {
Utilities.themeQueue.postRunnable(wallpaperLoadTask = () -> {
BackgroundDrawableSettings settings = createBackgroundDrawable(
currentTheme,
overrideWallpaper,
@ -9602,7 +9798,7 @@ public class Theme {
}
if (drawable == null && wallpaperLoadTask != null) {
CountDownLatch countDownLatch = new CountDownLatch(1);
Utilities.searchQueue.postRunnable(countDownLatch::countDown);
Utilities.themeQueue.postRunnable(countDownLatch::countDown);
try {
countDownLatch.await();
} catch (Exception e) {
@ -9773,9 +9969,7 @@ public class Theme {
}
}
public static void setColorToPaint(Paint paint, int color) {
if (paint.getColor() != color) {
paint.setColor(color);
}
public static boolean isCurrentThemeDay() {
return !getActiveTheme().isDark();
}
}

View File

@ -547,7 +547,8 @@ public class ContactsAdapter extends RecyclerListView.SectionsAdapter {
}
@Override
public int getPositionForScrollProgress(float progress) {
return (int) (getItemCount() * progress);
public void getPositionForScrollProgress(RecyclerListView listView, float progress, int[] position) {
position[0] = (int) (getItemCount() * progress);
position[1] = 0;
}
}

View File

@ -104,9 +104,6 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
showArchiveHint = preferences.getBoolean("archivehint", true);
preferences.edit().putBoolean("archivehint", false).commit();
if (showArchiveHint) {
archiveHintCell = new ArchiveHintCell(context);
}
}
if (folder == 0) {
this.preloader = new DialogsPreloader();
@ -428,11 +425,8 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
break;
}
case 9:
archiveHintCell = new ArchiveHintCell(mContext);
view = archiveHintCell;
if (archiveHintCell.getParent() != null) {
ViewGroup parent = (ViewGroup) archiveHintCell.getParent();
parent.removeView(archiveHintCell);
}
break;
case 10: {
view = new LastEmptyView(mContext);

View File

@ -1149,7 +1149,7 @@ public class MentionsAdapter extends RecyclerListView.SelectionAdapter implement
if (searchResultUsernamesMap.indexOfKey(peerId) >= 0 || !isSearchingMentions && peerId == currentUserId) {
continue;
}
if (peerId > 0) {
if (peerId >= 0) {
TLRPC.User user = messagesController.getUser(peerId);
if (user == null) {
return;

View File

@ -3664,7 +3664,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
});
containerView.addView(textSelectionHelper.getOverlayView(activity));
pinchToZoomHelper = new PinchToZoomHelper(containerView);
pinchToZoomHelper = new PinchToZoomHelper(containerView, windowView);
pinchToZoomHelper.setClipBoundsListener(new PinchToZoomHelper.ClipBoundsListener() {
@Override
public void getClipTopBottom(float[] topBottom) {

View File

@ -63,7 +63,7 @@ public class AvatarPreviewPagerIndicator extends View implements ProfileGalleryV
private float currentLoadingAnimationProgress;
private int currentLoadingAnimationDirection = 1;
ProfileGalleryView profileGalleryView;
protected ProfileGalleryView profileGalleryView;
TextPaint textPaint;
private float progressToCounter;
@ -378,4 +378,8 @@ public class AvatarPreviewPagerIndicator extends View implements ProfileGalleryV
public void setProfileGalleryView(ProfileGalleryView profileGalleryView) {
this.profileGalleryView = profileGalleryView;
}
public ProfileGalleryView getProfileGalleryView() {
return profileGalleryView;
}
}

View File

@ -596,7 +596,7 @@ public class CacheControlActivity extends BaseFragment {
database.executeFast("DELETE FROM messages_holes WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM bot_keyboard WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media_counts_v2 WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media_v3 WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media_v4 WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media_holes_v2 WHERE uid = " + did).stepThis().dispose();
MediaDataController.getInstance(currentAccount).clearBotKeyboard(did, null);
if (messageId != -1) {

View File

@ -11,11 +11,8 @@ package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.RectF;
import android.text.Layout;
import android.text.Spannable;
@ -28,8 +25,6 @@ import android.view.SoundEffectConstants;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo;
import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.DownloadController;
import org.telegram.messenger.FileLoader;
@ -54,6 +49,8 @@ import java.util.ArrayList;
public class ChatActionCell extends BaseCell implements DownloadController.FileDownloadProgressListener {
private boolean canDrawInParent;
public interface ChatActionCellDelegate {
default void didClickImage(ChatActionCell cell) {
}
@ -95,6 +92,8 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
private int previousWidth;
private boolean imagePressed;
TextPaint textPaint;
private float viewTop;
private int backgroundHeight;
private boolean visiblePartSet;
@ -128,11 +127,12 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
private ThemeDelegate themeDelegate;
public ChatActionCell(Context context) {
this(context, null);
this(context, false, null);
}
public ChatActionCell(Context context, ThemeDelegate themeDelegate) {
public ChatActionCell(Context context, boolean canDrawInParent, ThemeDelegate themeDelegate) {
super(context);
this.canDrawInParent = canDrawInParent;
this.themeDelegate = themeDelegate;
imageReceiver = new ImageReceiver(this);
imageReceiver.setRoundRadius(AndroidUtilities.roundMessageSize / 2);
@ -257,9 +257,6 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
visiblePartSet = true;
backgroundHeight = parentH;
viewTop = visibleTop;
if (hasGradientService()) {
invalidate();
}
}
@Override
@ -489,8 +486,30 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
return;
}
drawBackground(canvas, false);
if (textPaint != null) {
canvas.save();
canvas.translate(textXLeft, textY);
if (textLayout.getPaint() != textPaint) {
buildLayout();
}
textLayout.draw(canvas);
canvas.restore();
}
}
public void drawBackground(Canvas canvas, boolean fromParent) {
if (canDrawInParent) {
if (hasGradientService() && !fromParent) {
return;
}
if (!hasGradientService() && fromParent) {
return;
}
}
Paint backgroundPaint = getThemedPaint(Theme.key_paint_chatActionBackground);
TextPaint textPaint = (TextPaint) getThemedPaint(Theme.key_paint_chatActionText);
textPaint = (TextPaint) getThemedPaint(Theme.key_paint_chatActionText);
if (overrideBackground != null) {
int color = getThemedColor(overrideBackground);
if (overrideBackgroundPaint == null) {
@ -641,22 +660,28 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} else {
Theme.applyServiceShaderMatrix(getMeasuredWidth(), backgroundHeight, 0, viewTop + AndroidUtilities.dp(4));
}
int oldAlpha = -1;
int oldAlpha2 = -1;
if (fromParent && getAlpha() != 1f) {
oldAlpha = backgroundPaint.getAlpha();
oldAlpha2 = Theme.chat_actionBackgroundGradientDarkenPaint.getAlpha();
backgroundPaint.setAlpha((int) (oldAlpha * getAlpha()));
Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha((int) (oldAlpha2 * getAlpha()));
}
canvas.drawPath(backgroundPath, backgroundPaint);
if (hasGradientService()) {
canvas.drawPath(backgroundPath, Theme.chat_actionBackgroundGradientDarkenPaint);
}
canvas.save();
canvas.translate(textXLeft, textY);
if (textLayout.getPaint() != textPaint) {
buildLayout();
if (oldAlpha >= 0) {
backgroundPaint.setAlpha(oldAlpha);
Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha(oldAlpha2);
}
textLayout.draw(canvas);
canvas.restore();
}
protected boolean hasGradientService() {
return themeDelegate != null ? themeDelegate.hasGradientService() : Theme.hasGradientService();
public boolean hasGradientService() {
return overrideBackgroundPaint == null && (themeDelegate != null ? themeDelegate.hasGradientService() : Theme.hasGradientService());
}
@Override

View File

@ -68,6 +68,8 @@ import android.widget.Toast;
import androidx.core.graphics.ColorUtils;
import com.google.android.exoplayer2.util.Log;
import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ChatObject;
@ -825,18 +827,22 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private int currentFocusedVirtualView = -1;
public boolean drawFromPinchToZoom;
private Theme.MessageDrawable.PathDrawParams backgroundCacheParams = new Theme.MessageDrawable.PathDrawParams();
VideoForwardDrawable videoForwardDrawable;
VideoPlayerRewinder videoPlayerRewinder;
private final Theme.ResourcesProvider resourcesProvider;
private final boolean canDrawBackgroundInParent;
public ChatMessageCell(Context context) {
this(context, null);
this(context, false, null);
}
public ChatMessageCell(Context context, Theme.ResourcesProvider resourcesProvider) {
public ChatMessageCell(Context context, boolean canDrawBackgroundInParent, Theme.ResourcesProvider resourcesProvider) {
super(context);
this.resourcesProvider = resourcesProvider;
this.canDrawBackgroundInParent = canDrawBackgroundInParent;
backgroundDrawable = new MessageBackgroundDrawable(this);
avatarImage = new ImageReceiver();
@ -2584,7 +2590,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
this.parentViewTopOffset = parentOffset;
parentHeight = parent;
}
if (currentMessageObject != null && (hasGradientService() && currentMessageObject.shouldDrawWithoutBackground() || drawSideButton != 0 || !botButtons.isEmpty()) || currentBackgroundDrawable != null && currentBackgroundDrawable.getGradientShader() != null) {
if (currentMessageObject != null && (hasGradientService() && currentMessageObject.shouldDrawWithoutBackground() || drawSideButton != 0 || !botButtons.isEmpty()) ) {
invalidate();
}
@ -5295,8 +5301,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else {
availableTimeWidth = photoWidth - AndroidUtilities.dp(14);
}
if (messageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
availableTimeWidth -= Math.ceil(Theme.chat_audioTimePaint.measureText("00:00")) + AndroidUtilities.dp(26);
availableTimeWidth = (int) (AndroidUtilities.roundMessageSize - Math.ceil(Theme.chat_audioTimePaint.measureText("00:00")) + AndroidUtilities.dp(40));
}
measureTime(messageObject);
int timeWidthTotal = timeWidth + AndroidUtilities.dp((SharedConfig.bubbleRadius >= 10 ? 22 : 18) + (messageObject.isOutOwner() ? 20 : 0));
@ -6882,6 +6889,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (currentMessageObject.type == 12) {
totalHeight += AndroidUtilities.dp(14);
}
if (hasNewLineForTime) {
totalHeight += AndroidUtilities.dp(16);
}
if (instantViewLayout != null && instantViewLayout.getLineCount() > 0) {
instantTextX = (int) (instantWidth - Math.ceil(instantViewLayout.getLineWidth(0))) / 2 + (drawInstantViewType == 0 ? AndroidUtilities.dp(8) : 0);
instantTextLeftX = (int) instantViewLayout.getLineLeft(0);
@ -7693,7 +7703,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (audioVisualizerDrawable != null) {
audioVisualizerDrawable.setParentView(this);
audioVisualizerDrawable.draw(canvas, buttonX + AndroidUtilities.dp(22), buttonY + AndroidUtilities.dp(22), currentMessageObject.isOutOwner());
audioVisualizerDrawable.draw(canvas, buttonX + AndroidUtilities.dp(22), buttonY + AndroidUtilities.dp(22), currentMessageObject.isOutOwner(), resourcesProvider);
}
if (!enterTransitionInPorgress) {
@ -7922,6 +7932,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
linkX = unmovedTextX + AndroidUtilities.dp(1);
} else if (currentMessageObject.isSponsored()) {
startY = textY + currentMessageObject.textHeight - AndroidUtilities.dp(2);
if (hasNewLineForTime) {
startY += AndroidUtilities.dp(16);
}
linkX = unmovedTextX + AndroidUtilities.dp(1);
} else {
startY = textY + currentMessageObject.textHeight + AndroidUtilities.dp(8);
@ -9586,7 +9599,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
private boolean checkNeedDrawShareButton(MessageObject messageObject) {
if (currentMessageObject.deleted) {
if (currentMessageObject.deleted || currentMessageObject.isSponsored()) {
return false;
}
if (currentPosition != null) {
@ -10213,14 +10226,14 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
if (currentMessageObject.isOutOwner()) {
Theme.setColorToPaint(Theme.chat_msgTextPaint, getThemedColor(Theme.key_chat_messageTextOut));
Theme.setColorToPaint(Theme.chat_msgGameTextPaint, getThemedColor(Theme.key_chat_messageTextOut));
Theme.chat_msgTextPaint.setColor(getThemedColor(Theme.key_chat_messageTextOut));
Theme.chat_msgGameTextPaint.setColor(getThemedColor(Theme.key_chat_messageTextOut));
Theme.chat_msgGameTextPaint.linkColor = getThemedColor(Theme.key_chat_messageLinkOut);
Theme.chat_replyTextPaint.linkColor = getThemedColor(Theme.key_chat_messageLinkOut);
Theme.chat_msgTextPaint.linkColor = getThemedColor(Theme.key_chat_messageLinkOut);
} else {
Theme.setColorToPaint(Theme.chat_msgTextPaint, getThemedColor(Theme.key_chat_messageTextIn));
Theme.setColorToPaint(Theme.chat_msgGameTextPaint, getThemedColor(Theme.key_chat_messageTextIn));
Theme.chat_msgTextPaint.setColor(getThemedColor(Theme.key_chat_messageTextIn));
Theme.chat_msgGameTextPaint.setColor(getThemedColor(Theme.key_chat_messageTextIn));
Theme.chat_msgGameTextPaint.linkColor = getThemedColor(Theme.key_chat_messageLinkIn);
Theme.chat_replyTextPaint.linkColor = getThemedColor(Theme.key_chat_messageLinkIn);
Theme.chat_msgTextPaint.linkColor = getThemedColor(Theme.key_chat_messageLinkIn);
@ -10244,23 +10257,234 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
}
if (currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
Theme.setColorToPaint(Theme.chat_timePaint, getThemedColor(Theme.key_chat_serviceText));
Theme.chat_timePaint.setColor(getThemedColor(Theme.key_chat_serviceText));
} else {
if (mediaBackground) {
if (currentMessageObject.shouldDrawWithoutBackground()) {
Theme.setColorToPaint(Theme.chat_timePaint, getThemedColor(Theme.key_chat_serviceText));
Theme.chat_timePaint.setColor(getThemedColor(Theme.key_chat_serviceText));
} else {
Theme.setColorToPaint(Theme.chat_timePaint, getThemedColor(Theme.key_chat_mediaTimeText));
Theme.chat_timePaint.setColor(getThemedColor(Theme.key_chat_mediaTimeText));
}
} else {
if (currentMessageObject.isOutOwner()) {
Theme.setColorToPaint(Theme.chat_timePaint, getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_outTimeSelectedText : Theme.key_chat_outTimeText));
Theme.chat_timePaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_outTimeSelectedText : Theme.key_chat_outTimeText));
} else {
Theme.setColorToPaint(Theme.chat_timePaint, getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_inTimeSelectedText : Theme.key_chat_inTimeText));
Theme.chat_timePaint.setColor(getThemedColor(isDrawSelectionBackground() ? Theme.key_chat_inTimeSelectedText : Theme.key_chat_inTimeText));
}
}
}
drawBackgroundInternal(canvas, false);
if (isHighlightedAnimated) {
long newTime = System.currentTimeMillis();
long dt = Math.abs(newTime - lastHighlightProgressTime);
if (dt > 17) {
dt = 17;
}
highlightProgress -= dt;
lastHighlightProgressTime = newTime;
if (highlightProgress <= 0) {
highlightProgress = 0;
isHighlightedAnimated = false;
}
invalidate();
if (getParent() != null) {
((View) getParent()).invalidate();
}
}
int restore = Integer.MIN_VALUE;
if (alphaInternal != 1.0f) {
int top = 0;
int left = 0;
int bottom = getMeasuredHeight();
int right = getMeasuredWidth();
if (currentBackgroundDrawable != null) {
top = currentBackgroundDrawable.getBounds().top;
bottom = currentBackgroundDrawable.getBounds().bottom;
left = currentBackgroundDrawable.getBounds().left;
right = currentBackgroundDrawable.getBounds().right;
}
if (drawSideButton != 0) {
if (currentMessageObject.isOutOwner()) {
left -= AndroidUtilities.dp(8 + 32);
} else {
right += AndroidUtilities.dp(8 + 32);
}
}
if (getY() < 0) {
top = (int) -getY();
}
if (getY() + getMeasuredHeight() > parentHeight) {
bottom = (int) (parentHeight - getY());
}
rect.set(left, top, right, bottom);
restore = canvas.saveLayerAlpha(rect, (int) (255 * alphaInternal), Canvas.ALL_SAVE_FLAG);
}
boolean clipContent = false;
if (transitionParams.animateBackgroundBoundsInner && currentBackgroundDrawable != null && !isRoundVideo) {
Rect r = currentBackgroundDrawable.getBounds();
canvas.save();
canvas.clipRect(
r.left + AndroidUtilities.dp(4), r.top + AndroidUtilities.dp(4),
r.right - AndroidUtilities.dp(4), r.bottom - AndroidUtilities.dp(4)
);
clipContent = true;
}
drawContent(canvas);
if (clipContent) {
canvas.restore();
}
if (!transitionParams.animateBackgroundBoundsInner) {
if (!transitionParams.transitionBotButtons.isEmpty()) {
drawBotButtons(canvas, transitionParams.transitionBotButtons, 1f - transitionParams.animateChangeProgress);
}
if (!botButtons.isEmpty()) {
drawBotButtons(canvas, botButtons, transitionParams.animateChangeProgress);
}
}
if (drawSideButton != 0) {
if (currentMessageObject.isOutOwner()) {
sideStartX = getCurrentBackgroundLeft() - AndroidUtilities.dp(8 + 32);
if (currentMessagesGroup != null) {
sideStartX += currentMessagesGroup.transitionParams.offsetLeft - animationOffsetX;
}
} else {
sideStartX = currentBackgroundDrawable.getBounds().right + AndroidUtilities.dp(8);
if (currentMessagesGroup != null) {
sideStartX += currentMessagesGroup.transitionParams.offsetRight - animationOffsetX;
}
}
sideStartY = layoutHeight - AndroidUtilities.dp(41) + transitionParams.deltaBottom;
if (currentMessagesGroup != null) {
sideStartY += currentMessagesGroup.transitionParams.offsetBottom;
if (currentMessagesGroup.transitionParams.backgroundChangeBounds) {
sideStartY -= getTranslationY();
}
}
if (!currentMessageObject.isOutOwner() && isRoundVideo && isAvatarVisible) {
float offsetSize = (AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize) * 0.7f;
float offsetX = isPlayingRound ? offsetSize : 0;
if (transitionParams.animatePlayingRound) {
offsetX = (isPlayingRound ? transitionParams.animateChangeProgress : (1f - transitionParams.animateChangeProgress)) * offsetSize;
}
sideStartX -= offsetX;
}
if (drawSideButton == 3) {
if (!(enterTransitionInPorgress && !currentMessageObject.isVoice())) {
drawCommentButton(canvas, 1f);
}
} else {
rect.set(sideStartX, sideStartY, sideStartX + AndroidUtilities.dp(32), sideStartY + AndroidUtilities.dp(32));
applyServiceShaderMatrix(getMeasuredWidth(), backgroundHeight, getX(), viewTop);
canvas.drawRoundRect(rect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), getThemedPaint(sideButtonPressed ? Theme.key_paint_chatActionBackgroundSelected : Theme.key_paint_chatActionBackground));
if (hasGradientService()) {
canvas.drawRoundRect(rect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), Theme.chat_actionBackgroundGradientDarkenPaint);
}
if (drawSideButton == 2) {
Drawable goIconDrawable = getThemedDrawable(Theme.key_drawable_goIcon);
if (currentMessageObject.isOutOwner()) {
setDrawableBounds(goIconDrawable, sideStartX + AndroidUtilities.dp(10), sideStartY + AndroidUtilities.dp(9));
canvas.save();
canvas.scale(-1, 1, goIconDrawable.getBounds().centerX(), goIconDrawable.getBounds().centerY());
} else {
setDrawableBounds(goIconDrawable, sideStartX + AndroidUtilities.dp(12), sideStartY + AndroidUtilities.dp(9));
}
goIconDrawable.draw(canvas);
if (currentMessageObject.isOutOwner()) {
canvas.restore();
}
} else {
Drawable drawable = getThemedDrawable(Theme.key_drawable_shareIcon);
setDrawableBounds(drawable, sideStartX + AndroidUtilities.dp(8), sideStartY + AndroidUtilities.dp(9));
drawable.draw(canvas);
}
}
}
if (replyNameLayout != null) {
if (currentMessageObject.shouldDrawWithoutBackground()) {
if (currentMessageObject.isOutOwner()) {
replyStartX = AndroidUtilities.dp(23);
if (isPlayingRound) {
replyStartX -= (AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize);
}
} else if (currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
replyStartX = backgroundDrawableLeft + backgroundDrawableRight + AndroidUtilities.dp(4);
} else {
replyStartX = backgroundDrawableLeft + backgroundDrawableRight + AndroidUtilities.dp(17);
}
replyStartY = AndroidUtilities.dp(12);
} else {
if (currentMessageObject.isOutOwner()) {
replyStartX = backgroundDrawableLeft + AndroidUtilities.dp(12) + getExtraTextX();
} else {
if (mediaBackground) {
replyStartX = backgroundDrawableLeft + AndroidUtilities.dp(12) + getExtraTextX();
} else {
replyStartX = backgroundDrawableLeft + AndroidUtilities.dp(drawPinnedBottom ? 12 : 18) + getExtraTextX();
}
}
replyStartY = AndroidUtilities.dp(12 + (drawForwardedName && forwardedNameLayout[0] != null ? 36 : 0) + (drawNameLayout && nameLayout != null ? 20 : 0));
}
}
if (currentPosition == null && !transitionParams.animateBackgroundBoundsInner && !(enterTransitionInPorgress && !currentMessageObject.isVoice())) {
drawNamesLayout(canvas, 1f);
}
if ((!autoPlayingMedia || !MediaController.getInstance().isPlayingMessageAndReadyToDraw(currentMessageObject) || isRoundVideo) && !transitionParams.animateBackgroundBoundsInner) {
drawOverlays(canvas);
}
if ((drawTime || !mediaBackground) && !forceNotDrawTime && !transitionParams.animateBackgroundBoundsInner && !(enterTransitionInPorgress && !currentMessageObject.isVoice())) {
drawTime(canvas, 1f, false);
}
if ((controlsAlpha != 1.0f || timeAlpha != 1.0f) && currentMessageObject.type != 5) {
long newTime = System.currentTimeMillis();
long dt = Math.abs(lastControlsAlphaChangeTime - newTime);
if (dt > 17) {
dt = 17;
}
totalChangeTime += dt;
if (totalChangeTime > 100) {
totalChangeTime = 100;
}
lastControlsAlphaChangeTime = newTime;
if (controlsAlpha != 1.0f) {
controlsAlpha = AndroidUtilities.decelerateInterpolator.getInterpolation(totalChangeTime / 100.0f);
}
if (timeAlpha != 1.0f) {
timeAlpha = AndroidUtilities.decelerateInterpolator.getInterpolation(totalChangeTime / 100.0f);
}
invalidate();
if (forceNotDrawTime && currentPosition != null && currentPosition.last && getParent() != null) {
View parent = (View) getParent();
parent.invalidate();
}
}
if (restore != Integer.MIN_VALUE) {
canvas.restoreToCount(restore);
}
updateSelectionTextPosition();
}
@SuppressLint("WrongCall")
public void drawBackgroundInternal(Canvas canvas, boolean fromParent) {
if (currentMessageObject == null) {
return;
}
if (!wasLayout && !animationRunning) {
forceLayout();
return;
}
if (!wasLayout) {
onLayout(false, getLeft(), getTop(), getRight(), getBottom());
}
Drawable currentBackgroundShadowDrawable;
int additionalTop = 0;
int additionalBottom = 0;
@ -10473,27 +10697,36 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
}
if (!fromParent && drawBackgroundInParent()) {
return;
}
boolean needRestore = false;
if (transitionYOffsetForDrawables != 0) {
needRestore = true;
canvas.save();
canvas.translate(0, transitionYOffsetForDrawables);
}
if (drawBackground && currentBackgroundDrawable != null && (currentPosition == null || isDrawSelectionBackground() && (currentMessageObject.isMusic() || currentMessageObject.isDocument())) && !(enterTransitionInPorgress && !currentMessageObject.isVoice())) {
float alphaInternal = this.alphaInternal;
if (fromParent) {
alphaInternal *= getAlpha();
}
if (isHighlightedAnimated) {
currentBackgroundDrawable.setAlpha((int) (255 * alphaInternal));
currentBackgroundDrawable.draw(canvas);
currentBackgroundDrawable.drawCached(canvas, backgroundCacheParams);
float alpha = highlightProgress >= 300 ? 1.0f : highlightProgress / 300.0f;
currentSelectedBackgroundAlpha = alpha;
if (currentPosition == null) {
currentBackgroundSelectedDrawable.setAlpha((int) (alphaInternal * alpha * 255));
currentBackgroundSelectedDrawable.draw(canvas);
currentBackgroundSelectedDrawable.drawCached(canvas, backgroundCacheParams);
}
} else if (selectedBackgroundProgress != 0 && !(currentMessagesGroup != null && currentMessagesGroup.isDocuments)) {
currentBackgroundDrawable.draw(canvas);
currentBackgroundDrawable.drawCached(canvas, backgroundCacheParams);
currentSelectedBackgroundAlpha = selectedBackgroundProgress;
currentBackgroundSelectedDrawable.setAlpha((int) (selectedBackgroundProgress * alphaInternal * 255));
currentBackgroundSelectedDrawable.draw(canvas);
currentBackgroundSelectedDrawable.drawCached(canvas, backgroundCacheParams);
if (currentBackgroundDrawable.getGradientShader() == null) {
currentBackgroundShadowDrawable = null;
}
@ -10505,14 +10738,14 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
currentSelectedBackgroundAlpha = 1f;
currentBackgroundSelectedDrawable.setAlpha((int) (255 * alphaInternal));
currentBackgroundSelectedDrawable.draw(canvas);
currentBackgroundSelectedDrawable.drawCached(canvas, backgroundCacheParams);
if (currentPosition != null) {
canvas.restore();
}
} else {
currentSelectedBackgroundAlpha = 0;
currentBackgroundDrawable.setAlpha((int) (255 * alphaInternal));
currentBackgroundDrawable.draw(canvas);
currentBackgroundDrawable.drawCached(canvas, backgroundCacheParams);
}
}
if (currentBackgroundShadowDrawable != null && currentPosition == null) {
@ -10567,202 +10800,17 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (needRestore) {
canvas.restore();
}
if (isHighlightedAnimated) {
long newTime = System.currentTimeMillis();
long dt = Math.abs(newTime - lastHighlightProgressTime);
if (dt > 17) {
dt = 17;
}
highlightProgress -= dt;
lastHighlightProgressTime = newTime;
if (highlightProgress <= 0) {
highlightProgress = 0;
isHighlightedAnimated = false;
}
invalidate();
if (getParent() != null) {
((View) getParent()).invalidate();
}
}
}
int restore = Integer.MIN_VALUE;
if (alphaInternal != 1.0f) {
int top = 0;
int left = 0;
int bottom = getMeasuredHeight();
int right = getMeasuredWidth();
if (currentBackgroundDrawable != null) {
top = currentBackgroundDrawable.getBounds().top;
bottom = currentBackgroundDrawable.getBounds().bottom;
left = currentBackgroundDrawable.getBounds().left;
right = currentBackgroundDrawable.getBounds().right;
}
if (drawSideButton != 0) {
if (currentMessageObject.isOutOwner()) {
left -= AndroidUtilities.dp(8 + 32);
} else {
right += AndroidUtilities.dp(8 + 32);
}
}
if (getY() < 0) {
top = (int) -getY();
}
if (getY() + getMeasuredHeight() > parentHeight) {
bottom = (int) (parentHeight - getY());
}
rect.set(left, top, right, bottom);
restore = canvas.saveLayerAlpha(rect, (int) (255 * alphaInternal), Canvas.ALL_SAVE_FLAG);
}
boolean clipContent = false;
if (transitionParams.animateBackgroundBoundsInner && currentBackgroundDrawable != null && !isRoundVideo) {
Rect r = currentBackgroundDrawable.getBounds();
canvas.save();
canvas.clipRect(
r.left + AndroidUtilities.dp(4), r.top + AndroidUtilities.dp(4),
r.right - AndroidUtilities.dp(4), r.bottom - AndroidUtilities.dp(4)
);
clipContent = true;
}
drawContent(canvas);
if (clipContent) {
canvas.restore();
}
if (!transitionParams.animateBackgroundBoundsInner) {
if (!transitionParams.transitionBotButtons.isEmpty()) {
drawBotButtons(canvas, transitionParams.transitionBotButtons, 1f - transitionParams.animateChangeProgress);
}
if (!botButtons.isEmpty()) {
drawBotButtons(canvas, botButtons, transitionParams.animateChangeProgress);
}
}
if (drawSideButton != 0) {
if (currentMessageObject.isOutOwner()) {
sideStartX = getCurrentBackgroundLeft() - AndroidUtilities.dp(8 + 32);
if (currentMessagesGroup != null) {
sideStartX += currentMessagesGroup.transitionParams.offsetLeft - animationOffsetX;
}
public boolean drawBackgroundInParent() {
if (canDrawBackgroundInParent && currentMessageObject != null && currentMessageObject.isOutOwner()) {
if (resourcesProvider != null) {
return resourcesProvider.getCurrentColor(Theme.key_chat_outBubbleGradient1) != null;
} else {
sideStartX = currentBackgroundDrawable.getBounds().right + AndroidUtilities.dp(8);
if (currentMessagesGroup != null) {
sideStartX += currentMessagesGroup.transitionParams.offsetRight - animationOffsetX;
}
}
sideStartY = layoutHeight - AndroidUtilities.dp(41) + transitionParams.deltaBottom;
if (currentMessagesGroup != null) {
sideStartY += currentMessagesGroup.transitionParams.offsetBottom;
if (currentMessagesGroup.transitionParams.backgroundChangeBounds) {
sideStartY -= getTranslationY();
}
}
if (!currentMessageObject.isOutOwner() && isRoundVideo && isAvatarVisible) {
float offsetSize = (AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize) * 0.7f;
float offsetX = isPlayingRound ? offsetSize : 0;
if (transitionParams.animatePlayingRound) {
offsetX = (isPlayingRound ? transitionParams.animateChangeProgress : (1f - transitionParams.animateChangeProgress)) * offsetSize;
}
sideStartX -= offsetX;
}
if (drawSideButton == 3) {
if (!(enterTransitionInPorgress && !currentMessageObject.isVoice())) {
drawCommentButton(canvas, 1f);
}
} else {
rect.set(sideStartX, sideStartY, sideStartX + AndroidUtilities.dp(32), sideStartY + AndroidUtilities.dp(32));
applyServiceShaderMatrix(getMeasuredWidth(), backgroundHeight, getX(), viewTop);
canvas.drawRoundRect(rect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), getThemedPaint(sideButtonPressed ? Theme.key_paint_chatActionBackgroundSelected : Theme.key_paint_chatActionBackground));
if (hasGradientService()) {
canvas.drawRoundRect(rect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), Theme.chat_actionBackgroundGradientDarkenPaint);
}
if (drawSideButton == 2) {
Drawable goIconDrawable = getThemedDrawable(Theme.key_drawable_goIcon);
if (currentMessageObject.isOutOwner()) {
setDrawableBounds(goIconDrawable, sideStartX + AndroidUtilities.dp(10), sideStartY + AndroidUtilities.dp(9));
canvas.save();
canvas.scale(-1, 1, goIconDrawable.getBounds().centerX(), goIconDrawable.getBounds().centerY());
} else {
setDrawableBounds(goIconDrawable, sideStartX + AndroidUtilities.dp(12), sideStartY + AndroidUtilities.dp(9));
}
goIconDrawable.draw(canvas);
if (currentMessageObject.isOutOwner()) {
canvas.restore();
}
} else {
Drawable drawable = getThemedDrawable(Theme.key_drawable_shareIcon);
setDrawableBounds(drawable, sideStartX + AndroidUtilities.dp(8), sideStartY + AndroidUtilities.dp(9));
drawable.draw(canvas);
}
return Theme.getColorOrNull(Theme.key_chat_outBubbleGradient1) != null;
}
}
if (replyNameLayout != null) {
if (currentMessageObject.shouldDrawWithoutBackground()) {
if (currentMessageObject.isOutOwner()) {
replyStartX = AndroidUtilities.dp(23);
if (isPlayingRound) {
replyStartX -= (AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize);
}
} else if (currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
replyStartX = backgroundDrawableLeft + backgroundDrawableRight + AndroidUtilities.dp(4);
} else {
replyStartX = backgroundDrawableLeft + backgroundDrawableRight + AndroidUtilities.dp(17);
}
replyStartY = AndroidUtilities.dp(12);
} else {
if (currentMessageObject.isOutOwner()) {
replyStartX = backgroundDrawableLeft + AndroidUtilities.dp(12) + getExtraTextX();
} else {
if (mediaBackground) {
replyStartX = backgroundDrawableLeft + AndroidUtilities.dp(12) + getExtraTextX();
} else {
replyStartX = backgroundDrawableLeft + AndroidUtilities.dp(drawPinnedBottom ? 12 : 18) + getExtraTextX();
}
}
replyStartY = AndroidUtilities.dp(12 + (drawForwardedName && forwardedNameLayout[0] != null ? 36 : 0) + (drawNameLayout && nameLayout != null ? 20 : 0));
}
}
if (currentPosition == null && !transitionParams.animateBackgroundBoundsInner && !(enterTransitionInPorgress && !currentMessageObject.isVoice())) {
drawNamesLayout(canvas, 1f);
}
if ((!autoPlayingMedia || !MediaController.getInstance().isPlayingMessageAndReadyToDraw(currentMessageObject) || isRoundVideo) && !transitionParams.animateBackgroundBoundsInner) {
drawOverlays(canvas);
}
if ((drawTime || !mediaBackground) && !forceNotDrawTime && !transitionParams.animateBackgroundBoundsInner && !(enterTransitionInPorgress && !currentMessageObject.isVoice())) {
drawTime(canvas, 1f, false);
}
if ((controlsAlpha != 1.0f || timeAlpha != 1.0f) && currentMessageObject.type != 5) {
long newTime = System.currentTimeMillis();
long dt = Math.abs(lastControlsAlphaChangeTime - newTime);
if (dt > 17) {
dt = 17;
}
totalChangeTime += dt;
if (totalChangeTime > 100) {
totalChangeTime = 100;
}
lastControlsAlphaChangeTime = newTime;
if (controlsAlpha != 1.0f) {
controlsAlpha = AndroidUtilities.decelerateInterpolator.getInterpolation(totalChangeTime / 100.0f);
}
if (timeAlpha != 1.0f) {
timeAlpha = AndroidUtilities.decelerateInterpolator.getInterpolation(totalChangeTime / 100.0f);
}
invalidate();
if (forceNotDrawTime && currentPosition != null && currentPosition.last && getParent() != null) {
View parent = (View) getParent();
parent.invalidate();
}
}
if (restore != Integer.MIN_VALUE) {
canvas.restoreToCount(restore);
}
updateSelectionTextPosition();
return false;
}
public void drawCommentButton(Canvas canvas, float alpha) {
@ -10951,7 +10999,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
currentBackgroundDrawable.setAlpha((int) (getAlpha() * 255));
currentBackgroundDrawable.setBounds(left, top, right, bottom);
currentBackgroundDrawable.draw(canvas);
currentBackgroundDrawable.drawCached(canvas, backgroundCacheParams);
currentBackgroundDrawable.setAlpha(255);
}
}
@ -11998,6 +12046,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else {
if (currentMessageObject.isSponsored()) {
timeYOffset = -AndroidUtilities.dp(48);
if (hasNewLineForTime) {
timeYOffset -= AndroidUtilities.dp(16);
}
} else {
timeYOffset = -(drawCommentButton ? AndroidUtilities.dp(43) : 0);
}
@ -13058,7 +13109,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
TLRPC.TL_messageMediaPoll media = (TLRPC.TL_messageMediaPoll) currentMessageObject.messageOwner.media;
if (lastPoll.quiz && (pollVoted || pollClosed) && !TextUtils.isEmpty(media.results.solution)) {
Drawable drawable = Theme.chat_pollHintDrawable[currentMessageObject.isOutOwner() ? 1 : 0];
Drawable drawable = getThemedDrawable(currentMessageObject.isOutOwner() ? Theme.key_drawable_chat_pollHintDrawableOut : Theme.key_drawable_chat_pollHintDrawableIn);
if (pollVoteInProgress) {
drawable.setAlpha((int) (255 * pollAnimationProgress));
} else {
@ -14397,7 +14448,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private ClickableSpan getLinkById(int id, boolean caption) {
if (caption) {
id -= LINK_CAPTION_IDS_START;
if (!(currentMessageObject.caption instanceof Spannable)) {
if (!(currentMessageObject.caption instanceof Spannable) || id < 0) {
return null;
}
Spannable buffer = (Spannable) currentMessageObject.caption;
@ -14408,7 +14459,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
return links[id];
} else {
id -= LINK_IDS_START;
if (!(currentMessageObject.messageText instanceof Spannable)) {
if (!(currentMessageObject.messageText instanceof Spannable) || id < 0) {
return null;
}
Spannable buffer = (Spannable) currentMessageObject.messageText;

View File

@ -988,7 +988,7 @@ public class DialogCell extends BaseCell {
checkMessage = false;
messageString = formatArchivedDialogNames();
} else if (message.messageOwner instanceof TLRPC.TL_messageService) {
if (ChatObject.isChannel(chat) && (message.messageOwner.action instanceof TLRPC.TL_messageActionHistoryClear ||
if (ChatObject.isChannelAndNotMegaGroup(chat) && (message.messageOwner.action instanceof TLRPC.TL_messageActionHistoryClear ||
message.messageOwner.action instanceof TLRPC.TL_messageActionChannelMigrateFrom)) {
messageString = "";
showChecks = false;

View File

@ -109,7 +109,7 @@ public class DrawerProfileCell extends FrameLayout {
setArrowState(false);
sunDrawable = new RLottieDrawable(R.raw.sun, "" + R.raw.sun, AndroidUtilities.dp(28), AndroidUtilities.dp(28), true, null);
if (isCurrentThemeDay()) {
if (Theme.isCurrentThemeDay()) {
sunDrawable.setCustomEndFrame(36);
} else {
sunDrawable.setCustomEndFrame(0);
@ -147,11 +147,11 @@ public class DrawerProfileCell extends FrameLayout {
switchingTheme = true;
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("themeconfig", Activity.MODE_PRIVATE);
String dayThemeName = preferences.getString("lastDayTheme", "Blue");
if (Theme.getTheme(dayThemeName) == null) {
if (Theme.getTheme(dayThemeName) == null || Theme.getTheme(dayThemeName).isDark()) {
dayThemeName = "Blue";
}
String nightThemeName = preferences.getString("lastDarkTheme", "Dark Blue");
if (Theme.getTheme(nightThemeName) == null) {
if (Theme.getTheme(nightThemeName) == null || !Theme.getTheme(nightThemeName).isDark()) {
nightThemeName = "Dark Blue";
}
Theme.ThemeInfo themeInfo = Theme.getActiveTheme();
@ -196,23 +196,6 @@ public class DrawerProfileCell extends FrameLayout {
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.needSetDayNightTheme, themeInfo, false, pos, -1, toDark, darkThemeView);
}
private boolean isCurrentThemeDay() {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("themeconfig", Activity.MODE_PRIVATE);
String dayThemeName = preferences.getString("lastDayTheme", "Blue");
if (Theme.getTheme(dayThemeName) == null) {
dayThemeName = "Blue";
}
String nightThemeName = preferences.getString("lastDarkTheme", "Dark Blue");
if (Theme.getTheme(nightThemeName) == null) {
nightThemeName = "Dark Blue";
}
Theme.ThemeInfo themeInfo = Theme.getActiveTheme();
if (dayThemeName.equals(nightThemeName) && themeInfo.isDark()) {
dayThemeName = "Blue";
}
return dayThemeName.equals(themeInfo.getKey());
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();

View File

@ -0,0 +1,147 @@
package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.LongSparseArray;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.messenger.UserObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.LayoutHelper;
public class MemberRequestCell extends FrameLayout {
private final AvatarDrawable avatarDrawable = new AvatarDrawable();
private final BackupImageView avatarImageView = new BackupImageView(getContext());
private final SimpleTextView nameTextView = new SimpleTextView(getContext());
private final SimpleTextView statusTextView = new SimpleTextView(getContext());
private TLRPC.TL_chatInviteImporter importer;
private boolean isNeedDivider;
public MemberRequestCell(@NonNull Context context, OnClickListener clickListener, boolean isChannel) {
super(context);
avatarImageView.setRoundRadius(AndroidUtilities.dp(23));
addView(avatarImageView, LayoutHelper.createFrame(46, 46, Gravity.START, 12, 8, 12, 0));
nameTextView.setGravity(Gravity.START);
nameTextView.setMaxLines(1);
nameTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
nameTextView.setTextSize(17);
nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP, LocaleController.isRTL ? 12 : 74, 12, LocaleController.isRTL ? 74 : 12, 0));
statusTextView.setGravity(Gravity.START);
statusTextView.setMaxLines(1);
statusTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText));
statusTextView.setTextSize(14);
addView(statusTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP, LocaleController.isRTL ? 12 : 74, 36, LocaleController.isRTL ? 74 : 12, 0));
int btnPadding = AndroidUtilities.dp(17);
TextView addButton = new TextView(getContext());
addButton.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(4), Theme.getColor(Theme.key_featuredStickers_addButton), Theme.getColor(Theme.key_featuredStickers_addButtonPressed)));
addButton.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
addButton.setMaxLines(1);
addButton.setPadding(btnPadding, 0, btnPadding, 0);
addButton.setText(isChannel ? LocaleController.getString("AddToChannel", R.string.AddToChannel) : LocaleController.getString("AddToGroup", R.string.AddToGroup));
addButton.setTextColor(Theme.getColor(Theme.key_featuredStickers_buttonText));
addButton.setTextSize(14);
addButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
addButton.setOnClickListener(v -> {
if (clickListener != null && importer != null) {
clickListener.onAddClicked(importer);
}
});
addView(addButton, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, 32, Gravity.START, LocaleController.isRTL ? 0 : 73, 62, LocaleController.isRTL ? 73 : 0, 0));
float addButtonWidth = addButton.getPaint().measureText(addButton.getText().toString()) + btnPadding * 2;
TextView dismissButton = new TextView(getContext());
dismissButton.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(4), Color.TRANSPARENT, Theme.getColor(Theme.key_listSelector), 0xff000000));
dismissButton.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
dismissButton.setMaxLines(1);
dismissButton.setPadding(btnPadding, 0, btnPadding, 0);
dismissButton.setText(LocaleController.getString("Dismiss", R.string.Dismiss));
dismissButton.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText));
dismissButton.setTextSize(14);
dismissButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
dismissButton.setOnClickListener(v -> {
if (clickListener != null && importer != null) {
clickListener.onDismissClicked(importer);
}
});
FrameLayout.LayoutParams dismissLayoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, AndroidUtilities.dp(32));
dismissLayoutParams.topMargin = AndroidUtilities.dp(62);
dismissLayoutParams.leftMargin = LocaleController.isRTL ? 0 : (int)(addButtonWidth + AndroidUtilities.dp(73 + 6));
dismissLayoutParams.rightMargin = LocaleController.isRTL ? (int)(addButtonWidth + AndroidUtilities.dp(73 + 6)) : 0;
addView(dismissButton, dismissLayoutParams);
}
public void setData(LongSparseArray<TLRPC.User> users, TLRPC.TL_chatInviteImporter importer, boolean isNeedDivider) {
this.importer = importer;
this.isNeedDivider = isNeedDivider;
setWillNotDraw(!isNeedDivider);
TLRPC.User user = users.get(importer.user_id);
avatarDrawable.setInfo(user);
avatarImageView.setForUserOrChat(user, avatarDrawable);
nameTextView.setText(UserObject.getUserName(user));
String dateText = LocaleController.formatDateAudio(importer.date, false);
if (importer.approved_by == 0) {
statusTextView.setText(LocaleController.formatString("RequestedToJoinAt", R.string.RequestedToJoinAt, dateText));
} else {
TLRPC.User approvedByUser = users.get(importer.approved_by);
if (approvedByUser != null) {
statusTextView.setText(LocaleController.formatString("AddedBy", R.string.AddedBy, UserObject.getFirstName(approvedByUser), dateText));
} else {
statusTextView.setText("");
}
}
}
public TLRPC.TL_chatInviteImporter getImporter() {
return importer;
}
public BackupImageView getAvatarImageView() {
return avatarImageView;
}
public String getStatus() {
return statusTextView.getText().toString();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(107), MeasureSpec.EXACTLY));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isNeedDivider) {
canvas.drawLine(LocaleController.isRTL ? 0 : AndroidUtilities.dp(72), getMeasuredHeight() - 1, getMeasuredWidth() - (LocaleController.isRTL ? AndroidUtilities.dp(72) : 0), getMeasuredHeight() - 1, Theme.dividerPaint);
}
}
public interface OnClickListener {
void onAddClicked(TLRPC.TL_chatInviteImporter importer);
void onDismissClicked(TLRPC.TL_chatInviteImporter importer);
}
}

View File

@ -174,7 +174,7 @@ public class PatternCell extends BackupImageView implements DownloadController.F
@Override
protected void onDraw(Canvas canvas) {
float intensity = delegate.getIntensity();
imageReceiver.setAlpha(Math.abs(intensity));
//imageReceiver.setAlpha(Math.abs(intensity));
imageReceiver.setBlendMode(null);
int backgroundColor = delegate.getBackgroundColor();

View File

@ -32,6 +32,7 @@ import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.DotDividerSpan;
import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.MediaActionDrawable;
import org.telegram.ui.Components.RadialProgress2;
@ -381,48 +382,6 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
}
}
@Override
protected void onDraw(Canvas canvas) {
if (viewType == VIEW_TYPE_GLOBAL_SEARCH) {
description2TextPaint.setColor(getThemedColor(Theme.key_windowBackgroundWhiteGrayText3));
}
if (dateLayout != null) {
canvas.save();
canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline) + (LocaleController.isRTL ? 0 : dateLayoutX), titleY);
dateLayout.draw(canvas);
canvas.restore();
}
if (titleLayout != null) {
canvas.save();
canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline) + (LocaleController.isRTL && dateLayout != null ? dateLayout.getWidth() + AndroidUtilities.dp(4) : 0), titleY);
titleLayout.draw(canvas);
canvas.restore();
}
if (captionLayout != null) {
captionTextPaint.setColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText));
canvas.save();
canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline), captionY);
captionLayout.draw(canvas);
canvas.restore();
}
if (descriptionLayout != null) {
Theme.chat_contextResult_descriptionTextPaint.setColor(getThemedColor(Theme.key_windowBackgroundWhiteGrayText2));
canvas.save();
canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline), descriptionY);
descriptionLayout.draw(canvas);
canvas.restore();
}
radialProgress.setProgressColor(getThemedColor(buttonPressed ? Theme.key_chat_inAudioSelectedProgress : Theme.key_chat_inAudioProgress));
radialProgress.draw(canvas);
if (needDivider) {
canvas.drawLine(AndroidUtilities.dp(72), getHeight() - 1, getWidth() - getPaddingRight(), getHeight() - 1, Theme.dividerPaint);
}
}
private int getMiniIconForCurrentState() {
if (miniButtonState < 0) {
@ -582,5 +541,80 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
Integer color = resourcesProvider != null ? resourcesProvider.getColor(key) : null;
return color != null ? color : Theme.getColor(key);
}
float enterAlpha = 1f;
FlickerLoadingView globalGradientView;
public void setGlobalGradientView(FlickerLoadingView globalGradientView) {
this.globalGradientView = globalGradientView;
}
@Override
protected void dispatchDraw(Canvas canvas) {
if (enterAlpha != 1f && globalGradientView != null) {
canvas.saveLayerAlpha(0, 0, getMeasuredWidth(), getMeasuredHeight(), (int) ((1f - enterAlpha) * 255), Canvas.ALL_SAVE_FLAG);
globalGradientView.setViewType(FlickerLoadingView.AUDIO_TYPE);
globalGradientView.updateColors();
globalGradientView.updateGradient();
globalGradientView.draw(canvas);
canvas.restore();
canvas.saveLayerAlpha(0, 0, getMeasuredWidth(), getMeasuredHeight(), (int) (enterAlpha * 255), Canvas.ALL_SAVE_FLAG);
drawInternal(canvas);
super.dispatchDraw(canvas);
canvas.restore();
} else {
drawInternal(canvas);
super.dispatchDraw(canvas);
}
}
private void drawInternal(Canvas canvas) {
if (viewType == VIEW_TYPE_GLOBAL_SEARCH) {
description2TextPaint.setColor(getThemedColor(Theme.key_windowBackgroundWhiteGrayText3));
}
if (dateLayout != null) {
canvas.save();
canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline) + (LocaleController.isRTL ? 0 : dateLayoutX), titleY);
dateLayout.draw(canvas);
canvas.restore();
}
if (titleLayout != null) {
canvas.save();
canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline) + (LocaleController.isRTL && dateLayout != null ? dateLayout.getWidth() + AndroidUtilities.dp(4) : 0), titleY);
titleLayout.draw(canvas);
canvas.restore();
}
if (captionLayout != null) {
captionTextPaint.setColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText));
canvas.save();
canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline), captionY);
captionLayout.draw(canvas);
canvas.restore();
}
if (descriptionLayout != null) {
Theme.chat_contextResult_descriptionTextPaint.setColor(getThemedColor(Theme.key_windowBackgroundWhiteGrayText2));
canvas.save();
canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline), descriptionY);
descriptionLayout.draw(canvas);
canvas.restore();
}
radialProgress.setProgressColor(getThemedColor(buttonPressed ? Theme.key_chat_inAudioSelectedProgress : Theme.key_chat_inAudioProgress));
radialProgress.draw(canvas);
if (needDivider) {
canvas.drawLine(AndroidUtilities.dp(72), getHeight() - 1, getWidth() - getPaddingRight(), getHeight() - 1, Theme.dividerPaint);
}
}
public void setEnterAnimationAlpha(float alpha) {
if (enterAlpha != alpha) {
this.enterAlpha = alpha;
invalidate();
}
}
}

View File

@ -45,6 +45,7 @@ import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.DotDividerSpan;
import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.LineProgressView;
import org.telegram.ui.Components.RLottieDrawable;
@ -89,6 +90,7 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
private CharSequence caption;
private RLottieDrawable statusDrawable;
private final Theme.ResourcesProvider resourcesProvider;
FlickerLoadingView globalGradientView;
public SharedDocumentCell(Context context) {
this(context, VIEW_TYPE_DEFAULT);
@ -190,7 +192,7 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
addView(captionTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 8 : 72, 30, LocaleController.isRTL ? 72 : 8, 0));
captionTextView.setVisibility(View.GONE);
} else {
nameTextView.setMaxLines(2);
nameTextView.setMaxLines(1);
addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 8 : 72, 5, LocaleController.isRTL ? 72 : 8, 0));
}
@ -563,9 +565,11 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (viewType == VIEW_TYPE_PICKER) {
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(64) + (needDivider ? 1 : 0), MeasureSpec.EXACTLY));
} else if (viewType == VIEW_TYPE_DEFAULT) {
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(56), MeasureSpec.EXACTLY));
} else {
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(56), MeasureSpec.EXACTLY));
int h = AndroidUtilities.dp(5 + 29) + nameTextView.getMeasuredHeight() + (needDivider ? 1 : 0);
int h = AndroidUtilities.dp(5 + 29) + nameTextView.getMeasuredHeight() + (needDivider ? 1 : 0);
if (caption != null && captionTextView != null && message.hasHighlightedWords()) {
ignoreRequestLayout = true;
captionTextView.setText(AndroidUtilities.ellipsizeCenterEnd(caption, message.highlightedWords.get(0), captionTextView.getMeasuredWidth(), captionTextView.getPaint(), 130));
@ -601,12 +605,6 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
}
}
@Override
protected void onDraw(Canvas canvas) {
if (needDivider) {
canvas.drawLine(AndroidUtilities.dp(72), getHeight() - 1, getWidth() - getPaddingRight(), getHeight() - 1, Theme.dividerPaint);
}
}
@Override
public void onFailedDownload(String name, boolean canceled) {
@ -650,4 +648,42 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
Integer color = resourcesProvider != null ? resourcesProvider.getColor(key) : null;
return color != null ? color : Theme.getColor(key);
}
float enterAlpha = 1f;
public void setGlobalGradientView(FlickerLoadingView globalGradientView) {
this.globalGradientView = globalGradientView;
}
@Override
protected void dispatchDraw(Canvas canvas) {
if (enterAlpha != 1f && globalGradientView != null) {
canvas.saveLayerAlpha(0, 0, getMeasuredWidth(), getMeasuredHeight(), (int) ((1f - enterAlpha) * 255), Canvas.ALL_SAVE_FLAG);
globalGradientView.setViewType(FlickerLoadingView.FILES_TYPE);
globalGradientView.updateColors();
globalGradientView.updateGradient();
globalGradientView.draw(canvas);
canvas.restore();
canvas.saveLayerAlpha(0, 0, getMeasuredWidth(), getMeasuredHeight(), (int) (enterAlpha * 255), Canvas.ALL_SAVE_FLAG);
super.dispatchDraw(canvas);
drawDivider(canvas);
canvas.restore();
} else {
super.dispatchDraw(canvas);
drawDivider(canvas);
}
}
private void drawDivider(Canvas canvas) {
if (needDivider) {
canvas.drawLine(AndroidUtilities.dp(72), getHeight() - 1, getWidth() - getPaddingRight(), getHeight() - 1, Theme.dividerPaint);
}
}
public void setEnterAnimationAlpha(float alpha) {
if (enterAlpha != alpha) {
this.enterAlpha = alpha;
invalidate();
}
}
}

View File

@ -0,0 +1,467 @@
package org.telegram.ui.Cells;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.SparseArray;
import android.view.Gravity;
import android.view.View;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils;
import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.DownloadController;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.CheckBoxBase;
import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.PhotoViewer;
public class SharedPhotoVideoCell2 extends View {
public ImageReceiver imageReceiver = new ImageReceiver();
int currentAccount;
MessageObject currentMessageObject;
int currentParentColumnsCount;
FlickerLoadingView globalGradientView;
SharedPhotoVideoCell2 crossfadeView;
float imageAlpha = 1f;
float imageScale = 1f;
boolean showVideoLayout;
StaticLayout videoInfoLayot;
String videoText;
CheckBoxBase checkBoxBase;
SharedResources sharedResources;
private boolean attached;
float crossfadeProgress;
float crossfadeToColumnsCount;
float highlightProgress;
static long lastUpdateDownloadSettingsTime;
static boolean lastAutoDownload;
public SharedPhotoVideoCell2(Context context, SharedResources sharedResources, int currentAccount) {
super(context);
this.sharedResources = sharedResources;
this.currentAccount = currentAccount;
setChecked(false, false);
imageReceiver.setParentView(this);
}
public void setMessageObject(MessageObject messageObject, int parentColumnsCount) {
int oldParentColumsCount = currentParentColumnsCount;
currentParentColumnsCount = parentColumnsCount;
if (currentMessageObject == null && messageObject == null) {
return;
}
if (currentMessageObject != null && messageObject != null && currentMessageObject.getId() == messageObject.getId() && oldParentColumsCount == parentColumnsCount) {
return;
}
currentMessageObject = messageObject;
if (messageObject == null) {
imageReceiver.onDetachedFromWindow();
videoText = null;
videoInfoLayot = null;
showVideoLayout = false;
return;
} else {
if (attached) {
imageReceiver.onAttachedToWindow();
}
}
String restrictionReason = MessagesController.getRestrictionReason(messageObject.messageOwner.restriction_reason);
String imageFilter;
int stride;
int width = (int) (AndroidUtilities.displaySize.x / parentColumnsCount / AndroidUtilities.density);
imageFilter = sharedResources.getFilterString(width);
boolean showImageStub = false;
if (parentColumnsCount <= 2) {
stride = AndroidUtilities.getPhotoSize();
} else if (parentColumnsCount == 3) {
stride = 320;
} else if (parentColumnsCount == 5) {
stride = 320;
} else {
stride = 320;
}
videoText = null;
videoInfoLayot = null;
showVideoLayout = false;
if (!TextUtils.isEmpty(restrictionReason)) {
showImageStub = true;
} else if (messageObject.isVideo()) {
showVideoLayout = true;
if (parentColumnsCount != 9) {
videoText = AndroidUtilities.formatShortDuration(messageObject.getDuration());
}
if (messageObject.mediaThumb != null) {
if (messageObject.strippedThumb != null) {
imageReceiver.setImage(messageObject.mediaThumb, imageFilter, messageObject.strippedThumb, null, messageObject, 0);
} else {
imageReceiver.setImage(messageObject.mediaThumb, imageFilter, messageObject.mediaSmallThumb, imageFilter + "_b", null, 0, null, messageObject, 0);
}
} else {
TLRPC.Document document = messageObject.getDocument();
TLRPC.PhotoSize thumb = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 50);
TLRPC.PhotoSize qualityThumb = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, stride);
if (thumb == qualityThumb) {
qualityThumb = null;
}
if (thumb != null) {
if (messageObject.strippedThumb != null) {
imageReceiver.setImage(ImageLocation.getForDocument(qualityThumb, document), imageFilter, messageObject.strippedThumb, null, messageObject, 0);
} else {
imageReceiver.setImage(ImageLocation.getForDocument(qualityThumb, document), imageFilter, ImageLocation.getForDocument(thumb, document), imageFilter + "_b", null, 0, null, messageObject, 0);
}
} else {
showImageStub = true;
}
}
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && messageObject.messageOwner.media.photo != null && !messageObject.photoThumbs.isEmpty()) {
if (messageObject.mediaExists || canAutoDownload(messageObject)) {
if (messageObject.mediaThumb != null) {
if (messageObject.strippedThumb != null) {
imageReceiver.setImage(messageObject.mediaThumb, imageFilter, messageObject.strippedThumb, null, messageObject, 0);
} else {
imageReceiver.setImage(messageObject.mediaThumb, imageFilter, messageObject.mediaSmallThumb, imageFilter + "_b", null, 0, null, messageObject, 0);
}
} else {
TLRPC.PhotoSize currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 50);
TLRPC.PhotoSize currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, stride, false, currentPhotoObjectThumb, false);
if (currentPhotoObject == currentPhotoObjectThumb) {
currentPhotoObjectThumb = null;
}
if (messageObject.strippedThumb != null) {
imageReceiver.setImage(ImageLocation.getForObject(currentPhotoObject, messageObject.photoThumbsObject), imageFilter, null, null, messageObject.strippedThumb, currentPhotoObject != null ? currentPhotoObject.size : 0, null, messageObject, messageObject.shouldEncryptPhotoOrVideo() ? 2 : 1);
} else {
imageReceiver.setImage(ImageLocation.getForObject(currentPhotoObject, messageObject.photoThumbsObject), imageFilter, ImageLocation.getForObject(currentPhotoObjectThumb, messageObject.photoThumbsObject), imageFilter + "_b", currentPhotoObject != null ? currentPhotoObject.size : 0, null, messageObject, messageObject.shouldEncryptPhotoOrVideo() ? 2 : 1);
}
}
} else {
if (messageObject.strippedThumb != null) {
imageReceiver.setImage(null, null, null, null, messageObject.strippedThumb, 0, null, messageObject, 0);
} else {
imageReceiver.clearImage();
}
}
} else {
showImageStub = true;
}
if (showImageStub) {
imageReceiver.setImageBitmap(ContextCompat.getDrawable(getContext(), R.drawable.photo_placeholder_in));
}
invalidate();
}
private boolean canAutoDownload(MessageObject messageObject) {
if (System.currentTimeMillis() - lastUpdateDownloadSettingsTime > 5000) {
lastUpdateDownloadSettingsTime = System.currentTimeMillis();
lastAutoDownload = DownloadController.getInstance(currentAccount).canDownloadMedia(messageObject);
}
return lastAutoDownload;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float padding;
if (crossfadeProgress != 0 && (crossfadeToColumnsCount == 9 || currentParentColumnsCount == 9)) {
if (crossfadeToColumnsCount == 9) {
padding = AndroidUtilities.dp(0.5f) * crossfadeProgress + AndroidUtilities.dpf2(1) * (1f - crossfadeProgress);
} else {
padding = AndroidUtilities.dp(1f) * crossfadeProgress + AndroidUtilities.dpf2(0.5f) * (1f - crossfadeProgress);
}
} else {
padding = currentParentColumnsCount == 9 ? AndroidUtilities.dpf2(0.5f) : AndroidUtilities.dpf2(1);
}
float imageWidth = (getMeasuredWidth() - padding * 2) * imageScale;
float imageHeight = (getMeasuredHeight() - padding * 2) * imageScale;
if (crossfadeProgress > 0.5f && crossfadeToColumnsCount != 9 && currentParentColumnsCount != 9) {
imageWidth -= 2;
imageHeight -= 2;
}
if (currentMessageObject == null || !imageReceiver.hasBitmapImage() || imageReceiver.getCurrentAlpha() != 1.0f || imageAlpha != 1f) {
if (SharedPhotoVideoCell2.this.getParent() != null) {
globalGradientView.setParentSize(((View) SharedPhotoVideoCell2.this.getParent()).getMeasuredWidth(), SharedPhotoVideoCell2.this.getMeasuredHeight(), -getX());
globalGradientView.updateColors();
globalGradientView.updateGradient();
float localPadding = padding;
if (crossfadeProgress > 0.5f && crossfadeToColumnsCount != 9 && currentParentColumnsCount != 9) {
localPadding += 1;
}
canvas.drawRect(localPadding, localPadding, localPadding + imageWidth, localPadding + imageHeight, globalGradientView.getPaint());
}
invalidate();
}
if (currentMessageObject == null) {
return;
}
if (imageAlpha != 1f) {
canvas.saveLayerAlpha(0,0, padding * 2 + imageWidth, padding * 2 + imageHeight, (int) (255 * imageAlpha), Canvas.ALL_SAVE_FLAG);
} else {
canvas.save();
}
if ((checkBoxBase != null && checkBoxBase.isChecked()) || PhotoViewer.isShowingImage(currentMessageObject)) {
canvas.drawRect(padding, padding, imageWidth, imageHeight, sharedResources.backgroundPaint);
}
if (currentMessageObject != null) {
if (checkBoxProgress > 0) {
float offset = AndroidUtilities.dp(10) * checkBoxProgress;
imageReceiver.setImageCoords(padding + offset, padding + offset, imageWidth - offset * 2, imageHeight - offset * 2);
} else {
float localPadding = padding;
if (crossfadeProgress > 0.5f && crossfadeToColumnsCount != 9 && currentParentColumnsCount != 9) {
localPadding += 1;
}
imageReceiver.setImageCoords(localPadding, localPadding, imageWidth, imageHeight);
}
if (!PhotoViewer.isShowingImage(currentMessageObject)) {
imageReceiver.draw(canvas);
if (highlightProgress > 0) {
sharedResources.highlightPaint.setColor(ColorUtils.setAlphaComponent(Color.BLACK, (int) (0.5f * highlightProgress * 255)));
canvas.drawRect(imageReceiver.getDrawRegion(), sharedResources.highlightPaint);
}
}
}
if (showVideoLayout) {
canvas.save();
canvas.clipRect(padding, padding, padding + imageWidth, padding + imageHeight);
if (currentParentColumnsCount != 9 && videoInfoLayot == null && videoText != null) {
int textWidth = (int) Math.ceil(sharedResources.textPaint.measureText(videoText));
videoInfoLayot = new StaticLayout(videoText, sharedResources.textPaint, textWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
}
int width;
if (videoInfoLayot == null) {
width = AndroidUtilities.dp(17);
} else {
width = AndroidUtilities.dp(14) + videoInfoLayot.getWidth() + AndroidUtilities.dp(4);
}
canvas.translate(AndroidUtilities.dp(5), AndroidUtilities.dp(1) + imageHeight - AndroidUtilities.dp(17) - AndroidUtilities.dp(4));
AndroidUtilities.rectTmp.set(0, 0, width, AndroidUtilities.dp(17));
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(4), AndroidUtilities.dp(4), Theme.chat_timeBackgroundPaint);
canvas.save();
canvas.translate(videoInfoLayot == null ? AndroidUtilities.dp(5) : AndroidUtilities.dp(4), (AndroidUtilities.dp(17) - sharedResources.playDrawable.getIntrinsicHeight()) / 2f);
sharedResources.playDrawable.setAlpha((int) (255 * imageAlpha));
sharedResources.playDrawable.draw(canvas);
canvas.restore();
if (videoInfoLayot != null) {
canvas.translate(AndroidUtilities.dp(14), (AndroidUtilities.dp(17) - videoInfoLayot.getHeight()) / 2f);
videoInfoLayot.draw(canvas);
}
canvas.restore();
}
if (checkBoxBase != null && checkBoxBase.getProgress() != 0) {
canvas.save();
canvas.translate(imageWidth + AndroidUtilities.dp(2) - AndroidUtilities.dp(25), 0);
checkBoxBase.draw(canvas);
canvas.restore();
}
canvas.restore();
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
attached = true;
if (checkBoxBase != null) {
checkBoxBase.onAttachedToWindow();
}
if (currentMessageObject != null) {
imageReceiver.onAttachedToWindow();
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
attached = false;
if (checkBoxBase != null) {
checkBoxBase.onDetachedFromWindow();
}
if (currentMessageObject != null) {
imageReceiver.onDetachedFromWindow();
}
}
public void setGradientView(FlickerLoadingView globalGradientView) {
this.globalGradientView = globalGradientView;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY));
}
public int getMessageId() {
return currentMessageObject != null ? currentMessageObject.getId() : 0;
}
public MessageObject getMessageObject() {
return currentMessageObject;
}
public void setImageAlpha(float alpha, boolean invalidate) {
if (this.imageAlpha != alpha) {
this.imageAlpha = alpha;
if (invalidate) {
invalidate();
}
}
}
public void setImageScale(float scale, boolean invalidate) {
if (this.imageScale != scale) {
this.imageScale = scale;
if (invalidate) {
invalidate();
}
}
}
public void setCrossfadeView(SharedPhotoVideoCell2 cell, float crossfadeProgress, int crossfadeToColumnsCount) {
crossfadeView = cell;
this.crossfadeProgress = crossfadeProgress;
this.crossfadeToColumnsCount = crossfadeToColumnsCount;
}
public void drawCrossafadeImage(Canvas canvas) {
if (crossfadeView != null) {
canvas.save();
canvas.translate(getX(), getY());
float scale = ((getMeasuredWidth() - AndroidUtilities.dp(2)) * imageScale) / (float) (crossfadeView.getMeasuredWidth() - AndroidUtilities.dp(2));
crossfadeView.setImageScale(scale, false);
crossfadeView.draw(canvas);
canvas.restore();
}
}
public View getCrossfadeView() {
return crossfadeView;
}
ValueAnimator animator;
float checkBoxProgress;
public void setChecked(final boolean checked, boolean animated) {
boolean currentIsChecked = checkBoxBase != null && checkBoxBase.isChecked();
if (currentIsChecked == checked) {
return;
}
if (checkBoxBase == null) {
checkBoxBase = new CheckBoxBase(this,21, null);
checkBoxBase.setColor(null, Theme.key_sharedMedia_photoPlaceholder, Theme.key_checkboxCheck);
checkBoxBase.setDrawUnchecked(false);
checkBoxBase.setBackgroundType(1);
checkBoxBase.setBounds(0, 0, AndroidUtilities.dp(24), AndroidUtilities.dp(24));
if (attached) {
checkBoxBase.onAttachedToWindow();
}
}
checkBoxBase.setChecked(checked, animated);
if (animator != null) {
ValueAnimator animatorFinal = animator;
animator = null;
animatorFinal.cancel();
}
if (animated) {
animator = ValueAnimator.ofFloat(checkBoxProgress, checked ? 1f : 0);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
checkBoxProgress = (float) valueAnimator.getAnimatedValue();
invalidate();
}
});
animator.setDuration(200);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (animator != null && animator.equals(animation)) {
checkBoxProgress = checked ? 1f : 0;
animator = null;
}
}
});
animator.start();
} else {
checkBoxProgress = checked ? 1f : 0;
}
invalidate();
}
public void startHighlight() {
}
public void setHighlightProgress(float p) {
if (highlightProgress != p) {
highlightProgress = p;
invalidate();
}
}
public void moveImageToFront() {
imageReceiver.moveImageToFront();
}
public static class SharedResources {
TextPaint textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
private Paint backgroundPaint = new Paint();
Drawable playDrawable;
Paint highlightPaint = new Paint();
SparseArray<String> imageFilters = new SparseArray<>();
public SharedResources(Context context) {
textPaint.setTextSize(AndroidUtilities.dp(12));
textPaint.setColor(Color.WHITE);
textPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
playDrawable = ContextCompat.getDrawable(context, R.drawable.play_mini_video);
playDrawable.setBounds(0, 0, playDrawable.getIntrinsicWidth(), playDrawable.getIntrinsicHeight());
backgroundPaint.setColor(Theme.getColor(Theme.key_sharedMedia_photoPlaceholder));
}
public String getFilterString(int width) {
String str = imageFilters.get(width);
if (str == null) {
str = width + "_" + width + "_isc";
imageFilters.put(width, str);
}
return str;
}
}
}

View File

@ -23,6 +23,7 @@ import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.RLottieImageView;
public class TextCell extends FrameLayout {
@ -34,7 +35,7 @@ public class TextCell extends FrameLayout {
private int leftPadding;
private boolean needDivider;
private int offsetFromImage = 71;
private int imageLeft = 21;
public int imageLeft = 21;
private boolean inDialogs;
public TextCell(Context context) {
@ -80,7 +81,7 @@ public class TextCell extends FrameLayout {
return textView;
}
public ImageView getImageView() {
public RLottieImageView getImageView() {
return imageView;
}
@ -179,7 +180,11 @@ public class TextCell extends FrameLayout {
textView.setText(text);
valueTextView.setText(null);
imageView.setColorFilter(null);
imageView.setImageDrawable(drawable);
if (drawable instanceof RLottieDrawable) {
imageView.setAnimation((RLottieDrawable) drawable);
} else {
imageView.setImageDrawable(drawable);
}
imageView.setVisibility(VISIBLE);
valueTextView.setVisibility(GONE);
valueImageView.setVisibility(GONE);
@ -246,4 +251,12 @@ public class TextCell extends FrameLayout {
}
}
}
public void setNeedDivider(boolean needDivider) {
if (this.needDivider != needDivider) {
this.needDivider = needDivider;
setWillNotDraw(!needDivider);
invalidate();
}
}
}

View File

@ -45,6 +45,7 @@ import org.telegram.messenger.Utilities;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.EmojiThemes;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.MotionBackgroundDrawable;
@ -64,7 +65,7 @@ import androidx.recyclerview.widget.RecyclerView;
public class ThemesHorizontalListCell extends RecyclerListView implements NotificationCenter.NotificationCenterDelegate {
private static byte[] bytes = new byte[1024];
public static byte[] bytes = new byte[1024];
private boolean drawDivider;
private LinearLayoutManager horizontalLayoutManager;
@ -73,7 +74,7 @@ public class ThemesHorizontalListCell extends RecyclerListView implements Notifi
private Theme.ThemeInfo prevThemeInfo;
private ThemesListAdapter adapter;
private ArrayList<Theme.ThemeInfo> darkThemes;
private ArrayList<Theme.ThemeInfo> customThemes;
private ArrayList<Theme.ThemeInfo> defaultThemes;
private int currentType;
private int prevCount;
@ -104,7 +105,7 @@ public class ThemesHorizontalListCell extends RecyclerListView implements Notifi
if (position < defaultThemes.size()) {
arrayList = defaultThemes;
} else {
arrayList = darkThemes;
arrayList = customThemes;
p -= defaultThemes.size();
}
view.setTheme(arrayList.get(p), position == getItemCount() - 1, position == 0);
@ -112,7 +113,7 @@ public class ThemesHorizontalListCell extends RecyclerListView implements Notifi
@Override
public int getItemCount() {
return prevCount = defaultThemes.size() + darkThemes.size();
return prevCount = defaultThemes.size() + customThemes.size();
}
}
@ -683,10 +684,10 @@ public class ThemesHorizontalListCell extends RecyclerListView implements Notifi
}
}
public ThemesHorizontalListCell(Context context, int type, ArrayList<Theme.ThemeInfo> def, ArrayList<Theme.ThemeInfo> dark) {
public ThemesHorizontalListCell(Context context, int type, ArrayList<Theme.ThemeInfo> def, ArrayList<Theme.ThemeInfo> custom) {
super(context);
darkThemes = dark;
customThemes = custom;
defaultThemes = def;
currentType = type;
@ -738,11 +739,11 @@ public class ThemesHorizontalListCell extends RecyclerListView implements Notifi
if (!TextUtils.isEmpty(themeInfo.assetName)) {
Theme.PatternsLoader.createLoader(false);
}
if (currentType != ThemeActivity.THEME_TYPE_OTHER) {
SharedPreferences.Editor editor = ApplicationLoader.applicationContext.getSharedPreferences("themeconfig", Activity.MODE_PRIVATE).edit();
editor.putString(currentType == ThemeActivity.THEME_TYPE_NIGHT || themeInfo.isDark() ? "lastDarkTheme" : "lastDayTheme", themeInfo.getKey());
editor.commit();
}
SharedPreferences.Editor editor = ApplicationLoader.applicationContext.getSharedPreferences("themeconfig", Activity.MODE_PRIVATE).edit();
editor.putString(currentType == ThemeActivity.THEME_TYPE_NIGHT || themeInfo.isDark() ? "lastDarkTheme" : "lastDayTheme", themeInfo.getKey());
editor.commit();
if (currentType == ThemeActivity.THEME_TYPE_NIGHT) {
if (themeInfo == Theme.getCurrentNightTheme()) {
return;
@ -763,6 +764,7 @@ public class ThemesHorizontalListCell extends RecyclerListView implements Notifi
((InnerThemeView) child).updateCurrentThemeCheck();
}
}
EmojiThemes.saveCustomTheme(themeInfo, themeInfo.currentAccentId);
}
public void setDrawDivider(boolean draw) {
@ -922,7 +924,7 @@ public class ThemesHorizontalListCell extends RecyclerListView implements Notifi
prevThemeInfo = currentType == ThemeActivity.THEME_TYPE_NIGHT ? Theme.getCurrentNightTheme() : Theme.getCurrentTheme();
int index = defaultThemes.indexOf(prevThemeInfo);
if (index < 0) {
index = darkThemes.indexOf(prevThemeInfo) + defaultThemes.size();
index = customThemes.indexOf(prevThemeInfo) + defaultThemes.size();
if (index < 0) {
return;
}

View File

@ -149,7 +149,7 @@ import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BackDrawable;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.BottomSheet;
import org.telegram.ui.ActionBar.ChatTheme;
import org.telegram.ui.ActionBar.EmojiThemes;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ActionBar.ThemeDescription;
@ -235,6 +235,7 @@ import org.telegram.ui.Components.URLSpanUserMention;
import org.telegram.ui.Components.UndoView;
import org.telegram.ui.Components.ViewHelper;
import org.telegram.ui.Components.voip.VoIPHelper;
import org.telegram.ui.Delegates.ChatActivityMemberRequestsDelegate;
import java.io.BufferedWriter;
import java.io.File;
@ -749,6 +750,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private boolean isPauseOnThemePreview;
private ChatThemeBottomSheet chatThemeBottomSheet;
private ThemeDelegate themeDelegate;
private ChatActivityMemberRequestsDelegate pendingRequestsDelegate;
private final static int[] allowedNotificationsDuringChatListAnimations = new int[]{
NotificationCenter.messagesRead,
@ -1897,7 +1899,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (chatMessageCellsCache.isEmpty()) {
for (int a = 0; a < 15; a++) {
chatMessageCellsCache.add(new ChatMessageCell(context, themeDelegate));
chatMessageCellsCache.add(new ChatMessageCell(context, true, themeDelegate));
}
}
for (int a = 1; a >= 0; a--) {
@ -2128,10 +2130,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
updatePinnedMessageView(true);
updateVisibleRows();
} else if (id == chat_menu_attach) {
if (chatAttachAlert != null) {
chatAttachAlert.setEditingMessageObject(null);
}
openAttachMenu();
ActionBarMenuSubItem attach = new ActionBarMenuSubItem(context, false, true, true, getResourceProvider());
attach.setTextAndIcon(LocaleController.getString("AttachMenu", R.string.AttachMenu), R.drawable.input_attach);
attach.setOnClickListener(view -> {
headerItem.closeSubMenu();
if (chatAttachAlert != null) {
chatAttachAlert.setEditingMessageObject(null);
}
openAttachMenu();
});
headerItem.toggleSubMenu(attach, attachItem);
} else if (id == bot_help) {
getSendMessagesHelper().sendMessage("/help", dialog_id, null, null, null, false, null, null, null, true, 0, null);
} else if (id == bot_settings) {
@ -2910,7 +2918,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (child != scrimView && (scrimGroup == null || scrimGroup != group) || child.getAlpha() == 0f) {
continue;
}
if (!groupedBackgroundWasDraw && cell != null && scrimGroup != null && scrimGroup.transitionParams.cell != null) {
float x = scrimGroup.transitionParams.cell.getNonAnimationTranslationX(true);
@ -2970,6 +2977,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
canvas.clipRect(viewClipLeft, viewClipTop, viewClipRight, viewClipBottom);
canvas.translate(chatListView.getLeft() + child.getX(), chatListView.getY() + child.getY());
if (cell != null && scrimGroup == null && cell.drawBackgroundInParent()) {
cell.drawBackgroundInternal(canvas, true);
}
child.draw(canvas);
canvas.restore();
@ -4020,7 +4030,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
c.translate(0, getMeasuredHeight() - transitionOffset);
if (pullingDownDrawable == null) {
pullingDownDrawable = new ChatPullingDownDrawable(currentAccount, fragmentView, dialog_id, dialogFolderId, dialogFilterId, themeDelegate);
pullingDownDrawable.showBottomPanel(true);
pullingDownDrawable.onAttach();
}
pullingDownDrawable.setWidth(getMeasuredWidth());
@ -4088,6 +4097,18 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} else if (child instanceof ChatMessageCell) {
ChatMessageCell cell = (ChatMessageCell) child;
MessageObject.GroupedMessages group = cell.getCurrentMessagesGroup();
if (scrimView != cell && group == null && cell.drawBackgroundInParent()) {
canvas.save();
canvas.translate(cell.getX(), cell.getY());
if (cell.getScaleX() != 1f) {
canvas.scale(
cell.getScaleX(), cell.getScaleY(),
cell.getPivotX(), (cell.getHeight() >> 1)
);
}
cell.drawBackgroundInternal(canvas, true);
canvas.restore();
}
if (group != null && group == lastDrawnGroup) {
continue;
}
@ -4146,6 +4167,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
canvas.restore();
}
}
} else if (child instanceof ChatActionCell) {
ChatActionCell cell = (ChatActionCell) child;
if (cell.hasGradientService()) {
canvas.save();
canvas.translate(cell.getX(), cell.getY());
canvas.scale(cell.getScaleX(), cell.getScaleY(), cell.getMeasuredWidth() / 2f, cell.getMeasuredHeight() / 2f);
cell.drawBackground(canvas, true);
canvas.restore();
}
}
}
MessageObject.GroupedMessages scrimGroup = null;
@ -5034,8 +5064,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} else {
chatListView.setOverScrollMode(View.OVER_SCROLL_NEVER);
}
if (pullingDownDrawable != null && chatListView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING) {
pullingDownDrawable.showBottomPanel(pullingDownOffset > 0);
if (pullingDownDrawable != null) {
pullingDownDrawable.showBottomPanel(pullingDownOffset > 0 && chatListView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING);
}
return scrolled;
}
@ -5240,7 +5270,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
progressBar.setProgressColor(getThemedColor(Theme.key_chat_serviceText));
progressView.addView(progressBar, LayoutHelper.createFrame(32, 32, Gravity.CENTER));
floatingDateView = new ChatActionCell(context, themeDelegate) {
floatingDateView = new ChatActionCell(context, false, themeDelegate) {
@Override
public void setTranslationY(float translationY) {
@ -5302,6 +5332,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
jumpToDate((int) (calendar.getTime().getTime() / 1000));
});
if (currentChat != null) {
pendingRequestsDelegate = new ChatActivityMemberRequestsDelegate(this, currentChat, this::invalidateChatListViewTopPadding);
pendingRequestsDelegate.setChatInfo(chatInfo, false);
contentView.addView(pendingRequestsDelegate.getView(), ViewGroup.LayoutParams.MATCH_PARENT, pendingRequestsDelegate.getViewHeight());
}
if (currentEncryptedChat == null) {
pinnedMessageView = new FrameLayout(context) {
@ -6666,9 +6702,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
});
changeBoundAnimator.setDuration(ChatListItemAnimator.DEFAULT_DURATION);
// if (chatActivityEnterViewAnimateBeforeSending) {
// changeBoundAnimator.setStartDelay(20);
// }
changeBoundAnimator.setInterpolator(ChatListItemAnimator.DEFAULT_INTERPOLATOR);
if (!waitingForSendingMessageLoad) {
changeBoundAnimator.start();
@ -7730,7 +7763,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} else {
decorView = contentView;
}
pinchToZoomHelper = new PinchToZoomHelper(decorView) {
pinchToZoomHelper = new PinchToZoomHelper(decorView, contentView) {
@Override
protected void drawOverlays(Canvas canvas, float alpha, float parentOffsetX, float parentOffsetY, float clipTop, float clipBottom) {
if (alpha > 0) {
@ -8001,7 +8034,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
infoTopViewAnimator.cancel();
}
if (infoTopView == null) {
infoTopView = new ChatActionCell(contentView.getContext(), themeDelegate);
infoTopView = new ChatActionCell(contentView.getContext(), false, themeDelegate);
infoTopView.setCustomText(text);
infoTopView.setInvalidateColors(true);
infoTopView.setOnClickListener(onClickListener);
@ -8382,9 +8415,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (pinnedMessageView != null && pinnedMessageView.getVisibility() == View.VISIBLE) {
pinnedViewH = Math.max(0, AndroidUtilities.dp(48) + pinnedMessageEnterOffset);
}
float pendingViewH = 0;
View pendingRequestsView = pendingRequestsDelegate != null ? pendingRequestsDelegate.getView() : null;
if (pendingRequestsView != null && pendingRequestsView.getVisibility() == View.VISIBLE) {
pendingViewH = Math.max(0, pendingRequestsView.getHeight() + pendingRequestsDelegate.getViewEnterOffset());
}
float oldPadding = chatListViewPaddingTop;
chatListViewPaddingTopOnlyTopViews = topPanelViewH + pinnedViewH;
chatListViewPaddingTop = AndroidUtilities.dp(4) + contentPaddingTop + topPanelViewH + pinnedViewH;
chatListViewPaddingTop = AndroidUtilities.dp(4) + contentPaddingTop + topPanelViewH + pinnedViewH + pendingViewH;
chatListViewPaddingVisibleOffset = 0;
chatListViewPaddingTop += contentPanTranslation + bottomPanelTranslationY;
@ -8485,10 +8523,17 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
chatListView.invalidate();
}
float topPanelViewH = Math.max(0, AndroidUtilities.dp(48) + topChatPanelViewOffset);
float translation = contentPanTranslation + contentPaddingTop + Math.max(0, AndroidUtilities.dp(48) + topChatPanelViewOffset);
if (pinnedMessageView != null) {
pinnedMessageView.setTranslationY(contentPanTranslation + pinnedMessageEnterOffset + contentPaddingTop + topPanelViewH);
translation += pinnedMessageEnterOffset;
pinnedMessageView.setTranslationY(translation);
translation += AndroidUtilities.dp(48);
}
View pendingRequestsView = pendingRequestsDelegate != null ? pendingRequestsDelegate.getView() : null;
if (pendingRequestsView != null) {
translation += pendingRequestsDelegate.getViewEnterOffset();
pendingRequestsView.setTranslationY(translation);
translation += pendingRequestsDelegate.getViewHeight();
}
if (fragmentContextView != null) {
float from = 0;
@ -8961,6 +9006,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
fillEditingMediaWithCaption(photos.get(0).caption, photos.get(0).entities);
SendMessagesHelper.prepareSendingMedia(getAccountInstance(), photos, dialog_id, replyingMessageObject, getThreadMessage(), null, button == 4 || forceDocument, arg, editingMessageObject, notify, scheduleDate);
afterMessageSend();
chatActivityEnterView.setFieldText("");
}
if (scheduleDate != 0) {
if (scheduledMessagesCount == -1) {
@ -9686,6 +9732,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
chatAttachAlert.setMaxSelectedPhotos(-1, true);
}
chatAttachAlert.init();
chatAttachAlert.getCommentTextView().setText(chatActivityEnterView.getFieldText());
showDialog(chatAttachAlert);
}
@ -11529,7 +11576,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private int getHeightForMessage(MessageObject object) {
if (dummyMessageCell == null) {
dummyMessageCell = new ChatMessageCell(getParentActivity(), themeDelegate);
dummyMessageCell = new ChatMessageCell(getParentActivity(), true, themeDelegate);
}
dummyMessageCell.isChat = currentChat != null || UserObject.isUserSelf(currentUser);
dummyMessageCell.isBot = currentUser != null && currentUser.bot;
@ -12869,7 +12916,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
String tempPath = AndroidUtilities.getPath(uri);
String originalPath = tempPath;
if (tempPath == null) {
if (tempPath == null || !BuildVars.NO_SCOPED_STORAGE) {
originalPath = uri.toString();
tempPath = MediaController.copyFileToCache(uri, "file");
}
@ -12939,6 +12986,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} else {
showAttachmentError();
}
if (chatAttachAlert != null) {
chatAttachAlert.dismiss();
}
afterMessageSend();
}
}
@ -12986,7 +13036,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
doNotRemoveLoadIndex = false;
}
if (!doNotRemoveLoadIndex && !fragmentBeginToShow && !paused) {
int[] alowedNotifications = new int[]{NotificationCenter.chatInfoDidLoad, NotificationCenter.groupCallUpdated, NotificationCenter.dialogsNeedReload, NotificationCenter.scheduledMessagesUpdated,
int[] alowedNotifications = new int[]{NotificationCenter.messagesDidLoad, NotificationCenter.chatInfoDidLoad, NotificationCenter.groupCallUpdated, NotificationCenter.dialogsNeedReload, NotificationCenter.scheduledMessagesUpdated,
NotificationCenter.closeChats, NotificationCenter.botKeyboardDidLoad, NotificationCenter.userInfoDidLoad, NotificationCenter.pinnedInfoDidLoad, NotificationCenter.needDeleteDialog/*, NotificationCenter.botInfoDidLoad*/};
if (transitionAnimationIndex == 0) {
transitionAnimationIndex = getNotificationCenter().setAnimationInProgress(transitionAnimationIndex, alowedNotifications);
@ -13709,6 +13759,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
chatAdapter.notifyDataSetChanged(true);
}
if (scrollToMessage != null) {
addSponsoredMessages(!isFirstLoading);
int yOffset;
boolean bottom = true;
if (startLoadFromMessageOffset != Integer.MAX_VALUE) {
@ -14584,6 +14635,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
checkGroupCallJoin((Boolean) args[3]);
checkThemeEmoticon();
if (pendingRequestsDelegate != null) {
pendingRequestsDelegate.setChatInfo(chatInfo, true);
}
}
} else if (id == NotificationCenter.chatInfoCantLoad) {
long chatId = (Long) args[0];
@ -15712,6 +15766,17 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (arrayList == null) {
return;
}
for (int i = 0; i < arrayList.size(); i++) {
MessageObject messageObject = arrayList.get(i);
messageObject.resetLayout();
long dialogId = MessageObject.getPeerId(messageObject.messageOwner.from_id);
int messageId = 0 ;
if (messageObject.sponsoredChannelPost != 0) {
messageId = messageObject.sponsoredChannelPost;
}
getMessagesController().ensureMessagesLoaded(dialogId, messageId, null);
}
sponsoredMessagesAdded = true;
processNewMessages(arrayList);
}
@ -15997,7 +16062,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} else {
object.replyMessageObject = update;
}
chatAdapter.updateRowWithMessageObject(object, true);
if (chatAdapter != null) {
chatAdapter.updateRowWithMessageObject(object, true);
}
}
}
if (update == null) {
@ -17330,6 +17397,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
parentLayout.fragmentsStack.remove(backToPreviousFragment);
}
}
if (pendingRequestsDelegate != null && backward) {
pendingRequestsDelegate.onBackToScreen();
}
} else {
getNotificationCenter().onAnimationFinish(transitionAnimationIndex);
}
@ -19956,7 +20027,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
});
scrimPopupContainerLayout.setOrientation(LinearLayout.VERTICAL);
boolean showMessageSeen = currentChat != null && message.isOutOwner() && message.isSent() && !message.isEditing() && !message.isSending() && !message.isSendError() && !message.isContentUnread() && !message.isUnread() && (ConnectionsManager.getInstance(currentAccount).getCurrentTime() - message.messageOwner.date < 7 * 86400) && (ChatObject.isMegagroup(currentChat) || !ChatObject.isChannel(currentChat)) && chatInfo != null && chatInfo.participants_count < 50;
boolean showMessageSeen = currentChat != null && message.isOutOwner() && message.isSent() && !message.isEditing() && !message.isSending() && !message.isSendError() && !message.isContentUnread() && !message.isUnread() && (ConnectionsManager.getInstance(currentAccount).getCurrentTime() - message.messageOwner.date < 7 * 86400) && (ChatObject.isMegagroup(currentChat) || !ChatObject.isChannel(currentChat)) && chatInfo != null && chatInfo.participants_count < 50 && !(message.messageOwner.action instanceof TLRPC.TL_messageActionChatJoinedByRequest);
MessageSeenView messageSeenView = null;
if (showMessageSeen) {
messageSeenView = new MessageSeenView(contentView.getContext(), currentAccount, message, currentChat);
@ -22484,7 +22555,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
view = chatMessageCellsCache.get(0);
chatMessageCellsCache.remove(0);
} else {
view = new ChatMessageCell(mContext, themeDelegate);
view = new ChatMessageCell(mContext, true, themeDelegate);
}
ChatMessageCell chatMessageCell = (ChatMessageCell) view;
chatMessageCell.setDelegate(new ChatMessageCell.ChatMessageCellDelegate() {
@ -23061,6 +23132,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} else {
args.putLong("user_id", peerId);
}
if (messageObject.sponsoredChannelPost != 0) {
args.putInt("message_id", messageObject.sponsoredChannelPost);
}
if (messageObject.botStartParam != null) {
args.putString("inline_query", messageObject.botStartParam);
}
@ -23151,7 +23225,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
chatMessageCell.setAllowAssistant(true);
}
} else if (viewType == 1) {
view = new ChatActionCell(mContext, themeDelegate) {
view = new ChatActionCell(mContext, true, themeDelegate) {
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
@ -24818,6 +24892,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
themeDescriptions.add(new ThemeDescription(chatActivityEnterView.botCommandsMenuContainer.listView, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{BotCommandsMenuView.BotCommandView.class}, new String[]{"description"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
themeDescriptions.add(new ThemeDescription(chatActivityEnterView.botCommandsMenuContainer.listView, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{BotCommandsMenuView.BotCommandView.class}, new String[]{"command"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText));
}
if (pendingRequestsDelegate != null) {
pendingRequestsDelegate.fillThemeDescriptions(themeDescriptions);
}
for (ThemeDescription description : themeDescriptions) {
description.resourcesProvider = themeDelegate;
@ -24830,7 +24907,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
return avatarContainer;
}
@Override
protected AnimatorSet onCustomTransitionAnimation(boolean isOpen, Runnable callback) {
if (isOpen && fromPullingDownTransition && getParentLayout().fragmentsStack.size() > 1) {
@ -25019,7 +25095,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private HashMap<String, Integer> currentColors = new HashMap<>();
private HashMap<String, Integer> animatingColors;
private ChatTheme chatTheme;
private EmojiThemes chatTheme;
private Drawable backgroundDrawable;
private ValueAnimator patternIntensityAnimator;
private Bitmap serviceBitmap;
@ -25027,9 +25103,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private Paint paint = new Paint();
private Canvas serviceCanvas;
private BitmapShader serviceShader;
private BitmapShader serviceShaderSource;
private boolean useSourceShader;
private int currentColor;
private boolean isDark;
private List<ChatTheme> cachedThemes;
private List<EmojiThemes> cachedThemes;
private AnimatorSet patternAlphaAnimator;
Theme.MessageDrawable animatingMessageDrawable;
@ -25046,15 +25124,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
}
if (!setup) {
Theme.refreshThemeColors(true, false);
Theme.refreshThemeColors(true, true);
}
}
public List<ChatTheme> getCachedThemes() {
public List<EmojiThemes> getCachedThemes() {
return cachedThemes;
}
public void setCachedThemes(List<ChatTheme> cachedThemes) {
public void setCachedThemes(List<EmojiThemes> cachedThemes) {
this.cachedThemes = cachedThemes;
}
@ -25126,7 +25204,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (chatTheme == null || serviceBitmap == null || serviceShader == null) {
ChatActionCell.ThemeDelegate.super.applyServiceShaderMatrix(w, h, translationX, translationY);
} else {
Theme.applyServiceShaderMatrix(serviceBitmap, serviceShader, actionMatrix, w, h, translationX, translationY);
if (useSourceShader) {
Theme.applyServiceShaderMatrix(serviceBitmapSource, serviceShaderSource, actionMatrix, w, h, translationX, translationY);
} else {
Theme.applyServiceShaderMatrix(serviceBitmap, serviceShader, actionMatrix, w, h, translationX, translationY);
}
}
}
@ -25154,7 +25236,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
return currentChat == null && currentEncryptedChat == null && !currentUser.bot && dialog_id >= 0;
}
public ChatTheme getCurrentTheme() {
public EmojiThemes getCurrentTheme() {
return chatTheme;
}
@ -25168,11 +25250,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
return chatTheme != null ? false : Theme.isWallpaperMotion();
}
public void setCurrentTheme(final ChatTheme chatTheme, boolean animated, Boolean forceDark) {
public void setCurrentTheme(final EmojiThemes chatTheme, boolean animated, Boolean forceDark) {
if (parentLayout == null) {
return;
}
final ChatTheme prevTheme = this.chatTheme;
final EmojiThemes prevTheme = this.chatTheme;
boolean newIsDark = forceDark != null ? forceDark : Theme.getActiveTheme().isDark();
String newEmoticon = chatTheme != null ? chatTheme.getEmoticon() : null;
String oldEmoticon = this.chatTheme != null ? this.chatTheme.getEmoticon() : null;
@ -25186,20 +25268,20 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (this.chatTheme == null) {
Drawable background = Theme.getCachedWallpaperNonBlocking();
isBackgroundMotion = background instanceof MotionBackgroundDrawable;
drawServiceGradient = background instanceof MotionBackgroundDrawable;
initServiceMessageColors(background);
startServiceTextColor = isBackgroundMotion ? 0xffffffff : Theme.getColor(Theme.key_chat_serviceText);
startServiceLinkColor = isBackgroundMotion ? 0xffffffff : Theme.getColor(Theme.key_chat_serviceLink);
startServiceButtonColor = isBackgroundMotion ? 0xffffffff : Theme.getColor(Theme.key_chat_serviceLink);
startServiceIconColor = isBackgroundMotion ? 0xffffffff : Theme.getColor(Theme.key_chat_serviceIcon);
} else if (isBackgroundMotion) {
startServiceTextColor = drawServiceGradient ? 0xffffffff : Theme.getColor(Theme.key_chat_serviceText);
startServiceLinkColor = drawServiceGradient ? 0xffffffff : Theme.getColor(Theme.key_chat_serviceLink);
startServiceButtonColor = drawServiceGradient ? 0xffffffff : Theme.getColor(Theme.key_chat_serviceLink);
startServiceIconColor = drawServiceGradient ? 0xffffffff : Theme.getColor(Theme.key_chat_serviceIcon);
} else if (drawServiceGradient) {
startServiceBitmap = ((MotionBackgroundDrawable) backgroundDrawable).getBitmap();
}
startServiceColor = currentServiceColor;
startServiceTextColor = isBackgroundMotion ? 0xffffffff : getCurrentColorOrDefault(Theme.key_chat_serviceText, true);
startServiceLinkColor = isBackgroundMotion ? 0xffffffff : getCurrentColorOrDefault(Theme.key_chat_serviceLink, true);
startServiceButtonColor = isBackgroundMotion ? 0xffffffff : getCurrentColorOrDefault(Theme.key_chat_serviceLink, true);
startServiceIconColor = isBackgroundMotion ? 0xffffffff : getCurrentColorOrDefault(Theme.key_chat_serviceIcon, true);
startServiceTextColor = drawServiceGradient ? 0xffffffff : getCurrentColorOrDefault(Theme.key_chat_serviceText, true);
startServiceLinkColor = drawServiceGradient ? 0xffffffff : getCurrentColorOrDefault(Theme.key_chat_serviceLink, true);
startServiceButtonColor = drawServiceGradient ? 0xffffffff : getCurrentColorOrDefault(Theme.key_chat_serviceLink, true);
startServiceIconColor = drawServiceGradient ? 0xffffffff : getCurrentColorOrDefault(Theme.key_chat_serviceIcon, true);
if (chatTheme != null) {
int[] colors = AndroidUtilities.calcDrawableColor(backgroundDrawable);
@ -25246,7 +25328,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
parentLayout.animateThemedValues(animationSettings);
}
private void setupChatTheme(ChatTheme chatTheme, boolean withAnimation, boolean createNewResources) {
private void setupChatTheme(EmojiThemes chatTheme, boolean withAnimation, boolean createNewResources) {
this.chatTheme = chatTheme;
Drawable prevDrawable = null;
@ -25256,7 +25338,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
final MotionBackgroundDrawable prevMotionDrawable = (prevDrawable instanceof MotionBackgroundDrawable) ? (MotionBackgroundDrawable) prevDrawable : null;
final int prevPhase = prevMotionDrawable != null ? prevMotionDrawable.getPhase() : 0;
if (chatTheme == null || chatTheme.isDefault) {
if (chatTheme == null || chatTheme.showAsDefaultStub) {
currentColor = Theme.getServiceMessageColor();
}
if (chatTheme == null) {
@ -25275,11 +25357,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} else {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("themeconfig", Activity.MODE_PRIVATE);
String dayThemeName = preferences.getString("lastDayTheme", "Blue");
if (Theme.getTheme(dayThemeName) == null) {
if (Theme.getTheme(dayThemeName) == null || Theme.getTheme(dayThemeName).isDark()) {
dayThemeName = "Blue";
}
String nightThemeName = preferences.getString("lastDarkTheme", "Dark Blue");
if (Theme.getTheme(nightThemeName) == null) {
if (Theme.getTheme(nightThemeName) == null || !Theme.getTheme(nightThemeName).isDark()) {
nightThemeName = "Dark Blue";
}
activeTheme = isDark ? Theme.getTheme(nightThemeName) : Theme.getTheme(dayThemeName);
@ -25287,7 +25369,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
Theme.applyTheme(activeTheme, false, isDark);
} else {
currentColors = chatTheme.getCurrentColors(currentAccount, isDark);
currentColors = chatTheme.getCurrentColors(currentAccount, isDark ? 1 : 0);
backgroundDrawable = getBackgroundDrawableFromTheme(chatTheme, prevPhase);
if (patternAlphaAnimator != null) {
@ -25428,7 +25510,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
Bitmap startServiceBitmap;
int currentServiceColor;
boolean isBackgroundMotion;
boolean drawServiceGradient;
private void initServiceMessageColors(Drawable backgroundDrawable) {
int[] result = AndroidUtilities.calcDrawableColor(backgroundDrawable);
@ -25441,14 +25523,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
currentServiceColor = serviceColor;
isBackgroundMotion = backgroundDrawable instanceof MotionBackgroundDrawable;
drawServiceGradient = backgroundDrawable instanceof MotionBackgroundDrawable && SharedConfig.getDevicePerformanceClass() != SharedConfig.PERFORMANCE_CLASS_LOW;
if (isBackgroundMotion) {
if (drawServiceGradient) {
serviceBitmap = Bitmap.createBitmap(60, 80, Bitmap.Config.ARGB_8888);
serviceBitmapSource = ((MotionBackgroundDrawable) backgroundDrawable).getBitmap();
serviceCanvas = new Canvas(serviceBitmap);
serviceCanvas.drawBitmap(serviceBitmapSource, 0, 0, null);
serviceShader = new BitmapShader(serviceBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
serviceShaderSource = new BitmapShader(serviceBitmapSource, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
useSourceShader = true;
} else {
serviceBitmap = null;
serviceShader = null;
@ -25458,15 +25542,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
Paint actionBackgroundSelectedPaint = getPaint(Theme.key_paint_chatActionBackgroundSelected);
if (actionBackgroundPaint != null) {
if (isBackgroundMotion) {
if (drawServiceGradient) {
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(((MotionBackgroundDrawable) backgroundDrawable).getIntensity() >= 0 ? 1.8f : 0.5f);
actionBackgroundPaint.setAlpha(127);
actionBackgroundPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
actionBackgroundPaint.setShader(serviceShader);
actionBackgroundPaint.setShader(serviceShaderSource);
actionBackgroundSelectedPaint.setAlpha(127);
actionBackgroundSelectedPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
actionBackgroundSelectedPaint.setShader(serviceShader);
actionBackgroundSelectedPaint.setShader(serviceShaderSource);
} else {
actionBackgroundPaint.setColorFilter(null);
actionBackgroundPaint.setShader(null);
@ -25484,10 +25568,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
Paint actionBackgroundSelectedPaint = getPaint(Theme.key_paint_chatActionBackgroundSelected);
int serviceColor = currentServiceColor;
int serviceTextColor = isBackgroundMotion ? 0xffffffff : getCurrentColorOrDefault(Theme.key_chat_serviceText, true);
int serviceLinkColor = isBackgroundMotion ? 0xffffffff : getCurrentColorOrDefault(Theme.key_chat_serviceLink, true);
int serviceButtonColor = isBackgroundMotion ? 0xffffffff : getCurrentColorOrDefault(Theme.key_chat_serviceLink, true);
int serviceIconColor = isBackgroundMotion ? 0xffffffff : getCurrentColorOrDefault(Theme.key_chat_serviceIcon, true);
int serviceTextColor = drawServiceGradient ? 0xffffffff : getCurrentColorOrDefault(Theme.key_chat_serviceText, true);
int serviceLinkColor = drawServiceGradient ? 0xffffffff : getCurrentColorOrDefault(Theme.key_chat_serviceLink, true);
int serviceButtonColor = drawServiceGradient ? 0xffffffff : getCurrentColorOrDefault(Theme.key_chat_serviceLink, true);
int serviceIconColor = drawServiceGradient ? 0xffffffff : getCurrentColorOrDefault(Theme.key_chat_serviceIcon, true);
if (progress != 1f) {
serviceColor = ColorUtils.blendARGB(startServiceColor, serviceColor, progress);
serviceTextColor = ColorUtils.blendARGB(startServiceTextColor, serviceTextColor, progress);
@ -25495,7 +25579,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
serviceButtonColor = ColorUtils.blendARGB(startServiceButtonColor, serviceButtonColor, progress);
serviceIconColor = ColorUtils.blendARGB(startServiceIconColor, serviceIconColor, progress);
}
if (actionBackgroundPaint != null && !isBackgroundMotion) {
if (actionBackgroundPaint != null && !drawServiceGradient) {
actionBackgroundPaint.setColor(serviceColor);
actionBackgroundSelectedPaint.setColor(serviceColor);
}
@ -25525,21 +25609,32 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (serviceCanvas != null && serviceBitmapSource != null) {
if (progress != 1f && startServiceBitmap != null) {
useSourceShader = false;
serviceCanvas.drawBitmap(startServiceBitmap, 0, 0, null);
paint.setAlpha((int) (255 * progress));
serviceCanvas.drawBitmap(serviceBitmapSource, 0, 0, paint);
if (actionBackgroundPaint != null) {
actionBackgroundPaint.setShader(serviceShader);
actionBackgroundSelectedPaint.setShader(serviceShader);
}
} else {
useSourceShader = true;
serviceCanvas.drawBitmap(serviceBitmapSource, 0, 0, null);
if (actionBackgroundPaint != null) {
actionBackgroundPaint.setShader(serviceShaderSource);
actionBackgroundSelectedPaint.setShader(serviceShaderSource);
}
}
}
}
private Drawable getBackgroundDrawableFromTheme(ChatTheme chatTheme, int prevPhase) {
private Drawable getBackgroundDrawableFromTheme(EmojiThemes chatTheme, int prevPhase) {
Drawable drawable;
if (chatTheme.isDefault) {
Theme.ThemeInfo themeInfo = ChatTheme.getDefaultThemeInfo(isDark);
HashMap<String, Integer> currentColors = chatTheme.getCurrentColors(currentAccount, isDark);
String wallpaperLink = chatTheme.getWallpaperLink(isDark);
if (chatTheme.showAsDefaultStub) {
Theme.ThemeInfo themeInfo = EmojiThemes.getDefaultThemeInfo(isDark);
HashMap<String, Integer> currentColors = chatTheme.getCurrentColors(currentAccount, isDark ? 1 : 0);
String wallpaperLink = chatTheme.getWallpaperLink(isDark ? 1 : 0);
Theme.BackgroundDrawableSettings settings = Theme.createBackgroundDrawable(themeInfo, currentColors, wallpaperLink, prevPhase);
drawable = settings.wallpaper;
} else {
@ -25552,22 +25647,22 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
MotionBackgroundDrawable motionDrawable = new MotionBackgroundDrawable();
motionDrawable.setPatternBitmap(chatTheme.getWallpaper(isDark).settings.intensity);
motionDrawable.setPatternBitmap(chatTheme.getWallpaper(isDark ? 1 : 0).settings.intensity);
motionDrawable.setColors(backgroundColor, gradientColor1, gradientColor2, gradientColor3, true);
motionDrawable.setPhase(prevPhase);
int patternColor = motionDrawable.getPatternColor();
final boolean isDarkTheme = isDark;
chatTheme.loadWallpaper(isDark, pair -> {
chatTheme.loadWallpaper(isDark ? 1 : 0, pair -> {
if (pair == null) {
return;
}
long themeId = pair.first;
Bitmap bitmap = pair.second;
if (this.chatTheme != null && themeId == this.chatTheme.getTlTheme(isDark).id && bitmap != null) {
if (this.chatTheme != null && themeId == this.chatTheme.getTlTheme(isDark ? 1 : 0).id && bitmap != null) {
if (patternIntensityAnimator != null) {
patternIntensityAnimator.cancel();
}
int intensity = chatTheme.getWallpaper(isDarkTheme).settings.intensity;
int intensity = chatTheme.getWallpaper(isDarkTheme ? 1 : 0).settings.intensity;
motionDrawable.setPatternBitmap(intensity, bitmap);
motionDrawable.setPatternColorFilter(patternColor);
patternIntensityAnimator = ValueAnimator.ofFloat(0, 1f);

View File

@ -111,6 +111,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
private LinearLayout infoContainer;
private TextCell membersCell;
private TextCell memberRequestsCell;
private TextCell inviteLinksCell;
private TextCell adminCell;
private TextCell blockCell;
@ -831,6 +832,15 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
presentFragment(fragment);
});
if (!ChatObject.isChannelAndNotMegaGroup(currentChat)) {
memberRequestsCell = new TextCell(context);
memberRequestsCell.setBackground(Theme.getSelectorDrawable(false));
memberRequestsCell.setOnClickListener(v -> {
MemberRequestsActivity activity = new MemberRequestsActivity(chatId);
presentFragment(activity);
});
}
if (ChatObject.isChannel(currentChat) || currentChat.gigagroup) {
logCell = new TextCell(context);
logCell.setTextAndIcon(LocaleController.getString("EventLog", R.string.EventLog), R.drawable.group_log, false);
@ -846,6 +856,9 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
}
infoContainer.addView(adminCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
infoContainer.addView(membersCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
if (memberRequestsCell != null && info != null && info.requests_pending > 0) {
infoContainer.addView(memberRequestsCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
}
if (isChannel) {
infoContainer.addView(inviteLinksCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
}
@ -1358,14 +1371,21 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
if (membersCell != null) {
if (info != null) {
if (memberRequestsCell != null) {
if (memberRequestsCell.getParent() == null) {
int position = infoContainer.indexOfChild(membersCell) + 1;
infoContainer.addView(memberRequestsCell, position, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
}
memberRequestsCell.setVisibility(info.requests_pending > 0 ? View.VISIBLE : View.GONE);
}
if (isChannel) {
membersCell.setTextAndValueAndIcon(LocaleController.getString("ChannelSubscribers", R.string.ChannelSubscribers), String.format("%d", info.participants_count), R.drawable.actions_viewmembers, true);
blockCell.setTextAndValueAndIcon(LocaleController.getString("ChannelBlacklist", R.string.ChannelBlacklist), String.format("%d", Math.max(info.banned_count, info.kicked_count)), R.drawable.actions_removed, logCell != null && logCell.getVisibility() == View.VISIBLE);
} else {
if (ChatObject.isChannel(currentChat)) {
membersCell.setTextAndValueAndIcon(LocaleController.getString("ChannelMembers", R.string.ChannelMembers), String.format("%d", info.participants_count), R.drawable.actions_viewmembers, logCell != null && logCell.getVisibility() == View.VISIBLE);
membersCell.setTextAndValueAndIcon(LocaleController.getString("ChannelMembers", R.string.ChannelMembers), String.format("%d", info.participants_count), R.drawable.actions_viewmembers, true);
} else {
membersCell.setTextAndValueAndIcon(LocaleController.getString("ChannelMembers", R.string.ChannelMembers), String.format("%d", info.participants.participants.size()), R.drawable.actions_viewmembers, logCell != null && logCell.getVisibility() == View.VISIBLE);
membersCell.setTextAndValueAndIcon(LocaleController.getString("ChannelMembers", R.string.ChannelMembers), String.format("%d", info.participants.participants.size()), R.drawable.actions_viewmembers, memberRequestsCell.getVisibility() == View.VISIBLE);
}
if (currentChat.gigagroup) {
blockCell.setTextAndValueAndIcon(LocaleController.getString("ChannelBlacklist", R.string.ChannelBlacklist), String.format("%d", Math.max(info.banned_count, info.kicked_count)), R.drawable.actions_removed, logCell != null && logCell.getVisibility() == View.VISIBLE);
@ -1401,6 +1421,9 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
}
blockCell.setTextAndValueAndIcon(LocaleController.getString("ChannelPermissions", R.string.ChannelPermissions), String.format("%d/%d", count, 8), R.drawable.actions_permissions, true);
}
if (memberRequestsCell != null) {
memberRequestsCell.setTextAndValueAndIcon(LocaleController.getString("MemberRequests", R.string.MemberRequests), String.format("%d", info.requests_pending), R.drawable.actions_requests, logCell != null && logCell.getVisibility() == View.VISIBLE);
}
}
adminCell.setTextAndValueAndIcon(LocaleController.getString("ChannelAdministrators", R.string.ChannelAdministrators), String.format("%d", ChatObject.isChannel(currentChat) ? info.admins_count : getAdminCount()), R.drawable.actions_addadmin, true);
} else {
@ -1466,6 +1489,11 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
themeDescriptions.add(new ThemeDescription(inviteLinksCell, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector));
themeDescriptions.add(new ThemeDescription(inviteLinksCell, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
themeDescriptions.add(new ThemeDescription(inviteLinksCell, 0, new Class[]{TextCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayIcon));
if (memberRequestsCell != null) {
themeDescriptions.add(new ThemeDescription(memberRequestsCell, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector));
themeDescriptions.add(new ThemeDescription(memberRequestsCell, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
themeDescriptions.add(new ThemeDescription(memberRequestsCell, 0, new Class[]{TextCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayIcon));
}
themeDescriptions.add(new ThemeDescription(blockCell, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector));
themeDescriptions.add(new ThemeDescription(blockCell, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText));

View File

@ -525,7 +525,10 @@ public class ChatPullingDownDrawable implements NotificationCenter.NotificationC
TLRPC.Dialog dialog = dialogs.get(i);
TLRPC.Chat chat = messagesController.getChat(-dialog.id);
if (chat != null && dialog.id != currentDialogId && dialog.unread_count > 0 && DialogObject.isChannel(dialog) && !chat.megagroup && !messagesController.isPromoDialog(dialog.id, false)) {
return dialog;
String reason = MessagesController.getRestrictionReason(chat.restriction_reason);
if (reason == null) {
return dialog;
}
}
}

View File

@ -2321,7 +2321,11 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
objects.addAll(res.participants);
for (int a = 0, size = res.participants.size(); a < size; a++) {
TLRPC.ChannelParticipant participant = res.participants.get(a);
map.put(MessageObject.getPeerId(participant.peer), participant);
if (participant.user_id == selfId) {
objects.remove(participant);
} else {
map.put(MessageObject.getPeerId(participant.peer), participant);
}
}
if (type == TYPE_USERS) {
for (int a = 0, N = participants.size(); a < N; a++) {
@ -2830,7 +2834,9 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
peerObject = user;
} else {
TLRPC.Chat chat = getMessagesController().getChat(-peerId);
un = chat.username;
if (chat != null) {
un = chat.username;
}
peerObject = chat;
}
} else if (object instanceof TLRPC.ChatParticipant) {

View File

@ -9,6 +9,7 @@
package org.telegram.ui.Components;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
@ -20,6 +21,7 @@ import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
@ -45,8 +47,10 @@ import android.util.TypedValue;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewOutlineProvider;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
@ -82,6 +86,7 @@ import org.telegram.tgnet.SerializedData;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBarMenuItem;
import org.telegram.ui.ActionBar.ActionBarPopupWindow;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.BottomSheet;
@ -123,7 +128,7 @@ public class AlertsCreator {
TLRPC.InputPeer peer;
if (request instanceof TLRPC.TL_messages_initHistoryImport) {
peer = ((TLRPC.TL_messages_initHistoryImport) request).peer;
} else if (request instanceof TLRPC.TL_messages_startHistoryImport) {
} else if (request instanceof TLRPC.TL_messages_startHistoryImport) {
peer = ((TLRPC.TL_messages_startHistoryImport) request).peer;
} else {
peer = null;
@ -865,7 +870,7 @@ public class AlertsCreator {
setting = NotificationsController.SETTING_MUTE_HOUR;
} else if (i == 2) {
setting = NotificationsController.SETTING_MUTE_2_DAYS;
} else if (i == 4){
} else if (i == 4) {
setting = NotificationsController.SETTING_MUTE_FOREVER;
}
if (setting >= 0) {
@ -1588,7 +1593,7 @@ public class AlertsCreator {
checkTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText4));
checkTextView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
dialogView.addView(checkTextView, LayoutHelper.createFrame(20, 20, LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT, 0, 14, 21, 0));
editTextView.setPadding(LocaleController.isRTL ? AndroidUtilities.dp(24) : 0, AndroidUtilities.dp(8), LocaleController.isRTL ? 0 : AndroidUtilities.dp(24), AndroidUtilities.dp(8));
editTextView.setPadding(LocaleController.isRTL ? AndroidUtilities.dp(24) : 0, AndroidUtilities.dp(8), LocaleController.isRTL ? 0 : AndroidUtilities.dp(24), AndroidUtilities.dp(8));
editTextView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
@ -1602,7 +1607,7 @@ public class AlertsCreator {
@Override
public void afterTextChanged(Editable s) {
int count = maxSymbolsCount - Character.codePointCount(s, 0, s.length());
int count = maxSymbolsCount - Character.codePointCount(s, 0, s.length());
if (count < 30) {
checkTextView.setNumber(count, checkTextView.getVisibility() == View.VISIBLE);
AndroidUtilities.updateViewVisibilityAnimated(checkTextView, true);
@ -3525,7 +3530,7 @@ public class AlertsCreator {
background.setBackground(new BitmapDrawable(SvgHelper.getBitmap(svg, AndroidUtilities.dp(320), AndroidUtilities.dp(320 * aspectRatio), false)));
frameLayout.addView(background, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, 0, -1, -1, -1, -1));
frameLayout.addView(button, LayoutHelper.createFrame(117,117));
frameLayout.addView(button, LayoutHelper.createFrame(117, 117));
builder.setTopView(frameLayout);
builder.setTitle(LocaleController.getString("PermissionDrawAboveOtherAppsGroupCallTitle", R.string.PermissionDrawAboveOtherAppsGroupCallTitle));
@ -4782,4 +4787,51 @@ public class AlertsCreator {
}
return result;
}
@SuppressLint("ClickableViewAccessibility")
public static ActionBarPopupWindow showPopupMenu(ActionBarPopupWindow.ActionBarPopupWindowLayout popupLayout, View anchorView, int offsetX, int offsetY) {
Rect rect = new Rect();
ActionBarPopupWindow popupWindow = new ActionBarPopupWindow(popupLayout, LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT);
if (Build.VERSION.SDK_INT >= 19) {
popupWindow.setAnimationStyle(0);
} else {
popupWindow.setAnimationStyle(R.style.PopupAnimation);
}
popupWindow.setAnimationEnabled(true);
popupWindow.setOutsideTouchable(true);
popupWindow.setClippingEnabled(true);
popupWindow.setInputMethodMode(ActionBarPopupWindow.INPUT_METHOD_NOT_NEEDED);
popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED);
popupWindow.setFocusable(true);
popupLayout.setFocusableInTouchMode(true);
popupLayout.setOnKeyListener((v, keyCode, event) -> {
if (keyCode == KeyEvent.KEYCODE_MENU && event.getRepeatCount() == 0 && event.getAction() == KeyEvent.ACTION_UP && popupWindow.isShowing()) {
popupWindow.dismiss();
return true;
}
return false;
});
popupLayout.measure(View.MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.x - AndroidUtilities.dp(40), View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.y, View.MeasureSpec.AT_MOST));
popupWindow.showAsDropDown(anchorView, offsetX, offsetY);
popupLayout.updateRadialSelectors();
popupWindow.startAnimation();
popupLayout.setOnTouchListener((v, event) -> {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
if (popupWindow != null && popupWindow.isShowing()) {
v.getHitRect(rect);
if (!rect.contains((int) event.getX(), (int) event.getY())) {
popupWindow.dismiss();
}
}
}
return false;
});
return popupWindow;
}
}

View File

@ -110,12 +110,12 @@ public class AudioVisualizerDrawable {
float rotation;
public void draw(Canvas canvas, float cx, float cy, boolean outOwner) {
public void draw(Canvas canvas, float cx, float cy, boolean outOwner, Theme.ResourcesProvider resourcesProvider) {
if (outOwner) {
p1.setColor(Theme.getColor(Theme.key_chat_outLoader));
p1.setColor(Theme.getColor(Theme.key_chat_outLoader, resourcesProvider));
p1.setAlpha(ALPHA);
} else {
p1.setColor(Theme.getColor(Theme.key_chat_inLoader));
p1.setColor(Theme.getColor(Theme.key_chat_inLoader, resourcesProvider));
p1.setAlpha(ALPHA);
}
this.draw(canvas, cx, cy);

View File

@ -33,7 +33,6 @@ import java.util.Random;
public class AvatarsImageView extends FrameLayout {
public final static int STYLE_GROUP_CALL_TOOLTIP = 10;
public final static int STYLE_MESSAGE_SEEN = 11;
@ -53,6 +52,7 @@ public class AvatarsImageView extends FrameLayout {
boolean centered;
private boolean isInCall;
protected int count;
public void commitTransition(boolean animated) {
if (!wasDraw || !animated) {
@ -472,4 +472,15 @@ public class AvatarsImageView extends FrameLayout {
public void setCentered(boolean centered) {
this.centered = centered;
}
public void setCount(int count) {
this.count = count;
requestLayout();
}
public void reset() {
for (int i = 0; i < animatingStates.length; ++i) {
setObject(0, 0, null);
}
}
}

View File

@ -923,6 +923,25 @@ public final class Bulletin {
}
}
@SuppressLint("ViewConstructor")
public static class MultiLineLayout extends ButtonLayout {
public final BackupImageView imageView = new BackupImageView(getContext());
public final TextView textView = new TextView(getContext());
public MultiLineLayout(@NonNull Context context, Theme.ResourcesProvider resourcesProvider) {
super(context, resourcesProvider);
addView(imageView, LayoutHelper.createFrameRelatively(30, 30, Gravity.START | Gravity.CENTER_VERTICAL, 12, 8, 12, 8));
textView.setGravity(Gravity.START);
textView.setPadding(0, AndroidUtilities.dp(8), 0, AndroidUtilities.dp(8));
textView.setTextColor(getThemedColor(Theme.key_undo_infoColor));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
textView.setTypeface(Typeface.SANS_SERIF);
addView(textView, LayoutHelper.createFrameRelatively(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.START | Gravity.CENTER_VERTICAL, 56, 0, 16, 0));
}
}
@SuppressLint("ViewConstructor")
public static class TwoLineLayout extends ButtonLayout {

View File

@ -2891,7 +2891,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
}
sendButtonContainer.addView(sendButton, LayoutHelper.createFrame(48, 48));
sendButton.setOnClickListener(view -> {
if (sendPopupWindow != null && sendPopupWindow.isShowing() || (runningAnimationAudio != null && runningAnimationAudio.isRunning())) {
if ((sendPopupWindow != null && sendPopupWindow.isShowing()) || (runningAnimationAudio != null && runningAnimationAudio.isRunning()) || moveToSendStateRunnable != null) {
return;
}
sendMessage();

View File

@ -2906,4 +2906,8 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
public BaseFragment getBaseFragment() {
return baseFragment;
}
public EditTextEmoji getCommentTextView() {
return commentTextView;
}
}

View File

@ -25,7 +25,6 @@ import android.widget.FrameLayout;
import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
@ -42,7 +41,6 @@ import org.telegram.ui.ActionBar.ThemeDescription;
import java.util.ArrayList;
import java.util.HashMap;
import androidx.collection.LongSparseArray;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.RecyclerView;
@ -674,8 +672,9 @@ public class ChatAttachAlertContactsLayout extends ChatAttachAlert.AttachAlertLa
}
@Override
public int getPositionForScrollProgress(float progress) {
return 0;
public void getPositionForScrollProgress(RecyclerListView listView, float progress, int[] position) {
position[0] = 0;
position[1] = 0;
}
@Override

View File

@ -1935,8 +1935,9 @@ public class ChatAttachAlertDocumentLayout extends ChatAttachAlert.AttachAlertLa
}
@Override
public int getPositionForScrollProgress(float progress) {
return 0;
public void getPositionForScrollProgress(RecyclerListView listView, float progress, int[] position) {
position[0] = 0;
position[1] = 0;
}
}

View File

@ -375,6 +375,23 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
addToSelectedPhotos(photoEntry, -1);
}
parentAlert.applyCaption();
if (PhotoViewer.getInstance().hasCaptionForAllMedia) {
HashMap<Object, Object> selectedPhotos = getSelectedPhotos();
ArrayList<Object> selectedPhotosOrder = getSelectedPhotosOrder();
if (!selectedPhotos.isEmpty()) {
for (int a = 0; a < selectedPhotosOrder.size(); a++) {
Object o = selectedPhotos.get(selectedPhotosOrder.get(a));
if (o instanceof MediaController.PhotoEntry) {
MediaController.PhotoEntry photoEntry1 = (MediaController.PhotoEntry) o;
if (a == 0) {
photoEntry1.caption = PhotoViewer.getInstance().captionForAllMedia;
} else {
photoEntry1.caption = null;
}
}
}
}
}
parentAlert.delegate.didPressedButton(7, true, notify, scheduleDate, forceDocument);
}
};
@ -625,7 +642,9 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
AndroidUtilities.hideKeyboard(parentAlert.baseFragment.getFragmentView().findFocus());
AndroidUtilities.hideKeyboard(parentAlert.getContainer().findFocus());
}
((MediaController.PhotoEntry) arrayList.get(position)).caption = parentAlert.getCommentTextView().getText();
PhotoViewer.getInstance().openPhotoForSelect(arrayList, position, type, false, photoViewerProvider, chatActivity);
PhotoViewer.getInstance().setCaption(parentAlert.getCommentTextView().getText());
} else {
if (SharedConfig.inappCamera) {
openCamera(true);

View File

@ -13,7 +13,6 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
@ -44,7 +43,6 @@ import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.MediaActivity;
import org.telegram.ui.ProfileActivity;
public class ChatAvatarContainer extends FrameLayout implements NotificationCenter.NotificationCenterDelegate {
@ -211,7 +209,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
if (key != null && !imageLoader.isInMemCache(key, false)) {
Drawable drawable = imageReceiver.getDrawable();
if (drawable instanceof BitmapDrawable) {
imageLoader.putImageToCache((BitmapDrawable) drawable, key);
imageLoader.putImageToCache((BitmapDrawable) drawable, key, false);
}
}
@ -221,7 +219,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
args.putLong("dialog_id", parentFragment.getDialogId());
int[] media = new int[MediaDataController.MEDIA_TYPES_COUNT];
System.arraycopy(sharedMediaPreloader.getLastMediaCount(), 0, media, 0, media.length);
MediaActivity fragment = new MediaActivity(args, media, sharedMediaPreloader.getSharedMediaData(), -1);
MediaActivity fragment = new MediaActivity(args, sharedMediaPreloader);
fragment.setChatInfo(parentFragment.getCurrentChatInfo());
parentFragment.presentFragment(fragment);
} else {

View File

@ -6,6 +6,7 @@ import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
@ -16,8 +17,10 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.text.Layout;
import android.text.StaticLayout;
@ -28,7 +31,6 @@ import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.OvershootInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
@ -40,24 +42,32 @@ import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.RecyclerView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.ChatThemeController;
import org.telegram.messenger.DocumentObject;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.ResultCallback;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BottomSheet;
import org.telegram.ui.ActionBar.ChatTheme;
import org.telegram.ui.ActionBar.EmojiThemes;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ActionBar.ThemeDescription;
import org.telegram.ui.Cells.ThemesHorizontalListCell;
import org.telegram.ui.ChatActivity;
import java.io.File;
import java.io.FileInputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
@ -68,7 +78,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
private final Adapter adapter;
private final ChatActivity.ThemeDelegate themeDelegate;
private final ChatTheme originalTheme;
private final EmojiThemes originalTheme;
private final boolean originalIsDark;
private final ChatActivity chatActivity;
private final RecyclerListView recyclerView;
@ -97,7 +107,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
this.themeDelegate = themeDelegate;
this.originalTheme = themeDelegate.getCurrentTheme();
this.originalIsDark = Theme.getActiveTheme().isDark();
adapter = new Adapter(themeDelegate);
adapter = new Adapter(currentAccount, themeDelegate, Adapter.TYPE_DEFAULT);
setDimBehind(false);
setCanDismissWithSwipe(false);
setApplyBottomPadding(false);
@ -158,14 +168,14 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
selectedItem = adapter.items.get(position);
isLightDarkChangeAnimation = false;
if (selectedItem.chatTheme == null || selectedItem.chatTheme.isDefault) {
if (selectedItem.chatTheme == null || selectedItem.chatTheme.showAsDefaultStub) {
applyTextView.animate().alpha(0f).setDuration(300).start();
resetTextView.animate().alpha(1f).setDuration(300).start();
} else {
resetTextView.animate().alpha(0f).setDuration(300).start();
applyTextView.animate().alpha(1f).setDuration(300).start();
}
if (selectedItem.chatTheme.isDefault) {
if (selectedItem.chatTheme.showAsDefaultStub) {
themeDelegate.setCurrentTheme(null, true, forceDark);
} else {
themeDelegate.setCurrentTheme(selectedItem.chatTheme, true, forceDark);
@ -191,7 +201,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
child.cancelAnimation();
}
}
if (!adapter.items.get(position).chatTheme.isDefault) {
if (!adapter.items.get(position).chatTheme.showAsDefaultStub) {
((Adapter.ChatThemeView) view).playEmojiAnimation();
}
});
@ -245,11 +255,11 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiLoaded);
isApplyClicked = false;
List<ChatTheme> cachedThemes = themeDelegate.getCachedThemes();
List<EmojiThemes> cachedThemes = themeDelegate.getCachedThemes();
if (cachedThemes == null || cachedThemes.isEmpty()) {
ChatThemeController.requestAllChatThemes(new ResultCallback<List<ChatTheme>>() {
ChatThemeController.requestAllChatThemes(new ResultCallback<List<EmojiThemes>>() {
@Override
public void onComplete(List<ChatTheme> result) {
public void onComplete(List<EmojiThemes> result) {
if (result != null && !result.isEmpty()) {
themeDelegate.setCachedThemes(result);
}
@ -266,7 +276,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
if (chatActivity.getCurrentUser() != null && SharedConfig.dayNightThemeSwitchHintCount > 0) {
if (chatActivity.getCurrentUser() != null && SharedConfig.dayNightThemeSwitchHintCount > 0 && !chatActivity.getCurrentUser().self) {
SharedConfig.updateDayNightThemeSwitchHintCount(SharedConfig.dayNightThemeSwitchHintCount - 1);
hintView = new HintView(getContext(), 9, chatActivity.getResourceProvider());
hintView.setVisibility(View.INVISIBLE);
@ -287,6 +297,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
hintView.hide();
}
}
@Override
public void onBackPressed() {
close();
@ -446,7 +457,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
setForceDark(isDark, true);
if (selectedItem != null) {
isLightDarkChangeAnimation = true;
if (selectedItem.chatTheme.isDefault) {
if (selectedItem.chatTheme.showAsDefaultStub) {
themeDelegate.setCurrentTheme(null, false, isDark);
} else {
themeDelegate.setCurrentTheme(selectedItem.chatTheme, false, isDark);
@ -454,7 +465,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
if (adapter != null && adapter.items != null) {
for (int i = 0; i < adapter.items.size(); i++) {
adapter.items.get(i).isDark = isDark;
adapter.items.get(i).themeIndex = isDark ? 1 : 0;
}
adapter.notifyDataSetChanged();
}
@ -479,51 +490,25 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
}
private void onDataLoaded(List<ChatTheme> result) {
private void onDataLoaded(List<EmojiThemes> result) {
if (result == null || result.isEmpty()) {
return;
}
ChatThemeItem noThemeItem = new ChatThemeItem(result.get(0));
List<ChatThemeItem> items = new ArrayList<>(result.size());
ChatTheme currentTheme = themeDelegate.getCurrentTheme();
EmojiThemes currentTheme = themeDelegate.getCurrentTheme();
items.add(0, noThemeItem);
selectedItem = noThemeItem;
for (int i = 1; i < result.size(); ++i) {
ChatTheme chatTheme = result.get(i);
EmojiThemes chatTheme = result.get(i);
ChatThemeItem item = new ChatThemeItem(chatTheme);
HashMap<String, Integer> colorsMap = chatTheme.getCurrentColors(chatActivity.getCurrentAccount(), true);
Integer color = colorsMap.get(Theme.key_chat_inBubble);
if (color == null) {
color = getThemedColor(Theme.key_chat_inBubble);
}
item.inBubbleColorDark = color;
color = colorsMap.get(Theme.key_chat_outBubble);
if (color == null) {
color = getThemedColor(Theme.key_chat_outBubble);
}
item.outBubbleColorDark = color;
color = colorsMap.get(Theme.key_featuredStickers_addButton);
item.strokeColorLight = color != null ? color : 0;
chatTheme.loadPreviewColors(currentAccount);
colorsMap = chatTheme.getCurrentColors(chatActivity.getCurrentAccount(), false);
color = colorsMap.get(Theme.key_chat_inBubble);
if (color == null) {
color = getThemedColor(Theme.key_chat_inBubble);
}
item.inBubbleColorLight = color;
color = colorsMap.get(Theme.key_chat_outBubble);
if (color == null) {
color = getThemedColor(Theme.key_chat_outBubble);
}
item.outBubbleColorLight = color;
color = colorsMap.get(Theme.key_featuredStickers_addButton);
item.strokeColorDark = color != null ? color : 0;
item.isDark = forceDark;
item.themeIndex = forceDark ? 1 : 0;
items.add(item);
}
adapter.setItems(items);
@ -549,6 +534,9 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
if (selectedPosition != -1) {
prevSelectedPosition = selectedPosition;
adapter.setSelectedItem(selectedPosition);
if (selectedPosition > 0 && selectedPosition < items.size() / 2) {
selectedPosition -= 1;
}
int finalSelectedPosition = Math.min(selectedPosition, adapter.items.size() - 1);
layoutManager.scrollToPositionWithOffset(finalSelectedPosition, 0);
}
@ -567,7 +555,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
private void onAnimationStart() {
if (adapter != null && adapter.items != null) {
for (ChatThemeItem item : adapter.items) {
item.isDark = forceDark;
item.themeIndex = forceDark ? 1 : 0;
}
}
if (!isLightDarkChangeAnimation) {
@ -610,15 +598,15 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
private void applySelectedTheme() {
Bulletin bulletin = null;
ChatTheme newTheme = selectedItem.chatTheme;
if (newTheme.isDefault) {
EmojiThemes newTheme = selectedItem.chatTheme;
if (newTheme.showAsDefaultStub) {
newTheme = null;
}
if (selectedItem != null && newTheme != originalTheme) {
ChatTheme chatTheme = selectedItem.chatTheme;
String emoticon = (chatTheme != null && !chatTheme.isDefault) ? chatTheme.getEmoticon() : null;
EmojiThemes chatTheme = selectedItem.chatTheme;
String emoticon = (chatTheme != null && !chatTheme.showAsDefaultStub) ? chatTheme.getEmoticon() : null;
ChatThemeController.getInstance(currentAccount).setDialogTheme(chatActivity.getDialogId(), emoticon, true);
if (chatTheme != null && !chatTheme.isDefault) {
if (chatTheme != null && !chatTheme.showAsDefaultStub) {
themeDelegate.setCurrentTheme(chatTheme, true, originalIsDark);
} else {
themeDelegate.setCurrentTheme(null, true, originalIsDark);
@ -667,27 +655,45 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
@SuppressLint("NotifyDataSetChanged")
private class Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public static class Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public final static int TYPE_DEFAULT = 0;
public final static int TYPE_GRID = 1;
private final Theme.ResourcesProvider resourcesProvider;
private List<ChatThemeItem> items;
public List<ChatThemeItem> items;
private WeakReference<ChatThemeView> selectedViewRef;
private int selectedItemPosition = -1;
private final int currentAccount;
private final int currentType;
public Adapter(Theme.ResourcesProvider resourcesProvider) {
private HashMap<String, Theme.ThemeInfo> loadingThemes = new HashMap<>();
private HashMap<Theme.ThemeInfo, String> loadingWallpapers = new HashMap<>();
public Adapter(int currentAccount, Theme.ResourcesProvider resourcesProvider, int type) {
this.currentType = type;
this.resourcesProvider = resourcesProvider;
this.currentAccount = currentAccount;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new RecyclerListView.Holder(new ChatThemeView(parent.getContext(), resourcesProvider));
return new RecyclerListView.Holder(new ChatThemeView(parent.getContext(), currentAccount, resourcesProvider, currentType));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
ChatThemeView view = (ChatThemeView) holder.itemView;
Theme.ThemeInfo themeInfo = items.get(position).chatTheme.getThemeInfo(items.get(position).themeIndex);
if (themeInfo != null && themeInfo.pathToFile != null && !themeInfo.previewParsed) {
File file = new File(themeInfo.pathToFile);
boolean fileExists = file.exists();
if (fileExists) {
parseTheme(themeInfo);
}
}
view.setItem(items.get(position));
view.setSelected(position == selectedItemPosition);
if (position == selectedItemPosition) {
@ -695,6 +701,163 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
}
private boolean parseTheme(Theme.ThemeInfo themeInfo) {
if (themeInfo == null || themeInfo.pathToFile == null) {
return false;
}
boolean finished = false;
File file = new File(themeInfo.pathToFile);
try (FileInputStream stream = new FileInputStream(file)) {
int currentPosition = 0;
int idx;
int read;
int linesRead = 0;
while ((read = stream.read(ThemesHorizontalListCell.bytes)) != -1) {
int previousPosition = currentPosition;
int start = 0;
for (int a = 0; a < read; a++) {
if (ThemesHorizontalListCell.bytes[a] == '\n') {
linesRead++;
int len = a - start + 1;
String line = new String(ThemesHorizontalListCell.bytes, start, len - 1, "UTF-8");
if (line.startsWith("WLS=")) {
String wallpaperLink = line.substring(4);
Uri uri = Uri.parse(wallpaperLink);
themeInfo.slug = uri.getQueryParameter("slug");
themeInfo.pathToWallpaper = new File(ApplicationLoader.getFilesDirFixed(), Utilities.MD5(wallpaperLink) + ".wp").getAbsolutePath();
String mode = uri.getQueryParameter("mode");
if (mode != null) {
mode = mode.toLowerCase();
String[] modes = mode.split(" ");
if (modes != null && modes.length > 0) {
for (int b = 0; b < modes.length; b++) {
if ("blur".equals(modes[b])) {
themeInfo.isBlured = true;
break;
}
}
}
}
String pattern = uri.getQueryParameter("pattern");
if (!TextUtils.isEmpty(pattern)) {
try {
String bgColor = uri.getQueryParameter("bg_color");
if (!TextUtils.isEmpty(bgColor)) {
themeInfo.patternBgColor = Integer.parseInt(bgColor.substring(0, 6), 16) | 0xff000000;
if (bgColor.length() >= 13 && AndroidUtilities.isValidWallChar(bgColor.charAt(6))) {
themeInfo.patternBgGradientColor1 = Integer.parseInt(bgColor.substring(7, 13), 16) | 0xff000000;
}
if (bgColor.length() >= 20 && AndroidUtilities.isValidWallChar(bgColor.charAt(13))) {
themeInfo.patternBgGradientColor2 = Integer.parseInt(bgColor.substring(14, 20), 16) | 0xff000000;
}
if (bgColor.length() == 27 && AndroidUtilities.isValidWallChar(bgColor.charAt(20))) {
themeInfo.patternBgGradientColor3 = Integer.parseInt(bgColor.substring(21), 16) | 0xff000000;
}
}
} catch (Exception ignore) {
}
try {
String rotation = uri.getQueryParameter("rotation");
if (!TextUtils.isEmpty(rotation)) {
themeInfo.patternBgGradientRotation = Utilities.parseInt(rotation);
}
} catch (Exception ignore) {
}
String intensity = uri.getQueryParameter("intensity");
if (!TextUtils.isEmpty(intensity)) {
themeInfo.patternIntensity = Utilities.parseInt(intensity);
}
if (themeInfo.patternIntensity == 0) {
themeInfo.patternIntensity = 50;
}
}
} else if (line.startsWith("WPS")) {
themeInfo.previewWallpaperOffset = currentPosition + len;
finished = true;
break;
} else {
if ((idx = line.indexOf('=')) != -1) {
String key = line.substring(0, idx);
if (key.equals(Theme.key_chat_inBubble) || key.equals(Theme.key_chat_outBubble) || key.equals(Theme.key_chat_wallpaper) || key.equals(Theme.key_chat_wallpaper_gradient_to1) || key.equals(Theme.key_chat_wallpaper_gradient_to2) || key.equals(Theme.key_chat_wallpaper_gradient_to3)) {
String param = line.substring(idx + 1);
int value;
if (param.length() > 0 && param.charAt(0) == '#') {
try {
value = Color.parseColor(param);
} catch (Exception ignore) {
value = Utilities.parseInt(param);
}
} else {
value = Utilities.parseInt(param);
}
switch (key) {
case Theme.key_chat_inBubble:
themeInfo.setPreviewInColor(value);
break;
case Theme.key_chat_outBubble:
themeInfo.setPreviewOutColor(value);
break;
case Theme.key_chat_wallpaper:
themeInfo.setPreviewBackgroundColor(value);
break;
case Theme.key_chat_wallpaper_gradient_to1:
themeInfo.previewBackgroundGradientColor1 = value;
break;
case Theme.key_chat_wallpaper_gradient_to2:
themeInfo.previewBackgroundGradientColor2 = value;
break;
case Theme.key_chat_wallpaper_gradient_to3:
themeInfo.previewBackgroundGradientColor3 = value;
break;
}
}
}
}
start += len;
currentPosition += len;
}
}
if (finished || previousPosition == currentPosition) {
break;
}
stream.getChannel().position(currentPosition);
}
} catch (Throwable e) {
FileLog.e(e);
}
if (themeInfo.pathToWallpaper != null && !themeInfo.badWallpaper) {
file = new File(themeInfo.pathToWallpaper);
if (!file.exists()) {
if (!loadingWallpapers.containsKey(themeInfo)) {
loadingWallpapers.put(themeInfo, themeInfo.slug);
TLRPC.TL_account_getWallPaper req = new TLRPC.TL_account_getWallPaper();
TLRPC.TL_inputWallPaperSlug inputWallPaperSlug = new TLRPC.TL_inputWallPaperSlug();
inputWallPaperSlug.slug = themeInfo.slug;
req.wallpaper = inputWallPaperSlug;
ConnectionsManager.getInstance(themeInfo.account).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (response instanceof TLRPC.TL_wallPaper) {
TLRPC.WallPaper wallPaper = (TLRPC.WallPaper) response;
String name = FileLoader.getAttachFileName(wallPaper.document);
if (!loadingThemes.containsKey(name)) {
loadingThemes.put(name, themeInfo);
FileLoader.getInstance(themeInfo.account).loadFile(wallPaper.document, wallPaper, 1, 1);
}
} else {
themeInfo.badWallpaper = true;
}
}));
}
return false;
}
}
themeInfo.previewParsed = true;
return true;
}
@Override
public int getItemCount() {
return items == null ? 0 : items.size();
@ -711,7 +874,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
if (selectedItemPosition >= 0) {
notifyItemChanged(selectedItemPosition);
ChatThemeView view = selectedViewRef.get();
ChatThemeView view = selectedViewRef == null ? null : selectedViewRef.get();
if (view != null) {
view.setSelected(false);
}
@ -721,7 +884,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
private class ChatThemeView extends FrameLayout implements Animator.AnimatorListener, ValueAnimator.AnimatorUpdateListener {
public static class ChatThemeView extends FrameLayout implements Animator.AnimatorListener, ValueAnimator.AnimatorUpdateListener {
private final float STROKE_RADIUS = AndroidUtilities.dp(8);
private final float INNER_RADIUS = AndroidUtilities.dp(6);
@ -743,12 +906,16 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
private StaticLayout textLayout;
private ChatThemeItem chatThemeItem;
private BackupImageView backupImageView;
private boolean isDark;
private boolean hasAnimatedEmoji;
private final int currentAccount;
Runnable animationCancelRunnable;
private int currentType;
int patternColor;
public ChatThemeView(Context context, Theme.ResourcesProvider resourcesProvider) {
public ChatThemeView(Context context, int currentAccount, Theme.ResourcesProvider resourcesProvider, int currentType) {
super(context);
this.currentType = currentType;
this.currentAccount = currentAccount;
this.resourcesProvider = resourcesProvider;
strokePaint.setStyle(Paint.Style.STROKE);
strokePaint.setStrokeWidth(AndroidUtilities.dp(2));
@ -757,14 +924,28 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
backupImageView.getImageReceiver().setCrossfadeWithOldImage(true);
backupImageView.getImageReceiver().setAllowStartLottieAnimation(false);
backupImageView.getImageReceiver().setAutoRepeat(0);
addView(backupImageView, LayoutHelper.createFrame(28, 28, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, 0, 0, 0, 12));
if (currentType == TYPE_DEFAULT) {
addView(backupImageView, LayoutHelper.createFrame(28, 28, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, 0, 0, 0, 12));
} else {
addView(backupImageView, LayoutHelper.createFrame(36, 36, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, 0, 0, 0, 12));
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = MeasureSpec.getSize(heightMeasureSpec);
int width = AndroidUtilities.dp(77);
super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
if (currentType == TYPE_GRID) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = (int) (width * 1.2f);
super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
} else {
int height = MeasureSpec.getSize(heightMeasureSpec);
int width = AndroidUtilities.dp(77);
super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
}
backupImageView.setPivotY(backupImageView.getMeasuredHeight());
backupImageView.setPivotX(backupImageView.getMeasuredWidth() / 2f);
}
@Override
@ -790,7 +971,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
canvas.drawRoundRect(rectF, STROKE_RADIUS, STROKE_RADIUS, strokePaint);
}
rectF.set(INNER_RECT_SPACE, INNER_RECT_SPACE, getWidth() - INNER_RECT_SPACE, getHeight() - INNER_RECT_SPACE);
if (chatThemeItem.chatTheme == null || chatThemeItem.chatTheme.isDefault) {
if (chatThemeItem.chatTheme == null || chatThemeItem.chatTheme.showAsDefaultStub) {
canvas.drawRoundRect(rectF, INNER_RADIUS, INNER_RADIUS, backgroundFillPaint);
canvas.save();
StaticLayout textLayout = getNoThemeStaticLayout();
@ -801,7 +982,21 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
if (chatThemeItem.previewDrawable != null) {
canvas.save();
canvas.clipPath(clipPath);
chatThemeItem.previewDrawable.setBounds(0, 0, getWidth(), getHeight());
if (chatThemeItem.previewDrawable instanceof BitmapDrawable) {
int drawableW = chatThemeItem.previewDrawable.getIntrinsicWidth();
int drawableH = chatThemeItem.previewDrawable.getIntrinsicHeight();
if (drawableW / (float) drawableH > getWidth() / (float) getHeight()) {
int w = (int) (getWidth() * (float) drawableH / drawableW);
int padding = (w - getWidth()) / 2;
chatThemeItem.previewDrawable.setBounds(padding, 0, padding + w , getHeight());
} else {
int h = (int) (getHeight() * (float) drawableH / drawableW);
int padding = (getHeight() - h) / 2;
chatThemeItem.previewDrawable.setBounds(0, padding, getWidth(), padding + h);
}
} else {
chatThemeItem.previewDrawable.setBounds(0, 0, getWidth(), getHeight());
}
chatThemeItem.previewDrawable.draw(canvas);
canvas.restore();
} else {
@ -809,22 +1004,40 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
float bubbleTop = INNER_RECT_SPACE + AndroidUtilities.dp(8);
float bubbleLeft = INNER_RECT_SPACE + AndroidUtilities.dp(22);
rectF.set(bubbleLeft, bubbleTop, bubbleLeft + BUBBLE_WIDTH, bubbleTop + BUBBLE_HEIGHT);
if (currentType == TYPE_DEFAULT) {
rectF.set(bubbleLeft, bubbleTop, bubbleLeft + BUBBLE_WIDTH, bubbleTop + BUBBLE_HEIGHT);
} else {
bubbleTop = getMeasuredHeight() * 0.12f;
bubbleLeft = getMeasuredWidth() - getMeasuredWidth() * 0.6f;
float bubbleRight = getMeasuredWidth() - getMeasuredWidth() * 0.1f;
float bubbleBottom = getMeasuredHeight() * 0.32f;
rectF.set(bubbleLeft, bubbleTop, bubbleRight, bubbleBottom);
}
canvas.drawRoundRect(rectF, rectF.height() * 0.5f, rectF.height() * 0.5f, outBubblePaintFirst);
canvas.drawRoundRect(rectF, rectF.height() * 0.5f, rectF.height() * 0.5f, outBubblePaintSecond);
bubbleLeft = INNER_RECT_SPACE + AndroidUtilities.dp(5);
bubbleTop += BUBBLE_HEIGHT + AndroidUtilities.dp(4);
rectF.set(bubbleLeft, bubbleTop, bubbleLeft + BUBBLE_WIDTH, bubbleTop + BUBBLE_HEIGHT);
if (currentType == TYPE_DEFAULT) {
bubbleLeft = INNER_RECT_SPACE + AndroidUtilities.dp(5);
bubbleTop += BUBBLE_HEIGHT + AndroidUtilities.dp(4);
rectF.set(bubbleLeft, bubbleTop, bubbleLeft + BUBBLE_WIDTH, bubbleTop + BUBBLE_HEIGHT);
} else {
bubbleTop = getMeasuredHeight() * 0.35f;
bubbleLeft = getMeasuredWidth() * 0.1f;
float bubbleRight = getMeasuredWidth() * 0.6f;
float bubbleBottom = getMeasuredHeight() * 0.55f;
rectF.set(bubbleLeft, bubbleTop, bubbleRight, bubbleBottom);
}
canvas.drawRoundRect(rectF, rectF.height() * 0.5f, rectF.height() * 0.5f, inBubblePaint);
}
super.dispatchDraw(canvas);
}
int lastThemeIndex;
public void setItem(ChatThemeItem item) {
boolean itemChanged = chatThemeItem != item;
boolean darkModeChanged = isDark != item.isDark;
isDark = item.isDark;
boolean darkModeChanged = lastThemeIndex != item.themeIndex;
lastThemeIndex = item.themeIndex;
this.chatThemeItem = item;
hasAnimatedEmoji = false;
TLRPC.Document document = null;
@ -840,27 +1053,39 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
backupImageView.setScaleX(1f);
backupImageView.setScaleY(1f);
}
if (itemChanged) {
Drawable thumb = null;
if (document != null) {
thumb = DocumentObject.getSvgThumb(document, Theme.key_emptyListPlaceholder, 0.2f);
}
if (thumb == null) {
thumb = Emoji.getEmojiDrawable(item.chatTheme.getEmoticon());
}
backupImageView.setImage(ImageLocation.getForDocument(document), "50_50", thumb, null);
}
backupImageView.setImage(ImageLocation.getForDocument(document), "50_50", Emoji.getEmojiDrawable(item.chatTheme == null ? "" : item.chatTheme.getEmoticon()), null);
if (item.chatTheme != null && !item.chatTheme.isDefault) {
if (itemChanged || darkModeChanged) {
updatePreviewBackground();
if (itemChanged || darkModeChanged) {
final long themeId = item.chatTheme.getTlTheme(isDark).id;
final int intensity = item.chatTheme.getWallpaper(isDark).settings.intensity;
item.chatTheme.loadWallpaperThumb(isDark, result -> {
if (result != null && result.first == themeId) {
MotionBackgroundDrawable drawable = getPreviewDrawable();
if (drawable != null) {
drawable.setPatternBitmap(intensity >= 0 ? 100 : -100, result.second);
drawable.setPatternColorFilter(drawable.getPatternColor());
TLRPC.TL_theme theme = item.chatTheme.getTlTheme(lastThemeIndex);
if (theme != null) {
final long themeId = theme.id;
TLRPC.WallPaper wallPaper = item.chatTheme.getWallpaper(lastThemeIndex);
if (wallPaper != null) {
final int intensity = wallPaper.settings.intensity;
int index = item.chatTheme.getSettingsIndex(lastThemeIndex);
item.chatTheme.loadWallpaperThumb(lastThemeIndex, result -> {
if (result != null && result.first == themeId) {
if (item.previewDrawable instanceof MotionBackgroundDrawable) {
MotionBackgroundDrawable motionBackgroundDrawable = (MotionBackgroundDrawable) item.previewDrawable;
motionBackgroundDrawable.setPatternBitmap(intensity >= 0 ? 100 : -100, result.second);
motionBackgroundDrawable.setPatternColorFilter(patternColor);
}
invalidate();
}
invalidate();
}
});
});
}
}
}
setBackgroundColor(0);
}
@Override
@ -905,55 +1130,110 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
public void updatePreviewBackground() {
if (chatThemeItem == null || chatThemeItem.chatTheme == null || chatThemeItem.chatTheme.isDefault) {
if (chatThemeItem == null || chatThemeItem.chatTheme == null) {
return;
}
int color = chatThemeItem.isDark ? chatThemeItem.inBubbleColorDark : chatThemeItem.inBubbleColorLight;
EmojiThemes.ThemeItem themeItem = chatThemeItem.chatTheme.getThemeItem(chatThemeItem.themeIndex);
int color = themeItem.inBubbleColor;
inBubblePaint.setColor(color);
color = chatThemeItem.isDark ? chatThemeItem.outBubbleColorDark : chatThemeItem.outBubbleColorLight;
color = themeItem.outBubbleColor;
outBubblePaintSecond.setColor(color);
TLRPC.TL_theme firstTlTheme = chatThemeItem.chatTheme.getTlTheme(!chatThemeItem.isDark);
fillOutBubblePaint(outBubblePaintFirst, firstTlTheme.settings.message_colors);
TLRPC.TL_theme secondTlTheme = chatThemeItem.chatTheme.getTlTheme(chatThemeItem.isDark);
fillOutBubblePaint(outBubblePaintSecond, secondTlTheme.settings.message_colors);
outBubblePaintSecond.setAlpha(255);
int strokeColor = chatThemeItem.chatTheme.showAsDefaultStub
? getThemedColor(Theme.key_featuredStickers_addButton)
: themeItem.outLineColor;
int strokeAlpha = strokePaint.getAlpha();
strokePaint.setColor(strokeColor);
strokePaint.setAlpha(strokeAlpha);
MotionBackgroundDrawable drawable = getPreviewDrawable();
if (drawable != null) {
TLRPC.WallPaperSettings secondSettings = secondTlTheme.settings.wallpaper.settings;
int color1 = 0xff000000 | secondSettings.background_color;
if (color1 == 0xff000000) {
color1 = Color.TRANSPARENT;
}
int color2 = 0xff000000 | secondSettings.second_background_color;
if (color2 == 0xff000000) {
color2 = Color.TRANSPARENT;
}
int color3 = 0xff000000 | secondSettings.third_background_color;
if (color3 == 0xff000000) {
color3 = Color.TRANSPARENT;
}
int color4 = 0xff000000 | secondSettings.fourth_background_color;
if (color4 == 0xff000000) {
color4 = Color.TRANSPARENT;
}
drawable.setPatternBitmap(secondSettings.intensity >= 0 ? 100 : -100);
drawable.setColors(color1, color2, color3, color4, false);
drawable.setPatternColorFilter(drawable.getPatternColor());
TLRPC.TL_theme tlTheme = chatThemeItem.chatTheme.getTlTheme(chatThemeItem.themeIndex);
if (tlTheme != null) {
int index = chatThemeItem.chatTheme.getSettingsIndex(chatThemeItem.themeIndex);
TLRPC.ThemeSettings themeSettings = tlTheme.settings.get(index);
fillOutBubblePaint(outBubblePaintSecond, themeSettings.message_colors);
outBubblePaintSecond.setAlpha(255);
getPreviewDrawable(tlTheme, index);
} else {
EmojiThemes.ThemeItem item = chatThemeItem.chatTheme.getThemeItem(chatThemeItem.themeIndex);
getPreviewDrawable(item);
}
invalidate();
}
private MotionBackgroundDrawable getPreviewDrawable() {
private Drawable getPreviewDrawable(TLRPC.TL_theme theme, int settingsIndex) {
if (chatThemeItem == null) {
return null;
}
MotionBackgroundDrawable drawable = chatThemeItem.previewDrawable;
if (drawable == null) {
drawable = new MotionBackgroundDrawable();
chatThemeItem.previewDrawable = drawable;
int color1 = 0;
int color2 = 0;
int color3 = 0;
int color4 = 0;
Drawable drawable;
if (settingsIndex >= 0) {
TLRPC.ThemeSettings themeSettings = theme.settings.get(settingsIndex);
TLRPC.WallPaperSettings wallPaperSettings = themeSettings.wallpaper.settings;
color1 = wallPaperSettings.background_color;
color2 = wallPaperSettings.second_background_color;
color3 = wallPaperSettings.third_background_color;
color4 = wallPaperSettings.fourth_background_color;
}
if (color2 != 0) {
MotionBackgroundDrawable motionBackgroundDrawable = new MotionBackgroundDrawable(color1, color2, color3, color4, true);
patternColor = motionBackgroundDrawable.getPatternColor();
drawable = motionBackgroundDrawable;
} else {
drawable = new MotionBackgroundDrawable(color1, color1, color1, color1, true);
patternColor = Color.BLACK;
}
chatThemeItem.previewDrawable = drawable;
return drawable;
}
private Drawable getPreviewDrawable(EmojiThemes.ThemeItem item) {
if (chatThemeItem == null) {
return null;
}
Drawable drawable = null;
int color1 = item.patternBgColor;
int color2 = item.patternBgGradientColor1;
int color3 = item.patternBgGradientColor2;
int color4 = item.patternBgGradientColor3;
if (item.themeInfo.getAccent(false) != null) {
if (color2 != 0) {
MotionBackgroundDrawable motionBackgroundDrawable = new MotionBackgroundDrawable(color1, color2, color3, color4, true);
patternColor = motionBackgroundDrawable.getPatternColor();
drawable = motionBackgroundDrawable;
} else {
drawable = new MotionBackgroundDrawable(color1, color1, color1, color1, true);
patternColor = Color.BLACK;
}
} else {
if (color1 != 0 && color2 != 0) {
drawable = new MotionBackgroundDrawable(color1, color2, color3, color4, true);
} else if (color1 != 0) {
drawable = new ColorDrawable(color1);
} else if (item.themeInfo != null && (item.themeInfo.previewWallpaperOffset > 0 || item.themeInfo.pathToWallpaper != null)) {
Bitmap wallpaper = getScaledBitmap(AndroidUtilities.dp(76), AndroidUtilities.dp(97), item.themeInfo.pathToWallpaper, item.themeInfo.pathToFile, item.themeInfo.previewWallpaperOffset);
if (wallpaper != null) {
drawable = new BitmapDrawable(wallpaper);
}
} else {
drawable = new MotionBackgroundDrawable(0xffdbddbb, 0xff6ba587, 0xffd5d88d, 0xff88b884, true);
}
}
chatThemeItem.previewDrawable = drawable;
return drawable;
}
@ -983,9 +1263,10 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int strokeColor = chatThemeItem.chatTheme.isDefault
EmojiThemes.ThemeItem themeItem = chatThemeItem.chatTheme.getThemeItem(chatThemeItem.themeIndex);
int strokeColor = chatThemeItem.chatTheme.showAsDefaultStub
? getThemedColor(Theme.key_featuredStickers_addButton)
: chatThemeItem.isDark ? chatThemeItem.strokeColorDark : chatThemeItem.strokeColorLight;
: themeItem.outLineColor;
strokePaint.setColor(strokeColor);
strokePaint.setAlpha((int) valueAnimator.getAnimatedValue());
invalidate();
@ -1017,8 +1298,6 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
backupImageView.setVisibility(View.VISIBLE);
backupImageView.getImageReceiver().getLottieAnimation().setCurrentFrame(0, false);
backupImageView.getImageReceiver().getLottieAnimation().start();
backupImageView.setPivotY(AndroidUtilities.dp(24));
backupImageView.setPivotX(AndroidUtilities.dp(12));
backupImageView.animate().scaleX(2f).scaleY(2f).setDuration(300).setInterpolator(AndroidUtilities.overshootInterpolator).start();
AndroidUtilities.runOnUIThread(animationCancelRunnable = () -> {
@ -1037,21 +1316,15 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
}
private static class ChatThemeItem {
public static class ChatThemeItem {
public final ChatTheme chatTheme;
public MotionBackgroundDrawable previewDrawable;
public boolean isDark;
public final EmojiThemes chatTheme;
public Drawable previewDrawable;
public int themeIndex;
public boolean isSelected;
public float animationProgress = 1f;
public int inBubbleColorLight;
public int inBubbleColorDark;
public int outBubbleColorLight;
public int outBubbleColorDark;
public int strokeColorDark;
public int strokeColorLight;
public ChatThemeItem(ChatTheme chatTheme) {
public ChatThemeItem(EmojiThemes chatTheme) {
this.chatTheme = chatTheme;
}
}
@ -1061,4 +1334,54 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
super.show();
resetTextView.setText(themeDelegate.getCurrentTheme() == null ? LocaleController.getString("DoNoSetTheme", R.string.DoNoSetTheme) : LocaleController.getString("ChatResetTheme", R.string.ChatResetTheme));
}
public static Bitmap getScaledBitmap(float w, float h, String path, String streamPath, int streamOffset) {
FileInputStream stream = null;
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
if (path != null) {
BitmapFactory.decodeFile(path, options);
} else {
stream = new FileInputStream(streamPath);
stream.getChannel().position(streamOffset);
BitmapFactory.decodeStream(stream, null, options);
}
if (options.outWidth > 0 && options.outHeight > 0) {
if (w > h && options.outWidth < options.outHeight) {
float temp = w;
w = h;
h = temp;
}
float scale = Math.min(options.outWidth / w, options.outHeight / h);
options.inSampleSize = 1;
if (scale > 1.0f) {
do {
options.inSampleSize *= 2;
} while (options.inSampleSize < scale);
}
options.inJustDecodeBounds = false;
Bitmap wallpaper;
if (path != null) {
wallpaper = BitmapFactory.decodeFile(path, options);
} else {
stream.getChannel().position(streamOffset);
wallpaper = BitmapFactory.decodeStream(stream, null, options);
}
return wallpaper;
}
} catch (Throwable e) {
FileLog.e(e);
} finally {
try {
if (stream != null) {
stream.close();
}
} catch (Exception e2) {
FileLog.e(e2);
}
}
return null;
}
}

View File

@ -33,6 +33,7 @@ public class FlickerLoadingView extends View {
public final static int SHARE_ALERT_TYPE = 12;
public final static int MESSAGE_SEEN_TYPE = 13;
public final static int CHAT_THEMES_TYPE = 14;
public final static int MEMBER_REQUESTS_TYPE = 15;
private int gradientWidth;
private LinearGradient gradient;
@ -62,6 +63,11 @@ public class FlickerLoadingView extends View {
float[] randomParams;
private Paint backgroundPaint;
private int parentWidth;
private int parentHeight;
private float parentXOffset;
FlickerLoadingView globalGradientView;
public void setViewType(int type) {
this.viewType = type;
@ -119,19 +125,19 @@ public class FlickerLoadingView extends View {
@Override
protected void onDraw(Canvas canvas) {
int color0 = getThemedColor(colorKey1);
int color1 = getThemedColor(colorKey2);
if (this.color1 != color1 || this.color0 != color0) {
this.color0 = color0;
this.color1 = color1;
if (isSingleCell || viewType == MESSAGE_SEEN_TYPE || viewType == CHAT_THEMES_TYPE) {
gradient = new LinearGradient(0, 0, gradientWidth = AndroidUtilities.dp(200), 0, new int[]{color1, color0, color0, color1}, new float[]{0.0f, 0.4f, 0.6f, 1f}, Shader.TileMode.CLAMP);
} else {
gradient = new LinearGradient(0, 0, 0, gradientWidth = AndroidUtilities.dp(600), new int[]{color1, color0, color0, color1}, new float[]{0.0f, 0.4f, 0.6f, 1f}, Shader.TileMode.CLAMP);
Paint paint = this.paint;
if (globalGradientView != null) {
if (getParent() != null) {
View parent = (View) getParent();
globalGradientView.setParentSize(parent.getMeasuredWidth(), parent.getMeasuredHeight(), -getX());
}
paint.setShader(gradient);
paint = globalGradientView.paint;
}
updateColors();
updateGradient();
int h = paddingTop;
if (useHeaderOffset) {
h += AndroidUtilities.dp(32);
@ -465,29 +471,86 @@ public class FlickerLoadingView extends View {
canvas.drawCircle(x + itemWidth / 2, getMeasuredHeight() - AndroidUtilities.dp(20), AndroidUtilities.dp(8), backgroundPaint);
x += itemWidth;
}
}
} else if (getViewType() == MEMBER_REQUESTS_TYPE) {
int count = 0;
int radius = AndroidUtilities.dp(23);
int rectRadius = AndroidUtilities.dp(4);
while (h <= getMeasuredHeight()) {
canvas.drawCircle(checkRtl(paddingLeft + AndroidUtilities.dp(12)) + radius, h + AndroidUtilities.dp(8) + radius, radius, paint);
rectF.set(paddingLeft + AndroidUtilities.dp(74), h + AndroidUtilities.dp(12), paddingLeft + AndroidUtilities.dp(260), h + AndroidUtilities.dp(20));
checkRtl(rectF);
canvas.drawRoundRect(rectF, rectRadius, rectRadius, paint);
rectF.set(paddingLeft + AndroidUtilities.dp(74), h + AndroidUtilities.dp(36), paddingLeft + AndroidUtilities.dp(140), h + AndroidUtilities.dp(42));
checkRtl(rectF);
canvas.drawRoundRect(rectF, rectRadius, rectRadius, paint);
h += getCellHeight(getMeasuredWidth());
count++;
if (isSingleCell && count >= itemsCount) {
break;
}
}
}
invalidate();
}
public void updateGradient() {
if (globalGradientView != null) {
globalGradientView.updateGradient();
return;
}
long newUpdateTime = SystemClock.elapsedRealtime();
long dt = Math.abs(lastUpdateTime - newUpdateTime);
if (dt > 17) {
dt = 16;
}
if (dt < 4) {
dt = 0;
}
int width = parentWidth;
if (width == 0) {
width = getMeasuredWidth();
}
int height = parentHeight;
if (height == 0) {
height = getMeasuredHeight();
}
lastUpdateTime = newUpdateTime;
if (isSingleCell || viewType == MESSAGE_SEEN_TYPE || getViewType() == CHAT_THEMES_TYPE) {
totalTranslation += dt * getMeasuredWidth() / 400.0f;
if (totalTranslation >= getMeasuredWidth() * 2) {
totalTranslation += dt * width / 400.0f;
if (totalTranslation >= width * 2) {
totalTranslation = -gradientWidth * 2;
}
matrix.setTranslate(totalTranslation, 0);
matrix.setTranslate(totalTranslation + parentXOffset, 0);
} else {
totalTranslation += dt * getMeasuredHeight() / 400.0f;
if (totalTranslation >= getMeasuredHeight() * 2) {
totalTranslation += dt * height / 400.0f;
if (totalTranslation >= height * 2) {
totalTranslation = -gradientWidth * 2;
}
matrix.setTranslate(0, totalTranslation);
matrix.setTranslate(parentXOffset, totalTranslation);
}
gradient.setLocalMatrix(matrix);
invalidate();
}
public void updateColors() {
if (globalGradientView != null) {
globalGradientView.updateColors();
return;
}
int color0 = getThemedColor(colorKey1);
int color1 = getThemedColor(colorKey2);
if (this.color1 != color1 || this.color0 != color0) {
this.color0 = color0;
this.color1 = color1;
if (isSingleCell || viewType == MESSAGE_SEEN_TYPE || viewType == CHAT_THEMES_TYPE) {
gradient = new LinearGradient(0, 0, gradientWidth = AndroidUtilities.dp(200), 0, new int[]{color1, color0, color0, color1}, new float[]{0.0f, 0.4f, 0.6f, 1f}, Shader.TileMode.CLAMP);
} else {
gradient = new LinearGradient(0, 0, 0, gradientWidth = AndroidUtilities.dp(600), new int[]{color1, color0, color0, color1}, new float[]{0.0f, 0.4f, 0.6f, 1f}, Shader.TileMode.CLAMP);
}
paint.setShader(gradient);
}
}
private float checkRtl(float x) {
@ -513,9 +576,9 @@ public class FlickerLoadingView extends View {
int photoWidth = (width - (AndroidUtilities.dp(2) * (getColumnsCount() - 1))) / getColumnsCount();
return photoWidth + AndroidUtilities.dp(2);
} else if (getViewType() == 3) {
return AndroidUtilities.dp(56) + 1;
return AndroidUtilities.dp(56);
} else if (getViewType() == 4) {
return AndroidUtilities.dp(56) + 1;
return AndroidUtilities.dp(56);
} else if (getViewType() == 5) {
return AndroidUtilities.dp(80);
} else if (getViewType() == USERS_TYPE) {
@ -530,6 +593,8 @@ public class FlickerLoadingView extends View {
return AndroidUtilities.dp(36);
} else if (getViewType() == SHARE_ALERT_TYPE) {
return AndroidUtilities.dp(103);
} else if (getViewType() == MEMBER_REQUESTS_TYPE) {
return AndroidUtilities.dp(107);
}
return 0;
}
@ -564,4 +629,18 @@ public class FlickerLoadingView extends View {
Integer color = resourcesProvider != null ? resourcesProvider.getColor(key) : null;
return color != null ? color : Theme.getColor(key);
}
public void setGlobalGradientView(FlickerLoadingView globalGradientView) {
this.globalGradientView = globalGradientView;
}
public void setParentSize(int parentWidth, int parentHeight, float parentXOffset) {
this.parentWidth = parentWidth;
this.parentHeight = parentHeight;
this.parentXOffset = parentXOffset;
}
public Paint getPaint() {
return paint;
}
}

View File

@ -122,6 +122,14 @@ public class ForwardingPreviewView extends FrameLayout {
Drawable drawable = resourcesProvider.getWallpaperDrawable();
return drawable != null ? drawable : super.getNewDrawable();
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getY() < currentTopOffset) {
return false;
}
return super.dispatchTouchEvent(ev);
}
};
chatPreviewContainer.setBackgroundImage(resourcesProvider.getWallpaperDrawable(), resourcesProvider.isWallpaperMotion());
chatPreviewContainer.setOccupyStatusBar(false);
@ -326,6 +334,7 @@ public class ForwardingPreviewView extends FrameLayout {
}
}
}
};
chatListView.setItemAnimator(itemAnimator = new ChatListItemAnimator(null, chatListView, resourcesProvider) {
@ -961,7 +970,7 @@ public class ForwardingPreviewView extends FrameLayout {
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
ChatMessageCell chatMessageCell = new ChatMessageCell(parent.getContext(), resourcesProvider);
ChatMessageCell chatMessageCell = new ChatMessageCell(parent.getContext(), false, resourcesProvider);
return new RecyclerListView.Holder(chatMessageCell);
}

View File

@ -594,7 +594,9 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject();
if (fragment != null && messageObject != null) {
if (messageObject.isMusic()) {
fragment.showDialog(new AudioPlayerAlert(getContext(), resourcesProvider));
if (getContext() instanceof LaunchActivity) {
fragment.showDialog(new AudioPlayerAlert(getContext(), resourcesProvider));
}
} else {
long dialogId = 0;
if (fragment instanceof ChatActivity) {

View File

@ -116,11 +116,17 @@ public class GroupedPhotosListView extends View implements GestureDetector.OnGes
int newCount = 0;
Object currentObject = null;
if (imagesArrLocations != null && !imagesArrLocations.isEmpty()) {
if (currentIndex >= imagesArrLocations.size()) {
currentIndex = imagesArrLocations.size() - 1;
}
ImageLocation location = imagesArrLocations.get(currentIndex);
newCount = imagesArrLocations.size();
currentObject = location;
hasPhotos = true;
} else if (imagesArr != null && !imagesArr.isEmpty()) {
if (currentIndex >= imagesArr.size()) {
currentIndex = imagesArr.size() - 1;
}
MessageObject messageObject = imagesArr.get(currentIndex);
currentObject = messageObject;
long localGroupId = delegate.validGroupId(messageObject.getGroupIdForUse()) ? messageObject.getGroupIdForUse() : 0;

View File

@ -717,7 +717,7 @@ public class ImageUpdater implements NotificationCenter.NotificationCenterDelega
try {
Bitmap b = BitmapFactory.decodeFile(FileLoader.getPathToAttach(smallPhoto, true).getAbsolutePath());
String key = smallPhoto.location.volume_id + "_" + smallPhoto.location.local_id + "@50_50";
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(b), key);
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(b), key, true);
} catch (Throwable ignore) {
}
@ -869,7 +869,7 @@ public class ImageUpdater implements NotificationCenter.NotificationCenterDelega
try {
Bitmap b = BitmapFactory.decodeFile(FileLoader.getPathToAttach(smallPhoto, true).getAbsolutePath());
String key = smallPhoto.location.volume_id + "_" + smallPhoto.location.local_id + "@50_50";
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(b), key);
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(b), key, true);
} catch (Throwable ignore) {
}

View File

@ -12,6 +12,7 @@ import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
@ -26,6 +27,7 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.MessagesStorage;
@ -46,7 +48,9 @@ import org.telegram.ui.ManageLinksActivity;
import org.telegram.ui.ProfileActivity;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
public class InviteLinkBottomSheet extends BottomSheet {
@ -59,15 +63,20 @@ public class InviteLinkBottomSheet extends BottomSheet {
int creatorRow;
int dividerRow;
int divider2Row;
int usersHeaderRow;
int usersStartRow;
int usersEndRow;
int divider3Row;
int joinedHeaderRow;
int joinedStartRow;
int joinedEndRow;
int linkActionRow;
int linkInfoRow;
int loadingRow;
int emptyView;
int emptyView2;
int emptyView3;
int emptyHintRow;
int requestedHeaderRow;
int requestedStartRow;
int requestedEndRow;
boolean usersLoading;
boolean hasMore;
@ -86,7 +95,8 @@ public class InviteLinkBottomSheet extends BottomSheet {
private boolean permanent;
private boolean titleVisible;
ArrayList<TLRPC.TL_chatInviteImporter> invitedUsers = new ArrayList<>();
ArrayList<TLRPC.TL_chatInviteImporter> joinedUsers = new ArrayList<>();
ArrayList<TLRPC.TL_chatInviteImporter> requestedUsers = new ArrayList<>();
private long chatId;
private boolean isChannel;
@ -95,6 +105,7 @@ public class InviteLinkBottomSheet extends BottomSheet {
InviteDelegate inviteDelegate;
private boolean canEdit = true;
public boolean isNeedReopen = false;
public InviteLinkBottomSheet(Context context, TLRPC.TL_chatInviteExported invite, TLRPC.ChatFull info, HashMap<Long, TLRPC.User> users, BaseFragment fragment, long chatId, boolean permanent, boolean isChannel) {
super(context, false);
@ -263,28 +274,30 @@ public class InviteLinkBottomSheet extends BottomSheet {
}
}
});
listView.setOnItemClickListener(new RecyclerListView.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
if (position == creatorRow && invite.admin_id == UserConfig.getInstance(currentAccount).clientUserId) {
return;
listView.setOnItemClickListener((view, position) -> {
if (position == creatorRow && invite.admin_id == UserConfig.getInstance(currentAccount).clientUserId) {
return;
}
boolean isJoinedUserRow = position >= joinedStartRow && position < joinedEndRow;
boolean isRequestedUserRow = position >= requestedStartRow && position < requestedEndRow;
if ((position == creatorRow || isJoinedUserRow || isRequestedUserRow) && users != null) {
long userId = invite.admin_id;
if (isJoinedUserRow) {
userId = joinedUsers.get(position - joinedStartRow).user_id;
} else if (isRequestedUserRow) {
userId = requestedUsers.get(position - requestedStartRow).user_id;
}
if (position == creatorRow || (position >= usersStartRow && position < usersEndRow)) {
TLRPC.User user;
if (position == creatorRow) {
user = users.get(invite.admin_id);
} else {
TLRPC.TL_chatInviteImporter invitedUser = invitedUsers.get(position - usersStartRow);
user = users.get(invitedUser.user_id);
}
if (user != null) {
TLRPC.User user = users.get(userId);
if (user != null) {
MessagesController.getInstance(UserConfig.selectedAccount).putUser(user, false);
AndroidUtilities.runOnUIThread(() -> {
Bundle bundle = new Bundle();
bundle.putLong("user_id", user.id);
MessagesController.getInstance(UserConfig.selectedAccount).putUser(user, false);
ProfileActivity profileActivity = new ProfileActivity(bundle);
fragment.presentFragment(profileActivity);
dismiss();
}
isNeedReopen = true;
}, 100);
dismiss();
}
}
});
@ -305,7 +318,6 @@ public class InviteLinkBottomSheet extends BottomSheet {
} else {
titleTextView.setText(LocaleController.getString("InviteLink", R.string.InviteLink));
}
titleVisible = true;
} else {
titleTextView.setText(LocaleController.getString("InviteLink", R.string.InviteLink));
@ -313,6 +325,11 @@ public class InviteLinkBottomSheet extends BottomSheet {
titleTextView.setVisibility(View.INVISIBLE);
titleTextView.setAlpha(0f);
}
if (!TextUtils.isEmpty(invite.title)) {
SpannableStringBuilder builder = new SpannableStringBuilder(invite.title);
Emoji.replaceEmoji(builder, titleTextView.getPaint().getFontMetricsInt(), (int) titleTextView.getPaint().getTextSize(), false);
titleTextView.setText(builder);
}
containerView.addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, 0, !titleVisible ? 0 : 48, 0, 0));
containerView.addView(titleTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, !titleVisible ? 48 : 50, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 0));
@ -359,6 +376,12 @@ public class InviteLinkBottomSheet extends BottomSheet {
containerView.invalidate();
}
@Override
public void show() {
super.show();
isNeedReopen = false;
}
private void updateColorForView(View view) {
if (view instanceof HeaderCell) {
((HeaderCell) view).getTextView().setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlueHeader));
@ -417,13 +440,19 @@ public class InviteLinkBottomSheet extends BottomSheet {
rowCount = 0;
dividerRow = -1;
divider2Row = -1;
usersHeaderRow = -1;
usersStartRow = -1;
usersEndRow = -1;
divider3Row = -1;
joinedHeaderRow = -1;
joinedStartRow = -1;
joinedEndRow = -1;
emptyView2 = -1;
emptyView3 = -1;
linkActionRow = -1;
linkInfoRow = -1;
emptyHintRow = -1;
requestedHeaderRow = -1;
requestedStartRow = -1;
requestedEndRow = -1;
loadingRow = -1;
if (!permanent) {
linkActionRow = rowCount++;
@ -433,23 +462,35 @@ public class InviteLinkBottomSheet extends BottomSheet {
creatorRow = rowCount++;
emptyView = rowCount++;
if (!(invite.usage == 0 && invite.usage_limit == 0)) {
boolean needUsers = invite.usage > 0 || invite.usage_limit > 0 || invite.requested > 0;
boolean usersLoaded = false;
if (!joinedUsers.isEmpty()) {
dividerRow = rowCount++;
usersHeaderRow = rowCount++;
if (!invitedUsers.isEmpty()) {
usersStartRow = rowCount;
rowCount += invitedUsers.size();
usersEndRow = rowCount;
emptyView2 = rowCount++;
} else if (invite.usage > 0) {
joinedHeaderRow = rowCount++;
joinedStartRow = rowCount;
rowCount += joinedUsers.size();
joinedEndRow = rowCount;
emptyView2 = rowCount++;
usersLoaded = true;
}
if (!requestedUsers.isEmpty()) {
divider2Row = rowCount++;
requestedHeaderRow = rowCount++;
requestedStartRow = rowCount;
rowCount += requestedUsers.size();
requestedEndRow = rowCount;
emptyView3 = rowCount++;
usersLoaded = true;
}
if (needUsers) {
if (!usersLoaded) {
dividerRow = rowCount++;
loadingRow = rowCount++;
emptyView2 = rowCount++;
} else {
emptyHintRow = rowCount++;
}
}
if (emptyHintRow == -1) {
divider2Row = rowCount++;
divider3Row = rowCount++;
}
adapter.notifyDataSetChanged();
@ -459,11 +500,11 @@ public class InviteLinkBottomSheet extends BottomSheet {
@Override
public int getItemViewType(int position) {
if (position == creatorHeaderRow) {
if (position == creatorHeaderRow || position == requestedHeaderRow || position == joinedHeaderRow) {
return 0;
} else if (position == creatorRow || position >= usersStartRow && position < usersEndRow) {
} else if (position == creatorRow || position >= requestedStartRow && position < requestedEndRow || position >= joinedStartRow && position < joinedEndRow) {
return 1;
} else if (position == dividerRow) {
} else if (position == dividerRow || position == divider2Row) {
return 2;
} else if (position == linkActionRow) {
return 3;
@ -471,9 +512,9 @@ public class InviteLinkBottomSheet extends BottomSheet {
return 4;
} else if (position == loadingRow) {
return 5;
} else if (position == emptyView || position == emptyView2) {
} else if (position == emptyView || position == emptyView2 || position == emptyView3) {
return 6;
} else if (position == divider2Row) {
} else if (position == divider3Row) {
return 7;
} else if (position == emptyHintRow) {
return 8;
@ -609,6 +650,7 @@ public class InviteLinkBottomSheet extends BottomSheet {
flickerLoadingView.setIsSingleCell(true);
flickerLoadingView.setViewType(FlickerLoadingView.USERS2_TYPE);
flickerLoadingView.showDate(false);
flickerLoadingView.setPaddingLeft(AndroidUtilities.dp(10));
view = flickerLoadingView;
break;
case 6:
@ -643,7 +685,7 @@ public class InviteLinkBottomSheet extends BottomSheet {
if (position == creatorHeaderRow) {
headerCell.setText(LocaleController.getString("LinkCreatedeBy", R.string.LinkCreatedeBy));
headerCell.setText2(null);
} else if (position == usersHeaderRow) {
} else if (position == joinedHeaderRow) {
if (invite.usage > 0) {
headerCell.setText(LocaleController.formatPluralString("PeopleJoined", invite.usage));
} else {
@ -654,6 +696,8 @@ public class InviteLinkBottomSheet extends BottomSheet {
} else {
headerCell.setText2(null);
}
} else if (position == requestedHeaderRow) {
headerCell.setText(LocaleController.formatPluralString("JoinRequests", invite.requested));
}
break;
case 1:
@ -701,7 +745,13 @@ public class InviteLinkBottomSheet extends BottomSheet {
}
}
} else {
TLRPC.TL_chatInviteImporter invitedUser = invitedUsers.get(position - usersStartRow);
int startRow = joinedStartRow;
List<TLRPC.TL_chatInviteImporter> usersList = joinedUsers;
if (requestedStartRow != -1 && position >= requestedStartRow) {
startRow = requestedStartRow;
usersList = requestedUsers;
}
TLRPC.TL_chatInviteImporter invitedUser = usersList.get(position - startRow);
user = users.get(invitedUser.user_id);
}
userCell.setAdminRole(role);
@ -783,7 +833,7 @@ public class InviteLinkBottomSheet extends BottomSheet {
return false;
}
return true;
} else if (position >= usersStartRow && position < usersEndRow) {
} else if (position >= joinedStartRow && position < joinedEndRow || position >= requestedStartRow && position < requestedEndRow) {
return true;
}
return false;
@ -840,7 +890,6 @@ public class InviteLinkBottomSheet extends BottomSheet {
if (shadowAnimation != null && shadowAnimation.equals(animation)) {
if (!show) {
shadow.setVisibility(View.INVISIBLE);
titleTextView.setVisibility(View.INVISIBLE);
}
shadowAnimation = null;
}
@ -858,32 +907,48 @@ public class InviteLinkBottomSheet extends BottomSheet {
}
public void loadUsers() {
if (invite.usage <= 0 || usersLoading) {
if (usersLoading) {
return;
}
boolean hasMoreJoinedUsers = invite.usage > joinedUsers.size();
boolean hasMoreRequestedUsers = invite.request_needed && invite.requested > requestedUsers.size();
boolean loadRequestedUsers;
if (hasMoreJoinedUsers) {
loadRequestedUsers = false;
} else if (hasMoreRequestedUsers) {
loadRequestedUsers = true;
} else {
return;
}
final List<TLRPC.TL_chatInviteImporter> importersList = loadRequestedUsers ? requestedUsers : joinedUsers;
TLRPC.TL_messages_getChatInviteImporters req = new TLRPC.TL_messages_getChatInviteImporters();
req.flags |= 2;
req.link = invite.link;
req.peer = MessagesController.getInstance(UserConfig.selectedAccount).getInputPeer(-chatId);
if (invitedUsers.isEmpty()) {
req.requested = loadRequestedUsers;
if (importersList.isEmpty()) {
req.offset_user = new TLRPC.TL_inputUserEmpty();
} else {
TLRPC.TL_chatInviteImporter invitedUser = invitedUsers.get(invitedUsers.size() - 1);
TLRPC.TL_chatInviteImporter invitedUser = importersList.get(importersList.size() - 1);
req.offset_user = MessagesController.getInstance(currentAccount).getInputUser(users.get(invitedUser.user_id));
req.offset_date = invitedUser.date;
}
usersLoading = true;
ConnectionsManager.getInstance(UserConfig.selectedAccount).sendRequest(req, (response, error) -> {
AndroidUtilities.runOnUIThread(() -> {
if (error == null) {
TLRPC.TL_messages_chatInviteImporters inviteImporters = (TLRPC.TL_messages_chatInviteImporters) response;
invitedUsers.addAll(inviteImporters.importers);
importersList.addAll(inviteImporters.importers);
for (int i = 0; i < inviteImporters.users.size(); i++) {
TLRPC.User user = inviteImporters.users.get(i);
users.put(user.id, user);
}
hasMore = invitedUsers.size() < inviteImporters.count;
hasMore = loadRequestedUsers
? importersList.size() < inviteImporters.count
: importersList.size() < inviteImporters.count || hasMoreRequestedUsers;
updateRows();
}
usersLoading = false;

View File

@ -124,8 +124,8 @@ public class InviteMembersBottomSheet extends UsersAlertBase implements Notifica
void didSelectDialogs(ArrayList<Long> dids);
}
public InviteMembersBottomSheet(Context context, int account, LongSparseArray<TLObject> ignoreUsers, long chatId, BaseFragment parentFragment, Theme.ResourcesProvider resourcesProvider) {
super(context, false, account, null);
public InviteMembersBottomSheet(Context context, int account, LongSparseArray<TLObject> ignoreUsers, long chatId, BaseFragment parentFragment, Theme.ResourcesProvider resourcesProvider) {
super(context, false, account, resourcesProvider);
this.ignoreUsers = ignoreUsers;
needSnapToTop = false;
this.parentFragment = parentFragment;

View File

@ -15,6 +15,8 @@ import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@ -33,6 +35,7 @@ import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.JoinSheetUserCell;
import org.telegram.ui.ChatActivity;
import androidx.core.widget.NestedScrollView;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@ -41,6 +44,8 @@ public class JoinGroupAlert extends BottomSheet {
private TLRPC.ChatInvite chatInvite;
private String hash;
private BaseFragment fragment;
private TextView requestTextView;
private RadialProgressView requestProgressView;
public JoinGroupAlert(final Context context, TLRPC.ChatInvite invite, String group, BaseFragment parentFragment) {
super(context, false);
@ -54,7 +59,22 @@ public class JoinGroupAlert extends BottomSheet {
LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.setClickable(true);
setCustomView(linearLayout);
FrameLayout frameLayout = new FrameLayout(context);
frameLayout.addView(linearLayout);
NestedScrollView scrollView = new NestedScrollView(context);
scrollView.addView(frameLayout);
setCustomView(scrollView);
ImageView closeView = new ImageView(context);
closeView.setBackground(Theme.createSelectorDrawable(getThemedColor(Theme.key_listSelector)));
closeView.setColorFilter(Theme.getColor(Theme.key_sheet_other));
closeView.setImageResource(R.drawable.ic_layer_close);
closeView.setOnClickListener((view) -> dismiss());
int closeViewPadding = AndroidUtilities.dp(8);
closeView.setPadding(closeViewPadding, closeViewPadding, closeViewPadding, closeViewPadding);
frameLayout.addView(closeView, LayoutHelper.createFrame(36, 36, Gravity.TOP | Gravity.END, 6, 8, 6, 0));
String title;
AvatarDrawable avatarDrawable;
@ -87,86 +107,160 @@ public class JoinGroupAlert extends BottomSheet {
textView.setEllipsize(TextUtils.TruncateAt.END);
linearLayout.addView(textView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 10, 9, 10, participants_count > 0 ? 0 : 20));
final boolean isChannel = invite.channel && !invite.megagroup || ChatObject.isChannelAndNotMegaGroup(invite.chat);
boolean hasAbout = !TextUtils.isEmpty(invite.about);
if (participants_count > 0) {
textView = new TextView(context);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
textView.setTextColor(Theme.getColor(Theme.key_dialogTextGray3));
textView.setSingleLine(true);
textView.setEllipsize(TextUtils.TruncateAt.END);
if (invite.channel || ChatObject.isChannel(invite.chat) && !invite.chat.megagroup) {
if (isChannel) {
textView.setText(LocaleController.formatPluralString("Subscribers", participants_count));
} else {
textView.setText(LocaleController.formatPluralString("Members", participants_count));
}
linearLayout.addView(textView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 10, 3, 10, 20));
linearLayout.addView(textView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 10, 3, 10, hasAbout ? 0 : 20));
}
if (!invite.participants.isEmpty()) {
RecyclerListView listView = new RecyclerListView(context);
listView.setPadding(0, 0, 0, AndroidUtilities.dp(8));
listView.setNestedScrollingEnabled(false);
listView.setClipToPadding(false);
listView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
listView.setHorizontalScrollBarEnabled(false);
listView.setVerticalScrollBarEnabled(false);
listView.setAdapter(new UsersAdapter(context));
listView.setGlowColor(Theme.getColor(Theme.key_dialogScrollGlow));
linearLayout.addView(listView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 90, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 0, 0, 7));
if (hasAbout) {
TextView aboutTextView = new TextView(context);
aboutTextView.setGravity(Gravity.CENTER);
aboutTextView.setText(invite.about);
aboutTextView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
aboutTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
linearLayout.addView(aboutTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP, 24, 10, 24, 20));
}
View shadow = new View(context);
shadow.setBackgroundColor(Theme.getColor(Theme.key_dialogShadowLine));
linearLayout.addView(shadow, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, AndroidUtilities.getShadowHeight()));
if (invite.request_needed) {
FrameLayout requestFrameLayout = new FrameLayout(getContext());
linearLayout.addView(requestFrameLayout, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
PickerBottomLayout pickerBottomLayout = new PickerBottomLayout(context, false);
linearLayout.addView(pickerBottomLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM));
pickerBottomLayout.cancelButton.setPadding(AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18), 0);
pickerBottomLayout.cancelButton.setTextColor(Theme.getColor(Theme.key_dialogTextBlue2));
pickerBottomLayout.cancelButton.setText(LocaleController.getString("Cancel", R.string.Cancel).toUpperCase());
pickerBottomLayout.cancelButton.setOnClickListener(view -> dismiss());
pickerBottomLayout.doneButton.setPadding(AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18), 0);
pickerBottomLayout.doneButton.setVisibility(View.VISIBLE);
pickerBottomLayout.doneButtonBadgeTextView.setVisibility(View.GONE);
pickerBottomLayout.doneButtonTextView.setTextColor(Theme.getColor(Theme.key_dialogTextBlue2));
if (invite.channel && !invite.megagroup || ChatObject.isChannel(invite.chat) && !invite.chat.megagroup) {
pickerBottomLayout.doneButtonTextView.setText(LocaleController.getString("ProfileJoinChannel", R.string.ProfileJoinChannel).toUpperCase());
} else {
pickerBottomLayout.doneButtonTextView.setText(LocaleController.getString("JoinGroup", R.string.JoinGroup));
}
pickerBottomLayout.doneButton.setOnClickListener(v -> {
dismiss();
final TLRPC.TL_messages_importChatInvite req = new TLRPC.TL_messages_importChatInvite();
req.hash = hash;
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
if (error == null) {
TLRPC.Updates updates = (TLRPC.Updates) response;
MessagesController.getInstance(currentAccount).processUpdates(updates, false);
}
requestProgressView = new RadialProgressView(getContext(), resourcesProvider);
requestProgressView.setProgressColor(getThemedColor(Theme.key_featuredStickers_addButton));
requestProgressView.setSize(AndroidUtilities.dp(32));
requestProgressView.setVisibility(View.INVISIBLE);
requestFrameLayout.addView(requestProgressView, LayoutHelper.createFrame(48, 48, Gravity.CENTER));
requestTextView = new TextView(getContext());
requestTextView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(6), getThemedColor(Theme.key_featuredStickers_addButton), getThemedColor(Theme.key_featuredStickers_addButtonPressed)));
requestTextView.setEllipsize(TextUtils.TruncateAt.END);
requestTextView.setGravity(Gravity.CENTER);
requestTextView.setSingleLine(true);
requestTextView.setText(isChannel ? LocaleController.getString("RequestToJoinChannel", R.string.RequestToJoinChannel) : LocaleController.getString("RequestToJoinGroup", R.string.RequestToJoinGroup));
requestTextView.setTextColor(getThemedColor(Theme.key_featuredStickers_buttonText));
requestTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
requestTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
requestTextView.setOnClickListener((view) -> {
AndroidUtilities.runOnUIThread(() -> {
if (fragment == null || fragment.getParentActivity() == null) {
return;
if (!isDismissed()) {
requestTextView.setVisibility(View.INVISIBLE);
requestProgressView.setVisibility(View.VISIBLE);
}
if (error == null) {
TLRPC.Updates updates = (TLRPC.Updates) response;
if (!updates.chats.isEmpty()) {
TLRPC.Chat chat = updates.chats.get(0);
chat.left = false;
chat.kicked = false;
MessagesController.getInstance(currentAccount).putUsers(updates.users, false);
MessagesController.getInstance(currentAccount).putChats(updates.chats, false);
Bundle args = new Bundle();
args.putLong("chat_id", chat.id);
if (MessagesController.getInstance(currentAccount).checkCanOpenChat(args, fragment)) {
ChatActivity chatActivity = new ChatActivity(args);
fragment.presentFragment(chatActivity, fragment instanceof ChatActivity);
}, 400);
final TLRPC.TL_messages_importChatInvite request = new TLRPC.TL_messages_importChatInvite();
request.hash = hash;
ConnectionsManager.getInstance(currentAccount).sendRequest(request, (response, error) -> {
AndroidUtilities.runOnUIThread(() -> {
if (fragment == null || fragment.getParentActivity() == null) {
return;
}
if (error != null) {
if ("INVITE_REQUEST_SENT".equals(error.text)) {
setOnDismissListener(dialog -> {
Bulletin.TwoLineLottieLayout layout = new Bulletin.TwoLineLottieLayout(context, fragment.getResourceProvider());
layout.imageView.setAnimation(R.raw.timer_3, 28, 28);
layout.titleTextView.setText(LocaleController.getString("RequestToJoinSent", R.string.RequestToJoinSent));
String subTitle = isChannel
? LocaleController.getString("RequestToJoinChannelSentDescription", R.string.RequestToJoinChannelSentDescription)
: LocaleController.getString("RequestToJoinSentDescription", R.string.RequestToJoinGroupSentDescription);
layout.subtitleTextView.setText(subTitle);
Bulletin.make(fragment, layout, Bulletin.DURATION_LONG).show();
});
} else {
AlertsCreator.processError(currentAccount, error, fragment, request);
}
}
} else {
AlertsCreator.processError(currentAccount, error, fragment, req);
dismiss();
});
}, ConnectionsManager.RequestFlagFailOnServerErrors);
});
requestFrameLayout.addView(requestTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, Gravity.START, 16, 0, 16, 0));
TextView descriptionTextView = new TextView(getContext());
descriptionTextView.setGravity(Gravity.CENTER);
descriptionTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
descriptionTextView.setText(isChannel ? LocaleController.getString("RequestToJoinChannelDescription", R.string.RequestToJoinChannelDescription) : LocaleController.getString("RequestToJoinGroupDescription", R.string.RequestToJoinGroupDescription));
descriptionTextView.setTextColor(Theme.getColor(Theme.key_dialogTextGray3));
linearLayout.addView(descriptionTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP, 24, 17, 24, 15));
} else {
if (!invite.participants.isEmpty()) {
RecyclerListView listView = new RecyclerListView(context);
listView.setPadding(0, 0, 0, AndroidUtilities.dp(8));
listView.setNestedScrollingEnabled(false);
listView.setClipToPadding(false);
listView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
listView.setHorizontalScrollBarEnabled(false);
listView.setVerticalScrollBarEnabled(false);
listView.setAdapter(new UsersAdapter(context));
listView.setGlowColor(Theme.getColor(Theme.key_dialogScrollGlow));
linearLayout.addView(listView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 90, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 0, 0, 7));
}
View shadow = new View(context);
shadow.setBackgroundColor(Theme.getColor(Theme.key_dialogShadowLine));
linearLayout.addView(shadow, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, AndroidUtilities.getShadowHeight()));
PickerBottomLayout pickerBottomLayout = new PickerBottomLayout(context, false);
linearLayout.addView(pickerBottomLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM));
pickerBottomLayout.cancelButton.setPadding(AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18), 0);
pickerBottomLayout.cancelButton.setTextColor(Theme.getColor(Theme.key_dialogTextBlue2));
pickerBottomLayout.cancelButton.setText(LocaleController.getString("Cancel", R.string.Cancel).toUpperCase());
pickerBottomLayout.cancelButton.setOnClickListener(view -> dismiss());
pickerBottomLayout.doneButton.setPadding(AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18), 0);
pickerBottomLayout.doneButton.setVisibility(View.VISIBLE);
pickerBottomLayout.doneButtonBadgeTextView.setVisibility(View.GONE);
pickerBottomLayout.doneButtonTextView.setTextColor(Theme.getColor(Theme.key_dialogTextBlue2));
if (invite.channel && !invite.megagroup || ChatObject.isChannel(invite.chat) && !invite.chat.megagroup) {
pickerBottomLayout.doneButtonTextView.setText(LocaleController.getString("ProfileJoinChannel", R.string.ProfileJoinChannel).toUpperCase());
} else {
pickerBottomLayout.doneButtonTextView.setText(LocaleController.getString("JoinGroup", R.string.JoinGroup));
}
pickerBottomLayout.doneButton.setOnClickListener(v -> {
dismiss();
final TLRPC.TL_messages_importChatInvite req = new TLRPC.TL_messages_importChatInvite();
req.hash = hash;
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
if (error == null) {
TLRPC.Updates updates = (TLRPC.Updates) response;
MessagesController.getInstance(currentAccount).processUpdates(updates, false);
}
});
}, ConnectionsManager.RequestFlagFailOnServerErrors);
});
AndroidUtilities.runOnUIThread(() -> {
if (fragment == null || fragment.getParentActivity() == null) {
return;
}
if (error == null) {
TLRPC.Updates updates = (TLRPC.Updates) response;
if (!updates.chats.isEmpty()) {
TLRPC.Chat chat = updates.chats.get(0);
chat.left = false;
chat.kicked = false;
MessagesController.getInstance(currentAccount).putUsers(updates.users, false);
MessagesController.getInstance(currentAccount).putChats(updates.chats, false);
Bundle args = new Bundle();
args.putLong("chat_id", chat.id);
if (MessagesController.getInstance(currentAccount).checkCanOpenChat(args, fragment)) {
ChatActivity chatActivity = new ChatActivity(args);
fragment.presentFragment(chatActivity, fragment instanceof ChatActivity);
}
}
} else {
AlertsCreator.processError(currentAccount, error, fragment, req);
}
});
}, ConnectionsManager.RequestFlagFailOnServerErrors);
});
}
}
private class UsersAdapter extends RecyclerListView.SelectionAdapter {

View File

@ -0,0 +1,345 @@
package org.telegram.ui.Components;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.PorterDuff;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.DialogObject;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.ImageLoader;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.ActionBar.BackDrawable;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ActionBar.ThemeDescription;
import org.telegram.ui.Cells.UserCell;
import org.telegram.ui.ProfileActivity;
import java.util.ArrayList;
public class MediaActivity extends BaseFragment implements SharedMediaLayout.SharedMediaPreloaderDelegate {
private SharedMediaLayout.SharedMediaPreloader sharedMediaPreloader;
private TLRPC.ChatFull currentChatInfo;
private long dialogId;
private SimpleTextView nameTextView;
ProfileActivity.AvatarImageView avatarImageView;
SharedMediaLayout sharedMediaLayout;
AudioPlayerAlert.ClippingTextViewSwitcher mediaCounterTextView;
public MediaActivity(Bundle args, SharedMediaLayout.SharedMediaPreloader sharedMediaPreloader) {
super(args);
this.sharedMediaPreloader = sharedMediaPreloader;
}
@Override
public boolean onFragmentCreate() {
dialogId = getArguments().getLong("dialog_id");
if (this.sharedMediaPreloader == null) {
this.sharedMediaPreloader = new SharedMediaLayout.SharedMediaPreloader(this);
this.sharedMediaPreloader.addDelegate(this);
}
return super.onFragmentCreate();
}
@Override
public View createView(Context context) {
actionBar.setBackButtonDrawable(new BackDrawable(false));
actionBar.setCastShadows(false);
actionBar.setAddToContainer(false);
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
@Override
public void onItemClick(int id) {
if (id == -1) {
finishFragment();
}
}
});
FrameLayout avatarContainer = new FrameLayout(context);
FrameLayout fragmentView = new FrameLayout(context) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
FrameLayout.LayoutParams lp = (LayoutParams) sharedMediaLayout.getLayoutParams();
lp.topMargin = ActionBar.getCurrentActionBarHeight() + (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0);
lp = (LayoutParams) avatarContainer.getLayoutParams();
lp.topMargin = actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0;
lp.height = ActionBar.getCurrentActionBarHeight();
int textTop = (ActionBar.getCurrentActionBarHeight() / 2 - AndroidUtilities.dp(22)) / 2 + AndroidUtilities.dp(!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 4 : 5);
lp = (LayoutParams) nameTextView.getLayoutParams();
lp.topMargin = textTop;
textTop = ActionBar.getCurrentActionBarHeight() / 2 + (ActionBar.getCurrentActionBarHeight() / 2 - AndroidUtilities.dp(19)) / 2 - AndroidUtilities.dp(3);
lp = (LayoutParams) mediaCounterTextView.getLayoutParams();
lp.topMargin = textTop;
lp = (LayoutParams) avatarImageView.getLayoutParams();
lp.topMargin = (ActionBar.getCurrentActionBarHeight() - AndroidUtilities.dp(42)) / 2;
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (sharedMediaLayout != null && sharedMediaLayout.isInFastScroll() && sharedMediaLayout.getY() == 0) {
return sharedMediaLayout.dispatchFastScrollEvent(ev);
}
if (sharedMediaLayout != null && sharedMediaLayout.checkPinchToZoom(ev)) {
return true;
}
return super.dispatchTouchEvent(ev);
}
};
this.fragmentView = fragmentView;
nameTextView = new SimpleTextView(context);
nameTextView.setTextSize(18);
nameTextView.setGravity(Gravity.LEFT);
nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
nameTextView.setLeftDrawableTopPadding(-AndroidUtilities.dp(1.3f));
nameTextView.setScrollNonFitText(true);
nameTextView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
avatarContainer.addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 118, 0, 56, 0));
avatarImageView = new ProfileActivity.AvatarImageView(context) {
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
if (getImageReceiver().hasNotThumb()) {
info.setText(LocaleController.getString("AccDescrProfilePicture", R.string.AccDescrProfilePicture));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
info.addAction(new AccessibilityNodeInfo.AccessibilityAction(AccessibilityNodeInfo.ACTION_CLICK, LocaleController.getString("Open", R.string.Open)));
info.addAction(new AccessibilityNodeInfo.AccessibilityAction(AccessibilityNodeInfo.ACTION_LONG_CLICK, LocaleController.getString("AccDescrOpenInPhotoViewer", R.string.AccDescrOpenInPhotoViewer)));
}
} else {
info.setVisibleToUser(false);
}
}
};
avatarImageView.getImageReceiver().setAllowDecodeSingleFrame(true);
avatarImageView.setRoundRadius(AndroidUtilities.dp(21));
avatarImageView.setPivotX(0);
avatarImageView.setPivotY(0);
AvatarDrawable avatarDrawable = new AvatarDrawable();
avatarDrawable.setProfile(true);
avatarImageView.setImageDrawable(avatarDrawable);
avatarContainer.addView(avatarImageView, LayoutHelper.createFrame(42, 42, Gravity.TOP | Gravity.LEFT, 64, 0, 0, 0));
mediaCounterTextView = new AudioPlayerAlert.ClippingTextViewSwitcher(context) {
@Override
protected TextView createTextView() {
TextView textView = new TextView(context);
textView.setTextColor(Theme.getColor(Theme.key_player_actionBarSubtitle));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
textView.setSingleLine(true);
textView.setEllipsize(TextUtils.TruncateAt.END);
textView.setGravity(Gravity.LEFT);
return textView;
}
};
avatarContainer.addView(mediaCounterTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 118, 0, 56, 0));
sharedMediaLayout = new SharedMediaLayout(context, dialogId, sharedMediaPreloader, 0, null, currentChatInfo, false, this, new SharedMediaLayout.Delegate() {
@Override
public void scrollToSharedMedia() {
}
@Override
public boolean onMemberClick(TLRPC.ChatParticipant participant, boolean b, boolean resultOnly) {
return false;
}
@Override
public TLRPC.Chat getCurrentChat() {
return null;
}
@Override
public boolean isFragmentOpened() {
return true;
}
@Override
public RecyclerListView getListView() {
return null;
}
@Override
public boolean canSearchMembers() {
return false;
}
@Override
public void updateSelectedMediaTabText() {
updateMediaCount();
}
}, SharedMediaLayout.VIEW_TYPE_MEDIA_ACTIVITY) {
@Override
protected void onSelectedTabChanged() {
updateMediaCount();
}
@Override
protected void onSearchStateChanged(boolean expanded) {
if (SharedConfig.smoothKeyboard) {
AndroidUtilities.removeAdjustResize(getParentActivity(), classGuid);
}
AndroidUtilities.updateViewVisibilityAnimated(avatarContainer, !expanded, 0.95f, true);
}
};
sharedMediaLayout.getSearchItem().setTranslationY(0);
sharedMediaLayout.photoVideoOptionsItem.setTranslationY(0);
fragmentView.addView(sharedMediaLayout);
fragmentView.addView(actionBar);
fragmentView.addView(avatarContainer);
TLObject avatarObject = null;
if (DialogObject.isEncryptedDialog(dialogId)) {
TLRPC.EncryptedChat encryptedChat = getMessagesController().getEncryptedChat(DialogObject.getEncryptedChatId(dialogId));
if (encryptedChat != null) {
TLRPC.User user = getMessagesController().getUser(encryptedChat.user_id);
if (user != null) {
nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name));
avatarDrawable.setInfo(user);
avatarObject = user;
}
}
} else if (DialogObject.isUserDialog(dialogId)) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogId);
if (user != null) {
if (user.self) {
nameTextView.setText(LocaleController.getString("SavedMessages", R.string.SavedMessages));
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_SAVED);
avatarDrawable.setSmallSize(true);
} else {
nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name));
avatarDrawable.setInfo(user);
avatarObject = user;
}
}
} else {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialogId);
if (chat != null) {
nameTextView.setText(chat.title);
avatarDrawable.setInfo(chat);
avatarObject = chat;
}
}
final ImageLocation thumbLocation = ImageLocation.getForUserOrChat(avatarObject, ImageLocation.TYPE_SMALL);
avatarImageView.setImage(thumbLocation, "50_50", avatarDrawable, avatarObject);
if (TextUtils.isEmpty(nameTextView.getText())) {
nameTextView.setText(LocaleController.getString("SharedContentTitle", R.string.SharedContentTitle));
}
if (sharedMediaLayout.isSearchItemVisible()) {
sharedMediaLayout.getSearchItem().setVisibility(View.VISIBLE);
}
if (sharedMediaLayout.isCalendarItemVisible()) {
sharedMediaLayout.photoVideoOptionsItem.setVisibility(View.VISIBLE);
} else {
sharedMediaLayout.photoVideoOptionsItem.setVisibility(View.INVISIBLE);
}
AndroidUtilities.updateViewVisibilityAnimated(avatarContainer, true, 1, false);
updateMediaCount();
updateColors();
return fragmentView;
}
private void updateMediaCount() {
int id = sharedMediaLayout.getClosestTab();
int[] mediaCount = sharedMediaPreloader.getLastMediaCount();
if (id < 0 || mediaCount[id] < 0) {
return;
}
if (id == 0) {
if (sharedMediaLayout.getPhotosVideosTypeFilter() == SharedMediaLayout.FILTER_PHOTOS_ONLY) {
mediaCounterTextView.setText(LocaleController.formatPluralString("Photos", mediaCount[MediaDataController.MEDIA_PHOTOS_ONLY]));
} else if (sharedMediaLayout.getPhotosVideosTypeFilter() == SharedMediaLayout.FILTER_VIDEOS_ONLY) {
mediaCounterTextView.setText(LocaleController.formatPluralString("Videos", mediaCount[MediaDataController.MEDIA_VIDEOS_ONLY]));
} else {
mediaCounterTextView.setText(LocaleController.formatPluralString("Media", mediaCount[MediaDataController.MEDIA_PHOTOVIDEO]));
}
} else if (id == 1) {
mediaCounterTextView.setText(LocaleController.formatPluralString("Files", mediaCount[MediaDataController.MEDIA_FILE]));
} else if (id == 2) {
mediaCounterTextView.setText(LocaleController.formatPluralString("Voice", mediaCount[MediaDataController.MEDIA_AUDIO]));
} else if (id == 3) {
mediaCounterTextView.setText(LocaleController.formatPluralString("Links", mediaCount[MediaDataController.MEDIA_URL]));
} else if (id == 4) {
mediaCounterTextView.setText(LocaleController.formatPluralString("MusicFiles", mediaCount[MediaDataController.MEDIA_MUSIC]));
} else if (id == 5) {
mediaCounterTextView.setText(LocaleController.formatPluralString("GIFs", mediaCount[MediaDataController.MEDIA_GIF]));
}
}
public void setChatInfo(TLRPC.ChatFull currentChatInfo) {
this.currentChatInfo = currentChatInfo;
}
public long getDialogId() {
return dialogId;
}
@Override
public void mediaCountUpdated() {
if (sharedMediaLayout != null && sharedMediaPreloader != null) {
sharedMediaLayout.setNewMediaCounts(sharedMediaPreloader.getLastMediaCount());
}
updateMediaCount();
}
private void updateColors() {
actionBar.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
actionBar.setItemsColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2), false);
actionBar.setItemsBackgroundColor(Theme.getColor(Theme.key_actionBarActionModeDefaultSelector), false);
actionBar.setTitleColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
nameTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
}
@Override
public ArrayList<ThemeDescription> getThemeDescriptions() {
ThemeDescription.ThemeDescriptionDelegate themeDelegate = () -> {
updateColors();
};
ArrayList<ThemeDescription> arrayList = new ArrayList<>();
arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_windowBackgroundWhite));
arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_actionBarActionModeDefaultSelector));
arrayList.add(new ThemeDescription(null, 0, null, null, null, themeDelegate, Theme.key_windowBackgroundWhiteBlackText));
arrayList.addAll(sharedMediaLayout.getThemeDescriptions());
return arrayList;
}
}

View File

@ -0,0 +1,157 @@
package org.telegram.ui.Components;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import android.app.Activity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.Delegates.MemberRequestsDelegate;
import org.telegram.ui.LaunchActivity;
public class MemberRequestsBottomSheet extends UsersAlertBase {
private final int touchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
private final MemberRequestsDelegate delegate;
private final FlickerLoadingView currentLoadingView;
private final StickerEmptyView membersEmptyView;
private final StickerEmptyView membersSearchEmptyView;
private float yOffset;
private boolean enterEventSent;
public MemberRequestsBottomSheet(BaseFragment fragment, long chatId) {
super(fragment.getParentActivity(), false, fragment.getCurrentAccount(), fragment.getResourceProvider());
this.needSnapToTop = false;
this.isEmptyViewVisible = false;
this.delegate = new MemberRequestsDelegate(fragment, container, chatId, false) {
@Override
protected void onImportersChanged(String query, boolean fromCache, boolean fromHide) {
if (!hasAllImporters()) {
if (membersEmptyView.getVisibility() != View.INVISIBLE) {
membersEmptyView.setVisibility(View.INVISIBLE);
}
dismiss();
} else if (fromHide) {
searchView.searchEditText.setText("");
} else {
super.onImportersChanged(query, fromCache, fromHide);
}
}
};
this.delegate.setShowLastItemDivider(false);
setDimBehindAlpha(75);
searchView.searchEditText.setHint(LocaleController.getString("SearchMemberRequests", R.string.SearchMemberRequests));
searchListViewAdapter = listViewAdapter = delegate.getAdapter();
listView.setAdapter(listViewAdapter);
delegate.setRecyclerView(listView);
int position = ((ViewGroup) listView.getParent()).indexOfChild(listView);
currentLoadingView = delegate.getLoadingView();
containerView.addView(currentLoadingView, position, LayoutHelper.createFrame(MATCH_PARENT, MATCH_PARENT));
membersEmptyView = delegate.getEmptyView();
containerView.addView(membersEmptyView, position, LayoutHelper.createFrame(MATCH_PARENT, MATCH_PARENT));
membersSearchEmptyView = delegate.getSearchEmptyView();
containerView.addView(membersSearchEmptyView, position, LayoutHelper.createFrame(MATCH_PARENT, MATCH_PARENT));
delegate.loadMembers();
}
@Override
public void show() {
if (delegate.isNeedRestoreList && scrollOffsetY == 0) {
scrollOffsetY = AndroidUtilities.dp(8);
}
super.show();
delegate.isNeedRestoreList = false;
}
@Override
public void onBackPressed() {
if (delegate.onBackPressed()) {
super.onBackPressed();
}
}
public boolean isNeedRestoreDialog() {
return delegate.isNeedRestoreList;
}
@Override
protected boolean isAllowSelectChildAtPosition(float x, float y) {
return y >= scrollOffsetY + frameLayout.getMeasuredHeight();
}
@Override
protected void setTranslationY(int newOffset) {
super.setTranslationY(newOffset);
currentLoadingView.setTranslationY(newOffset + frameLayout.getMeasuredHeight());
membersEmptyView.setTranslationY(newOffset);
membersSearchEmptyView.setTranslationY(newOffset);
}
@Override
protected void updateLayout() {
if (listView.getChildCount() <= 0) {
int newOffset = listView.getVisibility() == View.VISIBLE
? listView.getPaddingTop() - AndroidUtilities.dp(8)
: 0;
if (scrollOffsetY != newOffset) {
scrollOffsetY = newOffset;
setTranslationY(newOffset);
}
} else {
super.updateLayout();
}
}
@Override
protected void search(String text) {
super.search(text);
delegate.setQuery(text);
}
@Override
protected void onSearchViewTouched(MotionEvent ev, EditTextBoldCursor searchEditText) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
yOffset = scrollOffsetY;
delegate.setAdapterItemsEnabled(false);
} else if (ev.getAction() == MotionEvent.ACTION_UP && Math.abs(scrollOffsetY - yOffset) < touchSlop) {
if (!enterEventSent) {
Activity activity = AndroidUtilities.findActivity(getContext());
BaseFragment fragment = null;
if (activity instanceof LaunchActivity) {
fragment = ((LaunchActivity) activity).getActionBarLayout().fragmentsStack.get(((LaunchActivity) activity).getActionBarLayout().fragmentsStack.size() - 1);
}
if (fragment instanceof ChatActivity) {
boolean keyboardVisible = ((ChatActivity) fragment).needEnterText();
enterEventSent = true;
AndroidUtilities.runOnUIThread(() -> {
setFocusable(true);
searchEditText.requestFocus();
AndroidUtilities.runOnUIThread(() -> AndroidUtilities.showKeyboard(searchEditText));
}, keyboardVisible ? 200 : 0);
} else {
enterEventSent = true;
setFocusable(true);
searchEditText.requestFocus();
AndroidUtilities.runOnUIThread(() -> AndroidUtilities.showKeyboard(searchEditText));
}
}
}
if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) {
delegate.setAdapterItemsEnabled(true);
}
}
}

View File

@ -25,6 +25,7 @@ import android.view.View;
import androidx.core.graphics.ColorUtils;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.Utilities;
@ -36,6 +37,8 @@ public class MotionBackgroundDrawable extends Drawable {
private static final boolean useLegacyBitmap = Build.VERSION.SDK_INT < 28;
private static final boolean useSoftLight = Build.VERSION.SDK_INT >= 29;
private static boolean errorWhileGenerateLegacyBitmap = false;
private static float legacyBitmapScale = 0.7f;
private int[] colors = new int[]{
0xff426D57,
@ -95,6 +98,9 @@ public class MotionBackgroundDrawable extends Drawable {
private float patternAlpha = 1f;
private int alpha = 255;
private ColorFilter legacyBitmapColorFilter;
private int legacyBitmapColor;
public MotionBackgroundDrawable() {
super();
init();
@ -240,18 +246,27 @@ public class MotionBackgroundDrawable extends Drawable {
private void generateNextGradient() {
if (useLegacyBitmap && intensity < 0) {
if (legacyBitmap != null) {
if (legacyBitmap2 == null || legacyBitmap2.getHeight() != legacyBitmap.getHeight() || legacyBitmap2.getWidth() != legacyBitmap.getWidth()) {
if (legacyBitmap2 != null) {
legacyBitmap2.recycle();
try {
if (legacyBitmap != null) {
if (legacyBitmap2 == null || legacyBitmap2.getHeight() != legacyBitmap.getHeight() || legacyBitmap2.getWidth() != legacyBitmap.getWidth()) {
if (legacyBitmap2 != null) {
legacyBitmap2.recycle();
}
legacyBitmap2 = Bitmap.createBitmap(legacyBitmap.getWidth(), legacyBitmap.getHeight(), Bitmap.Config.ARGB_8888);
legacyCanvas2 = new Canvas(legacyBitmap2);
} else {
legacyBitmap2.eraseColor(Color.TRANSPARENT);
}
legacyBitmap2 = Bitmap.createBitmap(legacyBitmap.getWidth(), legacyBitmap.getHeight(), Bitmap.Config.ARGB_8888);
legacyCanvas2 = new Canvas(legacyBitmap2);
} else {
legacyBitmap2.eraseColor(Color.TRANSPARENT);
legacyCanvas2.drawBitmap(legacyBitmap, 0, 0, null);
}
} catch (Exception e) {
FileLog.e(e);
if (legacyBitmap2 != null) {
legacyBitmap2.recycle();
legacyBitmap2 = null;
}
legacyCanvas2.drawBitmap(legacyBitmap,0 ,0, null);
}
Utilities.generateGradient(currentBitmap, true, phase, 1f, currentBitmap.getWidth(), currentBitmap.getHeight(), currentBitmap.getRowBytes(), colors);
invalidateLegacy = true;
}
@ -316,7 +331,6 @@ public class MotionBackgroundDrawable extends Drawable {
AndroidUtilities.cancelRunOnUIThread(updateAnimationRunnable);
AndroidUtilities.runOnUIThread(updateAnimationRunnable, 16);
}
// invalidateLegacy = true;
}
public boolean hasPattern() {
@ -371,7 +385,11 @@ public class MotionBackgroundDrawable extends Drawable {
matrix = new Matrix();
} else {
createLegacyBitmap();
paint2.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
if (!errorWhileGenerateLegacyBitmap) {
paint2.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
} else {
paint2.setXfermode(null);
}
}
} else {
if (!useLegacyBitmap) {
@ -400,9 +418,9 @@ public class MotionBackgroundDrawable extends Drawable {
}
private void createLegacyBitmap() {
if (useLegacyBitmap && intensity < 0) {
int w = patternBounds.width();
int h = patternBounds.height();
if (useLegacyBitmap && intensity < 0 && !errorWhileGenerateLegacyBitmap) {
int w = (int) (patternBounds.width() * legacyBitmapScale);
int h = (int) (patternBounds.height() * legacyBitmapScale);
if (w > 0 && h > 0 && (legacyBitmap == null || legacyBitmap.getWidth() != w || legacyBitmap.getHeight() != h)) {
if (legacyBitmap != null) {
legacyBitmap.recycle();
@ -411,9 +429,20 @@ public class MotionBackgroundDrawable extends Drawable {
legacyBitmap2.recycle();
legacyBitmap2 = null;
}
legacyBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
legacyCanvas = new Canvas(legacyBitmap);
invalidateLegacy = true;
try {
legacyBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
legacyCanvas = new Canvas(legacyBitmap);
invalidateLegacy = true;
} catch (Exception e) {
if (legacyBitmap != null) {
legacyBitmap.recycle();
legacyBitmap = null;
}
FileLog.e(e);
errorWhileGenerateLegacyBitmap = true;
paint2.setXfermode(null);
}
}
}
}
@ -441,7 +470,29 @@ public class MotionBackgroundDrawable extends Drawable {
canvas.drawColor(ColorUtils.setAlphaComponent(Color.BLACK, alpha));
if (patternBitmap != null) {
if (useLegacyBitmap) {
if (legacyBitmap != null) {
if (errorWhileGenerateLegacyBitmap) {
bitmapWidth = patternBitmap.getWidth();
bitmapHeight = patternBitmap.getHeight();
maxScale = Math.max(w / bitmapWidth, h / bitmapHeight);
width = bitmapWidth * maxScale;
height = bitmapHeight * maxScale;
x = (w - width) / 2;
y = (h - height) / 2;
rect.set(x, y, x + width, y + height);
int averageColor = AndroidUtilities.getAverageColor(colors[2], AndroidUtilities.getAverageColor(colors[0], colors[1]));
if (colors[3] != 0) {
averageColor = AndroidUtilities.getAverageColor(colors[3], averageColor);
}
if (legacyBitmapColorFilter == null || averageColor != legacyBitmapColor) {
legacyBitmapColor = averageColor;
legacyBitmapColorFilter = new PorterDuffColorFilter(averageColor, PorterDuff.Mode.SRC_IN);
}
paint2.setColorFilter(legacyBitmapColorFilter);
paint2.setAlpha((int) ((Math.abs(intensity) / 100f) * alpha * patternAlpha));
canvas.translate(0, tr);
canvas.drawBitmap(patternBitmap, null, rect, paint2);
} else if (legacyBitmap != null) {
if (invalidateLegacy) {
rect.set(0, 0, legacyBitmap.getWidth(), legacyBitmap.getHeight());
int oldAlpha = paint.getAlpha();
@ -460,7 +511,10 @@ public class MotionBackgroundDrawable extends Drawable {
paint2.setColorFilter(null);
paint2.setAlpha((int) ((Math.abs(intensity) / 100f) * 255));
legacyCanvas.save();
legacyCanvas.scale(legacyBitmapScale, legacyBitmapScale);
legacyCanvas.drawBitmap(patternBitmap, null, rect, paint2);
legacyCanvas.restore();
invalidateLegacy = false;
}
@ -477,6 +531,9 @@ public class MotionBackgroundDrawable extends Drawable {
}
}
} else {
if (matrix == null) {
matrix = new Matrix();
}
matrix.reset();
matrix.setTranslate(x, y + tr);
float scaleW = (currentBitmap.getWidth() / (float) bounds.width());

View File

@ -1188,8 +1188,9 @@ public class PollVotesAlert extends BottomSheet {
}
@Override
public int getPositionForScrollProgress(float progress) {
return 0;
public void getPositionForScrollProgress(RecyclerListView listView, float progress, int[] position) {
position[0] = 0;
position[1] = 0;
}
}

View File

@ -738,6 +738,7 @@ public class ProfileGalleryView extends CircularViewPager implements Notificatio
if (did == dialogId && parentClassGuid == guid && adapter != null) {
boolean fromCache = (Boolean) args[2];
ArrayList<TLRPC.Photo> arrayList = (ArrayList<TLRPC.Photo>) args[4];
thumbsFileNames.clear();
videoFileNames.clear();
imagesLocations.clear();

View File

@ -17,6 +17,8 @@ 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.RectF;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
@ -25,7 +27,6 @@ import android.os.SystemClock;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.util.StateSet;
import android.view.GestureDetector;
@ -43,6 +44,7 @@ import android.widget.FrameLayout;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.ui.ActionBar.Theme;
import java.lang.reflect.Field;
@ -50,11 +52,11 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.exoplayer2.util.Log;
public class RecyclerListView extends RecyclerView {
private OnItemClickListener onItemClickListener;
@ -102,7 +104,7 @@ public class RecyclerListView extends RecyclerView {
private boolean selfOnLayout;
private boolean scrollingByUser;
public boolean scrollingByUser;
private GestureDetector gestureDetector;
private View currentChildView;
@ -145,6 +147,10 @@ public class RecyclerListView extends RecyclerView {
protected final Theme.ResourcesProvider resourcesProvider;
public FastScroll getFastScroll() {
return fastScroll;
}
public interface OnItemClickListener {
void onItemClick(View view, int position);
}
@ -177,7 +183,28 @@ public class RecyclerListView extends RecyclerView {
public abstract static class FastScrollAdapter extends SelectionAdapter {
public abstract String getLetter(int position);
public abstract int getPositionForScrollProgress(float progress);
public abstract void getPositionForScrollProgress(RecyclerListView listView, float progress, int[] position);
public void onStartFastScroll() {
}
public void onFinishFastScroll(RecyclerListView listView) {
}
public int getTotalItemsCount() {
return getItemCount();
}
public float getScrollProgress(RecyclerListView listView) {
return listView.computeVerticalScrollOffset() / ((float) getTotalItemsCount() * listView.getChildAt(0).getMeasuredHeight() - listView.getMeasuredHeight());
}
public boolean fastScrollIsVisible(RecyclerListView listView) {
return true;
}
public void onFastScrollSingleTap() {
}
}
public interface IntReturnCallback {
@ -323,10 +350,14 @@ public class RecyclerListView extends RecyclerView {
}
}
private class FastScroll extends View {
public class FastScroll extends View {
public static final int LETTER_TYPE = 0;
public static final int DATE_TYPE = 1;
private RectF rect = new RectF();
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint paint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
private float progress;
private float lastY;
private float startDy;
@ -341,85 +372,147 @@ public class RecyclerListView extends RecyclerView {
private float textY;
private float bubbleProgress;
private long lastUpdateTime;
private int[] colors = new int[6];
private int scrollX;
private int type;
private int inactiveColor;
private int activeColor;
private boolean floatingDateVisible;
private float floatingDateProgress;
private int[] positionWithOffset = new int[2];
boolean isVisible;
float touchSlop;
public FastScroll(Context context) {
Drawable fastScrollBackgroundDrawable;
Runnable hideFloatingDateRunnable = new Runnable() {
@Override
public void run() {
if (pressed) {
AndroidUtilities.cancelRunOnUIThread(hideFloatingDateRunnable);
AndroidUtilities.runOnUIThread(hideFloatingDateRunnable, 4000);
} else {
floatingDateVisible = false;
invalidate();
}
}
};
public FastScroll(Context context, int type) {
super(context);
letterPaint.setTextSize(AndroidUtilities.dp(45));
this.type = type;
if (type == LETTER_TYPE) {
letterPaint.setTextSize(AndroidUtilities.dp(45));
} else {
letterPaint.setTextSize(AndroidUtilities.dp(13));
letterPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
paint2.setColor(Theme.getColor(Theme.key_windowBackgroundWhite));
fastScrollBackgroundDrawable = ContextCompat.getDrawable(context, R.drawable.calendar_date).mutate();
fastScrollBackgroundDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhite), PorterDuff.Mode.MULTIPLY));
}
for (int a = 0; a < 8; a++) {
radii[a] = AndroidUtilities.dp(44);
}
scrollX = LocaleController.isRTL ? AndroidUtilities.dp(10) : AndroidUtilities.dp(117);
scrollX = LocaleController.isRTL ? AndroidUtilities.dp(10) : AndroidUtilities.dp((type == LETTER_TYPE ? 132 : 240) - 15);
updateColors();
setFocusableInTouchMode(true);
ViewConfiguration vc = ViewConfiguration.get(context);
touchSlop = vc.getScaledTouchSlop();
}
private void updateColors() {
int inactive = Theme.getColor(Theme.key_fastScrollInactive);
int active = Theme.getColor(Theme.key_fastScrollActive);
paint.setColor(inactive);
letterPaint.setColor(Theme.getColor(Theme.key_fastScrollText));
colors[0] = Color.red(inactive);
colors[1] = Color.red(active);
colors[2] = Color.green(inactive);
colors[3] = Color.green(active);
colors[4] = Color.blue(inactive);
colors[5] = Color.blue(active);
inactiveColor = type == LETTER_TYPE ? Theme.getColor(Theme.key_fastScrollInactive) : ColorUtils.setAlphaComponent(Color.BLACK, (int) (255 * 0.4f));
activeColor = Theme.getColor(Theme.key_fastScrollActive);
paint.setColor(inactiveColor);
if (type == LETTER_TYPE) {
letterPaint.setColor(Theme.getColor(Theme.key_fastScrollText));
} else {
letterPaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
}
invalidate();
}
float startY;
boolean isMoving;
long startTime;
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isVisible) {
pressed = false;
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
float x = event.getX();
lastY = event.getY();
startY = lastY = event.getY();
float currentY = (float) Math.ceil((getMeasuredHeight() - AndroidUtilities.dp(24 + 30)) * progress) + AndroidUtilities.dp(12);
if (LocaleController.isRTL && x > AndroidUtilities.dp(25) || !LocaleController.isRTL && x < AndroidUtilities.dp(107) || lastY < currentY || lastY > currentY + AndroidUtilities.dp(30)) {
return false;
}
startDy = lastY - currentY;
startTime = System.currentTimeMillis();
pressed = true;
isMoving = false;
lastUpdateTime = System.currentTimeMillis();
getCurrentLetter();
invalidate();
Adapter adapter = getAdapter();
showFloatingDate();
if (adapter instanceof FastScrollAdapter) {
((FastScrollAdapter) adapter).onStartFastScroll();
}
return true;
case MotionEvent.ACTION_MOVE:
if (!pressed) {
return true;
}
float newY = event.getY();
float minY = AndroidUtilities.dp(12) + startDy;
float maxY = getMeasuredHeight() - AndroidUtilities.dp(12 + 30) + startDy;
if (newY < minY) {
newY = minY;
} else if (newY > maxY) {
newY = maxY;
if (Math.abs(event.getY() - startY) > touchSlop) {
isMoving = true;
}
float dy = newY - lastY;
lastY = newY;
progress += dy / (getMeasuredHeight() - AndroidUtilities.dp(24 + 30));
if (progress < 0) {
progress = 0;
} else if (progress > 1) {
progress = 1;
if (isMoving) {
float newY = event.getY();
float minY = AndroidUtilities.dp(12) + startDy;
float maxY = getMeasuredHeight() - AndroidUtilities.dp(12 + 30) + startDy;
if (newY < minY) {
newY = minY;
} else if (newY > maxY) {
newY = maxY;
}
float dy = newY - lastY;
lastY = newY;
progress += dy / (getMeasuredHeight() - AndroidUtilities.dp(24 + 30));
if (progress < 0) {
progress = 0;
} else if (progress > 1) {
progress = 1;
}
getCurrentLetter(true);
invalidate();
}
getCurrentLetter();
invalidate();
return true;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
adapter = getAdapter();
if (pressed && !isMoving && System.currentTimeMillis() - startTime < 150) {
if (adapter instanceof FastScrollAdapter) {
((FastScrollAdapter)adapter).onFastScrollSingleTap();
}
}
isMoving = false;
pressed = false;
lastUpdateTime = System.currentTimeMillis();
invalidate();
if (adapter instanceof FastScrollAdapter) {
((FastScrollAdapter) adapter).onFinishFastScroll(RecyclerListView.this);
}
showFloatingDate();
return true;
}
return super.onTouchEvent(event);
return pressed;
}
private void getCurrentLetter() {
private void getCurrentLetter(boolean updatePosition) {
LayoutManager layoutManager = getLayoutManager();
if (layoutManager instanceof LinearLayoutManager) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
@ -427,16 +520,24 @@ public class RecyclerListView extends RecyclerView {
Adapter adapter = getAdapter();
if (adapter instanceof FastScrollAdapter) {
FastScrollAdapter fastScrollAdapter = (FastScrollAdapter) adapter;
int position = fastScrollAdapter.getPositionForScrollProgress(progress);
linearLayoutManager.scrollToPositionWithOffset(position, sectionOffset);
String newLetter = fastScrollAdapter.getLetter(position);
fastScrollAdapter.getPositionForScrollProgress(RecyclerListView.this, progress, positionWithOffset);
if (updatePosition) {
linearLayoutManager.scrollToPositionWithOffset(positionWithOffset[0], -positionWithOffset[1] + sectionOffset);
}
String newLetter = fastScrollAdapter.getLetter(positionWithOffset[0]);
if (newLetter == null) {
if (letterLayout != null) {
oldLetterLayout = letterLayout;
}
letterLayout = null;
} else if (!newLetter.equals(currentLetter)) {
letterLayout = new StaticLayout(newLetter, letterPaint, 1000, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (type == LETTER_TYPE) {
letterLayout = new StaticLayout(newLetter, letterPaint, 1000, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
} else {
int w = ((int) letterPaint.measureText(newLetter)) + 1;
letterLayout = new StaticLayout(newLetter, letterPaint, w, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
}
oldLetterLayout = null;
if (letterLayout.getLineCount() > 0) {
float lWidth = letterLayout.getLineWidth(0);
@ -456,67 +557,96 @@ public class RecyclerListView extends RecyclerView {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(AndroidUtilities.dp(132), MeasureSpec.getSize(heightMeasureSpec));
setMeasuredDimension(AndroidUtilities.dp(type == LETTER_TYPE ? 132 : 240), MeasureSpec.getSize(heightMeasureSpec));
}
@Override
protected void onDraw(Canvas canvas) {
paint.setColor(Color.argb(255, colors[0] + (int) ((colors[1] - colors[0]) * bubbleProgress), colors[2] + (int) ((colors[3] - colors[2]) * bubbleProgress), colors[4] + (int) ((colors[5] - colors[4]) * bubbleProgress)));
paint.setColor(ColorUtils.blendARGB(inactiveColor, activeColor, bubbleProgress));
int y = (int) Math.ceil((getMeasuredHeight() - AndroidUtilities.dp(24 + 30)) * progress);
rect.set(scrollX, AndroidUtilities.dp(12) + y, scrollX + AndroidUtilities.dp(5), AndroidUtilities.dp(12 + 30) + y);
canvas.drawRoundRect(rect, AndroidUtilities.dp(2), AndroidUtilities.dp(2), paint);
if ((pressed || bubbleProgress != 0)) {
paint.setAlpha((int) (255 * bubbleProgress));
int progressY = y + AndroidUtilities.dp(30);
y -= AndroidUtilities.dp(46);
float diff = 0;
if (y <= AndroidUtilities.dp(12)) {
diff = AndroidUtilities.dp(12) - y;
y = AndroidUtilities.dp(12);
}
float raduisTop;
float raduisBottom;
canvas.translate(AndroidUtilities.dp(10), y);
if (diff <= AndroidUtilities.dp(29)) {
raduisTop = AndroidUtilities.dp(44);
raduisBottom = AndroidUtilities.dp(4) + (diff / AndroidUtilities.dp(29)) * AndroidUtilities.dp(40);
} else {
diff -= AndroidUtilities.dp(29);
raduisBottom = AndroidUtilities.dp(44);
raduisTop = AndroidUtilities.dp(4) + (1.0f - diff / AndroidUtilities.dp(29)) * AndroidUtilities.dp(40);
}
if (LocaleController.isRTL && (radii[0] != raduisTop || radii[6] != raduisBottom) || !LocaleController.isRTL && (radii[2] != raduisTop || radii[4] != raduisBottom)) {
if (LocaleController.isRTL) {
radii[0] = radii[1] = raduisTop;
radii[6] = radii[7] = raduisBottom;
} else {
radii[2] = radii[3] = raduisTop;
radii[4] = radii[5] = raduisBottom;
if (type == LETTER_TYPE) {
if ((isMoving || bubbleProgress != 0)) {
paint.setAlpha((int) (255 * bubbleProgress));
int progressY = y + AndroidUtilities.dp(30);
y -= AndroidUtilities.dp(46);
float diff = 0;
if (y <= AndroidUtilities.dp(12)) {
diff = AndroidUtilities.dp(12) - y;
y = AndroidUtilities.dp(12);
}
float raduisTop;
float raduisBottom;
canvas.translate(AndroidUtilities.dp(10), y);
if (diff <= AndroidUtilities.dp(29)) {
raduisTop = AndroidUtilities.dp(44);
raduisBottom = AndroidUtilities.dp(4) + (diff / AndroidUtilities.dp(29)) * AndroidUtilities.dp(40);
} else {
diff -= AndroidUtilities.dp(29);
raduisBottom = AndroidUtilities.dp(44);
raduisTop = AndroidUtilities.dp(4) + (1.0f - diff / AndroidUtilities.dp(29)) * AndroidUtilities.dp(40);
}
if (LocaleController.isRTL && (radii[0] != raduisTop || radii[6] != raduisBottom) || !LocaleController.isRTL && (radii[2] != raduisTop || radii[4] != raduisBottom)) {
if (LocaleController.isRTL) {
radii[0] = radii[1] = raduisTop;
radii[6] = radii[7] = raduisBottom;
} else {
radii[2] = radii[3] = raduisTop;
radii[4] = radii[5] = raduisBottom;
}
path.reset();
rect.set(LocaleController.isRTL ? AndroidUtilities.dp(10) : 0, 0, AndroidUtilities.dp(LocaleController.isRTL ? 98 : 88), AndroidUtilities.dp(88));
path.addRoundRect(rect, radii, Path.Direction.CW);
path.close();
}
StaticLayout layoutToDraw = letterLayout != null ? letterLayout : oldLetterLayout;
if (layoutToDraw != null) {
canvas.save();
canvas.scale(bubbleProgress, bubbleProgress, scrollX, progressY - y);
canvas.drawPath(path, paint);
canvas.translate(textX, textY);
layoutToDraw.draw(canvas);
canvas.restore();
}
path.reset();
rect.set(LocaleController.isRTL ? AndroidUtilities.dp(10) : 0, 0, AndroidUtilities.dp(LocaleController.isRTL ? 98 : 88), AndroidUtilities.dp(88));
path.addRoundRect(rect, radii, Path.Direction.CW);
path.close();
}
StaticLayout layoutToDraw = letterLayout != null ? letterLayout : oldLetterLayout;
if (layoutToDraw != null) {
} else if (type == DATE_TYPE) {
if (letterLayout != null && floatingDateProgress != 0) {
canvas.save();
canvas.scale(bubbleProgress, bubbleProgress, scrollX, progressY - y);
canvas.drawPath(path, paint);
canvas.translate(textX, textY);
layoutToDraw.draw(canvas);
float s = 0.7f + 0.3f * floatingDateProgress;
canvas.scale(s, s, rect.right - AndroidUtilities.dp(12), rect.centerY());
float cy = rect.centerY();
float x = rect.left - AndroidUtilities.dp(30) * bubbleProgress;
float r = letterLayout.getHeight() / 2f + AndroidUtilities.dp(6);
rect.set(x - letterLayout.getWidth() - AndroidUtilities.dp(36), cy - letterLayout.getHeight() / 2f - AndroidUtilities.dp(8), x - AndroidUtilities.dp(12), cy + letterLayout.getHeight() / 2f + AndroidUtilities.dp(8));
int oldAlpha1 = paint2.getAlpha();
int oldAlpha2 = letterPaint.getAlpha();
paint2.setAlpha((int) (oldAlpha1 * floatingDateProgress));
letterPaint.setAlpha((int) (oldAlpha2 * floatingDateProgress));
fastScrollBackgroundDrawable.setBounds((int) rect.left, (int) rect.top, (int) rect.right, (int) rect.bottom);
fastScrollBackgroundDrawable.draw(canvas);
canvas.save();
canvas.translate(x - letterLayout.getWidth() - AndroidUtilities.dp(24), cy - letterLayout.getHeight() / 2f);
letterLayout.draw(canvas);
canvas.restore();
paint2.setAlpha(oldAlpha1);
letterPaint.setAlpha(oldAlpha2);
canvas.restore();
}
}
if ((pressed && letterLayout != null && bubbleProgress < 1.0f) || (!pressed || letterLayout == null) && bubbleProgress > 0.0f) {
long newTime = System.currentTimeMillis();
long dt = (newTime - lastUpdateTime);
if (dt < 0 || dt > 17) {
dt = 17;
}
long newTime = System.currentTimeMillis();
long dt = (newTime - lastUpdateTime);
if (dt < 0 || dt > 17) {
dt = 17;
}
if ((isMoving && letterLayout != null && bubbleProgress < 1.0f) || (!isMoving || letterLayout == null) && bubbleProgress > 0.0f) {
lastUpdateTime = newTime;
invalidate();
if (pressed && letterLayout != null) {
if (isMoving && letterLayout != null) {
bubbleProgress += dt / 120.0f;
if (bubbleProgress > 1.0f) {
bubbleProgress = 1.0f;
@ -528,6 +658,21 @@ public class RecyclerListView extends RecyclerView {
}
}
}
if (floatingDateVisible && floatingDateProgress != 1f) {
floatingDateProgress += dt / 120.0f;
if (floatingDateProgress > 1.0f) {
floatingDateProgress = 1.0f;
}
invalidate();
} else if (!floatingDateVisible && floatingDateProgress != 0) {
floatingDateProgress -= dt / 120.0f;
if (floatingDateProgress < 0.0f) {
floatingDateProgress = 0.0f;
}
invalidate();
}
}
@Override
@ -538,10 +683,40 @@ public class RecyclerListView extends RecyclerView {
super.layout(l, t, r, b);
}
private void setProgress(float value) {
public void setProgress(float value) {
progress = value;
invalidate();
}
@Override
public boolean isPressed() {
return pressed;
}
public void showFloatingDate() {
if (type != DATE_TYPE) {
return;
}
if (!floatingDateVisible) {
floatingDateVisible = true;
invalidate();
}
AndroidUtilities.cancelRunOnUIThread(hideFloatingDateRunnable);
AndroidUtilities.runOnUIThread(hideFloatingDateRunnable, 4000);
}
public void setIsVisible(boolean visible) {
this.isVisible = visible;
setAlpha(visible ? 1f : 0f);
}
public int getScrollBarY() {
return (int) Math.ceil((getMeasuredHeight() - AndroidUtilities.dp(24 + 30)) * progress) + AndroidUtilities.dp(17);
}
public float getProgress() {
return progress;
}
}
private class RecyclerListViewItemClickListener implements OnItemTouchListener {
@ -900,6 +1075,9 @@ public class RecyclerListView extends RecyclerView {
try {
if (!gotAttributes) {
attributes = getResourceDeclareStyleableIntArray("com.android.internal", "View");
if (attributes == null) {
attributes = new int[0];
}
gotAttributes = true;
}
TypedArray a = context.getTheme().obtainStyledAttributes(attributes);
@ -951,7 +1129,10 @@ public class RecyclerListView extends RecyclerView {
} else {
selectorRect.setEmpty();
}
checkSection();
checkSection(false);
if (dy != 0 && fastScroll != null) {
fastScroll.showFloatingDate();
}
}
});
addOnItemTouchListener(new RecyclerListViewItemClickListener(context));
@ -989,7 +1170,7 @@ public class RecyclerListView extends RecyclerView {
}
selfOnLayout = false;
}
checkSection();
checkSection(false);
if (pendingHighlightPosition != null) {
highlightRowInternal(pendingHighlightPosition, false);
}
@ -1027,8 +1208,8 @@ public class RecyclerListView extends RecyclerView {
selectorDrawable.setCallback(this);
}
public void checkSection() {
if (scrollingByUser && fastScroll != null || sectionsType != 0 && sectionsAdapter != null) {
public void checkSection(boolean force) {
if ((scrollingByUser || force) && fastScroll != null || sectionsType != 0 && sectionsAdapter != null) {
LayoutManager layoutManager = getLayoutManager();
if (layoutManager instanceof LinearLayoutManager) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
@ -1072,10 +1253,10 @@ public class RecyclerListView extends RecyclerView {
int lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
int visibleItemCount = Math.abs(lastVisibleItem - firstVisibleItem) + 1;
if (scrollingByUser && fastScroll != null) {
if ((scrollingByUser || force) && fastScroll != null && !fastScroll.isPressed()) {
Adapter adapter = getAdapter();
if (adapter instanceof FastScrollAdapter) {
fastScroll.setProgress(Math.min(1.0f, firstVisibleItem / (float) (adapter.getItemCount() - visibleItemCount + 1)));
fastScroll.setProgress(Math.min(1.0f, firstVisibleItem / (float) (sectionsAdapter.getTotalItemsCount() - visibleItemCount + 1)));
}
}
@ -1217,13 +1398,20 @@ public class RecyclerListView extends RecyclerView {
int firstVisibleItem = linearLayoutManager.findFirstVisibleItemPosition();
int lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
int visibleItemCount = Math.abs(lastVisibleItem - firstVisibleItem) + 1;
if (firstVisibleItem == NO_POSITION) {
return;
}
if (scrollingByUser && fastScroll != null) {
if ((scrollingByUser || force) && fastScroll != null && !fastScroll.isPressed()) {
Adapter adapter = getAdapter();
if (adapter instanceof FastScrollAdapter) {
fastScroll.setProgress(Math.min(1.0f, firstVisibleItem / (float) (adapter.getItemCount() - visibleItemCount + 1)));
float p = ((FastScrollAdapter) adapter).getScrollProgress(RecyclerListView.this);
boolean visible = ((FastScrollAdapter) adapter).fastScrollIsVisible(RecyclerListView.this);
fastScroll.setIsVisible(visible);
fastScroll.setProgress(Math.min(1.0f, p));
fastScroll.getCurrentLetter(false);
}
}
}
@ -1505,8 +1693,8 @@ public class RecyclerListView extends RecyclerView {
disallowInterceptTouchEvents = value;
}
public void setFastScrollEnabled() {
fastScroll = new FastScroll(getContext());
public void setFastScrollEnabled(int type) {
fastScroll = new FastScroll(getContext(), type);
if (getParent() != null) {
((ViewGroup) getParent()).addView(fastScroll);
}
@ -1951,6 +2139,9 @@ public class RecyclerListView extends RecyclerView {
@Override
public boolean onTouchEvent(MotionEvent e) {
if (fastScroll != null && fastScroll.pressed) {
return false;
}
if (multiSelectionGesture && e.getAction() != MotionEvent.ACTION_DOWN &&e.getAction() != MotionEvent.ACTION_UP && e.getAction() != MotionEvent.ACTION_CANCEL) {
if (lastX == Float.MAX_VALUE && lastY == Float.MAX_VALUE) {
lastX = e.getX();

View File

@ -29,7 +29,6 @@ public class SearchField extends FrameLayout {
private ImageView clearSearchImageView;
private CloseProgressDrawable2 progressDrawable;
private EditTextBoldCursor searchEditText;
private View backgroundView;
private final Theme.ResourcesProvider resourcesProvider;
public SearchField(Context context, boolean supportRtl, Theme.ResourcesProvider resourcesProvider) {

View File

@ -0,0 +1,126 @@
package org.telegram.ui.Components;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.TextView;
import androidx.core.graphics.ColorUtils;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import java.util.Random;
public class SharedMediaFastScrollTooltip extends FrameLayout {
public SharedMediaFastScrollTooltip(Context context) {
super(context);
TextView textView = new TextView(context);
textView.setText(LocaleController.getString("SharedMediaFastScrollHint", R.string.SharedMediaFastScrollHint));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
textView.setMaxLines(3);
textView.setTextColor(Theme.getColor(Theme.key_chat_gifSaveHintText));
setBackground(Theme.createRoundRectDrawable(AndroidUtilities.dp(6), Theme.getColor(Theme.key_chat_gifSaveHintBackground)));
addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL, 46, 8, 8, 8));
TooltipDrawableView hintView = new TooltipDrawableView(context);
addView(hintView, LayoutHelper.createFrame(29, 32, 0, 8, 8, 8, 8));
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(MeasureSpec.makeMeasureSpec(Math.min(AndroidUtilities.dp(300), MeasureSpec.getSize(widthMeasureSpec) - AndroidUtilities.dp(32)), MeasureSpec.AT_MOST), heightMeasureSpec);
}
private class TooltipDrawableView extends View {
Random random = new Random();
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Paint paint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
Paint fadePaint;
Paint fadePaintBack;
public TooltipDrawableView(Context context) {
super(context);
paint.setColor(ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_chat_gifSaveHintText), (int) (255 * 0.3f)));
paint2.setColor(Theme.getColor(Theme.key_chat_gifSaveHintText));
fadePaint = new Paint();
LinearGradient gradient = new LinearGradient(0, AndroidUtilities.dp(4), 0, 0, new int[]{0, 0xffffffff}, new float[]{0f, 1f}, Shader.TileMode.CLAMP);
fadePaint.setShader(gradient);
fadePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
fadePaintBack = new Paint();
gradient = new LinearGradient(0, 0, 0, AndroidUtilities.dp(4), new int[]{0, 0xffffffff}, new float[]{0f, 1f}, Shader.TileMode.CLAMP);
fadePaintBack.setShader(gradient);
fadePaintBack.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
}
float progress = 1f;
float fromProgress = 0;
float toProgress;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.saveLayerAlpha(0, 0, getMeasuredWidth(), getMeasuredHeight(), 255, Canvas.ALL_SAVE_FLAG);
int rectSize = getMeasuredWidth() / 2 - AndroidUtilities.dp(3);
int totalHeight = (rectSize + AndroidUtilities.dp(1)) * 7 + AndroidUtilities.dp(1);
float progress = CubicBezierInterpolator.EASE_OUT.getInterpolation(this.progress > 0.4f ? (this.progress - 0.4f) / 0.6f : 0);
float p = fromProgress * (1f - progress) + toProgress * progress;
canvas.save();
canvas.translate(0, -(totalHeight - (getMeasuredHeight() - AndroidUtilities.dp(4))) * p);
for (int i = 0; i < 7; i++) {
int y = AndroidUtilities.dp(3) + i * (rectSize + AndroidUtilities.dp(1));
AndroidUtilities.rectTmp.set(0, y, rectSize, y + rectSize);
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(2), AndroidUtilities.dp(2), paint);
AndroidUtilities.rectTmp.set(rectSize + AndroidUtilities.dp(1), y, rectSize + AndroidUtilities.dp(1) + rectSize, y + rectSize);
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(2), AndroidUtilities.dp(2), paint);
}
canvas.restore();
canvas.drawRect(0, 0, getMeasuredWidth(), AndroidUtilities.dp(4), fadePaint);
canvas.translate(0, getMeasuredHeight() - AndroidUtilities.dp(4));
canvas.drawRect(0, 0, getMeasuredWidth(), AndroidUtilities.dp(4), fadePaintBack);
canvas.restore();
float y = AndroidUtilities.dp(3) + (getMeasuredHeight() - AndroidUtilities.dp(15 + 6)) * p;
AndroidUtilities.rectTmp.set(getMeasuredWidth() - AndroidUtilities.dp(3), y, getMeasuredWidth(), y + AndroidUtilities.dp(15));
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(1.5f), AndroidUtilities.dp(1.5f), paint2);
float cy = AndroidUtilities.rectTmp.centerY();
float cx = rectSize + AndroidUtilities.dp(0.5f);
AndroidUtilities.rectTmp.set(cx - AndroidUtilities.dp(8), cy - AndroidUtilities.dp(3), cx + AndroidUtilities.dp(8), cy + AndroidUtilities.dp(3));
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(3), AndroidUtilities.dp(3), paint2);
this.progress += 16 / 1000f;
if (this.progress > 1f) {
fromProgress = toProgress;
toProgress = Math.abs(random.nextInt() % 1001) / 1000f;
if (toProgress > fromProgress) {
toProgress += 0.3f;
} else {
toProgress -= 0.3f;
}
toProgress = Math.max(0, Math.min(1 ,toProgress));
this.progress = 0;
}
invalidate();
}
}
}

View File

@ -18,8 +18,14 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Build;
import android.view.View;
import android.view.WindowInsets;
import android.widget.FrameLayout;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.ActionBar.ActionBarLayout;

View File

@ -32,6 +32,8 @@ public class SlideChooseView extends View {
private boolean moving;
private boolean startMoving;
private float startX;
private float xTouchDown;
private float yTouchDown;
private int startMovingPreset;
@ -102,8 +104,10 @@ public class SlideChooseView extends View {
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
if (event.getAction() == MotionEvent.ACTION_DOWN) {
getParent().requestDisallowInterceptTouchEvent(true);
xTouchDown = x;
yTouchDown = y;
for (int a = 0; a < optionsStr.length; a++) {
int cx = sideSide + (lineSize + gapSize * 2 + circleSize) * a + circleSize / 2;
if (x > cx - AndroidUtilities.dp(15) && x < cx + AndroidUtilities.dp(15)) {
@ -114,6 +118,11 @@ public class SlideChooseView extends View {
}
}
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!moving) {
if (Math.abs(xTouchDown - x) > Math.abs(yTouchDown - y)) {
getParent().requestDisallowInterceptTouchEvent(true);
}
}
if (startMoving) {
if (Math.abs(startX - x) >= AndroidUtilities.getPixelsInCM(0.5f, true)) {
moving = true;
@ -152,6 +161,7 @@ public class SlideChooseView extends View {
}
startMoving = false;
moving = false;
getParent().requestDisallowInterceptTouchEvent(false);
}
return true;
}
@ -167,7 +177,6 @@ public class SlideChooseView extends View {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(74), MeasureSpec.EXACTLY));
int width = MeasureSpec.getSize(widthMeasureSpec);
circleSize = AndroidUtilities.dp(6);
gapSize = AndroidUtilities.dp(2);
sideSide = AndroidUtilities.dp(22);
@ -181,15 +190,9 @@ public class SlideChooseView extends View {
for (int a = 0; a < optionsStr.length; a++) {
int cx = sideSide + (lineSize + gapSize * 2 + circleSize) * a + circleSize / 2;
if (a <= selectedIndex) {
int color = getThemedColor(Theme.key_switchTrackChecked);
paint.setColor(color);
linePaint.setColor(color);
} else {
int color = getThemedColor(Theme.key_switchTrack);
paint.setColor(color);
linePaint.setColor(color);
}
int color = a <= selectedIndex ? getThemedColor(Theme.key_switchTrackChecked) : getThemedColor(Theme.key_switchTrack);
paint.setColor(color);
linePaint.setColor(color);
canvas.drawCircle(cx, cy, a == selectedIndex ? AndroidUtilities.dp(6) : circleSize / 2, paint);
if (a != 0) {
int x = cx - circleSize / 2 - gapSize - lineSize;

View File

@ -22,8 +22,9 @@ import org.telegram.ui.ActionBar.Theme;
public class StickerEmptyView extends FrameLayout implements NotificationCenter.NotificationCenterDelegate {
public final static int STICKER_TYPE_SEARCH = 1;
public final static int STICKER_TYPE_NO_CONTACTS = 0;
public final static int STICKER_TYPE_SEARCH = 1;
public final static int STICKER_TYPE_DONE = 2;
private LinearLayout linearLayout;
public BackupImageView stickerView;
@ -227,14 +228,24 @@ public class StickerEmptyView extends FrameLayout implements NotificationCenter.
}
private void setSticker() {
TLRPC.TL_messages_stickerSet set = MediaDataController.getInstance(currentAccount).getStickerSetByName(AndroidUtilities.STICKERS_PLACEHOLDER_PACK_NAME);
if (set == null) {
set = MediaDataController.getInstance(currentAccount).getStickerSetByEmojiOrName(AndroidUtilities.STICKERS_PLACEHOLDER_PACK_NAME);
String imageFilter = null;
TLRPC.Document document = null;
TLRPC.TL_messages_stickerSet set = null;
if (stickerType == STICKER_TYPE_DONE) {
document = MediaDataController.getInstance(currentAccount).getEmojiAnimatedSticker("\uD83D\uDC4D");
} else {
set = MediaDataController.getInstance(currentAccount).getStickerSetByName(AndroidUtilities.STICKERS_PLACEHOLDER_PACK_NAME);
if (set == null) {
set = MediaDataController.getInstance(currentAccount).getStickerSetByEmojiOrName(AndroidUtilities.STICKERS_PLACEHOLDER_PACK_NAME);
}
if (set != null && set.documents.size() >= 2) {
document = set.documents.get(stickerType);
}
imageFilter = "130_130";
}
if (set != null && set.documents.size() >= 2) {
TLRPC.Document document = set.documents.get(stickerType);
if (document != null) {
ImageLocation imageLocation = ImageLocation.getForDocument(document);
stickerView.setImage(imageLocation, "130_130", "tgs", stubDrawable, set);
stickerView.setImage(imageLocation, imageFilter, "tgs", stubDrawable, set);
stickerView.getImageReceiver().setAutoRepeat(2);
} else {
MediaDataController.getInstance(currentAccount).loadStickersByEmojiOrName(AndroidUtilities.STICKERS_PLACEHOLDER_PACK_NAME, false, set == null);

View File

@ -1252,6 +1252,8 @@ public class UndoView extends FrameLayout {
leftImageView.setAnimation(R.raw.chats_infotip, 36, 36);
leftImageView.setProgress(0);
leftImageView.playAnimation();
infoTextView.setMovementMethod(new AndroidUtilities.LinkMovementMethodMy());
} else if (currentAction == ACTION_THEME_CHANGED) {
infoTextView.setText(LocaleController.getString("ColorThemeChanged", R.string.ColorThemeChanged));
leftImageView.setImageResource(R.drawable.toast_pallete);

View File

@ -7,6 +7,7 @@ import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
@ -46,8 +47,8 @@ public class UsersAlertBase extends BottomSheet {
protected FrameLayout frameLayout;
protected RecyclerListView listView;
protected RecyclerListView.SelectionAdapter searchListViewAdapter;
protected RecyclerListView.SelectionAdapter listViewAdapter;
protected RecyclerView.Adapter searchListViewAdapter;
protected RecyclerView.Adapter listViewAdapter;
protected Drawable shadowDrawable;
protected View shadow;
protected AnimatorSet shadowAnimation;
@ -63,6 +64,7 @@ public class UsersAlertBase extends BottomSheet {
private int backgroundColor;
protected boolean needSnapToTop = true;
protected boolean isEmptyViewVisible = true;
protected String keyScrollUp = Theme.key_sheet_scrollUp;
protected String keyListSelector = Theme.key_listSelector;
@ -118,7 +120,7 @@ public class UsersAlertBase extends BottomSheet {
listView = new RecyclerListView(context) {
@Override
protected boolean allowSelectChildAtPosition(float x, float y) {
return y >= AndroidUtilities.dp(58) + (Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0);
return isAllowSelectChildAtPosition(x, y);
}
@Override
@ -133,7 +135,7 @@ public class UsersAlertBase extends BottomSheet {
if (getAdapter() == null) {
return false;
}
return getAdapter().getItemCount() <= 2;
return isEmptyViewVisible && getAdapter().getItemCount() <= 2;
}
};
listView.setTag(13);
@ -183,10 +185,20 @@ public class UsersAlertBase extends BottomSheet {
listView.setAnimateEmptyView(true, 0);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
AndroidUtilities.statusBarHeight = AndroidUtilities.getStatusBarHeight(getContext());
}
protected ContainerView createContainerView(Context context) {
return new ContainerView(context);
}
protected boolean isAllowSelectChildAtPosition(float x, float y) {
return y >= AndroidUtilities.dp(58) + (Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0);
}
protected void updateColorKeys() {
}
@ -376,7 +388,7 @@ public class UsersAlertBase extends BottomSheet {
}
@SuppressLint("NewApi")
private void updateLayout() {
protected void updateLayout() {
if (listView.getChildCount() <= 0) {
return;
}
@ -396,13 +408,18 @@ public class UsersAlertBase extends BottomSheet {
runShadowAnimation(true);
}
if (scrollOffsetY != newOffset) {
listView.setTopGlowOffset(scrollOffsetY = (int) (newOffset));
frameLayout.setTranslationY(scrollOffsetY);
emptyView.setTranslationY(scrollOffsetY);
containerView.invalidate();
scrollOffsetY = newOffset;
setTranslationY(newOffset);
}
}
protected void setTranslationY(int newOffset) {
listView.setTopGlowOffset(newOffset);
frameLayout.setTranslationY(newOffset);
emptyView.setTranslationY(newOffset);
containerView.invalidate();
}
private void runShadowAnimation(final boolean show) {
if (show && shadow.getTag() != null || !show && shadow.getTag() == null) {
shadow.setTag(show ? null : 1);

View File

@ -216,7 +216,9 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
@Override
protected void onTransitionAnimationProgress(boolean isOpen, float progress) {
super.onTransitionAnimationProgress(isOpen, progress);
fragmentView.invalidate();
if (fragmentView != null) {
fragmentView.invalidate();
}
}
@Override
@ -402,7 +404,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
};
listView.setSectionsType(1);
listView.setVerticalScrollBarEnabled(false);
listView.setFastScrollEnabled();
listView.setFastScrollEnabled(RecyclerListView.FastScroll.LETTER_TYPE);
listView.setLayoutManager(layoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
listView.setAdapter(listViewAdapter);
frameLayout.addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));

View File

@ -146,7 +146,7 @@ public class CountrySelectActivity extends BaseFragment {
listView.setSectionsType(1);
listView.setEmptyView(emptyView);
listView.setVerticalScrollBarEnabled(false);
listView.setFastScrollEnabled();
listView.setFastScrollEnabled(RecyclerListView.FastScroll.LETTER_TYPE);
listView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
listView.setAdapter(listViewAdapter);
listView.setVerticalScrollbarPosition(LocaleController.isRTL ? RecyclerListView.SCROLLBAR_POSITION_LEFT : RecyclerListView.SCROLLBAR_POSITION_RIGHT);
@ -358,8 +358,9 @@ public class CountrySelectActivity extends BaseFragment {
}
@Override
public int getPositionForScrollProgress(float progress) {
return (int) (getItemCount() * progress);
public void getPositionForScrollProgress(RecyclerListView listView, float progress, int[] position) {
position[0] = (int) (getItemCount() * progress);
position[1] = 0;
}
}

View File

@ -0,0 +1,338 @@
package org.telegram.ui;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Paint;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.EmojiThemes;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.TextCell;
import org.telegram.ui.Components.ChatThemeBottomSheet;
import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.RecyclerListView;
import java.util.ArrayList;
@SuppressLint("ViewConstructor")
public class DefaultThemesPreviewCell extends LinearLayout {
private final RecyclerListView recyclerView;
private final LinearLayoutManager layoutManager;
private final FlickerLoadingView progressView;
private final ChatThemeBottomSheet.Adapter adapter;
RLottieDrawable darkThemeDrawable;
TextCell dayNightCell;
TextCell browseThemesCell;
private int selectedPosition = -1;
BaseFragment parentFragment;
int currentType;
int themeIndex;
public DefaultThemesPreviewCell(Context context, BaseFragment parentFragment, int type) {
super(context);
this.currentType = type;
this.parentFragment = parentFragment;
setOrientation(LinearLayout.VERTICAL);
FrameLayout frameLayout = new FrameLayout(context);
addView(frameLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
adapter = new ChatThemeBottomSheet.Adapter(parentFragment.getCurrentAccount(), null, currentType == ThemeActivity.THEME_TYPE_BASIC ? ChatThemeBottomSheet.Adapter.TYPE_DEFAULT : ChatThemeBottomSheet.Adapter.TYPE_GRID);
recyclerView = new RecyclerListView(getContext());
recyclerView.setAdapter(adapter);
recyclerView.setClipChildren(false);
recyclerView.setClipToPadding(false);
recyclerView.setHasFixedSize(true);
recyclerView.setItemAnimator(null);
recyclerView.setNestedScrollingEnabled(false);
if (currentType == ThemeActivity.THEME_TYPE_BASIC) {
recyclerView.setLayoutManager(layoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
} else {
recyclerView.setHasFixedSize(false);
GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), 3);
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return 1;
}
});
recyclerView.setLayoutManager(layoutManager = gridLayoutManager);
}
recyclerView.setPadding(AndroidUtilities.dp(12), 0, AndroidUtilities.dp(12), 0);
recyclerView.setOnItemClickListener((view, position) -> {
ChatThemeBottomSheet.ChatThemeItem chatTheme = adapter.items.get(position);
Theme.ThemeInfo info = chatTheme.chatTheme.getThemeInfo(themeIndex);
int accentId = -1;
if (chatTheme.chatTheme.getEmoticon().equals("\uD83C\uDFE0")) {
accentId = chatTheme.chatTheme.getAccentId(themeIndex);
}
if (info == null) {
TLRPC.TL_theme theme = chatTheme.chatTheme.getTlTheme(themeIndex);
int settingsIndex = chatTheme.chatTheme.getSettingsIndex(themeIndex);
TLRPC.ThemeSettings settings = theme.settings.get(settingsIndex);
String key = Theme.getBaseThemeKey(settings);
info = Theme.getTheme(key);
if (info != null) {
Theme.ThemeAccent accent = info.accentsByThemeId.get(theme.id);
if (accent == null) {
accent = info.createNewAccent(theme, parentFragment.getCurrentAccount());
}
accentId = accent.id;
info.setCurrentAccentId(accentId);
}
}
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.needSetDayNightTheme, info, false, null, accentId);
selectedPosition = position;
adapter.setSelectedItem(selectedPosition);
for (int i = 0; i < recyclerView.getChildCount(); i++) {
ChatThemeBottomSheet.Adapter.ChatThemeView child = (ChatThemeBottomSheet.Adapter.ChatThemeView) recyclerView.getChildAt(i);
if (child != view) {
child.cancelAnimation();
}
}
((ChatThemeBottomSheet.Adapter.ChatThemeView) view).playEmojiAnimation();
});
progressView = new FlickerLoadingView(getContext(), null);
progressView.setViewType(FlickerLoadingView.CHAT_THEMES_TYPE);
progressView.setVisibility(View.VISIBLE);
if (currentType == ThemeActivity.THEME_TYPE_BASIC) {
frameLayout.addView(progressView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 104, Gravity.START, 0, 8, 0, 8));
frameLayout.addView(recyclerView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 104, Gravity.START, 0, 8, 0, 8));
} else {
frameLayout.addView(progressView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 104, Gravity.START, 0, 8, 0, 8));
frameLayout.addView(recyclerView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.START, 0, 8, 0, 8));
}
recyclerView.setEmptyView(progressView);
recyclerView.setAnimateEmptyView(true, 0);
if (currentType == ThemeActivity.THEME_TYPE_BASIC) {
darkThemeDrawable = new RLottieDrawable(R.raw.sun_outline, "" + R.raw.sun_outline, AndroidUtilities.dp(28), AndroidUtilities.dp(28), true, null);
darkThemeDrawable.setPlayInDirectionOfCustomEndFrame(true);
darkThemeDrawable.beginApplyLayerColors();
darkThemeDrawable.commitApplyLayerColors();
dayNightCell = new TextCell(context);
dayNightCell.setTextAndIcon(LocaleController.getString("SettingsSwitchToNightMode", R.string.SettingsSwitchToNightMode), darkThemeDrawable, true);
dayNightCell.imageLeft = 21;
addView(dayNightCell, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
browseThemesCell = new TextCell(context);
browseThemesCell.setTextAndIcon(LocaleController.getString("SettingsBrowseThemes", R.string.SettingsBrowseThemes), R.drawable.msg_colors, false);
addView(browseThemesCell, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
dayNightCell.setOnClickListener(new OnClickListener() {
@SuppressLint("NotifyDataSetChanged")
@Override
public void onClick(View view) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("themeconfig", Activity.MODE_PRIVATE);
String dayThemeName = preferences.getString("lastDayTheme", "Blue");
if (Theme.getTheme(dayThemeName) == null || Theme.getTheme(dayThemeName).isDark()) {
dayThemeName = "Blue";
}
String nightThemeName = preferences.getString("lastDarkTheme", "Dark Blue");
if (Theme.getTheme(nightThemeName) == null || !Theme.getTheme(nightThemeName).isDark()) {
nightThemeName = "Dark Blue";
}
Theme.ThemeInfo themeInfo = Theme.getActiveTheme();
if (dayThemeName.equals(nightThemeName)) {
if (themeInfo.isDark() || dayThemeName.equals("Dark Blue") || dayThemeName.equals("Night")) {
dayThemeName = "Blue";
} else {
nightThemeName = "Dark Blue";
}
}
boolean toDark;
if (toDark = !Theme.isCurrentThemeDark()) {
themeInfo = Theme.getTheme(nightThemeName);
} else {
themeInfo = Theme.getTheme(dayThemeName);
}
darkThemeDrawable.setCustomEndFrame(toDark ? darkThemeDrawable.getFramesCount() - 1 : 0);
dayNightCell.getImageView().playAnimation();
int[] pos = new int[2];
dayNightCell.getImageView().getLocationInWindow(pos);
pos[0] += dayNightCell.getImageView().getMeasuredWidth() / 2;
pos[1] += dayNightCell.getImageView().getMeasuredHeight() / 2 + AndroidUtilities.dp(3);
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.needSetDayNightTheme, themeInfo, false, pos, -1, toDark, dayNightCell.getImageView());
updateDayNightMode();
updateSelectedPosition();
}
});
darkThemeDrawable.setPlayInDirectionOfCustomEndFrame(true);
browseThemesCell.setOnClickListener(view -> {
parentFragment.presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_THEMES_BROWSER));
});
if (!Theme.isCurrentThemeDay()) {
darkThemeDrawable.setCurrentFrame(darkThemeDrawable.getFramesCount() - 1);
}
}
if (!Theme.defaultEmojiThemes.isEmpty()) {
ArrayList<ChatThemeBottomSheet.ChatThemeItem> themes = new ArrayList<>();
themes.addAll(Theme.defaultEmojiThemes);
if (currentType == ThemeActivity.THEME_TYPE_BASIC) {
EmojiThemes chatTheme = EmojiThemes.createPreviewCustom();
chatTheme.loadPreviewColors(parentFragment.getCurrentAccount());
ChatThemeBottomSheet.ChatThemeItem item = new ChatThemeBottomSheet.ChatThemeItem(chatTheme);
item.themeIndex = !Theme.isCurrentThemeDay() ? 2 : 0;
themes.add(item);
}
adapter.setItems(themes);
}
updateDayNightMode();
updateSelectedPosition();
updateColors();
if (selectedPosition >= 0) {
layoutManager.scrollToPositionWithOffset(selectedPosition, AndroidUtilities.dp(16));
}
}
public void updateDayNightMode() {
if (currentType == ThemeActivity.THEME_TYPE_BASIC) {
themeIndex = !Theme.isCurrentThemeDay() ? 2 : 0;
} else {
if (Theme.getActiveTheme().getKey().equals("Blue")) {
themeIndex = 0;
} else if (Theme.getActiveTheme().getKey().equals("Day")) {
themeIndex = 1;
} else if (Theme.getActiveTheme().getKey().equals("Night")) {
themeIndex = 2;
} else if (Theme.getActiveTheme().getKey().equals("Dark Blue")) {
themeIndex = 3;
} else {
if (Theme.isCurrentThemeDay() && (themeIndex == 2 || themeIndex == 3)) {
themeIndex = 0;
}
if (!Theme.isCurrentThemeDay() && (themeIndex == 0 || themeIndex == 1)) {
themeIndex = 2;
}
}
}
if (adapter.items != null) {
for (int i = 0; i < adapter.items.size(); i++) {
adapter.items.get(i).themeIndex = themeIndex;
}
adapter.notifyItemRangeChanged(0, adapter.items.size());
}
updateSelectedPosition();
}
private void updateSelectedPosition() {
if (adapter.items == null) {
return;
}
selectedPosition = -1;
for (int i = 0; i < adapter.items.size(); i++) {
TLRPC.TL_theme theme = adapter.items.get(i).chatTheme.getTlTheme(themeIndex);
if (theme != null) {
int settingsIndex = adapter.items.get(i).chatTheme.getSettingsIndex(themeIndex);
String key = Theme.getBaseThemeKey(theme.settings.get(settingsIndex));
if (Theme.getCurrentTheme().name.equals(key)) {
Theme.ThemeAccent accent = Theme.getCurrentTheme().accentsByThemeId.get(theme.id);
if (accent != null && accent.id == Theme.getCurrentTheme().currentAccentId) {
selectedPosition = i;
}
}
}
}
if (selectedPosition == -1) {
selectedPosition = adapter.items.size() - 1;
}
adapter.setSelectedItem(selectedPosition);
}
public void selectTheme(Theme.ThemeInfo themeInfo) {
if (themeInfo.info != null) {
if (!themeInfo.themeLoaded) {
return;
}
}
if (!TextUtils.isEmpty(themeInfo.assetName)) {
Theme.PatternsLoader.createLoader(false);
}
if (currentType != ThemeActivity.THEME_TYPE_OTHER) {
SharedPreferences.Editor editor = ApplicationLoader.applicationContext.getSharedPreferences("themeconfig", Activity.MODE_PRIVATE).edit();
editor.putString(currentType == ThemeActivity.THEME_TYPE_NIGHT || themeInfo.isDark() ? "lastDarkTheme" : "lastDayTheme", themeInfo.getKey());
editor.commit();
}
if (currentType == ThemeActivity.THEME_TYPE_NIGHT) {
if (themeInfo == Theme.getCurrentNightTheme()) {
return;
}
Theme.setCurrentNightTheme(themeInfo);
} else {
if (themeInfo == Theme.getCurrentTheme()) {
return;
}
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.needSetDayNightTheme, themeInfo, false, null, -1);
}
//updateRows();
int count = getChildCount();
// for (int a = 0; a < count; a++) {
// View child = getChildAt(a);
// if (child instanceof ThemesHorizontalListCell.InnerThemeView) {
// ((ThemesHorizontalListCell.InnerThemeView) child).updateCurrentThemeCheck();
// }
// }
}
public void updateColors() {
if (currentType == ThemeActivity.THEME_TYPE_BASIC) {
darkThemeDrawable.setLayerColor("Sunny.**", Theme.getColor(Theme.key_windowBackgroundWhiteBlueText4));
darkThemeDrawable.setLayerColor("Path.**", Theme.getColor(Theme.key_windowBackgroundWhiteBlueText4));
darkThemeDrawable.setLayerColor("Path 10.**", Theme.getColor(Theme.key_windowBackgroundWhiteBlueText4));
darkThemeDrawable.setLayerColor("Path 11.**", Theme.getColor(Theme.key_windowBackgroundWhiteBlueText4));
dayNightCell.setBackground(Theme.createSelectorWithBackgroundDrawable(Theme.getColor(Theme.key_windowBackgroundWhite), Theme.getColor(Theme.key_listSelector)));
browseThemesCell.setBackground(Theme.createSelectorWithBackgroundDrawable(Theme.getColor(Theme.key_windowBackgroundWhite), Theme.getColor(Theme.key_listSelector)));
dayNightCell.setColors(null, Theme.key_windowBackgroundWhiteBlueText4);
browseThemesCell.setColors(Theme.key_windowBackgroundWhiteBlueText4, Theme.key_windowBackgroundWhiteBlueText4);
}
}
@Override
public void setBackgroundColor(int color) {
super.setBackgroundColor(color);
updateColors();
}
}

View File

@ -0,0 +1,249 @@
package org.telegram.ui.Delegates;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.os.Build;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ActionBar.ThemeDescription;
import org.telegram.ui.Components.AvatarsImageView;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.MemberRequestsBottomSheet;
import java.util.List;
public class ChatActivityMemberRequestsDelegate {
private final BaseFragment fragment;
private final Callback callback;
private final TLRPC.Chat currentChat;
private final int currentAccount;
private FrameLayout root;
private AvatarsImageView avatarsView;
private TextView requestsCountTextView;
private ImageView closeView;
@Nullable
private MemberRequestsBottomSheet bottomSheet;
@Nullable
private TLRPC.ChatFull chatInfo;
@Nullable
private ValueAnimator pendingRequestsAnimator;
private float pendingRequestsEnterOffset;
private int pendingRequestsCount;
private int closePendingRequestsCount = -1;
public ChatActivityMemberRequestsDelegate(BaseFragment fragment, TLRPC.Chat currentChat, Callback callback) {
this.fragment = fragment;
this.currentChat = currentChat;
this.currentAccount = fragment.getCurrentAccount();
this.callback = callback;
}
public View getView() {
if (root == null) {
root = new FrameLayout(fragment.getParentActivity());
root.setBackgroundResource(R.drawable.blockpanel);
root.getBackground().mutate().setColorFilter(new PorterDuffColorFilter(fragment.getThemedColor(Theme.key_chat_topPanelBackground), PorterDuff.Mode.MULTIPLY));
root.setVisibility(View.GONE);
pendingRequestsEnterOffset = -getViewHeight();
View pendingRequestsSelector = new View(fragment.getParentActivity());
pendingRequestsSelector.setBackground(Theme.getSelectorDrawable(false));
pendingRequestsSelector.setOnClickListener((v) -> showBottomSheet());
root.addView(pendingRequestsSelector, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 2));
LinearLayout requestsDataLayout = new LinearLayout(fragment.getParentActivity());
requestsDataLayout.setOrientation(LinearLayout.HORIZONTAL);
root.addView(requestsDataLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP, 0, 0, 36, 0));
avatarsView = new AvatarsImageView(fragment.getParentActivity(), false) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = count == 0 ? 0 : (20 * (count - 1) + 24);
super.onMeasure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(width), MeasureSpec.EXACTLY), heightMeasureSpec);
}
};
avatarsView.reset();
requestsDataLayout.addView(avatarsView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP, 8, 0, 10, 0));
requestsCountTextView = new TextView(fragment.getParentActivity());
requestsCountTextView.setEllipsize(TextUtils.TruncateAt.END);
requestsCountTextView.setGravity(Gravity.CENTER_VERTICAL);
requestsCountTextView.setSingleLine();
requestsCountTextView.setText(null);
requestsCountTextView.setTextColor(fragment.getThemedColor(Theme.key_chat_topPanelTitle));
requestsCountTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
requestsDataLayout.addView(requestsCountTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP, 0, 0, 0, 0));
closeView = new ImageView(fragment.getParentActivity());
if (Build.VERSION.SDK_INT >= 21) {
closeView.setBackground(Theme.createSelectorDrawable(fragment.getThemedColor(Theme.key_inappPlayerClose) & 0x19ffffff, 1, AndroidUtilities.dp(14)));
}
closeView.setColorFilter(new PorterDuffColorFilter(fragment.getThemedColor(Theme.key_chat_topPanelClose), PorterDuff.Mode.MULTIPLY));
closeView.setContentDescription(LocaleController.getString("Close", R.string.Close));
closeView.setImageResource(R.drawable.miniplayer_close);
closeView.setScaleType(ImageView.ScaleType.CENTER);
closeView.setOnClickListener((v) -> {
fragment.getMessagesController().setChatPendingRequestsOnClose(currentChat.id, pendingRequestsCount);
closePendingRequestsCount = pendingRequestsCount;
animatePendingRequests(false, true);
});
root.addView(closeView, LayoutHelper.createFrame(36, LayoutHelper.MATCH_PARENT, Gravity.RIGHT | Gravity.TOP, 0, 0, 2, 0));
if (chatInfo != null) {
setPendingRequests(chatInfo.requests_pending, chatInfo.recent_requesters, false);
}
}
return root;
}
public void setChatInfo(@Nullable TLRPC.ChatFull chatInfo, boolean animated) {
this.chatInfo = chatInfo;
if (chatInfo != null) {
setPendingRequests(chatInfo.requests_pending, chatInfo.recent_requesters, animated);
}
}
public int getViewHeight() {
return AndroidUtilities.dp(40);
}
public float getViewEnterOffset() {
return pendingRequestsEnterOffset;
}
public void onBackToScreen() {
if (bottomSheet != null && bottomSheet.isNeedRestoreDialog()) {
showBottomSheet();
}
}
private void showBottomSheet() {
if (bottomSheet == null) {
bottomSheet = new MemberRequestsBottomSheet(fragment, currentChat.id) {
@Override
public void dismiss() {
if (bottomSheet != null && !bottomSheet.isNeedRestoreDialog()) {
bottomSheet = null;
}
super.dismiss();
}
};
}
fragment.showDialog(bottomSheet);
}
private void setPendingRequests(int count, List<Long> recentRequestersIdList, boolean animated) {
if (root == null) {
return;
}
if (count <= 0) {
if (currentChat != null) {
fragment.getMessagesController().setChatPendingRequestsOnClose(currentChat.id, 0);
closePendingRequestsCount = 0;
}
animatePendingRequests(false, animated);
pendingRequestsCount = 0;
return;
}
if (pendingRequestsCount != count) {
pendingRequestsCount = count;
requestsCountTextView.setText(LocaleController.formatPluralString("JoinUsersRequests", count));
animatePendingRequests(true, animated);
if (recentRequestersIdList != null && !recentRequestersIdList.isEmpty()) {
int usersCount = Math.min(3, recentRequestersIdList.size());
for (int i = 0; i < usersCount; ++i) {
TLRPC.User user = fragment.getMessagesController().getUser(recentRequestersIdList.get(i));
if (user != null) {
avatarsView.setObject(i, currentAccount, user);
}
}
avatarsView.setCount(usersCount);
avatarsView.commitTransition(true);
}
}
}
private void animatePendingRequests(boolean appear, boolean animated) {
boolean isVisibleNow = root.getVisibility() == View.VISIBLE;
if (appear == isVisibleNow) {
return;
}
if (appear) {
if (closePendingRequestsCount == -1 && currentChat != null) {
closePendingRequestsCount = fragment.getMessagesController().getChatPendingRequestsOnClosed(currentChat.id);
}
if (pendingRequestsCount == closePendingRequestsCount) {
return;
}
if (closePendingRequestsCount != 0 && currentChat != null) {
fragment.getMessagesController().setChatPendingRequestsOnClose(currentChat.id, 0);
}
}
if (pendingRequestsAnimator != null) {
pendingRequestsAnimator.cancel();
}
if (animated) {
pendingRequestsAnimator = ValueAnimator.ofFloat(appear ? 0f : 1f, appear ? 1f : 0f);
pendingRequestsAnimator.addUpdateListener(animation -> {
float progress = (float) animation.getAnimatedValue();
pendingRequestsEnterOffset = -getViewHeight() * (1f - progress);
if (callback != null) {
callback.onEnterOffsetChanged();
}
});
pendingRequestsAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
if (appear) {
root.setVisibility(View.VISIBLE);
}
}
@Override
public void onAnimationEnd(Animator animation) {
if (!appear) {
root.setVisibility(View.GONE);
}
}
});
pendingRequestsAnimator.setDuration(200);
pendingRequestsAnimator.start();
} else {
root.setVisibility(appear ? View.VISIBLE : View.GONE);
pendingRequestsEnterOffset = appear ? 0 : -getViewHeight();
if (callback != null) {
callback.onEnterOffsetChanged();
}
}
}
public void fillThemeDescriptions(List<ThemeDescription> themeDescriptions) {
themeDescriptions.add(new ThemeDescription(root, ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_chat_topPanelBackground));
themeDescriptions.add(new ThemeDescription(requestsCountTextView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_chat_topPanelTitle));
themeDescriptions.add(new ThemeDescription(closeView, ThemeDescription.FLAG_IMAGECOLOR, null, null, null, null, Theme.key_chat_topPanelClose));
}
public interface Callback {
void onEnterOffsetChanged();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,7 @@ import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserConfig;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Cells.ChatMessageCell;
@ -264,7 +265,7 @@ public class EmojiAnimationsOverlay implements NotificationCenter.NotificationCe
}
public void onTapItem(ChatMessageCell view, ChatActivity chatActivity) {
if (chatActivity.currentUser == null || chatActivity.isSecretChat()) {
if (chatActivity.currentUser == null || chatActivity.isSecretChat() || view.getMessageObject() == null || view.getMessageObject().getId() < 0) {
return;
}
boolean show = showAnimationForCell(view, -1, true, false);
@ -277,7 +278,7 @@ public class EmojiAnimationsOverlay implements NotificationCenter.NotificationCe
if (printingType != null && printingType == 5) {
canShowHint = false;
}
if (canShowHint && hintRunnable == null && show && (Bulletin.getVisibleBulletin() == null || !Bulletin.getVisibleBulletin().isShowing()) && SharedConfig.emojiInteractionsHintCount > 0) {
if (canShowHint && hintRunnable == null && show && (Bulletin.getVisibleBulletin() == null || !Bulletin.getVisibleBulletin().isShowing()) && SharedConfig.emojiInteractionsHintCount > 0 && UserConfig.getInstance(currentAccount).getClientUserId() != chatActivity.currentUser.id) {
SharedConfig.updateEmojiInteractionsHintCount(SharedConfig.emojiInteractionsHintCount - 1);
TLRPC.Document document = MediaDataController.getInstance(currentAccount).getEmojiAnimatedSticker(view.getMessageObject().getStickerEmoji());
StickerSetBulletinLayout layout = new StickerSetBulletinLayout(chatActivity.getParentActivity(), null, StickerSetBulletinLayout.TYPE_EMPTY, document, chatActivity.getResourceProvider());

View File

@ -620,7 +620,7 @@ public class FilterUsersActivity extends BaseFragment implements NotificationCen
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
listView = new RecyclerListView(context);
listView.setFastScrollEnabled();
listView.setFastScrollEnabled(RecyclerListView.FastScroll.LETTER_TYPE);
listView.setEmptyView(emptyView);
listView.setAdapter(adapter = new GroupCreateAdapter(context));
listView.setLayoutManager(linearLayoutManager);
@ -1223,8 +1223,9 @@ public class FilterUsersActivity extends BaseFragment implements NotificationCen
}
@Override
public int getPositionForScrollProgress(float progress) {
return (int) (getItemCount() * progress);
public void getPositionForScrollProgress(RecyclerListView listView, float progress, int[] position) {
position[0] = (int) (getItemCount() * progress);
position[1] = 0;
}
@Override

View File

@ -217,11 +217,11 @@ public class FilteredSearchView extends FrameLayout implements NotificationCente
if (view instanceof SharedDocumentCell) {
top += AndroidUtilities.dp(8f);
}
final int topOffset = top - object.viewY;
final int topOffset = (int) (top - object.viewY);
if (topOffset > view.getHeight()) {
listView.scrollBy(0, -(topOffset + pinnedHeader.getHeight()));
} else {
int bottomOffset = object.viewY - listView.getHeight();
int bottomOffset = (int) (object.viewY - listView.getHeight());
if (view instanceof SharedDocumentCell) {
bottomOffset -= AndroidUtilities.dp(8f);
}
@ -1217,8 +1217,9 @@ public class FilteredSearchView extends FrameLayout implements NotificationCente
}
@Override
public int getPositionForScrollProgress(float progress) {
return 0;
public void getPositionForScrollProgress(RecyclerListView listView, float progress, int[] position) {
position[0] = 0;
position[1] = 0;
}
}
@ -1410,8 +1411,9 @@ public class FilteredSearchView extends FrameLayout implements NotificationCente
}
@Override
public int getPositionForScrollProgress(float progress) {
return 0;
public void getPositionForScrollProgress(RecyclerListView listView, float progress, int[] position) {
position[0] = 0;
position[1] = 0;
}
}

View File

@ -5008,7 +5008,7 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
} else {
decorView = containerView;
}
pinchToZoomHelper = new PinchToZoomHelper(decorView) {
pinchToZoomHelper = new PinchToZoomHelper(decorView, containerView) {
@Override
protected void invalidateViews() {
super.invalidateViews();

Some files were not shown because too many files have changed in this diff Show More