This commit is contained in:
世界 2020-06-25 15:28:24 +00:00
parent cc5089caba
commit dd08362cc6
No known key found for this signature in database
GPG Key ID: CD109927C34A63C4
36 changed files with 1708 additions and 2079 deletions

View File

@ -26,21 +26,34 @@ import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.PowerManager; import android.os.PowerManager;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.text.TextUtils; import android.util.Log;
import androidx.core.app.NotificationManagerCompat;
import androidx.multidex.MultiDex;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.ForegroundDetector; import org.telegram.ui.Components.ForegroundDetector;
import java.io.File; import java.io.File;
import java.lang.reflect.Method;
import java.util.Set;
import tw.nekomimi.nekogram.ExternalGcm;
import tw.nekomimi.nekogram.NekoConfig; import tw.nekomimi.nekogram.NekoConfig;
import androidx.multidex.MultiDex; import tw.nekomimi.nekogram.database.WarppedPref;
import tw.nekomimi.nekogram.utils.EnvUtil;
import tw.nekomimi.nekogram.utils.FileUtil;
import tw.nekomimi.nekogram.utils.ProxyUtil;
import tw.nekomimi.nekogram.utils.UIUtil;
import static android.os.Build.VERSION.SDK_INT;
public class ApplicationLoader extends Application { public class ApplicationLoader extends Application {
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
public static volatile Context applicationContext; public static volatile Context applicationContext;
public static volatile NetworkInfo currentNetworkInfo; public static volatile NetworkInfo currentNetworkInfo;
public static volatile Handler applicationHandler; public static volatile Handler applicationHandler;
@ -55,28 +68,144 @@ public class ApplicationLoader extends Application {
public static boolean hasPlayServices; public static boolean hasPlayServices;
@Override @Override public SharedPreferences getSharedPreferences(String name, int mode) {
protected void attachBaseContext(Context base) { return new WarppedPref(super.getSharedPreferences(name, mode));
super.attachBaseContext(base);
MultiDex.install(this);
} }
public static File getFilesDirFixed() { @Override
for (int a = 0; a < 10; a++) { protected void attachBaseContext(Context base) {
File path = ApplicationLoader.applicationContext.getFilesDir(); if (SDK_INT >= Build.VERSION_CODES.P) {
if (path != null) { Reflection.unseal(base);
return path; }
super.attachBaseContext(base);
if (SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
MultiDex.install(this);
}
}
/**
* @author weishu
* @date 2018/6/7.
*/
public static class Reflection {
private static final String TAG = "Reflection";
private static Object sVmRuntime;
private static Method setHiddenApiExemptions;
static {
if (SDK_INT >= Build.VERSION_CODES.P) {
try {
Method forName = Class.class.getDeclaredMethod("forName", String.class);
Method getDeclaredMethod = Class.class.getDeclaredMethod("getDeclaredMethod", String.class, Class[].class);
Class<?> vmRuntimeClass = (Class<?>) forName.invoke(null, "dalvik.system.VMRuntime");
Method getRuntime = (Method) getDeclaredMethod.invoke(vmRuntimeClass, "getRuntime", null);
setHiddenApiExemptions = (Method) getDeclaredMethod.invoke(vmRuntimeClass, "setHiddenApiExemptions", new Class[]{String[].class});
sVmRuntime = getRuntime.invoke(null);
} catch (Throwable e) {
FileLog.e("reflect bootstrap failed:", e);
}
} }
}
private static int UNKNOWN = -9999;
private static final int ERROR_SET_APPLICATION_FAILED = -20;
private static final int ERROR_EXEMPT_FAILED = -21;
private static int unsealed = UNKNOWN;
public static int unseal(Context context) {
if (SDK_INT < 28) {
// Below Android P, ignore
return 0;
}
// try exempt API first.
if (exemptAll()) {
return 0;
} else {
return ERROR_EXEMPT_FAILED;
}
}
/**
* make the method exempted from hidden API check.
*
* @param method the method signature prefix.
* @return true if success.
*/
public static boolean exempt(String method) {
return exempt(new String[]{method});
}
/**
* make specific methods exempted from hidden API check.
*
* @param methods the method signature prefix, such as "Ldalvik/system", "Landroid" or even "L"
* @return true if success
*/
public static boolean exempt(String... methods) {
if (sVmRuntime == null || setHiddenApiExemptions == null) {
return false;
}
try {
setHiddenApiExemptions.invoke(sVmRuntime, new Object[]{methods});
return true;
} catch (Throwable e) {
return false;
}
}
/**
* Make all hidden API exempted.
*
* @return true if success.
*/
public static boolean exemptAll() {
return exempt(new String[]{"L"});
}
}
@SuppressLint("SdCardPath")
public static File getDataDirFixed() {
try {
File path = applicationContext.getFilesDir();
if (path != null) {
return path.getParentFile();
}
} catch (Exception ignored) {
} }
try { try {
ApplicationInfo info = applicationContext.getApplicationInfo(); ApplicationInfo info = applicationContext.getApplicationInfo();
File path = new File(info.dataDir, "files"); return new File(info.dataDir);
path.mkdirs(); } catch (Exception ignored) {
return path;
} catch (Exception e) {
FileLog.e(e);
} }
return new File("/data/data/org.telegram.messenger/files"); return new File("/data/data/" + BuildConfig.APPLICATION_ID + "/");
}
public static File getFilesDirFixed() {
File filesDir = new File(getDataDirFixed(), "files");
FileUtil.initDir(filesDir);
return filesDir;
}
public static File getCacheDirFixed() {
File filesDir = new File(getDataDirFixed(), "cache");
FileUtil.initDir(filesDir);
return filesDir;
} }
public static void postInitApplication() { public static void postInitApplication() {
@ -86,11 +215,22 @@ public class ApplicationLoader extends Application {
applicationInited = true; applicationInited = true;
try { UIUtil.runOnIoDispatcher(() -> {
LocaleController.getInstance();
} catch (Exception e) { try {
e.printStackTrace(); LocaleController.getInstance();
} } catch (Exception e) {
e.printStackTrace();
}
try {
EnvUtil.doTest();
} catch (Exception e) {
FileLog.e("EnvUtil test Failed", e);
}
});
try { try {
connectivityManager = (ConnectivityManager) ApplicationLoader.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE); connectivityManager = (ConnectivityManager) ApplicationLoader.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
@ -137,29 +277,50 @@ public class ApplicationLoader extends Application {
SharedConfig.loadConfig(); SharedConfig.loadConfig();
for (int a = 0; a < UserConfig.MAX_ACCOUNT_COUNT; a++) { for (int a = 0; a < UserConfig.MAX_ACCOUNT_COUNT; a++) {
UserConfig.getInstance(a).loadConfig(); final int finalA = a;
MessagesController.getInstance(a); Runnable initRunnable = () -> {
if (a == 0) { UserConfig.getInstance(finalA).loadConfig();
SharedConfig.pushStringStatus = "__FIREBASE_GENERATING_SINCE_" + ConnectionsManager.getInstance(a).getCurrentTime() + "__"; MessagesController.getInstance(finalA);
} else { if (finalA == 0) {
ConnectionsManager.getInstance(a); SharedConfig.pushStringStatus = "__FIREBASE_GENERATING_SINCE_" + ConnectionsManager.getInstance(finalA).getCurrentTime() + "__";
} } else {
TLRPC.User user = UserConfig.getInstance(a).getCurrentUser(); ConnectionsManager.getInstance(finalA);
if (user != null) { }
MessagesController.getInstance(a).putUser(user, true); TLRPC.User user = UserConfig.getInstance(finalA).getCurrentUser();
SendMessagesHelper.getInstance(a).checkUnsentMessages(); if (user != null) {
MessagesController.getInstance(finalA).putUser(user, true);
SendMessagesHelper.getInstance(finalA).checkUnsentMessages();
}
};
if (finalA == UserConfig.selectedAccount) initRunnable.run();
else UIUtil.runOnIoDispatcher(initRunnable);
}
if (ProxyUtil.isVPNEnabled()) {
if (NekoConfig.disableProxyWhenVpnEnabled) {
SharedConfig.setProxyEnable(false);
} }
} }
ApplicationLoader app = (ApplicationLoader) ApplicationLoader.applicationContext; ApplicationLoader app = (ApplicationLoader) ApplicationLoader.applicationContext;
ExternalGcm.initPlayServices();
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("app initied"); FileLog.d("app initied");
} }
MediaController.getInstance(); MediaController.getInstance();
for (int a = 0; a < UserConfig.MAX_ACCOUNT_COUNT; a++) { for (int a = 0; a < UserConfig.MAX_ACCOUNT_COUNT; a++) {
ContactsController.getInstance(a).checkAppAccount(); final int finalA = a;
DownloadController.getInstance(a); Runnable initRunnable = () -> {
ContactsController.getInstance(finalA).checkAppAccount();
DownloadController.getInstance(finalA);
};
if (finalA == UserConfig.selectedAccount) initRunnable.run();
else UIUtil.runOnIoDispatcher(initRunnable);
} }
} }
@ -169,10 +330,10 @@ public class ApplicationLoader extends Application {
@Override @Override
public void onCreate() { public void onCreate() {
try { try {
applicationContext = getApplicationContext(); applicationContext = getApplicationContext();
} catch (Throwable ignore) { } catch (Throwable ignore) {
} }
super.onCreate(); super.onCreate();
@ -196,41 +357,64 @@ public class ApplicationLoader extends Application {
applicationHandler = new Handler(applicationContext.getMainLooper()); applicationHandler = new Handler(applicationContext.getMainLooper());
AndroidUtilities.runOnUIThread(ApplicationLoader::startPushService); org.osmdroid.config.Configuration.getInstance().setUserAgentValue("Telegram-FOSS ( NekoX ) " + BuildConfig.VERSION_NAME);
org.osmdroid.config.Configuration.getInstance().setOsmdroidBasePath(new File(ApplicationLoader.applicationContext.getCacheDir(), "osmdroid"));
// SET TFOSS USERAGENT FOR OSM SERVERS startPushService();
org.osmdroid.config.Configuration.getInstance().setUserAgentValue("Telegram-FOSS(F-Droid) "+BuildConfig.VERSION_NAME);
org.osmdroid.config.Configuration.getInstance().setOsmdroidBasePath(new File(getCacheDir(),"osmdroid"));
} }
public static void startPushService() { public static void startPushService() {
if (ExternalGcm.checkPlayServices() || (SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && isNotificationListenerEnabled())) {
return;
}
SharedPreferences preferences = MessagesController.getGlobalNotificationsSettings(); SharedPreferences preferences = MessagesController.getGlobalNotificationsSettings();
boolean enabled; boolean enabled;
if (preferences.contains("pushService")) { if (preferences.contains("pushService")) {
enabled = preferences.getBoolean("pushService", true); enabled = preferences.getBoolean("pushService", true);
if (SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
if (!preferences.getBoolean("pushConnection", true)) return;
}
} else { } else {
enabled = MessagesController.getMainSettings(UserConfig.selectedAccount).getBoolean("keepAliveService", false); enabled = MessagesController.getMainSettings(UserConfig.selectedAccount).getBoolean("keepAliveService", true);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("pushService", enabled);
editor.putBoolean("pushConnection", enabled);
editor.apply();
SharedPreferences preferencesCA = MessagesController.getNotificationsSettings(UserConfig.selectedAccount);
SharedPreferences.Editor editorCA = preferencesCA.edit();
editorCA.putBoolean("pushConnection", enabled);
editorCA.putBoolean("pushService", enabled);
editorCA.apply();
ConnectionsManager.getInstance(UserConfig.selectedAccount).setPushConnectionEnabled(true);
} }
if (enabled) { if (enabled) {
try { try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && NekoConfig.residentNotification) { Log.d("TFOSS", "Starting push service...");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
applicationContext.startForegroundService(new Intent(applicationContext, NotificationsService.class)); applicationContext.startForegroundService(new Intent(applicationContext, NotificationsService.class));
} else { } else {
applicationContext.startService(new Intent(applicationContext, NotificationsService.class)); applicationContext.startService(new Intent(applicationContext, NotificationsService.class));
} }
} catch (Throwable ignore) { } catch (Throwable e) {
Log.d("TFOSS", "Failed to start push service");
} }
} else { } else {
applicationContext.stopService(new Intent(applicationContext, NotificationsService.class)); applicationContext.stopService(new Intent(applicationContext, NotificationsService.class));
PendingIntent pintent = PendingIntent.getService(applicationContext, 0, new Intent(applicationContext, NotificationsService.class), 0); PendingIntent pintent = PendingIntent.getService(applicationContext, 0, new Intent(applicationContext, NotificationsService.class), 0);
AlarmManager alarm = (AlarmManager)applicationContext.getSystemService(Context.ALARM_SERVICE); AlarmManager alarm = (AlarmManager) applicationContext.getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pintent); alarm.cancel(pintent);
} }
} }
public static boolean isNotificationListenerEnabled() {
Set<String> packageNames = NotificationManagerCompat.getEnabledListenerPackages(applicationContext);
if (packageNames.contains(applicationContext.getPackageName())) {
return true;
}
return false;
}
@Override @Override
public void onConfigurationChanged(Configuration newConfig) { public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig); super.onConfigurationChanged(newConfig);
@ -242,7 +426,6 @@ public class ApplicationLoader extends Application {
} }
} }
private static void ensureCurrentNetworkGet(boolean force) { private static void ensureCurrentNetworkGet(boolean force) {
if (force || currentNetworkInfo == null) { if (force || currentNetworkInfo == null) {
try { try {

View File

@ -4,7 +4,7 @@ import org.telegram.tgnet.ConnectionsManager;
public class BaseController { public class BaseController {
protected int currentAccount; public int currentAccount;
private AccountInstance parentAccountInstance; private AccountInstance parentAccountInstance;
public BaseController(int num) { public BaseController(int num) {

View File

@ -30,6 +30,9 @@ public class BuildVars {
public static int TGX_APP_ID = 21724; public static int TGX_APP_ID = 21724;
public static String TGX_APP_HASH = "3e0cb5efcd52300aec5994fdfc5bdc16"; public static String TGX_APP_HASH = "3e0cb5efcd52300aec5994fdfc5bdc16";
public static boolean isUnknown = !BuildConfig.BUILD_TYPE.startsWith("release");
public static boolean isMini = "mini".equals(BuildConfig.FLAVOR);
static { static {
try { try {

View File

@ -147,6 +147,8 @@ public class FileLoadOperation {
private ArrayList<RequestInfo> requestInfos; private ArrayList<RequestInfo> requestInfos;
private ArrayList<RequestInfo> delayedRequestInfos; private ArrayList<RequestInfo> delayedRequestInfos;
private String fileName;
private File cacheFileTemp; private File cacheFileTemp;
private File cacheFileGzipTemp; private File cacheFileGzipTemp;
private File cacheFileFinal; private File cacheFileFinal;
@ -266,7 +268,8 @@ public class FileLoadOperation {
ext = ImageLoader.getHttpUrlExtension(webDocument.url, defaultExt); ext = ImageLoader.getHttpUrlExtension(webDocument.url, defaultExt);
} }
public FileLoadOperation(TLRPC.Document documentLocation, Object parent) { public FileLoadOperation(TLRPC.Document documentLocation, Object parent,String fileName) {
this.fileName = fileName;
try { try {
parentObject = parent; parentObject = parent;
if (documentLocation instanceof TLRPC.TL_documentEncrypted) { if (documentLocation instanceof TLRPC.TL_documentEncrypted) {
@ -725,6 +728,8 @@ public class FileLoadOperation {
if (parentObject instanceof TLRPC.TL_theme) { if (parentObject instanceof TLRPC.TL_theme) {
TLRPC.TL_theme theme = (TLRPC.TL_theme) parentObject; TLRPC.TL_theme theme = (TLRPC.TL_theme) parentObject;
cacheFileFinal = new File(ApplicationLoader.getFilesDirFixed(), "remote" + theme.id + ".attheme"); cacheFileFinal = new File(ApplicationLoader.getFilesDirFixed(), "remote" + theme.id + ".attheme");
} else if (fileName != null) {
cacheFileFinal = new File(storePath, fileName);
} else { } else {
cacheFileFinal = new File(storePath, fileNameFinal); cacheFileFinal = new File(storePath, fileNameFinal);
} }

View File

@ -606,7 +606,7 @@ public class FileLoader extends BaseController {
operation = new FileLoadOperation(imageLocation, parentObject, locationExt, locationSize); operation = new FileLoadOperation(imageLocation, parentObject, locationExt, locationSize);
type = MEDIA_DIR_IMAGE; type = MEDIA_DIR_IMAGE;
} else if (document != null) { } else if (document != null) {
operation = new FileLoadOperation(document, parentObject); operation = new FileLoadOperation(document, parentObject, fileName);
if (MessageObject.isVoiceDocument(document)) { if (MessageObject.isVoiceDocument(document)) {
type = MEDIA_DIR_AUDIO; type = MEDIA_DIR_AUDIO;
} else if (MessageObject.isVideoDocument(document)) { } else if (MessageObject.isVideoDocument(document)) {
@ -1129,23 +1129,28 @@ public class FileLoader extends BaseController {
public static String getAttachFileName(TLObject attach, String ext) { public static String getAttachFileName(TLObject attach, String ext) {
if (attach instanceof TLRPC.Document) { if (attach instanceof TLRPC.Document) {
TLRPC.Document document = (TLRPC.Document) attach; TLRPC.Document document = (TLRPC.Document) attach;
String docExt = null; if (document.mime_type != null && (
if (docExt == null) { document.mime_type.startsWith("application/x") ||
docExt = getDocumentFileName(document); document.mime_type.startsWith("audio/") ||
document.mime_type.startsWith("video/") ||
document.mime_type.startsWith("image/"))) {
String docExt = getDocumentFileName(document);
int idx; int idx;
if (docExt == null || (idx = docExt.lastIndexOf('.')) == -1) { if (docExt == null || (idx = docExt.lastIndexOf('.')) == -1) {
docExt = ""; docExt = "";
} else { } else {
docExt = docExt.substring(idx); docExt = docExt.substring(idx);
} }
} if (docExt.length() <= 1) {
if (docExt.length() <= 1) { docExt = getExtensionByMimeType(document.mime_type);
docExt = getExtensionByMimeType(document.mime_type); }
} if (docExt.length() > 1) {
if (docExt.length() > 1) { return document.dc_id + "_" + document.id + docExt;
return document.dc_id + "_" + document.id + docExt; } else {
return document.dc_id + "_" + document.id;
}
} else { } else {
return document.dc_id + "_" + document.id; return (document.dc_id + "_" + document.id).hashCode() + "_" + getDocumentFileName(document);
} }
} else if (attach instanceof SecureDocument) { } else if (attach instanceof SecureDocument) {
SecureDocument secureDocument = (SecureDocument) attach; SecureDocument secureDocument = (SecureDocument) attach;

View File

@ -17,228 +17,50 @@ import java.io.FileOutputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.util.Locale; import java.util.Locale;
import cn.hutool.core.lang.caller.CallerUtil;
import cn.hutool.core.lang.caller.StackTraceCaller;
public class FileLog { public class FileLog {
private OutputStreamWriter streamWriter = null;
private FastDateFormat dateFormat = null;
private DispatchQueue logQueue = null;
private File currentFile = null;
private File networkFile = null;
private File tonlibFile = null;
private boolean initied;
private final static String tag = "tmessages"; private final static StackTraceCaller caller = new StackTraceCaller();
private static volatile FileLog Instance = null;
public static FileLog getInstance() {
FileLog localInstance = Instance;
if (localInstance == null) {
synchronized (FileLog.class) {
localInstance = Instance;
if (localInstance == null) {
Instance = localInstance = new FileLog();
}
}
}
return localInstance;
}
public FileLog() {
if (!BuildVars.LOGS_ENABLED) {
return;
}
init();
}
public void init() {
if (initied) {
return;
}
dateFormat = FastDateFormat.getInstance("dd_MM_yyyy_HH_mm_ss", Locale.US);
try {
File sdCard = ApplicationLoader.applicationContext.getExternalFilesDir(null);
if (sdCard == null) {
return;
}
File dir = new File(sdCard.getAbsolutePath() + "/logs");
dir.mkdirs();
currentFile = new File(dir, dateFormat.format(System.currentTimeMillis()) + ".txt");
} catch (Exception e) {
e.printStackTrace();
}
try {
logQueue = new DispatchQueue("logQueue");
currentFile.createNewFile();
FileOutputStream stream = new FileOutputStream(currentFile);
streamWriter = new OutputStreamWriter(stream);
streamWriter.write("-----start log " + dateFormat.format(System.currentTimeMillis()) + "-----\n");
streamWriter.flush();
} catch (Exception e) {
e.printStackTrace();
}
initied = true;
}
public static void ensureInitied() {
getInstance().init();
}
public static String getNetworkLogPath() { public static String getNetworkLogPath() {
if (!BuildVars.LOGS_ENABLED) {
return "";
}
try {
File sdCard = ApplicationLoader.applicationContext.getExternalFilesDir(null);
if (sdCard == null) {
return "";
}
File dir = new File(sdCard.getAbsolutePath() + "/logs");
dir.mkdirs();
getInstance().networkFile = new File(dir, getInstance().dateFormat.format(System.currentTimeMillis()) + "_net.txt");
return getInstance().networkFile.getAbsolutePath();
} catch (Throwable e) {
e.printStackTrace();
}
return ""; return "";
} }
public static String getTonlibLogPath() { private static String mkTag() {
if (!BuildVars.LOGS_ENABLED) { return caller.getCaller(3).getSimpleName();
return ""; }
}
try { private static String mkMessage(Throwable e) {
File sdCard = ApplicationLoader.applicationContext.getExternalFilesDir(null); String message = e.getMessage();
if (sdCard == null) { if (message != null) return message;
return ""; return e.getClass().getSimpleName();
}
File dir = new File(sdCard.getAbsolutePath() + "/logs");
dir.mkdirs();
getInstance().tonlibFile = new File(dir, getInstance().dateFormat.format(System.currentTimeMillis()) + "_tonlib.txt");
return getInstance().tonlibFile.getAbsolutePath();
} catch (Throwable e) {
e.printStackTrace();
}
return "";
} }
public static void e(final String message, final Throwable exception) { public static void e(final String message, final Throwable exception) {
if (!BuildVars.LOGS_ENABLED) { Log.e(mkTag(), message, exception);
return;
}
ensureInitied();
Log.e(tag, message, exception);
if (getInstance().streamWriter != null) {
getInstance().logQueue.postRunnable(() -> {
try {
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " E/tmessages: " + message + "\n");
getInstance().streamWriter.write(exception.toString());
getInstance().streamWriter.flush();
} catch (Exception e) {
e.printStackTrace();
}
});
}
} }
public static void e(final String message) { public static void e(final String message) {
if (!BuildVars.LOGS_ENABLED) { Log.e(mkTag(), message);
return;
}
ensureInitied();
Log.e(tag, message);
if (getInstance().streamWriter != null) {
getInstance().logQueue.postRunnable(() -> {
try {
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " E/tmessages: " + message + "\n");
getInstance().streamWriter.flush();
} catch (Exception e) {
e.printStackTrace();
}
});
}
} }
public static void e(final Throwable e) { public static void e(final Throwable e) {
if (!BuildVars.LOGS_ENABLED) { if (!BuildVars.LOGS_ENABLED) {
return; return;
} }
ensureInitied(); Log.e(mkTag(),mkMessage(e),e);
e.printStackTrace();
if (getInstance().streamWriter != null) {
getInstance().logQueue.postRunnable(() -> {
try {
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " E/tmessages: " + e + "\n");
StackTraceElement[] stack = e.getStackTrace();
for (int a = 0; a < stack.length; a++) {
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " E/tmessages: " + stack[a] + "\n");
}
getInstance().streamWriter.flush();
} catch (Exception e1) {
e1.printStackTrace();
}
});
} else {
e.printStackTrace();
}
} }
public static void d(final String message) { public static void d(final String message) {
if (!BuildVars.LOGS_ENABLED) { if (!BuildVars.LOGS_ENABLED) return;
return; Log.d(mkTag(), message);
}
ensureInitied();
Log.d(tag, message);
if (getInstance().streamWriter != null) {
getInstance().logQueue.postRunnable(() -> {
try {
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " D/tmessages: " + message + "\n");
getInstance().streamWriter.flush();
} catch (Exception e) {
e.printStackTrace();
}
});
}
} }
public static void w(final String message) { public static void w(final String message) {
if (!BuildVars.LOGS_ENABLED) { if (!BuildVars.LOGS_ENABLED) return;
return; Log.w(mkTag(), message);
}
ensureInitied();
Log.w(tag, message);
if (getInstance().streamWriter != null) {
getInstance().logQueue.postRunnable(() -> {
try {
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " W/tmessages: " + message + "\n");
getInstance().streamWriter.flush();
} catch (Exception e) {
e.printStackTrace();
}
});
}
} }
public static void cleanupLogs() {
ensureInitied();
File sdCard = ApplicationLoader.applicationContext.getExternalFilesDir(null);
if (sdCard == null) {
return;
}
File dir = new File (sdCard.getAbsolutePath() + "/logs");
File[] files = dir.listFiles();
if (files != null) {
for (int a = 0; a < files.length; a++) {
File file = files[a];
if (getInstance().currentFile != null && file.getAbsolutePath().equals(getInstance().currentFile.getAbsolutePath())) {
continue;
}
if (getInstance().networkFile != null && file.getAbsolutePath().equals(getInstance().networkFile.getAbsolutePath())) {
continue;
}
if (getInstance().tonlibFile != null && file.getAbsolutePath().equals(getInstance().tonlibFile.getAbsolutePath())) {
continue;
}
file.delete();
}
}
}
} }

View File

@ -246,9 +246,6 @@ public class FileUploadOperation {
started = true; started = true;
if (stream == null) { if (stream == null) {
File cacheFile = new File(uploadingFilePath); File cacheFile = new File(uploadingFilePath);
if (AndroidUtilities.isInternalUri(Uri.fromFile(cacheFile))) {
throw new Exception("trying to upload internal file");
}
stream = new RandomAccessFile(cacheFile, "r"); stream = new RandomAccessFile(cacheFile, "r");
if (estimatedSize != 0) { if (estimatedSize != 0) {
totalFileSize = estimatedSize; totalFileSize = estimatedSize;

View File

@ -17,17 +17,16 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.Matrix; import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import androidx.exifinterface.media.ExifInterface;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.SparseArray; import android.util.SparseArray;
import androidx.exifinterface.media.ExifInterface;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
import org.telegram.messenger.secretmedia.EncryptedFileInputStream; import org.telegram.messenger.secretmedia.EncryptedFileInputStream;
@ -65,7 +64,8 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import tw.nekomimi.nekogram.NekoConfig; import tw.nekomimi.nekogram.utils.EnvUtil;
import tw.nekomimi.nekogram.utils.FileUtil;
public class ImageLoader { public class ImageLoader {
@ -1781,79 +1781,67 @@ public class ImageLoader {
} }
} }
AndroidUtilities.createEmptyFile(new File(cachePath, ".nomedia")); AndroidUtilities.createEmptyFile(new File(cachePath, ".nomedia"));
mediaDirs.put(FileLoader.MEDIA_DIR_CACHE, cachePath); mediaDirs.put(FileLoader.MEDIA_DIR_CACHE, cachePath);
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("cache path = " + cachePath); FileLog.d("cache path = " + cachePath);
} }
try { try {
if (NekoConfig.saveCacheToPrivateDirectory || Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { telegramPath = EnvUtil.getTelegramPath();
if (NekoConfig.saveCacheToPrivateDirectory) {
telegramPath = new File(ApplicationLoader.applicationContext.getFilesDir(), "Telegram"); if (telegramPath.isDirectory()) {
} else { try {
telegramPath = new File(Environment.getExternalStorageDirectory(), "Telegram"); File imagePath = new File(telegramPath, "images");
FileUtil.initDir(imagePath);
if (imagePath.isDirectory() && canMoveFiles(cachePath, imagePath, FileLoader.MEDIA_DIR_IMAGE)) {
mediaDirs.put(FileLoader.MEDIA_DIR_IMAGE, imagePath);
if (BuildVars.LOGS_ENABLED) {
FileLog.d("image path = " + imagePath);
}
}
} catch (Exception e) {
FileLog.e(e);
} }
telegramPath.mkdirs();
if (telegramPath.isDirectory()) { try {
try { File videoPath = new File(telegramPath, "videos");
File imagePath = new File(telegramPath, "Telegram Images"); FileUtil.initDir(videoPath);
imagePath.mkdir(); if (videoPath.isDirectory() && canMoveFiles(cachePath, videoPath, FileLoader.MEDIA_DIR_VIDEO)) {
if (imagePath.isDirectory() && canMoveFiles(cachePath, imagePath, FileLoader.MEDIA_DIR_IMAGE)) { mediaDirs.put(FileLoader.MEDIA_DIR_VIDEO, videoPath);
mediaDirs.put(FileLoader.MEDIA_DIR_IMAGE, imagePath); if (BuildVars.LOGS_ENABLED) {
if (BuildVars.LOGS_ENABLED) { FileLog.d("video path = " + videoPath);
FileLog.d("image path = " + imagePath);
}
} }
} catch (Exception e) {
FileLog.e(e);
}
try {
File videoPath = new File(telegramPath, "Telegram Video");
videoPath.mkdir();
if (videoPath.isDirectory() && canMoveFiles(cachePath, videoPath, FileLoader.MEDIA_DIR_VIDEO)) {
mediaDirs.put(FileLoader.MEDIA_DIR_VIDEO, videoPath);
if (BuildVars.LOGS_ENABLED) {
FileLog.d("video path = " + videoPath);
}
}
} catch (Exception e) {
FileLog.e(e);
}
try {
File audioPath = new File(telegramPath, "Telegram Audio");
audioPath.mkdir();
if (audioPath.isDirectory() && canMoveFiles(cachePath, audioPath, FileLoader.MEDIA_DIR_AUDIO)) {
AndroidUtilities.createEmptyFile(new File(audioPath, ".nomedia"));
mediaDirs.put(FileLoader.MEDIA_DIR_AUDIO, audioPath);
if (BuildVars.LOGS_ENABLED) {
FileLog.d("audio path = " + audioPath);
}
}
} catch (Exception e) {
FileLog.e(e);
}
try {
File documentPath = new File(telegramPath, "Telegram Documents");
documentPath.mkdir();
if (documentPath.isDirectory() && canMoveFiles(cachePath, documentPath, FileLoader.MEDIA_DIR_DOCUMENT)) {
AndroidUtilities.createEmptyFile(new File(documentPath, ".nomedia"));
mediaDirs.put(FileLoader.MEDIA_DIR_DOCUMENT, documentPath);
if (BuildVars.LOGS_ENABLED) {
FileLog.d("documents path = " + documentPath);
}
}
} catch (Exception e) {
FileLog.e(e);
} }
} catch (Exception e) {
FileLog.e(e);
} }
} else {
if (BuildVars.LOGS_ENABLED) { try {
FileLog.d("this Android can't rename files"); File audioPath = new File(telegramPath, "audios");
FileUtil.initDir(audioPath);
if (audioPath.isDirectory() && canMoveFiles(cachePath, audioPath, FileLoader.MEDIA_DIR_AUDIO)) {
AndroidUtilities.createEmptyFile(new File(audioPath, ".nomedia"));
mediaDirs.put(FileLoader.MEDIA_DIR_AUDIO, audioPath);
if (BuildVars.LOGS_ENABLED) {
FileLog.d("audio path = " + audioPath);
}
}
} catch (Exception e) {
FileLog.e(e);
}
try {
File documentPath = new File(telegramPath, "documents");
FileUtil.initDir(documentPath);
if (documentPath.isDirectory() && canMoveFiles(cachePath, documentPath, FileLoader.MEDIA_DIR_DOCUMENT)) {
AndroidUtilities.createEmptyFile(new File(documentPath, ".nomedia"));
mediaDirs.put(FileLoader.MEDIA_DIR_DOCUMENT, documentPath);
if (BuildVars.LOGS_ENABLED) {
FileLog.d("documents path = " + documentPath);
}
}
} catch (Exception e) {
FileLog.e(e);
} }
} }
SharedConfig.checkSaveToGalleryFiles(); SharedConfig.checkSaveToGalleryFiles();

View File

@ -100,6 +100,14 @@ public class ImageLocation {
return getForPhoto(photoSize.location, photoSize.size, photo, null, null, false, dc_id, null, photoSize.type); return getForPhoto(photoSize.location, photoSize.size, photo, null, null, false, dc_id, null, photoSize.type);
} }
public static boolean isUserHasPhoto(TLRPC.User user) {
if (user == null || user.access_hash == 0 || user.photo == null || user.photo.photo_big == null) {
return false;
}
return true;
}
public static ImageLocation getForUser(TLRPC.User user, boolean big) { public static ImageLocation getForUser(TLRPC.User user, boolean big) {
if (user == null || user.access_hash == 0 || user.photo == null) { if (user == null || user.access_hash == 0 || user.photo == null) {
return null; return null;

View File

@ -14,12 +14,15 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.format.DateFormat; import android.text.format.DateFormat;
import android.util.Xml; import android.util.Xml;
import android.view.Gravity;
import org.telegram.messenger.support.ArrayUtils;
import org.telegram.messenger.time.FastDateFormat; import org.telegram.messenger.time.FastDateFormat;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLObject; import org.telegram.tgnet.TLObject;
@ -30,6 +33,7 @@ import java.io.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
@ -40,6 +44,7 @@ import java.util.Locale;
import java.util.TimeZone; import java.util.TimeZone;
import tw.nekomimi.nekogram.NekoConfig; import tw.nekomimi.nekogram.NekoConfig;
import tw.nekomimi.nekogram.utils.FileUtil;
public class LocaleController { public class LocaleController {
@ -51,7 +56,13 @@ public class LocaleController {
static final int QUANTITY_MANY = 0x0010; static final int QUANTITY_MANY = 0x0010;
public static boolean isRTL = false; public static boolean isRTL = false;
public static int nameDisplayOrder = 1;
public static int generateFlagStart() {
return isRTL ? Gravity.RIGHT : Gravity.LEFT;
}
public static boolean is24HourFormat = false; public static boolean is24HourFormat = false;
public FastDateFormat formatterDay; public FastDateFormat formatterDay;
public FastDateFormat formatterWeek; public FastDateFormat formatterWeek;
@ -109,6 +120,9 @@ public class LocaleController {
public boolean builtIn; public boolean builtIn;
public int serverIndex; public int serverIndex;
public TLRPC.TL_langPackLanguage pack;
public boolean toInstall;
public String getSaveString() { public String getSaveString() {
String langCode = baseLangCode == null ? "" : baseLangCode; String langCode = baseLangCode == null ? "" : baseLangCode;
String pluralCode = TextUtils.isEmpty(pluralLangCode) ? shortName : pluralLangCode; String pluralCode = TextUtils.isEmpty(pluralLangCode) ? shortName : pluralLangCode;
@ -151,17 +165,25 @@ public class LocaleController {
} }
public File getPathToFile() { public File getPathToFile() {
File baseDir = new File(ApplicationLoader.getDataDirFixed(), "languages");
FileUtil.initDir(baseDir);
if (isRemote()) { if (isRemote()) {
return new File(ApplicationLoader.getFilesDirFixed(), "remote_" + shortName + ".xml"); return new File(baseDir, "remote_" + shortName + ".xml");
} else if (isUnofficial()) { } else if (isUnofficial()) {
return new File(ApplicationLoader.getFilesDirFixed(), "unofficial_" + shortName + ".xml"); return new File(baseDir, "unofficial_" + shortName + ".xml");
} }
return !TextUtils.isEmpty(pathToFile) ? new File(pathToFile) : null; return !TextUtils.isEmpty(pathToFile) ? new File(pathToFile) : null;
} }
public File getPathToBaseFile() { public File getPathToBaseFile() {
if (isUnofficial()) { if (isUnofficial()) {
return new File(ApplicationLoader.getFilesDirFixed(), "unofficial_base_" + shortName + ".xml"); File baseDir = new File(ApplicationLoader.getDataDirFixed(), "languages");
FileUtil.initDir(baseDir);
return new File(baseDir, "unofficial_base_" + shortName + ".xml");
} }
return null; return null;
} }
@ -215,6 +237,7 @@ public class LocaleController {
private ArrayList<LocaleInfo> otherLanguages = new ArrayList<>(); private ArrayList<LocaleInfo> otherLanguages = new ArrayList<>();
private static volatile LocaleController Instance = null; private static volatile LocaleController Instance = null;
public static LocaleController getInstance() { public static LocaleController getInstance() {
LocaleController localInstance = Instance; LocaleController localInstance = Instance;
if (localInstance == null) { if (localInstance == null) {
@ -225,6 +248,8 @@ public class LocaleController {
} }
} }
} }
if (localInstance.formatterDay == null || localInstance.chatFullDate == null)
localInstance.recreateFormatters();
return localInstance; return localInstance;
} }
@ -325,6 +350,20 @@ public class LocaleController {
languages.add(localeInfo); languages.add(localeInfo);
languagesDict.put(localeInfo.shortName, localeInfo); languagesDict.put(localeInfo.shortName, localeInfo);
localeInfo = new LocaleInfo();
localeInfo.name = "简体中文 ( NekoX )";
localeInfo.nameEnglish = "Simplified Chinese ( NekoX )";
localeInfo.shortName = "nekox_zh_cn";
localeInfo.baseLangCode = "zh_hans_raw";
localeInfo.isRtl = false;
localeInfo.pathToFile = "unofficial";
localeInfo.pluralLangCode = "zh_cn";
localeInfo.builtIn = true;
languages.add(localeInfo);
languagesDict.put(localeInfo.getKey(), localeInfo);
languagesDict.put("zh_cn", localeInfo);
languagesDict.put("zh_sg", localeInfo);
localeInfo = new LocaleInfo(); localeInfo = new LocaleInfo();
localeInfo.name = "瓜体中文 \uD83D\uDE36"; localeInfo.name = "瓜体中文 \uD83D\uDE36";
localeInfo.nameEnglish = "Duangified Chinese (Simplified)"; localeInfo.nameEnglish = "Duangified Chinese (Simplified)";
@ -336,23 +375,6 @@ public class LocaleController {
localeInfo.builtIn = true; localeInfo.builtIn = true;
languages.add(localeInfo); languages.add(localeInfo);
languagesDict.put(localeInfo.getKey(), localeInfo); languagesDict.put(localeInfo.getKey(), localeInfo);
languagesDict.put("zh_cn", localeInfo);
languagesDict.put("zh_sg", localeInfo);
localeInfo = new LocaleInfo();
localeInfo.name = "瓜體中文";
localeInfo.nameEnglish = "Duangified Chinese (Traditional)";
localeInfo.shortName = "duang_zh_hant";
localeInfo.baseLangCode = "zh_hant_raw";
localeInfo.isRtl = false;
localeInfo.pathToFile = "unofficial";
localeInfo.pluralLangCode = "zh_tw";
localeInfo.builtIn = true;
languages.add(localeInfo);
languagesDict.put(localeInfo.getKey(), localeInfo);
languagesDict.put("zh_tw", localeInfo);
languagesDict.put("zh_hk", localeInfo);
languagesDict.put("zh_mo", localeInfo);
localeInfo = new LocaleInfo(); localeInfo = new LocaleInfo();
localeInfo.name = "正體中文"; localeInfo.name = "正體中文";
@ -365,6 +387,9 @@ public class LocaleController {
localeInfo.builtIn = true; localeInfo.builtIn = true;
languages.add(localeInfo); languages.add(localeInfo);
languagesDict.put(localeInfo.getKey(), localeInfo); languagesDict.put(localeInfo.getKey(), localeInfo);
languagesDict.put("zh_tw", localeInfo);
languagesDict.put("zh_hk", localeInfo);
languagesDict.put("zh_mo", localeInfo);
localeInfo = new LocaleInfo(); localeInfo = new LocaleInfo();
localeInfo.name = "日本語"; localeInfo.name = "日本語";
@ -721,7 +746,7 @@ public class LocaleController {
} }
} }
editor.putString("unofficial", stringBuilder.toString()); editor.putString("unofficial", stringBuilder.toString());
editor.commit(); editor.apply();
} }
public boolean deleteLanguage(LocaleInfo localeInfo, int currentAccount) { public boolean deleteLanguage(LocaleInfo localeInfo, int currentAccount) {
@ -897,6 +922,7 @@ public class LocaleController {
saveOtherLanguages(); saveOtherLanguages();
} }
} }
loadPrebuiltLocaleFile(localeInfo);
if ((localeInfo.isRemote() || localeInfo.isUnofficial()) && (force || !pathToFile.exists() || hasBase && !pathToBaseFile.exists())) { if ((localeInfo.isRemote() || localeInfo.isUnofficial()) && (force || !pathToFile.exists() || hasBase && !pathToBaseFile.exists())) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("reload locale because one of file doesn't exist" + pathToFile + " " + pathToBaseFile); FileLog.d("reload locale because one of file doesn't exist" + pathToFile + " " + pathToBaseFile);
@ -928,7 +954,7 @@ public class LocaleController {
SharedPreferences preferences = MessagesController.getGlobalMainSettings(); SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit(); SharedPreferences.Editor editor = preferences.edit();
editor.putString("language", localeInfo.getKey()); editor.putString("language", localeInfo.getKey());
editor.commit(); editor.apply();
} }
if (pathToFile == null) { if (pathToFile == null) {
localeValues.clear(); localeValues.clear();
@ -1562,7 +1588,6 @@ public class LocaleController {
isRTL = lang.length() == 2 && (lang.equals("ar") || lang.equals("fa") || lang.equals("he") || lang.equals("iw")) || isRTL = lang.length() == 2 && (lang.equals("ar") || lang.equals("fa") || lang.equals("he") || lang.equals("iw")) ||
lang.startsWith("ar_") || lang.startsWith("fa_") || lang.startsWith("he_") || lang.startsWith("iw_") lang.startsWith("ar_") || lang.startsWith("fa_") || lang.startsWith("he_") || lang.startsWith("iw_")
|| currentLocaleInfo != null && currentLocaleInfo.isRtl; || currentLocaleInfo != null && currentLocaleInfo.isRtl;
nameDisplayOrder = NekoConfig.nameOrder;
formatterDayMonth = createFormatter(locale, getStringInternal("formatterMonth", R.string.formatterMonth), "dd MMM"); formatterDayMonth = createFormatter(locale, getStringInternal("formatterMonth", R.string.formatterMonth), "dd MMM");
formatterYear = createFormatter(locale, getStringInternal("formatterYear", R.string.formatterYear), "dd.MM.yy"); formatterYear = createFormatter(locale, getStringInternal("formatterYear", R.string.formatterYear), "dd.MM.yy");
@ -1743,7 +1768,7 @@ public class LocaleController {
return getString("WithinAWeek", R.string.WithinAWeek); return getString("WithinAWeek", R.string.WithinAWeek);
} else if (user.status.expires == -102) { } else if (user.status.expires == -102) {
return getString("WithinAMonth", R.string.WithinAMonth); return getString("WithinAMonth", R.string.WithinAMonth);
} else { } else {
return formatDateOnline(user.status.expires); return formatDateOnline(user.status.expires);
} }
} }
@ -1859,7 +1884,7 @@ public class LocaleController {
SharedPreferences preferences = MessagesController.getGlobalMainSettings(); SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit(); SharedPreferences.Editor editor = preferences.edit();
editor.putString("language", localeInfo.getKey()); editor.putString("language", localeInfo.getKey());
editor.commit(); editor.apply();
} }
if (newLocale != null) { if (newLocale != null) {
localeValues = valuesToSet; localeValues = valuesToSet;
@ -1980,7 +2005,7 @@ public class LocaleController {
req.lang_pack = ""; req.lang_pack = "";
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> { ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
if (response != null) { if (response != null) {
AndroidUtilities.runOnUIThread(() -> saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount)); saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount);
} }
}, ConnectionsManager.RequestFlagWithoutLogin); }, ConnectionsManager.RequestFlagWithoutLogin);
} }
@ -1989,7 +2014,7 @@ public class LocaleController {
req.lang_code = localeInfo.getBaseLangCode(); req.lang_code = localeInfo.getBaseLangCode();
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (TLObject response, TLRPC.TL_error error) -> { ConnectionsManager.getInstance(currentAccount).sendRequest(req, (TLObject response, TLRPC.TL_error error) -> {
if (response != null) { if (response != null) {
AndroidUtilities.runOnUIThread(() -> saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount)); saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount);
} }
}, ConnectionsManager.RequestFlagWithoutLogin); }, ConnectionsManager.RequestFlagWithoutLogin);
} }
@ -2002,7 +2027,7 @@ public class LocaleController {
req.lang_pack = ""; req.lang_pack = "";
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> { ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
if (response != null) { if (response != null) {
AndroidUtilities.runOnUIThread(() -> saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount)); saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount);
} }
}, ConnectionsManager.RequestFlagWithoutLogin); }, ConnectionsManager.RequestFlagWithoutLogin);
} else { } else {
@ -2013,13 +2038,54 @@ public class LocaleController {
req.lang_code = localeInfo.getLangCode(); req.lang_code = localeInfo.getLangCode();
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (TLObject response, TLRPC.TL_error error) -> { ConnectionsManager.getInstance(currentAccount).sendRequest(req, (TLObject response, TLRPC.TL_error error) -> {
if (response != null) { if (response != null) {
AndroidUtilities.runOnUIThread(() -> saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount)); saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount);
} }
}, ConnectionsManager.RequestFlagWithoutLogin); }, ConnectionsManager.RequestFlagWithoutLogin);
} }
} }
} }
private static String[] prebuilt;
private void loadPrebuiltLocaleFile(LocaleInfo localeInfo) {
if (prebuilt == null) {
try {
AssetManager assets = ApplicationLoader.applicationContext.getAssets();
prebuilt = assets.list("languages");
} catch (IOException e) {
FileLog.e(e);
return;
}
}
if (prebuilt == null) {
FileLog.w("empty prebuilt languages list");
return;
}
File pathToFile = localeInfo.getPathToFile();
File pathToBaseFile = localeInfo.getPathToBaseFile();
if ((pathToFile != null && !pathToFile.isFile()) || (pathToBaseFile != null && !pathToBaseFile.isFile())) {
try {
if (pathToBaseFile != null && !pathToBaseFile.isFile() && ArrayUtils.contains(prebuilt, pathToBaseFile.getName())) {
FileUtil.saveAsset("languages/" + pathToBaseFile.getName(), pathToBaseFile);
}
if (pathToFile != null && !pathToFile.isFile() && ArrayUtils.contains(prebuilt, pathToFile.getName())) {
FileUtil.saveAsset("languages/" + pathToFile.getName(), pathToFile);
}
} catch (Exception e) {
FileLog.e(e);
}
}
}
public String getTranslitString(String src) { public String getTranslitString(String src) {
return getTranslitString(src, true, false); return getTranslitString(src, true, false);
} }

View File

@ -1794,7 +1794,7 @@ public class MediaDataController extends BaseController {
} }
/** @param toggle 0 - remove, 1 - archive, 2 - add */ /** @param toggle 0 - remove, 1 - archive, 2 - add */
public void toggleStickerSet(final Context context, final TLObject stickerSetObject, final int toggle, final BaseFragment baseFragment, final boolean showSettings, boolean showTooltip) { public void toggleStickerSet(Context context, final TLObject stickerSetObject, final int toggle, final BaseFragment baseFragment, final boolean showSettings, boolean showTooltip) {
final TLRPC.StickerSet stickerSet; final TLRPC.StickerSet stickerSet;
final TLRPC.TL_messages_stickerSet messages_stickerSet; final TLRPC.TL_messages_stickerSet messages_stickerSet;
@ -1840,6 +1840,8 @@ public class MediaDataController extends BaseController {
putStickersToCache(type, stickerSets[type], loadDate[type], loadHash[type]); putStickersToCache(type, stickerSets[type], loadDate[type], loadHash[type]);
getNotificationCenter().postNotificationName(NotificationCenter.stickersDidLoad, type); getNotificationCenter().postNotificationName(NotificationCenter.stickersDidLoad, type);
if (context == null && baseFragment != null) context = baseFragment.getParentActivity();
if (toggle == 2) { if (toggle == 2) {
if (!cancelRemovingStickerSet(stickerSet.id)) { if (!cancelRemovingStickerSet(stickerSet.id)) {
toggleStickerSetInternal(context, toggle, baseFragment, showSettings, stickerSetObject, stickerSet, type, showTooltip); toggleStickerSetInternal(context, toggle, baseFragment, showSettings, stickerSetObject, stickerSet, type, showTooltip);
@ -1849,6 +1851,7 @@ public class MediaDataController extends BaseController {
} else { } else {
final StickerSetBulletinLayout bulletinLayout = new StickerSetBulletinLayout(context, stickerSetObject, toggle); final StickerSetBulletinLayout bulletinLayout = new StickerSetBulletinLayout(context, stickerSetObject, toggle);
final int finalCurrentIndex = currentIndex; final int finalCurrentIndex = currentIndex;
Context finalContext = context;
final Bulletin.UndoButton undoButton = new Bulletin.UndoButton(context).setUndoAction(() -> { final Bulletin.UndoButton undoButton = new Bulletin.UndoButton(context).setUndoAction(() -> {
stickerSet.archived = false; stickerSet.archived = false;
@ -1861,7 +1864,7 @@ public class MediaDataController extends BaseController {
loadHash[type] = calcStickersHash(stickerSets[type]); loadHash[type] = calcStickersHash(stickerSets[type]);
putStickersToCache(type, stickerSets[type], loadDate[type], loadHash[type]); putStickersToCache(type, stickerSets[type], loadDate[type], loadHash[type]);
getNotificationCenter().postNotificationName(NotificationCenter.stickersDidLoad, type); getNotificationCenter().postNotificationName(NotificationCenter.stickersDidLoad, type);
}).setDelayedAction(() -> toggleStickerSetInternal(context, toggle, baseFragment, showSettings, stickerSetObject, stickerSet, type, false)); }).setDelayedAction(() -> toggleStickerSetInternal(finalContext, toggle, baseFragment, showSettings, stickerSetObject, stickerSet, type, false));
bulletinLayout.setButton(undoButton); bulletinLayout.setButton(undoButton);
removingStickerSetsUndos.put(stickerSet.id, undoButton::undo); removingStickerSetsUndos.put(stickerSet.id, undoButton::undo);
Bulletin.make(baseFragment, bulletinLayout, Bulletin.DURATION_LONG).show(); Bulletin.make(baseFragment, bulletinLayout, Bulletin.DURATION_LONG).show();
@ -4610,7 +4613,7 @@ public class MediaDataController extends BaseController {
if (draft == null || draft instanceof TLRPC.TL_draftMessageEmpty) { if (draft == null || draft instanceof TLRPC.TL_draftMessageEmpty) {
drafts.remove(did); drafts.remove(did);
draftMessages.remove(did); draftMessages.remove(did);
preferences.edit().remove("" + did).remove("r_" + did).commit(); preferences.edit().remove("" + did).remove("r_" + did).apply();
messagesController.removeDraftDialogIfNeed(did); messagesController.removeDraftDialogIfNeed(did);
} else { } else {
drafts.put(did, draft); drafts.put(did, draft);
@ -4634,7 +4637,7 @@ public class MediaDataController extends BaseController {
editor.putString("r_" + did, Utilities.bytesToHex(serializedData.toByteArray())); editor.putString("r_" + did, Utilities.bytesToHex(serializedData.toByteArray()));
serializedData.cleanup(); serializedData.cleanup();
} }
editor.commit(); editor.apply();
if (fromServer) { if (fromServer) {
if (draft.reply_to_msg_id != 0 && replyToMessage == null) { if (draft.reply_to_msg_id != 0 && replyToMessage == null) {
int lower_id = (int) did; int lower_id = (int) did;
@ -4717,7 +4720,7 @@ public class MediaDataController extends BaseController {
draftMessages.put(did, message); draftMessages.put(did, message);
SerializedData serializedData = new SerializedData(message.getObjectSize()); SerializedData serializedData = new SerializedData(message.getObjectSize());
message.serializeToStream(serializedData); message.serializeToStream(serializedData);
preferences.edit().putString("r_" + did, Utilities.bytesToHex(serializedData.toByteArray())).commit(); preferences.edit().putString("r_" + did, Utilities.bytesToHex(serializedData.toByteArray())).apply();
getNotificationCenter().postNotificationName(NotificationCenter.newDraftReceived, did); getNotificationCenter().postNotificationName(NotificationCenter.newDraftReceived, did);
serializedData.cleanup(); serializedData.cleanup();
} }
@ -4728,7 +4731,7 @@ public class MediaDataController extends BaseController {
drafts.clear(); drafts.clear();
draftMessages.clear(); draftMessages.clear();
draftsFolderIds.clear(); draftsFolderIds.clear();
preferences.edit().clear().commit(); preferences.edit().clear().apply();
if (notify) { if (notify) {
getMessagesController().sortDialogs(null); getMessagesController().sortDialogs(null);
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload); getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
@ -4743,7 +4746,7 @@ public class MediaDataController extends BaseController {
if (!replyOnly) { if (!replyOnly) {
drafts.remove(did); drafts.remove(did);
draftMessages.remove(did); draftMessages.remove(did);
preferences.edit().remove("" + did).remove("r_" + did).commit(); preferences.edit().remove("" + did).remove("r_" + did).apply();
getMessagesController().sortDialogs(null); getMessagesController().sortDialogs(null);
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload); getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
} else if (draftMessage.reply_to_msg_id != 0) { } else if (draftMessage.reply_to_msg_id != 0) {

View File

@ -11,14 +11,10 @@ package org.telegram.messenger;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.os.Build;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream; import tw.nekomimi.nekogram.utils.FileUtil;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class NativeLoader { public class NativeLoader {
@ -34,7 +30,7 @@ public class NativeLoader {
File f = null; File f = null;
if (context != null) { if (context != null) {
try { try {
f = new File((String)ApplicationInfo.class.getField("nativeLibraryDir").get(context.getApplicationInfo())); f = new File((String) ApplicationInfo.class.getField("nativeLibraryDir").get(context.getApplicationInfo()));
} catch (Throwable th) { } catch (Throwable th) {
th.printStackTrace(); th.printStackTrace();
} }
@ -48,67 +44,6 @@ public class NativeLoader {
return null; return null;
} }
@SuppressLint({"UnsafeDynamicallyLoadedCode", "SetWorldReadable"})
private static boolean loadFromZip(Context context, File destDir, File destLocalFile, String folder) {
try {
for (File file : destDir.listFiles()) {
file.delete();
}
} catch (Exception e) {
FileLog.e(e);
}
ZipFile zipFile = null;
InputStream stream = null;
try {
zipFile = new ZipFile(context.getApplicationInfo().sourceDir);
ZipEntry entry = zipFile.getEntry("lib/" + folder + "/" + LIB_SO_NAME);
if (entry == null) {
throw new Exception("Unable to find file in apk:" + "lib/" + folder + "/" + LIB_NAME);
}
stream = zipFile.getInputStream(entry);
OutputStream out = new FileOutputStream(destLocalFile);
byte[] buf = new byte[4096];
int len;
while ((len = stream.read(buf)) > 0) {
Thread.yield();
out.write(buf, 0, len);
}
out.close();
destLocalFile.setReadable(true, false);
destLocalFile.setExecutable(true, false);
destLocalFile.setWritable(true);
try {
System.load(destLocalFile.getAbsolutePath());
nativeLoaded = true;
} catch (Error e) {
FileLog.e(e);
}
return true;
} catch (Exception e) {
FileLog.e(e);
} finally {
if (stream != null) {
try {
stream.close();
} catch (Exception e) {
FileLog.e(e);
}
}
if (zipFile != null) {
try {
zipFile.close();
} catch (Exception e) {
FileLog.e(e);
}
}
}
return false;
}
@SuppressLint("UnsafeDynamicallyLoadedCode") @SuppressLint("UnsafeDynamicallyLoadedCode")
public static synchronized void initNativeLibs(Context context) { public static synchronized void initNativeLibs(Context context) {
if (nativeLoaded) { if (nativeLoaded) {
@ -116,93 +51,19 @@ public class NativeLoader {
} }
try { try {
try { System.loadLibrary(LIB_NAME);
System.loadLibrary(LIB_NAME); nativeLoaded = true;
nativeLoaded = true;
if (BuildVars.LOGS_ENABLED) {
FileLog.d("loaded normal lib");
}
return;
} catch (Error e) {
FileLog.e(e);
}
String folder;
try {
String str = Build.CPU_ABI;
if (Build.CPU_ABI.equalsIgnoreCase("x86_64")) {
folder = "x86_64";
} else if (Build.CPU_ABI.equalsIgnoreCase("arm64-v8a")) {
folder = "arm64-v8a";
} else if (Build.CPU_ABI.equalsIgnoreCase("armeabi-v7a")) {
folder = "armeabi-v7a";
} else if (Build.CPU_ABI.equalsIgnoreCase("armeabi")) {
folder = "armeabi";
} else if (Build.CPU_ABI.equalsIgnoreCase("x86")) {
folder = "x86";
} else if (Build.CPU_ABI.equalsIgnoreCase("mips")) {
folder = "mips";
} else {
folder = "armeabi";
if (BuildVars.LOGS_ENABLED) {
FileLog.e("Unsupported arch: " + Build.CPU_ABI);
}
}
} catch (Exception e) {
FileLog.e(e);
folder = "armeabi";
}
String javaArch = System.getProperty("os.arch");
if (javaArch != null && javaArch.contains("686")) {
folder = "x86";
}
/*File destFile = getNativeLibraryDir(context);
if (destFile != null) {
destFile = new File(destFile, LIB_SO_NAME);
if (destFile.exists()) {
try {
System.loadLibrary(LIB_NAME);
nativeLoaded = true;
return;
} catch (Error e) {
FileLog.e(e);
}
}
}*/
File destDir = new File(context.getFilesDir(), "lib");
destDir.mkdirs();
File destLocalFile = new File(destDir, LOCALE_LIB_SO_NAME);
if (destLocalFile.exists()) {
try {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("Load local lib");
}
System.load(destLocalFile.getAbsolutePath());
nativeLoaded = true;
return;
} catch (Error e) {
FileLog.e(e);
}
destLocalFile.delete();
}
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.e("Library not found, arch = " + folder); FileLog.d("loaded normal lib");
} }
return;
if (loadFromZip(context, destDir, destLocalFile, folder)) { } catch (Error e) {
return; FileLog.e(e);
}
} catch (Throwable e) {
e.printStackTrace();
} }
try { try {
System.loadLibrary(LIB_NAME); System.loadLibrary(FileUtil.extLib(LIB_NAME).getPath());
FileLog.d("loaded extracted lib");
nativeLoaded = true; nativeLoaded = true;
} catch (Error e) { } catch (Error e) {
FileLog.e(e); FileLog.e(e);

View File

@ -18,37 +18,36 @@ import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Build; import android.os.Build;
import android.os.IBinder; import android.os.IBinder;
import android.provider.Settings;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import org.telegram.ui.LaunchActivity;
import tw.nekomimi.nekogram.NekoConfig;
public class NotificationsService extends Service { public class NotificationsService extends Service {
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
ApplicationLoader.postInitApplication(); ApplicationLoader.postInitApplication();
if (NekoConfig.residentNotification) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent activityIntent = new Intent(this, LaunchActivity.class); String CHANNEL_ID = "push_service_channel";
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, activityIntent, 0); NotificationChannel channel = new NotificationChannel(CHANNEL_ID, LocaleController.getString("PlaceHolder", R.string.PlaceHolder), NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("NekoX - System");
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) { channel.enableLights(false);
NotificationChannel channel = new NotificationChannel("nekogram", LocaleController.getString("NekogramRunning", R.string.NekogramRunning), NotificationManager.IMPORTANCE_DEFAULT); channel.enableVibration(false);
channel.enableLights(false); channel.setSound(null, null);
channel.enableVibration(false); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
channel.setSound(null, null); if (notificationManager != null) {
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.createNotificationChannel(channel);
if (notificationManager != null) {
notificationManager.createNotificationChannel(channel);
}
} }
Notification notification = new NotificationCompat.Builder(this, "nekogram") Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
intent.putExtra(Settings.EXTRA_CHANNEL_ID, CHANNEL_ID);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.notification) .setSmallIcon(R.drawable.notification)
.setColor(0xff11acfa) .setColor(0xff11acfa)
.setContentTitle(LocaleController.getString("NekogramRunning", R.string.NekogramRunning)) .setContentTitle(LocaleController.getString("NekogramRunning", R.string.NekogramRunning))
.setContentText(LocaleController.getString("TapToDisable",R.string.TapToDisable))
.setContentIntent(pendingIntent) .setContentIntent(pendingIntent)
.setCategory(NotificationCompat.CATEGORY_STATUS) .setCategory(NotificationCompat.CATEGORY_STATUS)
.build(); .build();
@ -71,7 +70,12 @@ public class NotificationsService extends Service {
SharedPreferences preferences = MessagesController.getGlobalNotificationsSettings(); SharedPreferences preferences = MessagesController.getGlobalNotificationsSettings();
if (preferences.getBoolean("pushService", true)) { if (preferences.getBoolean("pushService", true)) {
Intent intent = new Intent("org.telegram.start"); Intent intent = new Intent("org.telegram.start");
sendBroadcast(intent); try {
sendBroadcast(intent);
} catch (Exception ex) {
// 辣鷄miui 就你事最多.jpg
}
} }
} }
} }

View File

@ -30,6 +30,8 @@ import java.util.Collections;
import java.util.Locale; import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import tw.nekomimi.nekogram.utils.AlertUtil;
public class SecretChatHelper extends BaseController { public class SecretChatHelper extends BaseController {
public static class TL_decryptedMessageHolder extends TLObject { public static class TL_decryptedMessageHolder extends TLObject {
@ -1950,25 +1952,12 @@ public class SecretChatHelper extends BaseController {
}); });
} else { } else {
delayedEncryptedChatUpdates.clear(); delayedEncryptedChatUpdates.clear();
AndroidUtilities.runOnUIThread(() -> { AlertUtil.showToast(error);
if (!((Activity) context).isFinishing()) {
startingSecretChat = false;
try {
progressDialog.dismiss();
} catch (Exception e) {
FileLog.e(e);
}
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
builder.setMessage(LocaleController.getString("CreateEncryptedChatError", R.string.CreateEncryptedChatError));
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null);
builder.show().setCanceledOnTouchOutside(true);
}
});
} }
}, ConnectionsManager.RequestFlagFailOnServerErrors); }, ConnectionsManager.RequestFlagFailOnServerErrors);
} else { } else {
delayedEncryptedChatUpdates.clear(); delayedEncryptedChatUpdates.clear();
AlertUtil.showToast(error);
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
startingSecretChat = false; startingSecretChat = false;
if (!((Activity) context).isFinishing()) { if (!((Activity) context).isFinishing()) {

View File

@ -36,6 +36,8 @@ import android.widget.Toast;
import androidx.annotation.UiThread; import androidx.annotation.UiThread;
import androidx.core.view.inputmethod.InputContentInfoCompat; import androidx.core.view.inputmethod.InputContentInfoCompat;
import com.google.gson.Gson;
import org.telegram.messenger.audioinfo.AudioInfo; import org.telegram.messenger.audioinfo.AudioInfo;
import org.telegram.messenger.support.SparseLongArray; import org.telegram.messenger.support.SparseLongArray;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
@ -51,7 +53,6 @@ import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.AlertsCreator; import org.telegram.ui.Components.AlertsCreator;
import org.telegram.ui.Components.AnimatedFileDrawable; import org.telegram.ui.Components.AnimatedFileDrawable;
import org.telegram.ui.Components.Point; import org.telegram.ui.Components.Point;
import org.telegram.ui.PaymentFormActivity;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -1842,7 +1843,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (!messageObject.isGif() && (videoEditedInfo == null || !videoEditedInfo.muted)) { if (!messageObject.isGif() && (videoEditedInfo == null || !videoEditedInfo.muted)) {
uploadedDocument.nosound_video = true; uploadedDocument.nosound_video = true;
if (BuildVars.DEBUG_VERSION) { if (BuildVars.DEBUG_VERSION) {
FileLog.d("nosound_video = true"); FileLog.e("nosound_video = true");
} }
} }
if (document.access_hash == 0) { if (document.access_hash == 0) {
@ -2193,14 +2194,6 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
TLRPC.TL_urlAuthResultDefault res = (TLRPC.TL_urlAuthResultDefault) response; TLRPC.TL_urlAuthResultDefault res = (TLRPC.TL_urlAuthResultDefault) response;
AlertsCreator.showOpenUrlAlert(parentFragment, button.url, false, true); AlertsCreator.showOpenUrlAlert(parentFragment, button.url, false, true);
} }
} else if (button instanceof TLRPC.TL_keyboardButtonBuy) {
if (response instanceof TLRPC.TL_payments_paymentForm) {
final TLRPC.TL_payments_paymentForm form = (TLRPC.TL_payments_paymentForm) response;
getMessagesController().putUsers(form.users, false);
parentFragment.presentFragment(new PaymentFormActivity(form, messageObject));
} else if (response instanceof TLRPC.TL_payments_paymentReceipt) {
parentFragment.presentFragment(new PaymentFormActivity(messageObject, (TLRPC.TL_payments_paymentReceipt) response));
}
} else { } else {
TLRPC.TL_messages_botCallbackAnswer res = (TLRPC.TL_messages_botCallbackAnswer) response; TLRPC.TL_messages_botCallbackAnswer res = (TLRPC.TL_messages_botCallbackAnswer) response;
if (!cacheFinal && res.cache_time != 0) { if (!cacheFinal && res.cache_time != 0) {
@ -4912,12 +4905,6 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if ((path == null || path.length() == 0) && uri == null) { if ((path == null || path.length() == 0) && uri == null) {
return false; return false;
} }
if (uri != null && AndroidUtilities.isInternalUri(uri)) {
return false;
}
if (path != null && AndroidUtilities.isInternalUri(Uri.fromFile(new File(path)))) {
return false;
}
MimeTypeMap myMime = MimeTypeMap.getSingleton(); MimeTypeMap myMime = MimeTypeMap.getSingleton();
TLRPC.TL_documentAttributeAudio attributeAudio = null; TLRPC.TL_documentAttributeAudio attributeAudio = null;
String extension = null; String extension = null;
@ -6049,7 +6036,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (forceDocument) { if (forceDocument) {
videoEditedInfo = null; videoEditedInfo = null;
} else { } else {
videoEditedInfo = info.videoEditedInfo != null ? info.videoEditedInfo : createCompressionSettings(info.path); videoEditedInfo = info.videoEditedInfo;
} }
if (!forceDocument && (videoEditedInfo != null || info.path.endsWith("mp4"))) { if (!forceDocument && (videoEditedInfo != null || info.path.endsWith("mp4"))) {

View File

@ -2,7 +2,6 @@ package org.telegram.messenger.voip;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.os.Build;
import org.telegram.messenger.BuildVars; import org.telegram.messenger.BuildVars;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
@ -15,6 +14,8 @@ import java.util.Locale;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import tw.nekomimi.nekogram.utils.FileUtil;
public final class TgVoipNativeLoader { public final class TgVoipNativeLoader {
private final static int LIB_REVISION = 1; private final static int LIB_REVISION = 1;
@ -37,149 +38,25 @@ public final class TgVoipNativeLoader {
@SuppressLint("UnsafeDynamicallyLoadedCode") @SuppressLint("UnsafeDynamicallyLoadedCode")
private static boolean loadNativeLib(Context context, String libName) { private static boolean loadNativeLib(Context context, String libName) {
try {
try {
System.loadLibrary(libName);
if (BuildVars.LOGS_ENABLED) {
FileLog.d("loaded normal lib: " + libName);
}
return true;
} catch (Error e) {
FileLog.e(e);
}
String folder;
try {
String str = Build.CPU_ABI;
if (Build.CPU_ABI.equalsIgnoreCase("x86_64")) {
folder = "x86_64";
} else if (Build.CPU_ABI.equalsIgnoreCase("arm64-v8a")) {
folder = "arm64-v8a";
} else if (Build.CPU_ABI.equalsIgnoreCase("armeabi-v7a")) {
folder = "armeabi-v7a";
} else if (Build.CPU_ABI.equalsIgnoreCase("armeabi")) {
folder = "armeabi";
} else if (Build.CPU_ABI.equalsIgnoreCase("x86")) {
folder = "x86";
} else if (Build.CPU_ABI.equalsIgnoreCase("mips")) {
folder = "mips";
} else {
folder = "armeabi";
if (BuildVars.LOGS_ENABLED) {
FileLog.e("Unsupported arch: " + Build.CPU_ABI);
}
}
} catch (Exception e) {
FileLog.e(e);
folder = "armeabi";
}
String javaArch = System.getProperty("os.arch");
if (javaArch != null && javaArch.contains("686")) {
folder = "x86";
}
File destDir = new File(context.getFilesDir(), "lib");
destDir.mkdirs();
File destLocalFile = new File(destDir, "lib" + libName + "loc.so");
if (destLocalFile.exists()) {
try {
System.load(destLocalFile.getAbsolutePath());
if (BuildVars.LOGS_ENABLED) {
FileLog.d("loaded local lib: " + libName);
}
return true;
} catch (Error e) {
FileLog.e(e);
}
destLocalFile.delete();
}
if (BuildVars.LOGS_ENABLED) {
FileLog.e(String.format(Locale.US, "library %s not found, arch = %s", libName, folder));
}
if (loadFromZip(context, destDir, destLocalFile, folder, libName)) {
return true;
}
} catch (Throwable e) {
e.printStackTrace();
}
try { try {
System.loadLibrary(libName); System.loadLibrary(libName);
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("loaded lib: " + libName); FileLog.d("loaded normal lib: " + libName);
} }
return true; return true;
} catch (Error e) { } catch (Error e) {
FileLog.e(e); FileLog.e(e);
} }
return false;
}
@SuppressLint({"UnsafeDynamicallyLoadedCode", "SetWorldReadable"})
private static boolean loadFromZip(Context context, File destDir, File destLocalFile, String folder, String libName) {
try { try {
for (File file : destDir.listFiles()) { System.load(FileUtil.extLib(libName).getPath());
file.delete(); FileLog.d("loaded extracted lib");
} nativeLoaded = true;
} catch (Exception e) { } catch (Error e) {
FileLog.e(e); FileLog.e(e);
} }
ZipFile zipFile = null;
InputStream stream = null;
try {
zipFile = new ZipFile(context.getApplicationInfo().sourceDir);
ZipEntry entry = zipFile.getEntry("lib/" + folder + "/lib" + libName + ".so");
if (entry == null) {
throw new Exception("Unable to find file in apk:" + "lib/" + folder + "/" + libName);
}
stream = zipFile.getInputStream(entry);
OutputStream out = new FileOutputStream(destLocalFile);
byte[] buf = new byte[4096];
int len;
while ((len = stream.read(buf)) > 0) {
Thread.yield();
out.write(buf, 0, len);
}
out.close();
destLocalFile.setReadable(true, false);
destLocalFile.setExecutable(true, false);
destLocalFile.setWritable(true);
try {
System.load(destLocalFile.getAbsolutePath());
if (BuildVars.LOGS_ENABLED) {
FileLog.d("loaded lib from zip: " + libName);
}
return true;
} catch (Error e) {
FileLog.e(e);
}
} catch (Exception e) {
FileLog.e(e);
} finally {
if (stream != null) {
try {
stream.close();
} catch (Exception e) {
FileLog.e(e);
}
}
if (zipFile != null) {
try {
zipFile.close();
} catch (Exception e) {
FileLog.e(e);
}
}
}
return false; return false;
} }
} }

View File

@ -365,7 +365,9 @@ public abstract class VoIPBaseService extends Service implements SensorEventList
sheet.show(); sheet.show();
ViewGroup container=sheet.getSheetContainer(); ViewGroup container=sheet.getSheetContainer();
for(int i=0;i<container.getChildCount();i++){ for(int i=0;i<container.getChildCount();i++){
BottomSheet.BottomSheetCell cell=(BottomSheet.BottomSheetCell) container.getChildAt(i); View child = container.getChildAt(i);
if (!(child instanceof BottomSheet.BottomSheetCell)) continue;
BottomSheet.BottomSheetCell cell=(BottomSheet.BottomSheetCell) child;
cell.setTextColor(0xFFFFFFFF); cell.setTextColor(0xFFFFFFFF);
} }
return; return;
@ -1414,7 +1416,7 @@ public abstract class VoIPBaseService extends Service implements SensorEventList
PhoneAccountHandle handle=new PhoneAccountHandle(new ComponentName(this, TelegramConnectionService.class), ""+self.id); PhoneAccountHandle handle=new PhoneAccountHandle(new ComponentName(this, TelegramConnectionService.class), ""+self.id);
PhoneAccount account=new PhoneAccount.Builder(handle, ContactsController.formatName(self.first_name, self.last_name)) PhoneAccount account=new PhoneAccount.Builder(handle, ContactsController.formatName(self.first_name, self.last_name))
.setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED) .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
.setIcon(Icon.createWithResource(this, R.mipmap.ic_launcher)) .setIcon(Icon.createWithResource(this, R.drawable.ic_launcher_foreground))
.setHighlightColor(0xff2ca5e0) .setHighlightColor(0xff2ca5e0)
.addSupportedUriScheme("sip") .addSupportedUriScheme("sip")
.build(); .build();

View File

@ -1,7 +1,6 @@
package org.telegram.tgnet; package org.telegram.tgnet;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.os.AsyncTask; import android.os.AsyncTask;
@ -10,14 +9,14 @@ import android.os.SystemClock;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Base64; import android.util.Base64;
import org.json.JSONArray; import com.v2ray.ang.util.Utils;
import org.json.JSONObject;
import org.telegram.messenger.AccountInstance; import org.telegram.messenger.AccountInstance;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BaseController; import org.telegram.messenger.BaseController;
import org.telegram.messenger.BuildConfig; import org.telegram.messenger.BuildConfig;
import org.telegram.messenger.BuildVars; import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.EmuDetector; import org.telegram.messenger.EmuDetector;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
import org.telegram.messenger.KeepAliveJob; import org.telegram.messenger.KeepAliveJob;
@ -29,18 +28,12 @@ import org.telegram.messenger.StatsController;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import tw.nekomimi.nekogram.NekoConfig;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.InputStream;
import java.net.Inet4Address; import java.net.Inet4Address;
import java.net.Inet6Address; import java.net.Inet6Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InterfaceAddress; import java.net.InterfaceAddress;
import java.net.NetworkInterface; import java.net.NetworkInterface;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
@ -55,6 +48,12 @@ import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import tw.nekomimi.nekogram.NekoConfig;
import tw.nekomimi.nekogram.utils.DnsFactory;
import tw.nekomimi.nekogram.utils.UIUtil;
//import org.telegram.messenger.BuildConfig;
public class ConnectionsManager extends BaseController { public class ConnectionsManager extends BaseController {
public final static int ConnectionTypeGeneric = 1; public final static int ConnectionTypeGeneric = 1;
@ -120,24 +119,26 @@ public class ConnectionsManager extends BaseController {
private static class ResolvedDomain { private static class ResolvedDomain {
public ArrayList<String> addresses; public InetAddress[] addresses;
long ttl; long ttl;
public ResolvedDomain(ArrayList<String> a, long t) { public ResolvedDomain(InetAddress[] a, long t) {
addresses = a; addresses = a;
ttl = t; ttl = t;
} }
public String getAddress() { public String getAddress() {
return addresses.get(Utilities.random.nextInt(addresses.size())); if (addresses.length == 0) return "";
return addresses[Utilities.random.nextInt(addresses.length)].getHostAddress();
} }
} }
private static HashMap<String, ResolvedDomain> dnsCache = new HashMap<>(); private static HashMap<String, ResolvedDomain> dnsCache = new HashMap<>();
private static int lastClassGuid = 1; private static int lastClassGuid = 1;
private static volatile ConnectionsManager[] Instance = new ConnectionsManager[UserConfig.MAX_ACCOUNT_COUNT]; private static volatile ConnectionsManager[] Instance = new ConnectionsManager[UserConfig.MAX_ACCOUNT_COUNT];
public static ConnectionsManager getInstance(int num) { public static ConnectionsManager getInstance(int num) {
ConnectionsManager localInstance = Instance[num]; ConnectionsManager localInstance = Instance[num];
if (localInstance == null) { if (localInstance == null) {
@ -172,11 +173,6 @@ public class ConnectionsManager extends BaseController {
deviceModel = Build.MANUFACTURER + Build.MODEL; deviceModel = Build.MANUFACTURER + Build.MODEL;
PackageInfo pInfo = ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0); PackageInfo pInfo = ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0);
appVersion = pInfo.versionName + " (" + pInfo.versionCode + ")"; appVersion = pInfo.versionName + " (" + pInfo.versionCode + ")";
if (BuildVars.DEBUG_PRIVATE_VERSION) {
appVersion += " pbeta";
} else if (BuildVars.DEBUG_VERSION) {
appVersion += " beta";
}
systemVersion = "SDK " + Build.VERSION.SDK_INT; systemVersion = "SDK " + Build.VERSION.SDK_INT;
} catch (Exception e) { } catch (Exception e) {
systemLangCode = "en"; systemLangCode = "en";
@ -256,9 +252,9 @@ public class ConnectionsManager extends BaseController {
public int sendRequest(final TLObject object, final RequestDelegate onComplete, final QuickAckDelegate onQuickAck, final WriteToSocketDelegate onWriteToSocket, final int flags, final int datacenterId, final int connetionType, final boolean immediate) { public int sendRequest(final TLObject object, final RequestDelegate onComplete, final QuickAckDelegate onQuickAck, final WriteToSocketDelegate onWriteToSocket, final int flags, final int datacenterId, final int connetionType, final boolean immediate) {
final int requestToken = lastRequestToken.getAndIncrement(); final int requestToken = lastRequestToken.getAndIncrement();
Utilities.stageQueue.postRunnable(() -> { UIUtil.runOnIoDispatcher(() -> {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("send request " + object + " with token = " + requestToken); FileLog.d("send request " + object.getClass().getSimpleName() + " with token = " + requestToken);
} }
try { try {
NativeByteBuffer buffer = new NativeByteBuffer(object.getObjectSize()); NativeByteBuffer buffer = new NativeByteBuffer(object.getObjectSize());
@ -278,14 +274,14 @@ public class ConnectionsManager extends BaseController {
error.code = errorCode; error.code = errorCode;
error.text = errorText; error.text = errorText;
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.e(object + " got error " + error.code + " " + error.text); FileLog.e(object.getClass().getSimpleName() + " got error " + error.code + " " + error.text + " with token = " + requestToken);
} }
} }
if (resp != null) { if (resp != null) {
resp.networkType = networkType; resp.networkType = networkType;
} }
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("java received " + resp + " error = " + error); FileLog.d("java received " + resp + " error = " + (error == null ? "null" : (error.code + ": " + error.text)));
} }
final TLObject finalResponse = resp; final TLObject finalResponse = resp;
final TLRPC.TL_error finalError = error; final TLRPC.TL_error finalError = error;
@ -347,18 +343,16 @@ public class ConnectionsManager extends BaseController {
} }
public void init(int version, int layer, int apiId, String deviceModel, String systemVersion, String appVersion, String langCode, String systemLangCode, String configPath, String logPath, String regId, String cFingerprint, int timezoneOffset, int userId, boolean enablePushConnection) { public void init(int version, int layer, int apiId, String deviceModel, String systemVersion, String appVersion, String langCode, String systemLangCode, String configPath, String logPath, String regId, String cFingerprint, int timezoneOffset, int userId, boolean enablePushConnection) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
String proxyAddress = preferences.getString("proxy_ip", ""); if (SharedConfig.proxyEnabled && SharedConfig.currentProxy != null) {
String proxyUsername = preferences.getString("proxy_user", "");
String proxyPassword = preferences.getString("proxy_pass", ""); native_setProxySettings(currentAccount, SharedConfig.currentProxy.address, SharedConfig.currentProxy.port, SharedConfig.currentProxy.username, SharedConfig.currentProxy.password, SharedConfig.currentProxy.secret);
String proxySecret = preferences.getString("proxy_secret", "");
int proxyPort = preferences.getInt("proxy_port", 1080);
if (preferences.getBoolean("proxy_enabled", false) && !TextUtils.isEmpty(proxyAddress)) {
native_setProxySettings(currentAccount, proxyAddress, proxyPort, proxyUsername, proxyPassword, proxySecret);
} }
native_init(currentAccount, version, layer, apiId, deviceModel, systemVersion, appVersion, langCode, systemLangCode, configPath, logPath, regId, cFingerprint, timezoneOffset, userId, enablePushConnection, ApplicationLoader.isNetworkOnline(), ApplicationLoader.getCurrentNetworkType()); native_init(currentAccount, version, layer, apiId, deviceModel, systemVersion, appVersion, langCode, systemLangCode, configPath, logPath, regId, cFingerprint, timezoneOffset, userId, enablePushConnection, ApplicationLoader.isNetworkOnline(), ApplicationLoader.getCurrentNetworkType());
checkConnection(); checkConnection();
} }
public static void setLangCode(String langCode) { public static void setLangCode(String langCode) {
@ -387,7 +381,7 @@ public class ConnectionsManager extends BaseController {
public void switchBackend() { public void switchBackend() {
SharedPreferences preferences = MessagesController.getGlobalMainSettings(); SharedPreferences preferences = MessagesController.getGlobalMainSettings();
preferences.edit().remove("language_showed2").commit(); preferences.edit().remove("language_showed2").apply();
native_switchBackend(currentAccount); native_switchBackend(currentAccount);
} }
@ -534,54 +528,36 @@ public class ConnectionsManager extends BaseController {
public static void onRequestNewServerIpAndPort(final int second, final int currentAccount) { public static void onRequestNewServerIpAndPort(final int second, final int currentAccount) {
Utilities.stageQueue.postRunnable(() -> { Utilities.stageQueue.postRunnable(() -> {
if (currentTask != null || second == 0 && Math.abs(lastDnsRequestTime - System.currentTimeMillis()) < 10000 || !ApplicationLoader.isNetworkOnline()) { if (currentTask != null || second == 0 && Math.abs(lastDnsRequestTime - System.currentTimeMillis()) < 10000 || !ApplicationLoader.isNetworkOnline()) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("don't start task, current task = " + currentTask + " next task = " + second + " time diff = " + Math.abs(lastDnsRequestTime - System.currentTimeMillis()) + " network = " + ApplicationLoader.isNetworkOnline()); FileLog.d("don't start task, current task = " + currentTask + " next task = " + second + " time diff = " + Math.abs(lastDnsRequestTime - System.currentTimeMillis()) + " network = " + ApplicationLoader.isNetworkOnline());
} }
return; return;
} }
lastDnsRequestTime = System.currentTimeMillis(); lastDnsRequestTime = System.currentTimeMillis();
if (second == 3) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("start mozilla txt task"); FileLog.d("start dns txt task");
}
MozillaDnsLoadTask task = new MozillaDnsLoadTask(currentAccount);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null, null, null);
currentTask = task;
} else if (second == 2) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("start google txt task");
}
GoogleDnsLoadTask task = new GoogleDnsLoadTask(currentAccount);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null, null, null);
currentTask = task;
} else if (second == 1) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("start dns txt task");
}
DnsTxtLoadTask task = new DnsTxtLoadTask(currentAccount);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null, null, null);
currentTask = task;
} else {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("start firebase task");
}
FirebaseTask task = new FirebaseTask(currentAccount);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null, null, null);
currentTask = task;
} }
DnsTxtLoadTask task = new DnsTxtLoadTask(currentAccount);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null, null, null);
currentTask = task;
}); });
} }
public static void onProxyError() { public static void onProxyError() {
AndroidUtilities.runOnUIThread(() -> NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.needShowAlert, 3)); NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.needShowAlert, 3);
} }
public static void getHostByName(String hostName, long address) { public static void getHostByName(String hostName, long address) {
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
ResolvedDomain resolvedDomain = dnsCache.get(hostName); ResolvedDomain resolvedDomain = dnsCache.get(hostName);
if (resolvedDomain != null && SystemClock.elapsedRealtime() - resolvedDomain.ttl < 5 * 60 * 1000) { if (resolvedDomain != null && SystemClock.elapsedRealtime() - resolvedDomain.ttl < 5 * 60 * 1000) {
native_onHostNameResolved(hostName, address, resolvedDomain.getAddress()); String addr = resolvedDomain.getAddress();
native_onHostNameResolved(hostName, address, addr, Utils.isIpv6Address(addr));
} else { } else {
ResolveHostByNameTask task = resolvingHostnameTasks.get(hostName); ResolveHostByNameTask task = resolvingHostnameTasks.get(hostName);
if (task == null) { if (task == null) {
@ -590,7 +566,7 @@ public class ConnectionsManager extends BaseController {
task.executeOnExecutor(DNS_THREAD_POOL_EXECUTOR, null, null, null); task.executeOnExecutor(DNS_THREAD_POOL_EXECUTOR, null, null, null);
} catch (Throwable e) { } catch (Throwable e) {
FileLog.e(e); FileLog.e(e);
native_onHostNameResolved(hostName, address, ""); native_onHostNameResolved(hostName, address, "", false);
return; return;
} }
resolvingHostnameTasks.put(hostName, task); resolvingHostnameTasks.put(hostName, task);
@ -652,34 +628,65 @@ public class ConnectionsManager extends BaseController {
} }
public static native void native_switchBackend(int currentAccount); public static native void native_switchBackend(int currentAccount);
public static native int native_isTestBackend(int currentAccount); public static native int native_isTestBackend(int currentAccount);
public static native void native_pauseNetwork(int currentAccount); public static native void native_pauseNetwork(int currentAccount);
public static native void native_setUseIpv6(int currentAccount, boolean value); public static native void native_setUseIpv6(int currentAccount, boolean value);
public static native void native_updateDcSettings(int currentAccount); public static native void native_updateDcSettings(int currentAccount);
public static native void native_setNetworkAvailable(int currentAccount, boolean value, int networkType, boolean slow); public static native void native_setNetworkAvailable(int currentAccount, boolean value, int networkType, boolean slow);
public static native void native_resumeNetwork(int currentAccount, boolean partial); public static native void native_resumeNetwork(int currentAccount, boolean partial);
public static native long native_getCurrentTimeMillis(int currentAccount); public static native long native_getCurrentTimeMillis(int currentAccount);
public static native int native_getCurrentTime(int currentAccount); public static native int native_getCurrentTime(int currentAccount);
public static native int native_getTimeDifference(int currentAccount); public static native int native_getTimeDifference(int currentAccount);
public static native void native_sendRequest(int currentAccount, long object, RequestDelegateInternal onComplete, QuickAckDelegate onQuickAck, WriteToSocketDelegate onWriteToSocket, int flags, int datacenterId, int connetionType, boolean immediate, int requestToken); public static native void native_sendRequest(int currentAccount, long object, RequestDelegateInternal onComplete, QuickAckDelegate onQuickAck, WriteToSocketDelegate onWriteToSocket, int flags, int datacenterId, int connetionType, boolean immediate, int requestToken);
public static native void native_cancelRequest(int currentAccount, int token, boolean notifyServer); public static native void native_cancelRequest(int currentAccount, int token, boolean notifyServer);
public static native void native_cleanUp(int currentAccount, boolean resetKeys); public static native void native_cleanUp(int currentAccount, boolean resetKeys);
public static native void native_cancelRequestsForGuid(int currentAccount, int guid); public static native void native_cancelRequestsForGuid(int currentAccount, int guid);
public static native void native_bindRequestToGuid(int currentAccount, int requestToken, int guid); public static native void native_bindRequestToGuid(int currentAccount, int requestToken, int guid);
public static native void native_applyDatacenterAddress(int currentAccount, int datacenterId, String ipAddress, int port); public static native void native_applyDatacenterAddress(int currentAccount, int datacenterId, String ipAddress, int port);
public static native void native_setDatacenterAddress(int currentAccount, int datacenterId, String ipv4Address,String ipv6Address, int port);
public static native void native_setDatacenterPublicKey(int currentAccount, int datacenterId, String publicKey, long fingerprint);
public static native void native_saveDatacenters(int currentAccount);
public static native void native_setLayer(int currentAccount,int layer);
public static native int native_getConnectionState(int currentAccount); public static native int native_getConnectionState(int currentAccount);
public static native void native_setUserId(int currentAccount, int id); public static native void native_setUserId(int currentAccount, int id);
public static native void native_init(int currentAccount, int version, int layer, int apiId, String deviceModel, String systemVersion, String appVersion, String langCode, String systemLangCode, String configPath, String logPath, String regId, String cFingerprint, int timezoneOffset, int userId, boolean enablePushConnection, boolean hasNetwork, int networkType); public static native void native_init(int currentAccount, int version, int layer, int apiId, String deviceModel, String systemVersion, String appVersion, String langCode, String systemLangCode, String configPath, String logPath, String regId, String cFingerprint, int timezoneOffset, int userId, boolean enablePushConnection, boolean hasNetwork, int networkType);
public static native void native_setProxySettings(int currentAccount, String address, int port, String username, String password, String secret); public static native void native_setProxySettings(int currentAccount, String address, int port, String username, String password, String secret);
public static native void native_setLangCode(int currentAccount, String langCode); public static native void native_setLangCode(int currentAccount, String langCode);
public static native void native_setRegId(int currentAccount, String regId); public static native void native_setRegId(int currentAccount, String regId);
public static native void native_setSystemLangCode(int currentAccount, String langCode); public static native void native_setSystemLangCode(int currentAccount, String langCode);
public static native void native_seSystemLangCode(int currentAccount, String langCode);
public static native void native_setJava(boolean useJavaByteBuffers); public static native void native_setJava(boolean useJavaByteBuffers);
public static native void native_setPushConnectionEnabled(int currentAccount, boolean value); public static native void native_setPushConnectionEnabled(int currentAccount, boolean value);
public static native void native_applyDnsConfig(int currentAccount, long address, String phone, int date); public static native void native_applyDnsConfig(int currentAccount, long address, String phone, int date);
public static native long native_checkProxy(int currentAccount, String address, int port, String username, String password, String secret, RequestTimeDelegate requestTimeDelegate); public static native long native_checkProxy(int currentAccount, String address, int port, String username, String password, String secret, RequestTimeDelegate requestTimeDelegate);
public static native void native_onHostNameResolved(String host, long address, String ip);
public static native void native_onHostNameResolved(String host, long address, String ip, boolean ipv6);
public static int generateClassGuid() { public static int generateClassGuid() {
return lastClassGuid++; return lastClassGuid++;
@ -698,7 +705,7 @@ public class ConnectionsManager extends BaseController {
} }
@SuppressLint("NewApi") @SuppressLint("NewApi")
protected static boolean useIpv6Address() { public static boolean useIpv6Address() {
if (Build.VERSION.SDK_INT < 19) { if (Build.VERSION.SDK_INT < 19) {
return false; return false;
} }
@ -711,22 +718,13 @@ public class ConnectionsManager extends BaseController {
if (!networkInterface.isUp() || networkInterface.isLoopback() || networkInterface.getInterfaceAddresses().isEmpty()) { if (!networkInterface.isUp() || networkInterface.isLoopback() || networkInterface.getInterfaceAddresses().isEmpty()) {
continue; continue;
} }
if (BuildVars.LOGS_ENABLED) {
FileLog.d("valid interface: " + networkInterface);
}
List<InterfaceAddress> interfaceAddresses = networkInterface.getInterfaceAddresses(); List<InterfaceAddress> interfaceAddresses = networkInterface.getInterfaceAddresses();
for (int a = 0; a < interfaceAddresses.size(); a++) { for (int a = 0; a < interfaceAddresses.size(); a++) {
InterfaceAddress address = interfaceAddresses.get(a); InterfaceAddress address = interfaceAddresses.get(a);
InetAddress inetAddress = address.getAddress(); InetAddress inetAddress = address.getAddress();
if (BuildVars.LOGS_ENABLED) {
FileLog.d("address: " + inetAddress.getHostAddress());
}
if (inetAddress.isLinkLocalAddress() || inetAddress.isLoopbackAddress() || inetAddress.isMulticastAddress()) { if (inetAddress.isLinkLocalAddress() || inetAddress.isLoopbackAddress() || inetAddress.isMulticastAddress()) {
continue; continue;
} }
if (BuildVars.LOGS_ENABLED) {
FileLog.d("address is good");
}
} }
} }
} catch (Throwable e) { } catch (Throwable e) {
@ -760,7 +758,7 @@ public class ConnectionsManager extends BaseController {
} }
} }
} }
if(NekoConfig.useIPv6){ if (NekoConfig.useIPv6) {
return hasIpv6; return hasIpv6;
} else { } else {
return !hasIpv4 && hasIpv6; return !hasIpv4 && hasIpv6;
@ -790,75 +788,17 @@ public class ConnectionsManager extends BaseController {
} }
protected ResolvedDomain doInBackground(Void... voids) { protected ResolvedDomain doInBackground(Void... voids) {
ByteArrayOutputStream outbuf = null;
InputStream httpConnectionStream = null; InetAddress[] result;
boolean done = false;
try { try {
URL downloadUrl = new URL("https://www.google.com/resolve?name=" + currentHostName + "&type=A"); result = DnsFactory.Companion.lookup(currentHostName).toArray(new InetAddress[0]);
URLConnection httpConnection = downloadUrl.openConnection(); } catch (Exception e) {
httpConnection.addRequestProperty("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A5297c Safari/602.1"); result = new InetAddress[0];
httpConnection.addRequestProperty("Host", "dns.google.com");
httpConnection.setConnectTimeout(1000);
httpConnection.setReadTimeout(2000);
httpConnection.connect();
httpConnectionStream = httpConnection.getInputStream();
outbuf = new ByteArrayOutputStream();
byte[] data = new byte[1024 * 32];
while (true) {
int read = httpConnectionStream.read(data);
if (read > 0) {
outbuf.write(data, 0, read);
} else if (read == -1) {
break;
} else {
break;
}
}
JSONObject jsonObject = new JSONObject(new String(outbuf.toByteArray()));
if (jsonObject.has("Answer")) {
JSONArray array = jsonObject.getJSONArray("Answer");
int len = array.length();
if (len > 0) {
ArrayList<String> addresses = new ArrayList<>(len);
for (int a = 0; a < len; a++) {
addresses.add(array.getJSONObject(a).getString("data"));
}
return new ResolvedDomain(addresses, SystemClock.elapsedRealtime());
}
}
done = true;
} catch (Throwable e) {
FileLog.e(e);
} finally {
try {
if (httpConnectionStream != null) {
httpConnectionStream.close();
}
} catch (Throwable e) {
FileLog.e(e);
}
try {
if (outbuf != null) {
outbuf.close();
}
} catch (Exception ignore) {
}
} }
if (!done) {
try { return new ResolvedDomain(result, 10 * 60 * 1000L);
InetAddress address = InetAddress.getByName(currentHostName);
ArrayList<String> addresses = new ArrayList<>(1);
addresses.add(address.getHostAddress());
return new ResolvedDomain(addresses, SystemClock.elapsedRealtime());
} catch (Exception e) {
FileLog.e(e);
}
}
return null;
} }
@Override @Override
@ -866,11 +806,12 @@ public class ConnectionsManager extends BaseController {
if (result != null) { if (result != null) {
dnsCache.put(currentHostName, result); dnsCache.put(currentHostName, result);
for (int a = 0, N = addresses.size(); a < N; a++) { for (int a = 0, N = addresses.size(); a < N; a++) {
native_onHostNameResolved(currentHostName, addresses.get(a), result.getAddress()); String address = result.getAddress();
native_onHostNameResolved(currentHostName, addresses.get(a), address, Utils.isIpv6Address(address));
} }
} else { } else {
for (int a = 0, N = addresses.size(); a < N; a++) { for (int a = 0, N = addresses.size(); a < N; a++) {
native_onHostNameResolved(currentHostName, addresses.get(a), ""); native_onHostNameResolved(currentHostName, addresses.get(a), "", false);
} }
} }
resolvingHostnameTasks.remove(currentHostName); resolvingHostnameTasks.remove(currentHostName);
@ -888,101 +829,30 @@ public class ConnectionsManager extends BaseController {
} }
protected NativeByteBuffer doInBackground(Void... voids) { protected NativeByteBuffer doInBackground(Void... voids) {
ByteArrayOutputStream outbuf = null;
InputStream httpConnectionStream = null;
for (int i = 0; i < 3; i++) {
try {
String googleDomain;
if (i == 0) {
googleDomain = "www.google.com";
} else if (i == 1) {
googleDomain = "www.google.ru";
} else {
googleDomain = "google.com";
}
String domain = native_isTestBackend(currentAccount) != 0 ? "tapv3.stel.com" : AccountInstance.getInstance(currentAccount).getMessagesController().dcDomainName;
int len = Utilities.random.nextInt(116) + 13;
final String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
StringBuilder padding = new StringBuilder(len);
for (int a = 0; a < len; a++) {
padding.append(characters.charAt(Utilities.random.nextInt(characters.length())));
}
URL downloadUrl = new URL("https://" + googleDomain + "/resolve?name=" + domain + "&type=ANY&random_padding=" + padding);
URLConnection httpConnection = downloadUrl.openConnection();
httpConnection.addRequestProperty("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A5297c Safari/602.1");
httpConnection.addRequestProperty("Host", "dns.google.com");
httpConnection.setConnectTimeout(5000);
httpConnection.setReadTimeout(5000);
httpConnection.connect();
httpConnectionStream = httpConnection.getInputStream();
responseDate = (int) (httpConnection.getDate() / 1000);
outbuf = new ByteArrayOutputStream();
byte[] data = new byte[1024 * 32];
while (true) {
if (isCancelled()) {
break;
}
int read = httpConnectionStream.read(data);
if (read > 0) {
outbuf.write(data, 0, read);
} else if (read == -1) {
break;
} else {
break;
}
}
JSONObject jsonObject = new JSONObject(new String(outbuf.toByteArray()));
JSONArray array = jsonObject.getJSONArray("Answer");
len = array.length();
ArrayList<String> arrayList = new ArrayList<>(len);
for (int a = 0; a < len; a++) {
JSONObject object = array.getJSONObject(a);
int type = object.getInt("type");
if (type != 16) {
continue;
}
arrayList.add(object.getString("data"));
}
Collections.sort(arrayList, (o1, o2) -> {
int l1 = o1.length();
int l2 = o2.length();
if (l1 > l2) {
return -1;
} else if (l1 < l2) {
return 1;
}
return 0;
});
StringBuilder builder = new StringBuilder();
for (int a = 0; a < arrayList.size(); a++) {
builder.append(arrayList.get(a).replace("\"", ""));
}
byte[] bytes = Base64.decode(builder.toString(), Base64.DEFAULT);
NativeByteBuffer buffer = new NativeByteBuffer(bytes.length);
buffer.writeBytes(bytes);
return buffer;
} catch (Throwable e) {
FileLog.e(e);
} finally {
try {
if (httpConnectionStream != null) {
httpConnectionStream.close();
}
} catch (Throwable e) {
FileLog.e(e);
}
try {
if (outbuf != null) {
outbuf.close();
}
} catch (Exception ignore) {
String domain = native_isTestBackend(currentAccount) != 0 ? "tapv3.stel.com" : AccountInstance.getInstance(currentAccount).getMessagesController().dcDomainName;
try {
ArrayList<String> arrayList = DnsFactory.Companion.getTxts(domain);
Collections.sort(arrayList, (o1, o2) -> {
int l1 = o1.length();
int l2 = o2.length();
if (l1 > l2) {
return -1;
} else if (l1 < l2) {
return 1;
} }
return 0;
});
StringBuilder builder = new StringBuilder();
for (int a = 0; a < arrayList.size(); a++) {
builder.append(arrayList.get(a).replace("\"", ""));
} }
byte[] bytes = Base64.decode(builder.toString(), Base64.DEFAULT);
NativeByteBuffer buffer = new NativeByteBuffer(bytes.length);
buffer.writeBytes(bytes);
return buffer;
} catch (Throwable e) {
FileLog.e(e);
} }
return null; return null;
} }
@ -996,9 +866,9 @@ public class ConnectionsManager extends BaseController {
} else { } else {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("failed to get dns txt result"); FileLog.d("failed to get dns txt result");
FileLog.d("start google task"); FileLog.d("restart load task");
} }
GoogleDnsLoadTask task = new GoogleDnsLoadTask(currentAccount); DnsTxtLoadTask task = new DnsTxtLoadTask(currentAccount);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null, null, null); task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null, null, null);
currentTask = task; currentTask = task;
} }
@ -1006,264 +876,4 @@ public class ConnectionsManager extends BaseController {
} }
} }
private static class GoogleDnsLoadTask extends AsyncTask<Void, Void, NativeByteBuffer> {
private int currentAccount;
private int responseDate;
public GoogleDnsLoadTask(int instance) {
super();
currentAccount = instance;
}
protected NativeByteBuffer doInBackground(Void... voids) {
ByteArrayOutputStream outbuf = null;
InputStream httpConnectionStream = null;
try {
String domain = native_isTestBackend(currentAccount) != 0 ? "tapv3.stel.com" : AccountInstance.getInstance(currentAccount).getMessagesController().dcDomainName;
int len = Utilities.random.nextInt(116) + 13;
final String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
StringBuilder padding = new StringBuilder(len);
for (int a = 0; a < len; a++) {
padding.append(characters.charAt(Utilities.random.nextInt(characters.length())));
}
URL downloadUrl = new URL("https://dns.google.com/resolve?name=" + domain + "&type=ANY&random_padding=" + padding);
URLConnection httpConnection = downloadUrl.openConnection();
httpConnection.addRequestProperty("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A5297c Safari/602.1");
httpConnection.setConnectTimeout(5000);
httpConnection.setReadTimeout(5000);
httpConnection.connect();
httpConnectionStream = httpConnection.getInputStream();
responseDate = (int) (httpConnection.getDate() / 1000);
outbuf = new ByteArrayOutputStream();
byte[] data = new byte[1024 * 32];
while (true) {
if (isCancelled()) {
break;
}
int read = httpConnectionStream.read(data);
if (read > 0) {
outbuf.write(data, 0, read);
} else if (read == -1) {
break;
} else {
break;
}
}
JSONObject jsonObject = new JSONObject(new String(outbuf.toByteArray()));
JSONArray array = jsonObject.getJSONArray("Answer");
len = array.length();
ArrayList<String> arrayList = new ArrayList<>(len);
for (int a = 0; a < len; a++) {
JSONObject object = array.getJSONObject(a);
int type = object.getInt("type");
if (type != 16) {
continue;
}
arrayList.add(object.getString("data"));
}
Collections.sort(arrayList, (o1, o2) -> {
int l1 = o1.length();
int l2 = o2.length();
if (l1 > l2) {
return -1;
} else if (l1 < l2) {
return 1;
}
return 0;
});
StringBuilder builder = new StringBuilder();
for (int a = 0; a < arrayList.size(); a++) {
builder.append(arrayList.get(a).replace("\"", ""));
}
byte[] bytes = Base64.decode(builder.toString(), Base64.DEFAULT);
NativeByteBuffer buffer = new NativeByteBuffer(bytes.length);
buffer.writeBytes(bytes);
return buffer;
} catch (Throwable e) {
FileLog.e(e);
} finally {
try {
if (httpConnectionStream != null) {
httpConnectionStream.close();
}
} catch (Throwable e) {
FileLog.e(e);
}
try {
if (outbuf != null) {
outbuf.close();
}
} catch (Exception ignore) {
}
}
return null;
}
@Override
protected void onPostExecute(final NativeByteBuffer result) {
Utilities.stageQueue.postRunnable(() -> {
currentTask = null;
if (result != null) {
native_applyDnsConfig(currentAccount, result.address, AccountInstance.getInstance(currentAccount).getUserConfig().getClientPhone(), responseDate);
} else {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("failed to get google result");
FileLog.d("start mozilla task");
}
MozillaDnsLoadTask task = new MozillaDnsLoadTask(currentAccount);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null, null, null);
currentTask = task;
}
});
}
}
private static class MozillaDnsLoadTask extends AsyncTask<Void, Void, NativeByteBuffer> {
private int currentAccount;
private int responseDate;
public MozillaDnsLoadTask(int instance) {
super();
currentAccount = instance;
}
protected NativeByteBuffer doInBackground(Void... voids) {
ByteArrayOutputStream outbuf = null;
InputStream httpConnectionStream = null;
try {
String domain = native_isTestBackend(currentAccount) != 0 ? "tapv3.stel.com" : AccountInstance.getInstance(currentAccount).getMessagesController().dcDomainName;
int len = Utilities.random.nextInt(116) + 13;
final String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
StringBuilder padding = new StringBuilder(len);
for (int a = 0; a < len; a++) {
padding.append(characters.charAt(Utilities.random.nextInt(characters.length())));
}
URL downloadUrl = new URL("https://mozilla.cloudflare-dns.com/dns-query?name=" + domain + "&type=TXT&random_padding=" + padding);
URLConnection httpConnection = downloadUrl.openConnection();
httpConnection.addRequestProperty("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A5297c Safari/602.1");
httpConnection.addRequestProperty("accept", "application/dns-json");
httpConnection.setConnectTimeout(5000);
httpConnection.setReadTimeout(5000);
httpConnection.connect();
httpConnectionStream = httpConnection.getInputStream();
responseDate = (int) (httpConnection.getDate() / 1000);
outbuf = new ByteArrayOutputStream();
byte[] data = new byte[1024 * 32];
while (true) {
if (isCancelled()) {
break;
}
int read = httpConnectionStream.read(data);
if (read > 0) {
outbuf.write(data, 0, read);
} else if (read == -1) {
break;
} else {
break;
}
}
JSONObject jsonObject = new JSONObject(new String(outbuf.toByteArray()));
JSONArray array = jsonObject.getJSONArray("Answer");
len = array.length();
ArrayList<String> arrayList = new ArrayList<>(len);
for (int a = 0; a < len; a++) {
JSONObject object = array.getJSONObject(a);
int type = object.getInt("type");
if (type != 16) {
continue;
}
arrayList.add(object.getString("data"));
}
Collections.sort(arrayList, (o1, o2) -> {
int l1 = o1.length();
int l2 = o2.length();
if (l1 > l2) {
return -1;
} else if (l1 < l2) {
return 1;
}
return 0;
});
StringBuilder builder = new StringBuilder();
for (int a = 0; a < arrayList.size(); a++) {
builder.append(arrayList.get(a).replace("\"", ""));
}
byte[] bytes = Base64.decode(builder.toString(), Base64.DEFAULT);
NativeByteBuffer buffer = new NativeByteBuffer(bytes.length);
buffer.writeBytes(bytes);
return buffer;
} catch (Throwable e) {
FileLog.e(e);
} finally {
try {
if (httpConnectionStream != null) {
httpConnectionStream.close();
}
} catch (Throwable e) {
FileLog.e(e);
}
try {
if (outbuf != null) {
outbuf.close();
}
} catch (Exception ignore) {
}
}
return null;
}
@Override
protected void onPostExecute(final NativeByteBuffer result) {
Utilities.stageQueue.postRunnable(() -> {
currentTask = null;
if (result != null) {
native_applyDnsConfig(currentAccount, result.address, AccountInstance.getInstance(currentAccount).getUserConfig().getClientPhone(), responseDate);
} else {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("failed to get mozilla txt result");
}
}
});
}
}
private static class FirebaseTask extends AsyncTask<Void, Void, NativeByteBuffer> {
private int currentAccount;
public FirebaseTask(int instance) {
super();
currentAccount = instance;
}
protected NativeByteBuffer doInBackground(Void... voids) {
Utilities.stageQueue.postRunnable(() -> {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("failed to get firebase result");
FileLog.d("start dns txt task");
}
DnsTxtLoadTask task = new DnsTxtLoadTask(currentAccount);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null, null, null);
currentTask = task;
});
return null;
}
@Override
protected void onPostExecute(NativeByteBuffer result) {
}
}
} }

View File

@ -123,6 +123,19 @@ public class ActionBarMenuItem extends FrameLayout {
private boolean measurePopup = true; private boolean measurePopup = true;
private boolean forceSmoothKeyboard; private boolean forceSmoothKeyboard;
@Override
public boolean isVerticalScrollBarEnabled() {
return verticalScrollBarEnabled;
}
@Override
public void setVerticalScrollBarEnabled(boolean verticalScrollBarEnabled) {
this.verticalScrollBarEnabled = verticalScrollBarEnabled;
}
private boolean verticalScrollBarEnabled;
public ActionBarMenuItem(Context context, ActionBarMenu menu, int backgroundColor, int iconColor) { public ActionBarMenuItem(Context context, ActionBarMenu menu, int backgroundColor, int iconColor) {
this(context, menu, backgroundColor, iconColor, false); this(context, menu, backgroundColor, iconColor, false);
} }
@ -149,7 +162,7 @@ public class ActionBarMenuItem extends FrameLayout {
iconView.setScaleType(ImageView.ScaleType.CENTER); iconView.setScaleType(ImageView.ScaleType.CENTER);
addView(iconView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); addView(iconView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
if (iconColor != 0) { if (iconColor != 0) {
iconView.setColorFilter(new PorterDuffColorFilter(iconColor, PorterDuff.Mode.MULTIPLY)); iconView.setColorFilter(new PorterDuffColorFilter(iconColor, PorterDuff.Mode.SRC_IN));
} }
} }
} }
@ -242,13 +255,13 @@ public class ActionBarMenuItem extends FrameLayout {
public void setIconColor(int color) { public void setIconColor(int color) {
if (iconView != null) { if (iconView != null) {
iconView.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY)); iconView.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
} }
if (textView != null) { if (textView != null) {
textView.setTextColor(color); textView.setTextColor(color);
} }
if (clearButton != null) { if (clearButton != null) {
clearButton.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY)); clearButton.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
} }
} }
@ -270,7 +283,7 @@ public class ActionBarMenuItem extends FrameLayout {
} }
rect = new Rect(); rect = new Rect();
location = new int[2]; location = new int[2];
popupLayout = new ActionBarPopupWindow.ActionBarPopupWindowLayout(getContext()); popupLayout = new ActionBarPopupWindow.ActionBarPopupWindowLayout(getContext(), verticalScrollBarEnabled);
popupLayout.setOnTouchListener((v, event) -> { popupLayout.setOnTouchListener((v, event) -> {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
if (popupWindow != null && popupWindow.isShowing()) { if (popupWindow != null && popupWindow.isShowing()) {
@ -402,7 +415,7 @@ public class ActionBarMenuItem extends FrameLayout {
} }
public void redrawPopup(int color) { public void redrawPopup(int color) {
if (popupLayout != null && popupLayout.getBackgroundColor() != color) { if (popupLayout != null) {
popupLayout.setBackgroundColor(color); popupLayout.setBackgroundColor(color);
if (popupWindow != null && popupWindow.isShowing()) { if (popupWindow != null && popupWindow.isShowing()) {
popupLayout.invalidate(); popupLayout.invalidate();
@ -450,6 +463,26 @@ public class ActionBarMenuItem extends FrameLayout {
yOffset = offset; yOffset = offset;
} }
private View anchor;
public View getAnchor() {
return anchor;
}
public void setAnchor(View anchor) {
this.anchor = anchor;
}
public boolean isShowOnTop() {
return showOnTop;
}
public void setShowOnTop(boolean showOnTop) {
this.showOnTop = showOnTop;
}
private boolean showOnTop;
public void toggleSubMenu() { public void toggleSubMenu() {
if (popupLayout == null || parentMenu != null && parentMenu.isActionMode && parentMenu.parentActionBar != null && !parentMenu.parentActionBar.isActionModeShowed()) { if (popupLayout == null || parentMenu != null && parentMenu.isActionMode && parentMenu.parentActionBar != null && !parentMenu.parentActionBar.isActionModeShowed()) {
return; return;
@ -844,7 +877,7 @@ public class ActionBarMenuItem extends FrameLayout {
} }
}; };
clearButton.setImageDrawable(progressDrawable = new CloseProgressDrawable2()); clearButton.setImageDrawable(progressDrawable = new CloseProgressDrawable2());
clearButton.setColorFilter(new PorterDuffColorFilter(parentMenu.parentActionBar.itemsColor, PorterDuff.Mode.MULTIPLY)); clearButton.setColorFilter(new PorterDuffColorFilter(parentMenu.parentActionBar.itemsColor, PorterDuff.Mode.SRC_IN));
clearButton.setScaleType(ImageView.ScaleType.CENTER); clearButton.setScaleType(ImageView.ScaleType.CENTER);
clearButton.setAlpha(0.0f); clearButton.setAlpha(0.0f);
clearButton.setRotation(45); clearButton.setRotation(45);
@ -946,7 +979,25 @@ public class ActionBarMenuItem extends FrameLayout {
private void updateOrShowPopup(boolean show, boolean update) { private void updateOrShowPopup(boolean show, boolean update) {
int offsetY; int offsetY;
if (parentMenu != null) { if (anchor != null) {
float scaleY = anchor.getScaleY();
offsetY = -(int) (anchor.getMeasuredHeight() * scaleY - anchor.getTranslationY() / scaleY) + additionalYOffset;
int height = AndroidUtilities.displayMetrics.heightPixels;
int[] location = new int[2];
anchor.getLocationOnScreen(location);
int y = location[1];
if (showOnTop) {
offsetY -= popupLayout.getMeasuredHeight();
} else if (height - y < popupLayout.getMeasuredHeight() + offsetY) {
if (height - (height - y) >= popupLayout.getMeasuredHeight()) {
offsetY -= popupLayout.getMeasuredHeight();
} else if (popupLayout.getMeasuredHeight() > height) {
offsetY -= scaleY;
} else {
offsetY -= popupLayout.getMeasuredHeight() / 2;
}
}
} else if (parentMenu != null) {
offsetY = -parentMenu.parentActionBar.getMeasuredHeight() + parentMenu.getTop() + parentMenu.getPaddingTop()/* - (int) parentMenu.parentActionBar.getTranslationY()*/; offsetY = -parentMenu.parentActionBar.getMeasuredHeight() + parentMenu.getTop() + parentMenu.getPaddingTop()/* - (int) parentMenu.parentActionBar.getTranslationY()*/;
} else { } else {
float scaleY = getScaleY(); float scaleY = getScaleY();
@ -958,7 +1009,33 @@ public class ActionBarMenuItem extends FrameLayout {
popupLayout.scrollToTop(); popupLayout.scrollToTop();
} }
if (parentMenu != null) { if (anchor != null) {
if (subMenuOpenSide == 0) {
//if (anchor.getParent() != null) {
//View parent = (View) anchor.getParent();
if (show) {
popupWindow.showAsDropDown(anchor, anchor.getLeft() + anchor.getMeasuredWidth() - popupLayout.getMeasuredWidth() + additionalXOffset, offsetY);
}
if (update) {
popupWindow.update(anchor, anchor.getLeft() + anchor.getMeasuredWidth() - popupLayout.getMeasuredWidth() + additionalXOffset, offsetY, -1, -1);
}
//}
} else if (subMenuOpenSide == 1) {
if (show) {
popupWindow.showAsDropDown(anchor, -AndroidUtilities.dp(8) + additionalXOffset, offsetY);
}
if (update) {
popupWindow.update(anchor, -AndroidUtilities.dp(8) + additionalXOffset, offsetY, -1, -1);
}
} else {
if (show) {
popupWindow.showAsDropDown(anchor, anchor.getMeasuredWidth() - popupLayout.getMeasuredWidth() + additionalXOffset, offsetY);
}
if (update) {
popupWindow.update(anchor, anchor.getMeasuredWidth() - popupLayout.getMeasuredWidth() + additionalXOffset, offsetY, -1, -1);
}
}
} else if (parentMenu != null) {
View parent = parentMenu.parentActionBar; View parent = parentMenu.parentActionBar;
if (subMenuOpenSide == 0) { if (subMenuOpenSide == 0) {
if (SharedConfig.smoothKeyboard) { if (SharedConfig.smoothKeyboard) {

View File

@ -21,6 +21,9 @@ import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import androidx.annotation.Keep; import androidx.annotation.Keep;
import androidx.core.view.ViewCompat;
import androidx.core.widget.ScrollerCompat;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -51,6 +54,7 @@ public class ActionBarPopupWindow extends PopupWindow {
private AnimatorSet windowAnimatorSet; private AnimatorSet windowAnimatorSet;
private boolean animationEnabled = allowAnimation; private boolean animationEnabled = allowAnimation;
private int dismissAnimationDuration = 150; private int dismissAnimationDuration = 150;
static { static {
Field f = null; Field f = null;
try { try {
@ -92,9 +96,13 @@ public class ActionBarPopupWindow extends PopupWindow {
protected Drawable backgroundDrawable; protected Drawable backgroundDrawable;
public ActionBarPopupWindowLayout(Context context) { public ActionBarPopupWindowLayout(Context context) {
this(context,false);
}
public ActionBarPopupWindowLayout(Context context, boolean verticalScrollBarEnabled) {
super(context); super(context);
backgroundDrawable = getResources().getDrawable(R.drawable.popup_fixed_alert2).mutate(); backgroundDrawable = getResources().getDrawable(R.drawable.popup_fixed).mutate();
setBackgroundColor(Theme.getColor(Theme.key_actionBarDefaultSubmenuBackground)); setBackgroundColor(Theme.getColor(Theme.key_actionBarDefaultSubmenuBackground));
setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(8), AndroidUtilities.dp(8), AndroidUtilities.dp(8)); setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(8), AndroidUtilities.dp(8), AndroidUtilities.dp(8));
@ -102,7 +110,7 @@ public class ActionBarPopupWindow extends PopupWindow {
try { try {
scrollView = new ScrollView(context); scrollView = new ScrollView(context);
scrollView.setVerticalScrollBarEnabled(false); scrollView.setVerticalScrollBarEnabled(verticalScrollBarEnabled);
addView(scrollView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT)); addView(scrollView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
} catch (Throwable e) { } catch (Throwable e) {
FileLog.e(e); FileLog.e(e);
@ -111,7 +119,7 @@ public class ActionBarPopupWindow extends PopupWindow {
linearLayout = new LinearLayout(context); linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.VERTICAL); linearLayout.setOrientation(LinearLayout.VERTICAL);
if (scrollView != null) { if (scrollView != null) {
scrollView.addView(linearLayout, new ScrollView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); scrollView.addView(linearLayout, new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
} else { } else {
addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT)); addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
} }
@ -131,7 +139,7 @@ public class ActionBarPopupWindow extends PopupWindow {
public void setBackgroundColor(int color) { public void setBackgroundColor(int color) {
if (backgroundColor != color) { if (backgroundColor != color) {
backgroundDrawable.setColorFilter(new PorterDuffColorFilter(backgroundColor = color, PorterDuff.Mode.MULTIPLY)); backgroundDrawable.setColorFilter(new PorterDuffColorFilter(backgroundColor = color, PorterDuff.Mode.SRC_IN));
} }
} }
@ -397,6 +405,12 @@ public class ActionBarPopupWindow extends PopupWindow {
content.setPivotX(content.getMeasuredWidth()); content.setPivotX(content.getMeasuredWidth());
content.setPivotY(0); content.setPivotY(0);
int count = content.getItemsCount(); int count = content.getItemsCount();
int height = AndroidUtilities.displayMetrics.heightPixels;
int item = content.getItemAt(0).getMeasuredHeight();
if (item > 0) {
int maxItems = height / item;
if (count > maxItems) count = maxItems;
}
content.positions.clear(); content.positions.clear();
int visibleCount = 0; int visibleCount = 0;
for (int a = 0; a < count; a++) { for (int a = 0; a < count; a++) {
@ -418,6 +432,7 @@ public class ActionBarPopupWindow extends PopupWindow {
ObjectAnimator.ofFloat(content, "backScaleY", 0.0f, 1.0f), ObjectAnimator.ofFloat(content, "backScaleY", 0.0f, 1.0f),
ObjectAnimator.ofInt(content, "backAlpha", 0, 255)); ObjectAnimator.ofInt(content, "backAlpha", 0, 255));
windowAnimatorSet.setDuration(150 + 16 * visibleCount); windowAnimatorSet.setDuration(150 + 16 * visibleCount);
int finalCount = count;
windowAnimatorSet.addListener(new Animator.AnimatorListener() { windowAnimatorSet.addListener(new Animator.AnimatorListener() {
@Override @Override
public void onAnimationStart(Animator animation) { public void onAnimationStart(Animator animation) {
@ -428,8 +443,7 @@ public class ActionBarPopupWindow extends PopupWindow {
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
windowAnimatorSet = null; windowAnimatorSet = null;
ActionBarPopupWindowLayout content = (ActionBarPopupWindowLayout) getContentView(); ActionBarPopupWindowLayout content = (ActionBarPopupWindowLayout) getContentView();
int count = content.getItemsCount(); for (int a = 0; a < finalCount; a++) {
for (int a = 0; a < count; a++) {
View child = content.getItemAt(a); View child = content.getItemAt(a);
child.setAlpha(1.0f); child.setAlpha(1.0f);
} }

View File

@ -25,11 +25,6 @@ import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.RequiresApi;
import androidx.core.view.NestedScrollingParent;
import androidx.core.view.NestedScrollingParentHelper;
import androidx.core.view.ViewCompat;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
@ -44,11 +39,18 @@ import android.view.WindowManager;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.RequiresApi;
import androidx.core.view.NestedScrollingParent;
import androidx.core.view.NestedScrollingParentHelper;
import androidx.core.view.ViewCompat;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
@ -119,8 +121,8 @@ public class BottomSheet extends Dialog {
protected int backgroundPaddingTop; protected int backgroundPaddingTop;
protected int backgroundPaddingLeft; protected int backgroundPaddingLeft;
private boolean applyTopPadding = true; private boolean applyTopPadding = false;
private boolean applyBottomPadding = true; private boolean applyBottomPadding = false;
private ArrayList<BottomSheetCell> itemViews = new ArrayList<>(); private ArrayList<BottomSheetCell> itemViews = new ArrayList<>();
@ -138,7 +140,7 @@ public class BottomSheet extends Dialog {
disableScroll = b; disableScroll = b;
} }
protected class ContainerView extends FrameLayout implements NestedScrollingParent { protected class ContainerView extends LinearLayout implements NestedScrollingParent {
private VelocityTracker velocityTracker = null; private VelocityTracker velocityTracker = null;
private int startedTrackingX; private int startedTrackingX;
@ -429,7 +431,7 @@ public class BottomSheet extends Dialog {
continue; continue;
} }
if (!onCustomLayout(child, left, top, right, bottom - (drawNavigationBar ? bottomInset : 0))) { if (!onCustomLayout(child, left, top, right, bottom - (drawNavigationBar ? bottomInset : 0))) {
final FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) child.getLayoutParams(); final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams();
final int width = child.getMeasuredWidth(); final int width = child.getMeasuredWidth();
final int height = child.getMeasuredHeight(); final int height = child.getMeasuredHeight();
@ -544,7 +546,9 @@ public class BottomSheet extends Dialog {
public interface BottomSheetDelegateInterface { public interface BottomSheetDelegateInterface {
void onOpenAnimationStart(); void onOpenAnimationStart();
void onOpenAnimationEnd(); void onOpenAnimationEnd();
boolean canDismiss(); boolean canDismiss();
} }
@ -565,7 +569,7 @@ public class BottomSheet extends Dialog {
} }
} }
public static class BottomSheetCell extends FrameLayout { public static class BottomSheetCell extends LinearLayout {
private TextView textView; private TextView textView;
private ImageView imageView; private ImageView imageView;
@ -575,36 +579,41 @@ public class BottomSheet extends Dialog {
super(context); super(context);
currentType = type; currentType = type;
setBackgroundDrawable(Theme.getSelectorDrawable(false));
//setPadding(AndroidUtilities.dp(16), 0, AndroidUtilities.dp(16), 0); setOrientation(LinearLayout.HORIZONTAL);
setBackground(Theme.getSelectorDrawable(false));
super.setGravity(Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT));
imageView = new ImageView(context); imageView = new ImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER); imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogIcon), PorterDuff.Mode.MULTIPLY)); imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogIcon), PorterDuff.Mode.SRC_IN));
addView(imageView, LayoutHelper.createFrame(56, 48, Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT))); addView(imageView, LayoutHelper.createLinear(56, 48));
textView = new TextView(context); textView = new TextView(context);
textView.setLines(1); textView.setLines(1);
textView.setSingleLine(true); textView.setSingleLine(true);
textView.setGravity(Gravity.CENTER_HORIZONTAL);
textView.setEllipsize(TextUtils.TruncateAt.END); textView.setEllipsize(TextUtils.TruncateAt.END);
if (type == 0) { if (type == 0) {
textView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack)); textView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL)); textView.setGravity(Gravity.CENTER_VERTICAL);
textView.setPadding(AndroidUtilities.dp(16), 0, 0, 0);
addView(textView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL));
} else if (type == 1) { } else if (type == 1) {
textView.setGravity(Gravity.CENTER);
textView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack)); textView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); textView.setGravity(Gravity.CENTER);
addView(textView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
} else if (type == 2) { } else if (type == 2) {
textView.setGravity(Gravity.CENTER); textView.setGravity(Gravity.CENTER);
textView.setTextColor(Theme.getColor(Theme.key_featuredStickers_buttonText)); textView.setTextColor(Theme.getColor(Theme.key_featuredStickers_buttonText));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(4), Theme.getColor(Theme.key_featuredStickers_addButton), Theme.getColor(Theme.key_featuredStickers_addButtonPressed))); textView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(4), Theme.getColor(Theme.key_featuredStickers_addButton), Theme.getColor(Theme.key_featuredStickers_addButtonPressed)));
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, 0, 16, 16, 16, 16)); addView(textView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, 0, 16, 16, 16, 16));
} }
} }
@ -642,16 +651,10 @@ public class BottomSheet extends Dialog {
imageView.setImageResource(icon); imageView.setImageResource(icon);
} }
imageView.setVisibility(VISIBLE); imageView.setVisibility(VISIBLE);
if (bigTitle) { textView.setPadding(0, 0, 0, 0);
textView.setPadding(AndroidUtilities.dp(LocaleController.isRTL ? 21 : 72), 0, AndroidUtilities.dp(LocaleController.isRTL ? 72 : 21), 0);
imageView.setPadding(LocaleController.isRTL ? 0 : AndroidUtilities.dp(5), 0, LocaleController.isRTL ? AndroidUtilities.dp(5) : 5, 0);
} else {
textView.setPadding(AndroidUtilities.dp(LocaleController.isRTL ? 16 : 72), 0, AndroidUtilities.dp(LocaleController.isRTL ? 72 : 16), 0);
imageView.setPadding(0, 0, 0, 0);
}
} else { } else {
imageView.setVisibility(INVISIBLE); imageView.setVisibility(GONE);
textView.setPadding(AndroidUtilities.dp(bigTitle ? 21 : 16), 0, AndroidUtilities.dp(bigTitle ? 21 : 16), 0); textView.setPadding(AndroidUtilities.dp(bigTitle ? 21 : 16), 0, 0, 0);
} }
} }
@ -682,12 +685,15 @@ public class BottomSheet extends Dialog {
if (Build.VERSION.SDK_INT >= 21) { if (Build.VERSION.SDK_INT >= 21) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
} }
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
ViewConfiguration vc = ViewConfiguration.get(context); ViewConfiguration vc = ViewConfiguration.get(context);
touchSlop = vc.getScaledTouchSlop(); touchSlop = vc.getScaledTouchSlop();
Rect padding = new Rect(); Rect padding = new Rect();
shadowDrawable = context.getResources().getDrawable(R.drawable.sheet_shadow_round).mutate(); shadowDrawable = context.getResources().getDrawable(R.drawable.sheet_shadow).mutate();
shadowDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogBackground), PorterDuff.Mode.MULTIPLY)); shadowDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogBackground), PorterDuff.Mode.SRC_IN));
shadowDrawable.getPadding(padding); shadowDrawable.getPadding(padding);
backgroundPaddingLeft = padding.left; backgroundPaddingLeft = padding.left;
backgroundPaddingTop = padding.top; backgroundPaddingTop = padding.top;
@ -736,7 +742,7 @@ public class BottomSheet extends Dialog {
} }
if (containerView == null) { if (containerView == null) {
containerView = new FrameLayout(getContext()) { containerView = new LinearLayout(getContext()) {
@Override @Override
public boolean hasOverlappingRendering() { public boolean hasOverlappingRendering() {
return false; return false;
@ -747,6 +753,10 @@ public class BottomSheet extends Dialog {
super.setTranslationY(translationY); super.setTranslationY(translationY);
onContainerTranslationYChanged(translationY); onContainerTranslationYChanged(translationY);
} }
{
setOrientation(VERTICAL);
}
}; };
containerView.setBackgroundDrawable(shadowDrawable); containerView.setBackgroundDrawable(shadowDrawable);
containerView.setPadding(backgroundPaddingLeft, (applyTopPadding ? AndroidUtilities.dp(8) : 0) + backgroundPaddingTop - 1, backgroundPaddingLeft, (applyBottomPadding ? AndroidUtilities.dp(8) : 0)); containerView.setPadding(backgroundPaddingLeft, (applyTopPadding ? AndroidUtilities.dp(8) : 0) + backgroundPaddingTop - 1, backgroundPaddingLeft, (applyBottomPadding ? AndroidUtilities.dp(8) : 0));
@ -754,46 +764,46 @@ public class BottomSheet extends Dialog {
containerView.setVisibility(View.INVISIBLE); containerView.setVisibility(View.INVISIBLE);
container.addView(containerView, 0, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM)); container.addView(containerView, 0, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM));
int topOffset = 0;
if (title != null) { if (title != null) {
titleView = new TextView(getContext()); titleView = new TextView(getContext());
titleView.setLines(1);
titleView.setSingleLine(true);
titleView.setText(title); titleView.setText(title);
titleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
titleView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
titleView.setMinHeight(AndroidUtilities.dp(25));
if (bigTitle) { if (bigTitle) {
titleView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack)); titleView.setSingleLine(true);
titleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); titleView.setEllipsize(TextUtils.TruncateAt.MIDDLE);
titleView.setTextColor(Theme.getColor(Theme.key_dialogTextBlue2));
titleView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); titleView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
titleView.setPadding(AndroidUtilities.dp(21), AndroidUtilities.dp(6), AndroidUtilities.dp(21), AndroidUtilities.dp(8));
} else { } else {
titleView.setTextColor(Theme.getColor(Theme.key_dialogTextGray2)); titleView.setTextColor(Theme.getColor(Theme.key_dialogTextGray2));
titleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
titleView.setPadding(AndroidUtilities.dp(16), 0, AndroidUtilities.dp(16), AndroidUtilities.dp(8));
} }
titleView.setEllipsize(TextUtils.TruncateAt.MIDDLE);
titleView.setGravity(Gravity.CENTER_VERTICAL); titleView.setGravity(Gravity.CENTER_VERTICAL);
containerView.addView(titleView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48)); containerView.addView(titleView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 21, 15, 21, 0));
titleView.setOnTouchListener((v, event) -> true); titleView.setOnTouchListener((v, event) -> true);
topOffset += 48;
} }
if (customView != null) { if (customView != null) {
if (customView.getParent() != null) { if (customView.getParent() != null) {
ViewGroup viewGroup = (ViewGroup) customView.getParent(); ViewGroup viewGroup = (ViewGroup) customView.getParent();
viewGroup.removeView(customView); viewGroup.removeView(customView);
} }
containerView.addView(customView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 0, topOffset, 0, 0)); containerView.addView(customView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 0));
} else { } else {
if (items != null) { if (items != null) {
FrameLayout rowLayout = null; FrameLayout rootView = new ScrollView(getContext());
int lastRowLayoutNum = 0; LinearLayout rowView = new LinearLayout(getContext());
rowView.setOrientation(LinearLayout.VERTICAL);
rootView.addView(rowView, new ScrollView.LayoutParams(-1, -1));
containerView.addView(rootView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 0));
for (int a = 0; a < items.length; a++) { for (int a = 0; a < items.length; a++) {
if (items[a] == null) { if (items[a] == null) {
continue; continue;
} }
BottomSheetCell cell = new BottomSheetCell(getContext(), 0); BottomSheetCell cell = new BottomSheetCell(getContext(), 0);
cell.setTextAndIcon(items[a], itemIcons != null ? itemIcons[a] : 0, null, bigTitle); cell.setTextAndIcon(items[a], itemIcons != null ? itemIcons[a] : 0, null, bigTitle);
containerView.addView(cell, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.TOP, 0, topOffset, 0, 0)); rowView.addView(cell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 56, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 0));
topOffset += 48;
cell.setTag(a); cell.setTag(a);
cell.setOnClickListener(v -> dismissWithButtonClick((Integer) v.getTag())); cell.setOnClickListener(v -> dismissWithButtonClick((Integer) v.getTag()));
itemViews.add(cell); itemViews.add(cell);
@ -840,7 +850,7 @@ public class BottomSheet extends Dialog {
WindowManager.LayoutParams params = window.getAttributes(); WindowManager.LayoutParams params = window.getAttributes();
if (focusable) { if (focusable) {
params.softInputMode = (useSmoothKeyboard ? WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN : WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); params.softInputMode = (useSmoothKeyboard ? WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN : WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
params.flags &=~ WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; params.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
} else { } else {
params.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; params.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
params.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; params.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
@ -853,7 +863,7 @@ public class BottomSheet extends Dialog {
} }
public void setBackgroundColor(int color) { public void setBackgroundColor(int color) {
shadowDrawable.setColorFilter(color, PorterDuff.Mode.MULTIPLY); shadowDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
} }
@Override @Override
@ -883,7 +893,7 @@ public class BottomSheet extends Dialog {
startAnimationRunnable = null; startAnimationRunnable = null;
startOpenAnimation(); startOpenAnimation();
} }
}, 150); });
} else { } else {
startOpenAnimation(); startOpenAnimation();
} }
@ -928,6 +938,7 @@ public class BottomSheet extends Dialog {
public void setTitle(CharSequence value, boolean big) { public void setTitle(CharSequence value, boolean big) {
title = value; title = value;
bigTitle = big; bigTitle = big;
setApplyTopPadding(true);
} }
public void setApplyTopPadding(boolean value) { public void setApplyTopPadding(boolean value) {
@ -983,7 +994,6 @@ public class BottomSheet extends Dialog {
ObjectAnimator.ofFloat(containerView, View.TRANSLATION_Y, 0), ObjectAnimator.ofFloat(containerView, View.TRANSLATION_Y, 0),
ObjectAnimator.ofInt(backDrawable, AnimationProperties.COLOR_DRAWABLE_ALPHA, dimBehind ? 51 : 0)); ObjectAnimator.ofInt(backDrawable, AnimationProperties.COLOR_DRAWABLE_ALPHA, dimBehind ? 51 : 0));
currentSheetAnimation.setDuration(400); currentSheetAnimation.setDuration(400);
currentSheetAnimation.setStartDelay(20);
currentSheetAnimation.setInterpolator(openInterpolator); currentSheetAnimation.setInterpolator(openInterpolator);
currentSheetAnimation.addListener(new AnimatorListenerAdapter() { currentSheetAnimation.addListener(new AnimatorListenerAdapter() {
@Override @Override
@ -1024,7 +1034,7 @@ public class BottomSheet extends Dialog {
delegate = bottomSheetDelegate; delegate = bottomSheetDelegate;
} }
public FrameLayout getContainer() { public LinearLayout getContainer() {
return container; return container;
} }
@ -1054,7 +1064,7 @@ public class BottomSheet extends Dialog {
} }
BottomSheetCell cell = itemViews.get(item); BottomSheetCell cell = itemViews.get(item);
cell.textView.setTextColor(color); cell.textView.setTextColor(color);
cell.imageView.setColorFilter(new PorterDuffColorFilter(icon, PorterDuff.Mode.MULTIPLY)); cell.imageView.setColorFilter(new PorterDuffColorFilter(icon, PorterDuff.Mode.SRC_IN));
} }
public void setItems(CharSequence[] i, int[] icons, final OnClickListener listener) { public void setItems(CharSequence[] i, int[] icons, final OnClickListener listener) {

View File

@ -1901,7 +1901,7 @@ public class Theme {
} }
}; };
public static int DEFALT_THEME_ACCENT_ID = 99; public static int DEFALT_THEME_ACCENT_ID = 0;
public static int selectedAutoNightType = AUTO_NIGHT_TYPE_NONE; public static int selectedAutoNightType = AUTO_NIGHT_TYPE_NONE;
public static boolean autoNightScheduleByLocation; public static boolean autoNightScheduleByLocation;
public static float autoNightBrighnessThreshold = 0.25f; public static float autoNightBrighnessThreshold = 0.25f;
@ -3829,24 +3829,28 @@ public class Theme {
ThemeInfo themeInfo = new ThemeInfo(); ThemeInfo themeInfo = new ThemeInfo();
themeInfo.name = "Blue"; themeInfo.name = "Blue";
themeInfo.assetName = "bluebubbles.attheme"; themeInfo.assetName = NekoConfig.useDefaultTheme ? "bluebubbles.attheme" : "nekox-indigo.attheme";
themeInfo.previewBackgroundColor = 0xff95beec; themeInfo.previewBackgroundColor = -657931;
themeInfo.previewInColor = 0xffffffff; themeInfo.previewInColor = NekoConfig.useDefaultTheme ? 0xffffffff : Color.parseColor("#c0ffffff");
themeInfo.previewOutColor = 0xffd0e6ff; themeInfo.previewOutColor = NekoConfig.useDefaultTheme ? 0xffd0e6ff: Color.parseColor("#3f51b5");
themeInfo.firstAccentIsDefault = true;
themeInfo.currentAccentId = DEFALT_THEME_ACCENT_ID; themeInfo.currentAccentId = DEFALT_THEME_ACCENT_ID;
themeInfo.sortIndex = 1; themeInfo.sortIndex = 1;
themeInfo.setAccentColorOptions( if (NekoConfig.useDefaultTheme) {
new int[] { 0xFF5890C5, 0xFF239853, 0xFFCE5E82, 0xFF7F63C3, 0xFF2491AD, 0xFF299C2F, 0xFF8854B4, 0xFF328ACF, 0xFF43ACC7, 0xFF52AC44, 0xFFCD5F93, 0xFFD28036, 0xFF8366CC, 0xFFCE4E57, 0xFFD3AE40, 0xFF7B88AB }, themeInfo.firstAccentIsDefault = true;
new int[] { 0xFFB8E18D, 0xFFFAFBCC, 0xFFFFF9DC, 0xFFC14F6E, 0xFFD1BD1B, 0xFFFFFAC9, 0xFFFCF6D8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, themeInfo.setAccentColorOptions(
new int[] { 0x00000000, 0xFFF2FBC9, 0xFFFBF4DF, 0, 0, 0xFFFDEDB4, 0xFFFCF7B6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, new int[]{0xFF5890C5, 0xFF239853, 0xFFCE5E82, 0xFF7F63C3, 0xFF2491AD, 0xFF299C2F, 0xFF8854B4, 0xFF328ACF, 0xFF43ACC7, 0xFF52AC44, 0xFFCD5F93, 0xFFD28036, 0xFF8366CC, 0xFFCE4E57, 0xFFD3AE40, 0xFF7B88AB},
new int[] { 0x00000000, 0xFFDFE2A0, 0xFFE2B991, 0xFFD7C1E9, 0xFFDCD1C0, 0xFFEFB576, 0xFFC0A2D1, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, new int[]{0xFFB8E18D, 0xFFFAFBCC, 0xFFFFF9DC, 0xFFC14F6E, 0xFFD1BD1B, 0xFFFFFAC9, 0xFFFCF6D8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
new int[] { 0x00000000, 0xFFC1E1A3, 0xFFEBE2BA, 0xFFE8CDD6, 0xFFE0DFC6, 0xFFECE771, 0xFFDECCDE, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, new int[]{0x00000000, 0xFFF2FBC9, 0xFFFBF4DF, 0, 0, 0xFFFDEDB4, 0xFFFCF7B6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
new int[] { 99, 9, 10, 11, 12, 13, 14, 0, 1, 2, 3, 4, 5, 6, 7, 8 }, new int[]{0x00000000, 0xFFDFE2A0, 0xFFE2B991, 0xFFD7C1E9, 0xFFDCD1C0, 0xFFEFB576, 0xFFC0A2D1, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
new String[] { "", "p-pXcflrmFIBAAAAvXYQk-mCwZU", "JqSUrO0-mFIBAAAAWwTvLzoWGQI", "O-wmAfBPSFADAAAA4zINVfD_bro", "RepJ5uE_SVABAAAAr4d0YhgB850", "-Xc-np9y2VMCAAAARKr0yNNPYW0", "dhf9pceaQVACAAAAbzdVo4SCiZA", "", "", "", "", "", "", "", "", "" }, new int[]{0x00000000, 0xFFC1E1A3, 0xFFEBE2BA, 0xFFE8CDD6, 0xFFE0DFC6, 0xFFECE771, 0xFFDECCDE, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
new int[] { 0, 180, 45, 0, 45, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, new int[]{99, 9, 10, 11, 12, 13, 14, 0, 1, 2, 3, 4, 5, 6, 7, 8},
new int[] { 0, 52, 46, 57, 45, 64, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0 } new String[]{"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""},
); new int[]{0, 180, 45, 0, 45, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
new int[]{0, 52, 46, 57, 45, 64, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0}
);
} else {
}
themes.add(currentDayTheme = currentTheme = defaultTheme = themeInfo); themes.add(currentDayTheme = currentTheme = defaultTheme = themeInfo);
themesDict.put("Blue", themeInfo); themesDict.put("Blue", themeInfo);
@ -3977,7 +3981,7 @@ public class Theme {
ThemeInfo applyingTheme = null; ThemeInfo applyingTheme = null;
SharedPreferences preferences = MessagesController.getGlobalMainSettings(); SharedPreferences preferences = MessagesController.getGlobalMainSettings();
try { try {
final ThemeInfo themeDarkBlue = themesDict.get("Dark Blue"); final ThemeInfo themeDarkBlue = themesDict.get("Night");
String theme = preferences.getString("theme", null); String theme = preferences.getString("theme", null);
if ("Default".equals(theme)) { if ("Default".equals(theme)) {
@ -3995,7 +3999,7 @@ public class Theme {
} }
} }
theme = preferences.getString("nighttheme", null); theme = preferences.getString("nighttheme", "Night");
if ("Default".equals(theme)) { if ("Default".equals(theme)) {
applyingTheme = themesDict.get("Blue"); applyingTheme = themesDict.get("Blue");
applyingTheme.currentAccentId = DEFALT_THEME_ACCENT_ID; applyingTheme.currentAccentId = DEFALT_THEME_ACCENT_ID;
@ -4202,7 +4206,7 @@ public class Theme {
currentNightTheme.setOverrideWallpaper(overrideWallpaper); currentNightTheme.setOverrideWallpaper(overrideWallpaper);
} }
} }
preferences.edit().remove("overrideThemeWallpaper").remove("selectedBackground2").commit(); preferences.edit().remove("overrideThemeWallpaper").remove("selectedBackground2").apply();
} }
int switchToTheme = needSwitchToTheme(); int switchToTheme = needSwitchToTheme();
@ -4265,11 +4269,11 @@ public class Theme {
Resources resources = context.getResources(); Resources resources = context.getResources();
Drawable defaultDrawable = resources.getDrawable(resource).mutate(); Drawable defaultDrawable = resources.getDrawable(resource).mutate();
if (defaultColor != 0) { if (defaultColor != 0) {
defaultDrawable.setColorFilter(new PorterDuffColorFilter(defaultColor, PorterDuff.Mode.MULTIPLY)); defaultDrawable.setColorFilter(new PorterDuffColorFilter(defaultColor, PorterDuff.Mode.SRC_IN));
} }
Drawable pressedDrawable = resources.getDrawable(resource).mutate(); Drawable pressedDrawable = resources.getDrawable(resource).mutate();
if (pressedColor != 0) { if (pressedColor != 0) {
pressedDrawable.setColorFilter(new PorterDuffColorFilter(pressedColor, PorterDuff.Mode.MULTIPLY)); pressedDrawable.setColorFilter(new PorterDuffColorFilter(pressedColor, PorterDuff.Mode.SRC_IN));
} }
StateListDrawable stateListDrawable = new StateListDrawable() { StateListDrawable stateListDrawable = new StateListDrawable() {
@Override @Override
@ -4301,9 +4305,9 @@ public class Theme {
public static Drawable createEditTextDrawable(Context context, boolean alert) { public static Drawable createEditTextDrawable(Context context, boolean alert) {
Resources resources = context.getResources(); Resources resources = context.getResources();
Drawable defaultDrawable = resources.getDrawable(R.drawable.search_dark).mutate(); Drawable defaultDrawable = resources.getDrawable(R.drawable.search_dark).mutate();
defaultDrawable.setColorFilter(new PorterDuffColorFilter(getColor(alert ? key_dialogInputField : key_windowBackgroundWhiteInputField), PorterDuff.Mode.MULTIPLY)); defaultDrawable.setColorFilter(new PorterDuffColorFilter(getColor(alert ? key_dialogInputField : key_windowBackgroundWhiteInputField), PorterDuff.Mode.SRC_IN));
Drawable pressedDrawable = resources.getDrawable(R.drawable.search_dark_activated).mutate(); Drawable pressedDrawable = resources.getDrawable(R.drawable.search_dark_activated).mutate();
pressedDrawable.setColorFilter(new PorterDuffColorFilter(getColor(alert ? key_dialogInputFieldActivated : key_windowBackgroundWhiteInputFieldActivated), PorterDuff.Mode.MULTIPLY)); pressedDrawable.setColorFilter(new PorterDuffColorFilter(getColor(alert ? key_dialogInputFieldActivated : key_windowBackgroundWhiteInputFieldActivated), PorterDuff.Mode.SRC_IN));
StateListDrawable stateListDrawable = new StateListDrawable() { StateListDrawable stateListDrawable = new StateListDrawable() {
@Override @Override
public boolean selectDrawable(int index) { public boolean selectDrawable(int index) {
@ -4388,11 +4392,11 @@ public class Theme {
Resources resources = context.getResources(); Resources resources = context.getResources();
Drawable defaultDrawable = resources.getDrawable(resource).mutate(); Drawable defaultDrawable = resources.getDrawable(resource).mutate();
if (defaultColor != 0) { if (defaultColor != 0) {
defaultDrawable.setColorFilter(new PorterDuffColorFilter(defaultColor, PorterDuff.Mode.MULTIPLY)); defaultDrawable.setColorFilter(new PorterDuffColorFilter(defaultColor, PorterDuff.Mode.SRC_IN));
} }
Drawable pressedDrawable = resources.getDrawable(resource).mutate(); Drawable pressedDrawable = resources.getDrawable(resource).mutate();
if (pressedColor != 0) { if (pressedColor != 0) {
pressedDrawable.setColorFilter(new PorterDuffColorFilter(pressedColor, PorterDuff.Mode.MULTIPLY)); pressedDrawable.setColorFilter(new PorterDuffColorFilter(pressedColor, PorterDuff.Mode.SRC_IN));
} }
StateListDrawable stateListDrawable = new StateListDrawable() { StateListDrawable stateListDrawable = new StateListDrawable() {
@Override @Override
@ -4481,7 +4485,7 @@ public class Theme {
if (drawable instanceof ColorDrawable) { if (drawable instanceof ColorDrawable) {
((ColorDrawable) drawable).setColor(color); ((ColorDrawable) drawable).setColor(color);
} else { } else {
drawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY)); drawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
} }
} }
@ -5569,7 +5573,7 @@ public class Theme {
currentThemeDeleted = true; currentThemeDeleted = true;
} }
if (themeInfo == currentNightTheme) { if (themeInfo == currentNightTheme) {
currentNightTheme = themesDict.get("Dark Blue"); currentNightTheme = themesDict.get("Night");
} }
themeInfo.removeObservers(); themeInfo.removeObservers();
@ -5903,7 +5907,7 @@ public class Theme {
if (currentDayTheme == info) { if (currentDayTheme == info) {
currentDayTheme = defaultTheme; currentDayTheme = defaultTheme;
} else if (currentNightTheme == info) { } else if (currentNightTheme == info) {
currentNightTheme = themesDict.get("Dark Blue"); currentNightTheme = themesDict.get("Night");
isNightTheme = true; isNightTheme = true;
} }
if (currentTheme == info) { if (currentTheme == info) {
@ -6048,7 +6052,7 @@ public class Theme {
} }
public static File getAssetFile(String assetName) { public static File getAssetFile(String assetName) {
File file = new File(ApplicationLoader.getFilesDirFixed(), assetName); File file = new File(ApplicationLoader.getCacheDirFixed(), assetName);
long size; long size;
try { try {
InputStream stream = ApplicationLoader.applicationContext.getAssets().open(assetName); InputStream stream = ApplicationLoader.applicationContext.getAssets().open(assetName);
@ -6404,7 +6408,7 @@ public class Theme {
Resources resources = context.getResources(); Resources resources = context.getResources();
avatarDrawables[0] = resources.getDrawable(R.drawable.chats_saved); avatarDrawables[0] = resources.getDrawable(R.drawable.baseline_bookmark_24);
avatarDrawables[1] = resources.getDrawable(R.drawable.ghost); avatarDrawables[1] = resources.getDrawable(R.drawable.ghost);
avatarDrawables[2] = resources.getDrawable(R.drawable.folders_private); avatarDrawables[2] = resources.getDrawable(R.drawable.folders_private);
avatarDrawables[3] = resources.getDrawable(R.drawable.folders_requests); avatarDrawables[3] = resources.getDrawable(R.drawable.folders_requests);
@ -6441,7 +6445,7 @@ public class Theme {
dialogs_pinArchiveDrawable = new RLottieDrawable(R.raw.chats_hide, "chats_hide", AndroidUtilities.dp(36), AndroidUtilities.dp(36)); dialogs_pinArchiveDrawable = new RLottieDrawable(R.raw.chats_hide, "chats_hide", AndroidUtilities.dp(36), AndroidUtilities.dp(36));
dialogs_unpinArchiveDrawable = new RLottieDrawable(R.raw.chats_unhide, "chats_unhide", AndroidUtilities.dp(36), AndroidUtilities.dp(36)); dialogs_unpinArchiveDrawable = new RLottieDrawable(R.raw.chats_unhide, "chats_unhide", AndroidUtilities.dp(36), AndroidUtilities.dp(36));
dialogs_hidePsaDrawable = new RLottieDrawable(R.raw.chat_audio_record_delete, "chats_psahide", AndroidUtilities.dp(30), AndroidUtilities.dp(30)); dialogs_hidePsaDrawable = new RLottieDrawable(R.raw.chat_audio_record_delete, "chats_psahide", AndroidUtilities.dp(30), AndroidUtilities.dp(30));
applyCommonTheme(); applyCommonTheme();
} }
} }
@ -6542,7 +6546,7 @@ public class Theme {
dialogs_checkDrawable = resources.getDrawable(R.drawable.list_check).mutate(); dialogs_checkDrawable = resources.getDrawable(R.drawable.list_check).mutate();
dialogs_checkReadDrawable = resources.getDrawable(R.drawable.list_check).mutate(); dialogs_checkReadDrawable = resources.getDrawable(R.drawable.list_check).mutate();
dialogs_halfCheckDrawable = resources.getDrawable(R.drawable.list_halfcheck); dialogs_halfCheckDrawable = resources.getDrawable(R.drawable.list_halfcheck);
dialogs_clockDrawable = resources.getDrawable(R.drawable.msg_clock).mutate(); dialogs_clockDrawable = resources.getDrawable(R.drawable.deproko_baseline_clock_24).mutate();
dialogs_errorDrawable = resources.getDrawable(R.drawable.list_warning_sign); dialogs_errorDrawable = resources.getDrawable(R.drawable.list_warning_sign);
dialogs_reorderDrawable = resources.getDrawable(R.drawable.list_reorder).mutate(); dialogs_reorderDrawable = resources.getDrawable(R.drawable.list_reorder).mutate();
dialogs_groupDrawable = resources.getDrawable(R.drawable.list_group); dialogs_groupDrawable = resources.getDrawable(R.drawable.list_group);
@ -6737,12 +6741,12 @@ public class Theme {
chat_msgOutHalfCheckSelectedDrawable = resources.getDrawable(R.drawable.msg_halfcheck).mutate(); chat_msgOutHalfCheckSelectedDrawable = resources.getDrawable(R.drawable.msg_halfcheck).mutate();
chat_msgMediaHalfCheckDrawable = resources.getDrawable(R.drawable.msg_halfcheck_s).mutate(); chat_msgMediaHalfCheckDrawable = resources.getDrawable(R.drawable.msg_halfcheck_s).mutate();
chat_msgStickerHalfCheckDrawable = resources.getDrawable(R.drawable.msg_halfcheck_s).mutate(); chat_msgStickerHalfCheckDrawable = resources.getDrawable(R.drawable.msg_halfcheck_s).mutate();
chat_msgOutClockDrawable = resources.getDrawable(R.drawable.msg_clock).mutate(); chat_msgOutClockDrawable = resources.getDrawable(R.drawable.deproko_baseline_clock_24).mutate();
chat_msgOutSelectedClockDrawable = resources.getDrawable(R.drawable.msg_clock).mutate(); chat_msgOutSelectedClockDrawable = resources.getDrawable(R.drawable.deproko_baseline_clock_24).mutate();
chat_msgInClockDrawable = resources.getDrawable(R.drawable.msg_clock).mutate(); chat_msgInClockDrawable = resources.getDrawable(R.drawable.deproko_baseline_clock_24).mutate();
chat_msgInSelectedClockDrawable = resources.getDrawable(R.drawable.msg_clock).mutate(); chat_msgInSelectedClockDrawable = resources.getDrawable(R.drawable.deproko_baseline_clock_24).mutate();
chat_msgMediaClockDrawable = resources.getDrawable(R.drawable.msg_clock).mutate(); chat_msgMediaClockDrawable = resources.getDrawable(R.drawable.deproko_baseline_clock_24).mutate();
chat_msgStickerClockDrawable = resources.getDrawable(R.drawable.msg_clock).mutate(); chat_msgStickerClockDrawable = resources.getDrawable(R.drawable.deproko_baseline_clock_24).mutate();
chat_msgInViewsDrawable = resources.getDrawable(R.drawable.msg_views).mutate(); chat_msgInViewsDrawable = resources.getDrawable(R.drawable.msg_views).mutate();
chat_msgInViewsSelectedDrawable = resources.getDrawable(R.drawable.msg_views).mutate(); chat_msgInViewsSelectedDrawable = resources.getDrawable(R.drawable.msg_views).mutate();
chat_msgOutViewsDrawable = resources.getDrawable(R.drawable.msg_views).mutate(); chat_msgOutViewsDrawable = resources.getDrawable(R.drawable.msg_views).mutate();
@ -6772,7 +6776,7 @@ public class Theme {
chat_pollCheckDrawable[a] = resources.getDrawable(R.drawable.poll_right).mutate(); chat_pollCheckDrawable[a] = resources.getDrawable(R.drawable.poll_right).mutate();
chat_pollCrossDrawable[a] = resources.getDrawable(R.drawable.poll_wrong).mutate(); chat_pollCrossDrawable[a] = resources.getDrawable(R.drawable.poll_wrong).mutate();
chat_pollHintDrawable[a] = resources.getDrawable(R.drawable.smiles_panel_objects).mutate(); chat_pollHintDrawable[a] = resources.getDrawable(R.drawable.smiles_panel_objects).mutate();
chat_psaHelpDrawable[a] = resources.getDrawable(R.drawable.msg_psa).mutate(); chat_psaHelpDrawable[a] = resources.getDrawable(R.drawable.baseline_help_24).mutate();
} }
calllog_msgCallUpRedDrawable = resources.getDrawable(R.drawable.ic_call_made_green_18dp).mutate(); calllog_msgCallUpRedDrawable = resources.getDrawable(R.drawable.ic_call_made_green_18dp).mutate();
@ -6902,8 +6906,8 @@ public class Theme {
chat_photoStatesDrawables[12][0] = resources.getDrawable(R.drawable.doc_big).mutate(); chat_photoStatesDrawables[12][0] = resources.getDrawable(R.drawable.doc_big).mutate();
chat_photoStatesDrawables[12][1] = resources.getDrawable(R.drawable.doc_big).mutate(); chat_photoStatesDrawables[12][1] = resources.getDrawable(R.drawable.doc_big).mutate();
chat_contactDrawable[0] = createCircleDrawableWithIcon(AndroidUtilities.dp(44), R.drawable.msg_contact); chat_contactDrawable[0] = createCircleDrawableWithIcon(AndroidUtilities.dp(44), R.drawable.baseline_person_24);
chat_contactDrawable[1] = createCircleDrawableWithIcon(AndroidUtilities.dp(44), R.drawable.msg_contact); chat_contactDrawable[1] = createCircleDrawableWithIcon(AndroidUtilities.dp(44), R.drawable.baseline_person_24);
chat_locationDrawable[0] = resources.getDrawable(R.drawable.msg_location).mutate(); chat_locationDrawable[0] = resources.getDrawable(R.drawable.msg_location).mutate();
chat_locationDrawable[1] = resources.getDrawable(R.drawable.msg_location).mutate(); chat_locationDrawable[1] = resources.getDrawable(R.drawable.msg_location).mutate();
@ -7209,8 +7213,8 @@ public class Theme {
} }
if (currentColor != serviceColor) { if (currentColor != serviceColor) {
chat_actionBackgroundPaint.setColor(serviceColor); chat_actionBackgroundPaint.setColor(serviceColor);
colorFilter = new PorterDuffColorFilter(serviceColor, PorterDuff.Mode.MULTIPLY); colorFilter = new PorterDuffColorFilter(serviceColor, PorterDuff.Mode.SRC_IN);
colorFilter2 = new PorterDuffColorFilter(serviceColor2, PorterDuff.Mode.MULTIPLY); colorFilter2 = new PorterDuffColorFilter(serviceColor2, PorterDuff.Mode.SRC_IN);
currentColor = serviceColor; currentColor = serviceColor;
if (chat_cornerOuter[0] != null) { if (chat_cornerOuter[0] != null) {
for (int a = 0; a < 4; a++) { for (int a = 0; a < 4; a++) {
@ -7221,8 +7225,8 @@ public class Theme {
} }
if (currentSelectedColor != servicePressedColor) { if (currentSelectedColor != servicePressedColor) {
currentSelectedColor = servicePressedColor; currentSelectedColor = servicePressedColor;
colorPressedFilter = new PorterDuffColorFilter(servicePressedColor, PorterDuff.Mode.MULTIPLY); colorPressedFilter = new PorterDuffColorFilter(servicePressedColor, PorterDuff.Mode.SRC_IN);
colorPressedFilter2 = new PorterDuffColorFilter(servicePressedColor2, PorterDuff.Mode.MULTIPLY); colorPressedFilter2 = new PorterDuffColorFilter(servicePressedColor2, PorterDuff.Mode.SRC_IN);
} }
} }
@ -7249,13 +7253,13 @@ public class Theme {
if (selected) { if (selected) {
if (currentShareSelectedColorFilter == null || currentShareSelectedColorFilterColor != color) { if (currentShareSelectedColorFilter == null || currentShareSelectedColorFilterColor != color) {
currentShareSelectedColorFilterColor = color; currentShareSelectedColorFilterColor = color;
currentShareSelectedColorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY); currentShareSelectedColorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN);
} }
return currentShareSelectedColorFilter; return currentShareSelectedColorFilter;
} else { } else {
if (currentShareColorFilter == null || currentShareColorFilterColor != color) { if (currentShareColorFilter == null || currentShareColorFilterColor != color) {
currentShareColorFilterColor = color; currentShareColorFilterColor = color;
currentShareColorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY); currentShareColorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN);
} }
return currentShareColorFilter; return currentShareColorFilter;
} }
@ -7282,7 +7286,7 @@ public class Theme {
return null; return null;
} }
Drawable drawable = context.getResources().getDrawable(resId).mutate(); Drawable drawable = context.getResources().getDrawable(resId).mutate();
drawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY)); drawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
return drawable; return drawable;
} }
@ -7477,7 +7481,7 @@ public class Theme {
} else if (drawable instanceof ScamDrawable) { } else if (drawable instanceof ScamDrawable) {
((ScamDrawable) drawable).setColor(color); ((ScamDrawable) drawable).setColor(color);
} else { } else {
drawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY)); drawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
} }
} }
@ -7496,14 +7500,14 @@ public class Theme {
if (state instanceof ShapeDrawable) { if (state instanceof ShapeDrawable) {
((ShapeDrawable) state).getPaint().setColor(color); ((ShapeDrawable) state).getPaint().setColor(color);
} else { } else {
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY)); state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
} }
} else { } else {
Drawable state = getStateDrawable(drawable, 1); Drawable state = getStateDrawable(drawable, 1);
if (state instanceof ShapeDrawable) { if (state instanceof ShapeDrawable) {
((ShapeDrawable) state).getPaint().setColor(color); ((ShapeDrawable) state).getPaint().setColor(color);
} else { } else {
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY)); state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
} }
} }
} catch (Throwable ignore) { } catch (Throwable ignore) {
@ -7534,20 +7538,20 @@ public class Theme {
if (state instanceof ShapeDrawable) { if (state instanceof ShapeDrawable) {
((ShapeDrawable) state).getPaint().setColor(color); ((ShapeDrawable) state).getPaint().setColor(color);
} else { } else {
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY)); state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
} }
state = getStateDrawable(drawable, 1); state = getStateDrawable(drawable, 1);
if (state instanceof ShapeDrawable) { if (state instanceof ShapeDrawable) {
((ShapeDrawable) state).getPaint().setColor(color); ((ShapeDrawable) state).getPaint().setColor(color);
} else { } else {
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY)); state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
} }
} else { } else {
Drawable state = getStateDrawable(drawable, 2); Drawable state = getStateDrawable(drawable, 2);
if (state instanceof ShapeDrawable) { if (state instanceof ShapeDrawable) {
((ShapeDrawable) state).getPaint().setColor(color); ((ShapeDrawable) state).getPaint().setColor(color);
} else { } else {
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY)); state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
} }
} }
} catch (Throwable ignore) { } catch (Throwable ignore) {
@ -7566,7 +7570,7 @@ public class Theme {
if (drawable1 instanceof ShapeDrawable) { if (drawable1 instanceof ShapeDrawable) {
((ShapeDrawable) drawable1).getPaint().setColor(color); ((ShapeDrawable) drawable1).getPaint().setColor(color);
} else { } else {
drawable1.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY)); drawable1.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
} }
} }
} }

View File

@ -56,6 +56,9 @@ import org.telegram.ui.Components.URLSpanNoUnderline;
import java.util.ArrayList; import java.util.ArrayList;
import kotlin.Unit;
import tw.nekomimi.nekogram.BottomBuilder;
@TargetApi(23) @TargetApi(23)
public class ActionIntroActivity extends BaseFragment implements LocationController.LocationFetchCallback { public class ActionIntroActivity extends BaseFragment implements LocationController.LocationFetchCallback {
@ -544,11 +547,13 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
break; break;
} }
case ACTION_TYPE_CHANGE_PHONE_NUMBER: { case ACTION_TYPE_CHANGE_PHONE_NUMBER: {
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); BottomBuilder builder = new BottomBuilder(getParentActivity());
builder.setTitle(LocaleController.getString("PhoneNumberChangeTitle", R.string.PhoneNumberChangeTitle)); builder.addTitle(LocaleController.getString("PhoneNumberAlert", R.string.PhoneNumberAlert));
builder.setMessage(LocaleController.getString("PhoneNumberAlert", R.string.PhoneNumberAlert)); builder.addItem(LocaleController.getString("Change", R.string.Change), (i) -> {
builder.setPositiveButton(LocaleController.getString("Change", R.string.Change), (dialogInterface, i) -> presentFragment(new ChangePhoneActivity(), true)); presentFragment(new ChangePhoneActivity(), true);
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); return Unit.INSTANCE;
});
builder.addCancelItem();
showDialog(builder.create()); showDialog(builder.create());
break; break;
} }
@ -608,8 +613,8 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
subtitleTextView.setVisibility(View.VISIBLE); subtitleTextView.setVisibility(View.VISIBLE);
drawable1 = context.getResources().getDrawable(R.drawable.sim_old); drawable1 = context.getResources().getDrawable(R.drawable.sim_old);
drawable2 = context.getResources().getDrawable(R.drawable.sim_new); drawable2 = context.getResources().getDrawable(R.drawable.sim_new);
drawable1.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_changephoneinfo_image), PorterDuff.Mode.MULTIPLY)); drawable1.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_changephoneinfo_image), PorterDuff.Mode.SRC_IN));
drawable2.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_changephoneinfo_image2), PorterDuff.Mode.MULTIPLY)); drawable2.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_changephoneinfo_image2), PorterDuff.Mode.SRC_IN));
imageView.setImageDrawable(new CombinedDrawable(drawable1, drawable2)); imageView.setImageDrawable(new CombinedDrawable(drawable1, drawable2));
imageView.setScaleType(ImageView.ScaleType.CENTER); imageView.setScaleType(ImageView.ScaleType.CENTER);
UserConfig userConfig = getUserConfig(); UserConfig userConfig = getUserConfig();
@ -668,7 +673,7 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
return; return;
} }
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); builder.setTitle(LocaleController.getString("NekoX", R.string.NekoX));
builder.setMessage(LocaleController.getString("PermissionNoLocationPosition", R.string.PermissionNoLocationPosition)); builder.setMessage(LocaleController.getString("PermissionNoLocationPosition", R.string.PermissionNoLocationPosition));
builder.setNegativeButton(LocaleController.getString("PermissionOpenSettings", R.string.PermissionOpenSettings), (dialog, which) -> { builder.setNegativeButton(LocaleController.getString("PermissionOpenSettings", R.string.PermissionOpenSettings), (dialog, which) -> {
if (getParentActivity() == null) { if (getParentActivity() == null) {
@ -722,7 +727,7 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
if (grantResults != null && grantResults.length != 0) { if (grantResults != null && grantResults.length != 0) {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) { if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); builder.setTitle(LocaleController.getString("NekoX", R.string.NekoX));
builder.setMessage(LocaleController.getString("PermissionNoLocationPosition", R.string.PermissionNoLocationPosition)); builder.setMessage(LocaleController.getString("PermissionNoLocationPosition", R.string.PermissionNoLocationPosition));
builder.setNegativeButton(LocaleController.getString("PermissionOpenSettings", R.string.PermissionOpenSettings), (dialog, which) -> { builder.setNegativeButton(LocaleController.getString("PermissionOpenSettings", R.string.PermissionOpenSettings), (dialog, which) -> {
if (getParentActivity() == null) { if (getParentActivity() == null) {
@ -747,7 +752,7 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
processOpenQrReader(); processOpenQrReader();
} else { } else {
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); builder.setTitle(LocaleController.getString("NekoX", R.string.NekoX));
builder.setMessage(LocaleController.getString("QRCodePermissionNoCamera", R.string.QRCodePermissionNoCamera)); builder.setMessage(LocaleController.getString("QRCodePermissionNoCamera", R.string.QRCodePermissionNoCamera));
builder.setNegativeButton(LocaleController.getString("PermissionOpenSettings", R.string.PermissionOpenSettings), (dialog, which) -> { builder.setNegativeButton(LocaleController.getString("PermissionOpenSettings", R.string.PermissionOpenSettings), (dialog, which) -> {
try { try {

View File

@ -14,19 +14,25 @@ import android.content.SharedPreferences;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.DrawerActionCell;
import org.telegram.ui.Cells.DividerCell; import org.telegram.ui.Cells.DividerCell;
import org.telegram.ui.Cells.DrawerActionCell;
import org.telegram.ui.Cells.DrawerActionCheckCell;
import org.telegram.ui.Cells.DrawerAddCell; import org.telegram.ui.Cells.DrawerAddCell;
import org.telegram.ui.Cells.DrawerProfileCell;
import org.telegram.ui.Cells.DrawerUserCell; import org.telegram.ui.Cells.DrawerUserCell;
import org.telegram.ui.Cells.EmptyCell; import org.telegram.ui.Cells.EmptyCell;
import org.telegram.ui.Cells.DrawerProfileCell;
import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.SideMenultItemAnimator; import org.telegram.ui.Components.SideMenultItemAnimator;
@ -34,12 +40,13 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Locale; import java.util.Locale;
import androidx.recyclerview.widget.RecyclerView; import kotlin.jvm.functions.Function0;
import tw.nekomimi.nekogram.NekoConfig;
public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter { public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter implements NotificationCenter.NotificationCenterDelegate {
private Context mContext; private Context mContext;
private ArrayList<Item> items = new ArrayList<>(11); public ArrayList<Item> items = new ArrayList<>(11);
private ArrayList<Integer> accountNumbers = new ArrayList<>(); private ArrayList<Integer> accountNumbers = new ArrayList<>();
private boolean accountsShown; private boolean accountsShown;
private DrawerProfileCell profileCell; private DrawerProfileCell profileCell;
@ -48,7 +55,7 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
public DrawerLayoutAdapter(Context context, SideMenultItemAnimator animator) { public DrawerLayoutAdapter(Context context, SideMenultItemAnimator animator) {
mContext = context; mContext = context;
itemAnimator = animator; itemAnimator = animator;
accountsShown = UserConfig.getActivatedAccountsCount() > 1 && MessagesController.getGlobalMainSettings().getBoolean("accountsShown", true); accountsShown = true;
Theme.createDialogsResources(context); Theme.createDialogsResources(context);
resetItems(); resetItems();
} }
@ -78,7 +85,7 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
if (profileCell != null) { if (profileCell != null) {
profileCell.setAccountsShown(accountsShown, animated); profileCell.setAccountsShown(accountsShown, animated);
} }
MessagesController.getGlobalMainSettings().edit().putBoolean("accountsShown", accountsShown).commit(); MessagesController.getGlobalMainSettings().edit().putBoolean("accountsShown", accountsShown).apply();
if (animated) { if (animated) {
itemAnimator.setShouldClipChildren(false); itemAnimator.setShouldClipChildren(false);
if (accountsShown) { if (accountsShown) {
@ -95,6 +102,11 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
return accountsShown; return accountsShown;
} }
@Override public void didReceivedNotification(int id, int account, Object... args) {
resetItems();
notifyDataSetChanged();
}
@Override @Override
public void notifyDataSetChanged() { public void notifyDataSetChanged() {
resetItems(); resetItems();
@ -120,6 +132,9 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
case 3: case 3:
view = new DrawerActionCell(mContext); view = new DrawerActionCell(mContext);
break; break;
case 6:
view = new DrawerActionCheckCell(mContext);
break;
case 4: case 4:
view = new DrawerUserCell(mContext); view = new DrawerUserCell(mContext);
break; break;
@ -153,8 +168,19 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
drawerActionCell.setPadding(0, 0, 0, 0); drawerActionCell.setPadding(0, 0, 0, 0);
break; break;
} }
case 6: {
DrawerActionCheckCell drawerActionCell = (DrawerActionCheckCell) holder.itemView;
position -= 2;
if (accountsShown) {
position -= getAccountRowsCount();
}
((CheckItem) items.get(position)).bindCheck(drawerActionCell);
drawerActionCell.setPadding(0, 0, 0, 0);
break;
}
case 4: { case 4: {
DrawerUserCell drawerUserCell = (DrawerUserCell) holder.itemView; DrawerUserCell drawerUserCell = (DrawerUserCell) holder.itemView;
drawerUserCell.invalidate();
drawerUserCell.setAccount(accountNumbers.get(position - 2)); drawerUserCell.setAccount(accountNumbers.get(position - 2));
break; break;
} }
@ -174,7 +200,7 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
return 4; return 4;
} else { } else {
if (accountNumbers.size() < UserConfig.MAX_ACCOUNT_COUNT) { if (accountNumbers.size() < UserConfig.MAX_ACCOUNT_COUNT) {
if (i == accountNumbers.size()){ if (i == accountNumbers.size()) {
return 5; return 5;
} else if (i == accountNumbers.size() + 1) { } else if (i == accountNumbers.size() + 1) {
return 2; return 2;
@ -190,7 +216,7 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
if (items.get(i) == null) { if (items.get(i) == null) {
return 2; return 2;
} }
return 3; return items.get(i) instanceof CheckItem ? 6 : 3;
} }
private void resetItems() { private void resetItems() {
@ -221,56 +247,23 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
return; return;
} }
int eventType = Theme.getEventType(); int eventType = Theme.getEventType();
int newGroupIcon; int contactsIcon = R.drawable.baseline_perm_contact_calendar_24;
int newSecretIcon; int savedIcon = R.drawable.baseline_bookmark_24;
int newChannelIcon; int settingsIcon = R.drawable.baseline_settings_24;
int contactsIcon; int inviteIcon = R.drawable.baseline_person_add_24;
int callsIcon; int helpIcon = R.drawable.baseline_help_24;
int savedIcon;
int settingsIcon;
int inviteIcon;
int helpIcon;
if (eventType == 0) {
newGroupIcon = R.drawable.menu_groups_ny;
newSecretIcon = R.drawable.menu_secret_ny;
newChannelIcon = R.drawable.menu_channel_ny;
contactsIcon = R.drawable.menu_contacts_ny;
callsIcon = R.drawable.menu_calls_ny;
savedIcon = R.drawable.menu_bookmarks_ny;
settingsIcon = R.drawable.menu_settings_ny;
inviteIcon = R.drawable.menu_invite_ny;
helpIcon = R.drawable.menu_help_ny;
} else if (eventType == 1) {
newGroupIcon = R.drawable.menu_groups_14;
newSecretIcon = R.drawable.menu_secret_14;
newChannelIcon = R.drawable.menu_broadcast_14;
contactsIcon = R.drawable.menu_contacts_14;
callsIcon = R.drawable.menu_calls_14;
savedIcon = R.drawable.menu_bookmarks_14;
settingsIcon = R.drawable.menu_settings_14;
inviteIcon = R.drawable.menu_secret_ny;
helpIcon = R.drawable.menu_help;
} else {
newGroupIcon = R.drawable.menu_groups;
newSecretIcon = R.drawable.menu_secret;
newChannelIcon = R.drawable.menu_broadcast;
contactsIcon = R.drawable.menu_contacts;
callsIcon = R.drawable.menu_calls;
savedIcon = R.drawable.menu_saved;
settingsIcon = R.drawable.menu_settings;
inviteIcon = R.drawable.menu_invite;
helpIcon = R.drawable.menu_help;
}
items.add(new Item(2, LocaleController.getString("NewGroup", R.string.NewGroup), newGroupIcon));
items.add(new Item(3, LocaleController.getString("NewSecretChat", R.string.NewSecretChat), newSecretIcon));
items.add(new Item(4, LocaleController.getString("NewChannel", R.string.NewChannel), newChannelIcon));
items.add(new Item(6, LocaleController.getString("Contacts", R.string.Contacts), contactsIcon)); items.add(new Item(6, LocaleController.getString("Contacts", R.string.Contacts), contactsIcon));
items.add(new Item(10, LocaleController.getString("Calls", R.string.Calls), callsIcon));
items.add(new Item(11, LocaleController.getString("SavedMessages", R.string.SavedMessages), savedIcon)); items.add(new Item(11, LocaleController.getString("SavedMessages", R.string.SavedMessages), savedIcon));
items.add(new Item(8, LocaleController.getString("Settings", R.string.Settings), settingsIcon)); items.add(new Item(8, LocaleController.getString("Settings", R.string.Settings), settingsIcon));
items.add(null); // divider
items.add(new Item(7, LocaleController.getString("InviteFriends", R.string.InviteFriends), inviteIcon)); items.add(new Item(7, LocaleController.getString("InviteFriends", R.string.InviteFriends), inviteIcon));
items.add(new Item(9, LocaleController.getString("TelegramFAQ", R.string.TelegramFAQ), helpIcon)); if (NekoConfig.useProxyItem && (!NekoConfig.hideProxyByDefault || SharedConfig.proxyEnabled)) {
items.add(new CheckItem(13, LocaleController.getString("Proxy", R.string.Proxy), R.drawable.baseline_security_24, () -> SharedConfig.proxyEnabled, () -> {
SharedConfig.setProxyEnable(!SharedConfig.proxyEnabled);
return true;
}));
}
items.add(null); // divider
items.add(new CheckItem(12,LocaleController.getString("DarkMode",R.string.NightMode),R.drawable.baseline_brightness_2_24,() -> Theme.getActiveTheme().isDark(),null));
} }
public int getId(int position) { public int getId(int position) {
@ -285,7 +278,19 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
return item != null ? item.id : -1; return item != null ? item.id : -1;
} }
private class Item { public CheckItem getItem(int position) {
position -= 2;
if (accountsShown) {
position -= getAccountRowsCount();
}
if (position < 0 || position >= items.size()) {
return null;
}
Item item = items.get(position);
return item instanceof CheckItem ? (CheckItem) item : null;
}
public class Item {
public int icon; public int icon;
public String text; public String text;
public int id; public int id;
@ -301,6 +306,30 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
} }
} }
public class CheckItem extends Item {
public Function0<Boolean> isChecked;
public Function0<Boolean> doSwitch;
public CheckItem(int id, String text, int icon, Function0<Boolean> isChecked,@Nullable Function0<Boolean> doSwitch) {
super(id, text, icon);
this.isChecked = isChecked;
this.doSwitch = doSwitch;
}
public void bindCheck(DrawerActionCheckCell actionCell) {
actionCell.setTextAndValueAndCheck(text, icon, null, isChecked.invoke(), false, false);
if (doSwitch != null) {
actionCell.setOnCheckClickListener((v) -> {
if (doSwitch.invoke()) {
actionCell.setChecked(isChecked.invoke());
}
});
}
}
}
public int getAccountsCount() { public int getAccountsCount() {
return accountNumbers.size(); return accountNumbers.size();
} }

View File

@ -38,7 +38,7 @@ public class DrawerAddCell extends FrameLayout {
textView.setMaxLines(1); textView.setMaxLines(1);
textView.setSingleLine(true); textView.setSingleLine(true);
textView.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL); textView.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
textView.setCompoundDrawablePadding(AndroidUtilities.dp(34)); textView.setCompoundDrawablePadding(AndroidUtilities.dp(29));
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 23, 0, 16, 0)); addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 23, 0, 16, 0));
} }
@ -54,7 +54,7 @@ public class DrawerAddCell extends FrameLayout {
textView.setText(LocaleController.getString("AddAccount", R.string.AddAccount)); textView.setText(LocaleController.getString("AddAccount", R.string.AddAccount));
Drawable drawable = getResources().getDrawable(R.drawable.account_add); Drawable drawable = getResources().getDrawable(R.drawable.account_add);
if (drawable != null) { if (drawable != null) {
drawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_chats_menuItemIcon), PorterDuff.Mode.MULTIPLY)); drawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_chats_menuItemIcon), PorterDuff.Mode.SRC_IN));
} }
textView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null); textView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
} }

View File

@ -15,22 +15,23 @@ import android.os.Build;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import java.util.ArrayList; import java.util.ArrayList;
public class HeaderCell extends FrameLayout { public class HeaderCell extends LinearLayout {
private TextView textView; private TextView textView;
private SimpleTextView textView2; private TextView textView2;
private int height = 40; private int height = 40;
public HeaderCell(Context context) { public HeaderCell(Context context) {
@ -42,24 +43,43 @@ public class HeaderCell extends FrameLayout {
} }
public HeaderCell(Context context, String textColorKey, int padding, int topMargin, boolean text2) { public HeaderCell(Context context, String textColorKey, int padding, int topMargin, boolean text2) {
this(context, textColorKey, padding, topMargin, text2, false);
}
public HeaderCell(Context context, String textColorKey, int padding, int topMargin, boolean text2,boolean bigTitle) {
super(context); super(context);
setOrientation(LinearLayout.VERTICAL);
setPadding(AndroidUtilities.dp(padding), AndroidUtilities.dp(topMargin), AndroidUtilities.dp(padding), 0);
textView = new TextView(getContext()); textView = new TextView(getContext());
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); if (bigTitle) {
textView.setTypeface(AndroidUtilities.getTypeface("fonts/mw_bold.ttf"));
}
textView.setEllipsize(TextUtils.TruncateAt.END); textView.setEllipsize(TextUtils.TruncateAt.END);
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL); textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
textView.setMinHeight(AndroidUtilities.dp(height - topMargin)); textView.setMinHeight(AndroidUtilities.dp(height - topMargin));
textView.setTextColor(Theme.getColor(textColorKey)); textView.setTextColor(Theme.getColor(textColorKey));
textView.setTag(textColorKey); textView.setTag(textColorKey);
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, padding, topMargin, padding, 0)); addView(textView, LayoutHelper.createLinear(-1, -2));
if (text2) { textView2 = new TextView(getContext());
textView2 = new SimpleTextView(getContext()); textView2.setTextSize(13);
textView2.setTextSize(13); textView2.setMovementMethod(new AndroidUtilities.LinkMovementMethodMy());
textView2.setGravity((LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.TOP); textView2.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
addView(textView2, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.TOP, padding, 21, padding, 0)); addView(textView2, LayoutHelper.createLinear(-2, -2, 0, 4, 0, 0));
}
if (!text2) textView2.setVisibility(View.GONE);
}
@Override
public void setLayoutParams(ViewGroup.LayoutParams params) {
params.width = -1;
super.setLayoutParams(params);
} }
public void setHeight(int value) { public void setHeight(int value) {
@ -74,18 +94,13 @@ public class HeaderCell extends FrameLayout {
} }
} }
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
}
public void setText(CharSequence text) { public void setText(CharSequence text) {
textView.setText(text); textView.setText(text);
} }
public void setText2(CharSequence text) { public void setText2(CharSequence text) {
if (textView2 == null) { if (textView2.getVisibility() != View.VISIBLE) {
return; textView2.setVisibility(View.VISIBLE);
} }
textView2.setText(text); textView2.setText(text);
} }
@ -93,8 +108,7 @@ public class HeaderCell extends FrameLayout {
public TextView getTextView() { public TextView getTextView() {
return textView; return textView;
} }
public TextView getTextView2() {
public SimpleTextView getTextView2() {
return textView2; return textView2;
} }

View File

@ -12,9 +12,8 @@ import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
@ -23,8 +22,9 @@ import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RadioButton; import org.telegram.ui.Components.RadioButton;
public class RadioButtonCell extends FrameLayout { public class RadioButtonCell extends LinearLayout {
private LinearLayout textLayout;
private TextView textView; private TextView textView;
private TextView valueTextView; private TextView valueTextView;
private RadioButton radioButton; private RadioButton radioButton;
@ -37,14 +37,17 @@ public class RadioButtonCell extends FrameLayout {
public RadioButtonCell(Context context, boolean dialog) { public RadioButtonCell(Context context, boolean dialog) {
super(context); super(context);
radioButton = new RadioButton(context); setOrientation(LinearLayout.HORIZONTAL);
radioButton.setSize(AndroidUtilities.dp(20)); setGravity(Gravity.CENTER_VERTICAL);
if (dialog) {
radioButton.setColor(Theme.getColor(Theme.key_dialogRadioBackground), Theme.getColor(Theme.key_dialogRadioBackgroundChecked)); textLayout = new LinearLayout(context);
} else { textLayout.setOrientation(LinearLayout.VERTICAL);
radioButton.setColor(Theme.getColor(Theme.key_radioBackground), Theme.getColor(Theme.key_radioBackgroundChecked)); textLayout.setGravity(Gravity.CENTER);
} int padding = AndroidUtilities.dp(10);
addView(radioButton, LayoutHelper.createFrame(22, 22, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 0 : 20), 10, (LocaleController.isRTL ? 20 : 0), 0)); textLayout.setPadding(AndroidUtilities.dp(24),padding,padding,padding);
addView(textLayout, new LinearLayout.LayoutParams(-1, -2) {{
weight = 1;
}});
textView = new TextView(context); textView = new TextView(context);
if (dialog) { if (dialog) {
@ -53,11 +56,8 @@ public class RadioButtonCell extends FrameLayout {
textView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText)); textView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
} }
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
textView.setLines(1);
textView.setMaxLines(1);
textView.setSingleLine(true);
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL); textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 23 : 61), 10, (LocaleController.isRTL ? 61 : 23), 0)); textLayout.addView(textView, LayoutHelper.createLinear(-2, -2, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 0, 0, 0, 5));
valueTextView = new TextView(context); valueTextView = new TextView(context);
if (dialog) { if (dialog) {
@ -70,18 +70,30 @@ public class RadioButtonCell extends FrameLayout {
valueTextView.setLines(0); valueTextView.setLines(0);
valueTextView.setMaxLines(0); valueTextView.setMaxLines(0);
valueTextView.setSingleLine(false); valueTextView.setSingleLine(false);
valueTextView.setPadding(0, 0, 0, AndroidUtilities.dp(12)); textLayout.addView(valueTextView, LayoutHelper.createLinear(-2, -2, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP));
addView(valueTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 17 : 61), 35, (LocaleController.isRTL ? 61 : 17), 0));
radioButton = new RadioButton(context);
radioButton.setSize(AndroidUtilities.dp(20));
if (dialog) {
radioButton.setColor(Theme.getColor(Theme.key_dialogRadioBackground), Theme.getColor(Theme.key_dialogRadioBackgroundChecked));
} else {
radioButton.setColor(Theme.getColor(Theme.key_radioBackground), Theme.getColor(Theme.key_radioBackgroundChecked));
}
addView(radioButton, LayoutHelper.createLinear(22, 22, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL,0,0,21,0));
} }
@Override public void setTextAndValue(String text, boolean divider, boolean checked) {
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { textView.setText(text);
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); valueTextView.setVisibility(GONE);
radioButton.setChecked(checked, false);
needDivider = divider;
} }
public void setTextAndValue(String text, String value, boolean divider, boolean checked) { public void setTextAndValueAndCheck(String text, String value, boolean divider, boolean checked) {
textView.setText(text); textView.setText(text);
valueTextView.setText(value); valueTextView.setText(value);
valueTextView.setVisibility(VISIBLE);
radioButton.setChecked(checked, false); radioButton.setChecked(checked, false);
needDivider = divider; needDivider = divider;
} }
@ -90,6 +102,10 @@ public class RadioButtonCell extends FrameLayout {
radioButton.setChecked(checked, animated); radioButton.setChecked(checked, animated);
} }
public boolean isChecked() {
return radioButton.isChecked();
}
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw(Canvas canvas) {
if (needDivider) { if (needDivider) {

View File

@ -42,6 +42,9 @@ public class RadioColorCell extends FrameLayout {
textView.setSingleLine(true); textView.setSingleLine(true);
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL); textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 21 : 51), 13, (LocaleController.isRTL ? 51 : 21), 0)); addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 21 : 51), 13, (LocaleController.isRTL ? 51 : 21), 0));
setBackground(Theme.createSelectorDrawable(Theme.getColor(Theme.key_actionBarActionModeDefaultSelector), 3));
} }
@Override @Override

View File

@ -92,8 +92,8 @@ public class SessionCell extends FrameLayout {
detailTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); detailTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
detailTextView.setLines(1); detailTextView.setLines(1);
detailTextView.setMaxLines(1); detailTextView.setMaxLines(1);
detailTextView.setSingleLine(true); //detailTextView.setSingleLine(true);
detailTextView.setEllipsize(TextUtils.TruncateAt.END); //detailTextView.setEllipsize(TextUtils.TruncateAt.END);
detailTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP); detailTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
addView(detailTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 21, 36, 21, 0)); addView(detailTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 21, 36, 21, 0));

View File

@ -55,8 +55,9 @@ public class TextCell extends FrameLayout {
addView(valueTextView); addView(valueTextView);
imageView = new ImageView(context); imageView = new ImageView(context);
imageView.setVisibility(GONE);
imageView.setScaleType(ImageView.ScaleType.CENTER); imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(dialog ? Theme.key_dialogIcon : Theme.key_windowBackgroundWhiteGrayIcon), PorterDuff.Mode.MULTIPLY)); imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(dialog ? Theme.key_dialogIcon : Theme.key_windowBackgroundWhiteGrayIcon), PorterDuff.Mode.SRC_IN));
addView(imageView); addView(imageView);
valueImageView = new ImageView(context); valueImageView = new ImageView(context);
@ -132,7 +133,7 @@ public class TextCell extends FrameLayout {
textView.setTextColor(Theme.getColor(text)); textView.setTextColor(Theme.getColor(text));
textView.setTag(text); textView.setTag(text);
if (icon != null) { if (icon != null) {
imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(icon), PorterDuff.Mode.MULTIPLY)); imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(icon), PorterDuff.Mode.SRC_IN));
imageView.setTag(icon); imageView.setTag(icon);
} }
} }
@ -150,11 +151,13 @@ public class TextCell extends FrameLayout {
public void setTextAndIcon(String text, int resId, boolean divider) { public void setTextAndIcon(String text, int resId, boolean divider) {
textView.setText(text); textView.setText(text);
valueTextView.setText(null); valueTextView.setText(null);
imageView.setImageResource(resId); if (resId != 0) {
imageView.setVisibility(VISIBLE); imageView.setImageResource(resId);
imageView.setVisibility(VISIBLE);
}
imageView.setPadding(0, AndroidUtilities.dp(7), 0, 0);
valueTextView.setVisibility(GONE); valueTextView.setVisibility(GONE);
valueImageView.setVisibility(GONE); valueImageView.setVisibility(GONE);
imageView.setPadding(0, AndroidUtilities.dp(7), 0, 0);
needDivider = divider; needDivider = divider;
setWillNotDraw(!needDivider); setWillNotDraw(!needDivider);
} }

View File

@ -14,7 +14,10 @@ import android.animation.ObjectAnimator;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Property; import android.util.Property;
import android.util.TypedValue; import android.util.TypedValue;
@ -25,13 +28,16 @@ import android.widget.FrameLayout;
import android.widget.TextView; import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimationProperties; import org.telegram.ui.Components.AnimationProperties;
import org.telegram.ui.Components.CheckBoxSquare;
import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.Switch; import org.telegram.ui.Components.Switch;
import org.telegram.ui.Components.ViewHelper;
import java.util.ArrayList; import java.util.ArrayList;
@ -40,6 +46,7 @@ public class TextCheckCell extends FrameLayout {
private TextView textView; private TextView textView;
private TextView valueTextView; private TextView valueTextView;
private Switch checkBox; private Switch checkBox;
private CheckBoxSquare checkBoxSquare;
private boolean needDivider; private boolean needDivider;
private boolean isMultiline; private boolean isMultiline;
private int height = 50; private int height = 50;
@ -77,11 +84,7 @@ public class TextCheckCell extends FrameLayout {
textView = new TextView(context); textView = new TextView(context);
textView.setTextColor(Theme.getColor(dialog ? Theme.key_dialogTextBlack : Theme.key_windowBackgroundWhiteBlackText)); textView.setTextColor(Theme.getColor(dialog ? Theme.key_dialogTextBlack : Theme.key_windowBackgroundWhiteBlackText));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
textView.setLines(1);
textView.setMaxLines(1);
textView.setSingleLine(true);
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL); textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
textView.setEllipsize(TextUtils.TruncateAt.END);
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 70 : padding, 0, LocaleController.isRTL ? padding : 70, 0)); addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 70 : padding, 0, LocaleController.isRTL ? padding : 70, 0));
valueTextView = new TextView(context); valueTextView = new TextView(context);
@ -95,9 +98,18 @@ public class TextCheckCell extends FrameLayout {
valueTextView.setEllipsize(TextUtils.TruncateAt.END); valueTextView.setEllipsize(TextUtils.TruncateAt.END);
addView(valueTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 64 : padding, 36, LocaleController.isRTL ? padding : 64, 0)); addView(valueTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 64 : padding, 36, LocaleController.isRTL ? padding : 64, 0));
checkBox = new Switch(context); if (!dialog) {
checkBox.setColors(Theme.key_switchTrack, Theme.key_switchTrackChecked, Theme.key_windowBackgroundWhite, Theme.key_windowBackgroundWhite);
addView(checkBox, LayoutHelper.createFrame(37, 20, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.CENTER_VERTICAL, 22, 0, 22, 0)); checkBox = new Switch(context);
checkBox.setColors(Theme.key_switchTrack, Theme.key_switchTrackChecked, Theme.key_windowBackgroundWhite, Theme.key_windowBackgroundWhite);
addView(checkBox, LayoutHelper.createFrame(37, 20, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.CENTER_VERTICAL, 22, 0, 22, 0));
} else {
checkBoxSquare = new CheckBoxSquare(context,true);
addView(checkBoxSquare, LayoutHelper.createFrame(18, 18, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.CENTER_VERTICAL, 22, 0, 22, 0));
}
setClipChildren(false); setClipChildren(false);
} }
@ -107,7 +119,7 @@ public class TextCheckCell extends FrameLayout {
if (isMultiline) { if (isMultiline) {
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
} else { } else {
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(valueTextView.getVisibility() == VISIBLE ? 64 : height) + (needDivider ? 1 : 0), MeasureSpec.EXACTLY)); super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(valueTextView.getVisibility() == VISIBLE ? 64 : height) + (needDivider ? 3 : 0), MeasureSpec.EXACTLY));
} }
} }
@ -120,7 +132,11 @@ public class TextCheckCell extends FrameLayout {
public void setTextAndCheck(String text, boolean checked, boolean divider) { public void setTextAndCheck(String text, boolean checked, boolean divider) {
textView.setText(text); textView.setText(text);
isMultiline = false; isMultiline = false;
checkBox.setChecked(checked, false); if (checkBox != null) {
checkBox.setChecked(checked, false);
} else {
checkBoxSquare.setChecked(checked,false);
}
needDivider = divider; needDivider = divider;
valueTextView.setVisibility(GONE); valueTextView.setVisibility(GONE);
LayoutParams layoutParams = (LayoutParams) textView.getLayoutParams(); LayoutParams layoutParams = (LayoutParams) textView.getLayoutParams();
@ -150,7 +166,7 @@ public class TextCheckCell extends FrameLayout {
@Override @Override
public void setPressed(boolean pressed) { public void setPressed(boolean pressed) {
if (drawCheckRipple) { if (drawCheckRipple && checkBox != null) {
checkBox.setDrawRipple(pressed); checkBox.setDrawRipple(pressed);
} }
super.setPressed(pressed); super.setPressed(pressed);
@ -159,7 +175,11 @@ public class TextCheckCell extends FrameLayout {
public void setTextAndValueAndCheck(String text, String value, boolean checked, boolean multiline, boolean divider) { public void setTextAndValueAndCheck(String text, String value, boolean checked, boolean multiline, boolean divider) {
textView.setText(text); textView.setText(text);
valueTextView.setText(value); valueTextView.setText(value);
checkBox.setChecked(checked, false); if (checkBox != null) {
checkBox.setChecked(checked, false);
} else {
checkBoxSquare.setChecked(checked,false);
}
needDivider = divider; needDivider = divider;
valueTextView.setVisibility(VISIBLE); valueTextView.setVisibility(VISIBLE);
isMultiline = multiline; isMultiline = multiline;
@ -187,13 +207,17 @@ public class TextCheckCell extends FrameLayout {
super.setEnabled(value); super.setEnabled(value);
if (animators != null) { if (animators != null) {
animators.add(ObjectAnimator.ofFloat(textView, "alpha", value ? 1.0f : 0.5f)); animators.add(ObjectAnimator.ofFloat(textView, "alpha", value ? 1.0f : 0.5f));
animators.add(ObjectAnimator.ofFloat(checkBox, "alpha", value ? 1.0f : 0.5f)); if (checkBox != null) {
animators.add(ObjectAnimator.ofFloat(checkBox, "alpha", value ? 1.0f : 0.5f));
} else {
animators.add(ObjectAnimator.ofFloat(checkBoxSquare, "alpha", value ? 1.0f : 0.5f));
}
if (valueTextView.getVisibility() == VISIBLE) { if (valueTextView.getVisibility() == VISIBLE) {
animators.add(ObjectAnimator.ofFloat(valueTextView, "alpha", value ? 1.0f : 0.5f)); animators.add(ObjectAnimator.ofFloat(valueTextView, "alpha", value ? 1.0f : 0.5f));
} }
} else { } else {
textView.setAlpha(value ? 1.0f : 0.5f); textView.setAlpha(value ? 1.0f : 0.5f);
checkBox.setAlpha(value ? 1.0f : 0.5f); (checkBox != null ? checkBox : checkBoxSquare).setAlpha(value ? 1.0f : 0.5f);
if (valueTextView.getVisibility() == VISIBLE) { if (valueTextView.getVisibility() == VISIBLE) {
valueTextView.setAlpha(value ? 1.0f : 0.5f); valueTextView.setAlpha(value ? 1.0f : 0.5f);
} }
@ -201,11 +225,15 @@ public class TextCheckCell extends FrameLayout {
} }
public void setChecked(boolean checked) { public void setChecked(boolean checked) {
checkBox.setChecked(checked, true); if (checkBox != null) {
checkBox.setChecked(checked, true);
} else {
checkBoxSquare.setChecked(checked,true);
}
} }
public boolean isChecked() { public boolean isChecked() {
return checkBox.isChecked(); return checkBox != null ? checkBox.isChecked() : checkBoxSquare.isChecked();
} }
@Override @Override
@ -226,7 +254,9 @@ public class TextCheckCell extends FrameLayout {
if (animationPaint == null) { if (animationPaint == null) {
animationPaint = new Paint(Paint.ANTI_ALIAS_FLAG); animationPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
} }
checkBox.setOverrideColor(checked ? 1 : 2); if (checkBox != null) {
checkBox.setOverrideColor(checked ? 1 : 2);
}
animatedColorBackground = color; animatedColorBackground = color;
animationPaint.setColor(animatedColorBackground); animationPaint.setColor(animatedColorBackground);
animationProgress = 0.0f; animationProgress = 0.0f;
@ -262,7 +292,7 @@ public class TextCheckCell extends FrameLayout {
canvas.drawCircle(cx, cy, animatedRad, animationPaint); canvas.drawCircle(cx, cy, animatedRad, animationPaint);
} }
if (needDivider) { if (needDivider) {
canvas.drawLine(LocaleController.isRTL ? 0 : AndroidUtilities.dp(20), getMeasuredHeight() - 1, getMeasuredWidth() - (LocaleController.isRTL ? AndroidUtilities.dp(20) : 0), getMeasuredHeight() - 1, Theme.dividerPaint); canvas.drawLine(LocaleController.isRTL ? 0 : AndroidUtilities.dp(20), getMeasuredHeight() - 3, getMeasuredWidth() - (LocaleController.isRTL ? AndroidUtilities.dp(20) : 0), getMeasuredHeight() - 3, Theme.dividerPaint);
} }
} }
@ -271,7 +301,7 @@ public class TextCheckCell extends FrameLayout {
super.onInitializeAccessibilityNodeInfo(info); super.onInitializeAccessibilityNodeInfo(info);
info.setClassName("android.widget.Switch"); info.setClassName("android.widget.Switch");
info.setCheckable(true); info.setCheckable(true);
info.setChecked(checkBox.isChecked()); info.setChecked(isChecked());
info.setContentDescription(checkBox.isChecked() ? LocaleController.getString("NotificationsOn", R.string.NotificationsOn) : LocaleController.getString("NotificationsOff", R.string.NotificationsOff)); info.setContentDescription(isChecked() ? LocaleController.getString("NotificationsOn", R.string.NotificationsOn) : LocaleController.getString("NotificationsOff", R.string.NotificationsOff));
} }
} }

View File

@ -25,6 +25,8 @@ import org.telegram.messenger.LocaleController;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import cn.hutool.core.util.StrUtil;
public class TextDetailSettingsCell extends FrameLayout { public class TextDetailSettingsCell extends FrameLayout {
private TextView textView; private TextView textView;
@ -58,7 +60,7 @@ public class TextDetailSettingsCell extends FrameLayout {
imageView = new ImageView(context); imageView = new ImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER); imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayIcon), PorterDuff.Mode.MULTIPLY)); imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayIcon), PorterDuff.Mode.SRC_IN));
imageView.setVisibility(GONE); imageView.setVisibility(GONE);
addView(imageView, LayoutHelper.createFrame(52, 52, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 8, 6, 8, 0)); addView(imageView, LayoutHelper.createFrame(52, 52, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 8, 6, 8, 0));
} }
@ -97,6 +99,11 @@ public class TextDetailSettingsCell extends FrameLayout {
public void setTextAndValue(String text, CharSequence value, boolean divider) { public void setTextAndValue(String text, CharSequence value, boolean divider) {
textView.setText(text); textView.setText(text);
if (StrUtil.isBlank(value)) {
valueTextView.setVisibility(GONE);
} else {
valueTextView.setVisibility(VISIBLE);
}
valueTextView.setText(value); valueTextView.setText(value);
needDivider = divider; needDivider = divider;
imageView.setVisibility(GONE); imageView.setVisibility(GONE);

View File

@ -16,6 +16,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.PorterDuffColorFilter;
import android.os.Bundle; import android.os.Bundle;
import android.os.Vibrator; import android.os.Vibrator;
import android.text.Editable; import android.text.Editable;
@ -70,6 +71,9 @@ import org.telegram.ui.Components.SizeNotifierFrameLayout;
import java.util.ArrayList; import java.util.ArrayList;
import kotlin.Unit;
import tw.nekomimi.nekogram.BottomBuilder;
public class ChannelCreateActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate, ImageUpdater.ImageUpdaterDelegate { public class ChannelCreateActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate, ImageUpdater.ImageUpdaterDelegate {
private View doneButton; private View doneButton;
@ -474,7 +478,9 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
} }
}; };
avatarEditor.setScaleType(ImageView.ScaleType.CENTER); avatarEditor.setScaleType(ImageView.ScaleType.CENTER);
avatarEditor.setImageResource(R.drawable.menu_camera_av); avatarEditor.setImageResource(R.drawable.deproko_baseline_camera_26);
avatarEditor.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_actionBarDefaultIcon), PorterDuff.Mode.SRC_IN));
avatarEditor.setEnabled(false); avatarEditor.setEnabled(false);
avatarEditor.setClickable(false); avatarEditor.setClickable(false);
frameLayout.addView(avatarEditor, LayoutHelper.createFrame(64, 64, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), LocaleController.isRTL ? 0 : 16, 12, LocaleController.isRTL ? 16 : 0, 12)); frameLayout.addView(avatarEditor, LayoutHelper.createFrame(64, 64, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), LocaleController.isRTL ? 0 : 16, 12, LocaleController.isRTL ? 16 : 0, 12));
@ -569,7 +575,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
radioButtonCell1 = new RadioButtonCell(context); radioButtonCell1 = new RadioButtonCell(context);
radioButtonCell1.setBackgroundDrawable(Theme.getSelectorDrawable(false)); radioButtonCell1.setBackgroundDrawable(Theme.getSelectorDrawable(false));
radioButtonCell1.setTextAndValue(LocaleController.getString("ChannelPublic", R.string.ChannelPublic), LocaleController.getString("ChannelPublicInfo", R.string.ChannelPublicInfo), false, !isPrivate); radioButtonCell1.setTextAndValueAndCheck(LocaleController.getString("ChannelPublic", R.string.ChannelPublic), LocaleController.getString("ChannelPublicInfo", R.string.ChannelPublicInfo), false, !isPrivate);
linearLayout2.addView(radioButtonCell1, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); linearLayout2.addView(radioButtonCell1, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
radioButtonCell1.setOnClickListener(v -> { radioButtonCell1.setOnClickListener(v -> {
if (!isPrivate) { if (!isPrivate) {
@ -581,7 +587,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
radioButtonCell2 = new RadioButtonCell(context); radioButtonCell2 = new RadioButtonCell(context);
radioButtonCell2.setBackgroundDrawable(Theme.getSelectorDrawable(false)); radioButtonCell2.setBackgroundDrawable(Theme.getSelectorDrawable(false));
radioButtonCell2.setTextAndValue(LocaleController.getString("ChannelPrivate", R.string.ChannelPrivate), LocaleController.getString("ChannelPrivateInfo", R.string.ChannelPrivateInfo), false, isPrivate); radioButtonCell2.setTextAndValueAndCheck(LocaleController.getString("ChannelPrivate", R.string.ChannelPrivate), LocaleController.getString("ChannelPrivateInfo", R.string.ChannelPrivateInfo), false, isPrivate);
linearLayout2.addView(radioButtonCell2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); linearLayout2.addView(radioButtonCell2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
radioButtonCell2.setOnClickListener(v -> { radioButtonCell2.setOnClickListener(v -> {
if (isPrivate) { if (isPrivate) {
@ -949,15 +955,13 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
AdminedChannelCell adminedChannelCell = new AdminedChannelCell(getParentActivity(), view -> { AdminedChannelCell adminedChannelCell = new AdminedChannelCell(getParentActivity(), view -> {
AdminedChannelCell cell = (AdminedChannelCell) view.getParent(); AdminedChannelCell cell = (AdminedChannelCell) view.getParent();
final TLRPC.Chat channel = cell.getCurrentChannel(); final TLRPC.Chat channel = cell.getCurrentChannel();
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); BottomBuilder builder = new BottomBuilder(getParentActivity());
builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
if (channel.megagroup) { if (channel.megagroup) {
builder.setMessage(AndroidUtilities.replaceTags(LocaleController.formatString("RevokeLinkAlert", R.string.RevokeLinkAlert, MessagesController.getInstance(currentAccount).linkPrefix + "/" + channel.username, channel.title))); builder.addTitle(AndroidUtilities.replaceTags(LocaleController.formatString("RevokeLinkAlert", R.string.RevokeLinkAlert, MessagesController.getInstance(currentAccount).linkPrefix + "/" + channel.username, channel.title)));
} else { } else {
builder.setMessage(AndroidUtilities.replaceTags(LocaleController.formatString("RevokeLinkAlertChannel", R.string.RevokeLinkAlertChannel, MessagesController.getInstance(currentAccount).linkPrefix + "/" + channel.username, channel.title))); builder.addTitle(AndroidUtilities.replaceTags(LocaleController.formatString("RevokeLinkAlertChannel", R.string.RevokeLinkAlertChannel, MessagesController.getInstance(currentAccount).linkPrefix + "/" + channel.username, channel.title)));
} }
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); builder.addItem(LocaleController.getString("RevokeButton", R.string.RevokeButton),R.drawable.baseline_delete_forever_24, (i) -> {
builder.setPositiveButton(LocaleController.getString("RevokeButton", R.string.RevokeButton), (dialogInterface, i) -> {
TLRPC.TL_channels_updateUsername req1 = new TLRPC.TL_channels_updateUsername(); TLRPC.TL_channels_updateUsername req1 = new TLRPC.TL_channels_updateUsername();
req1.channel = MessagesController.getInputChannel(channel); req1.channel = MessagesController.getInputChannel(channel);
req1.username = ""; req1.username = "";
@ -972,7 +976,9 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
}); });
} }
}, ConnectionsManager.RequestFlagInvokeAfter); }, ConnectionsManager.RequestFlagInvokeAfter);
return Unit.INSTANCE;
}); });
builder.addCancelItem();
showDialog(builder.create()); showDialog(builder.create());
}); });
adminedChannelCell.setChannel(res.chats.get(a), a == res.chats.size() - 1); adminedChannelCell.setChannel(res.chats.get(a), a == res.chats.size() - 1);

View File

@ -41,7 +41,6 @@ import android.widget.Toast;
import org.telegram.messenger.AccountInstance; import org.telegram.messenger.AccountInstance;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ChatObject; import org.telegram.messenger.ChatObject;
import org.telegram.messenger.ContactsController; import org.telegram.messenger.ContactsController;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
@ -92,6 +91,9 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import kotlin.Unit;
import tw.nekomimi.nekogram.BottomBuilder;
public class AlertsCreator { public class AlertsCreator {
public static Dialog processError(int currentAccount, TLRPC.TL_error error, BaseFragment fragment, TLObject request, Object... args) { public static Dialog processError(int currentAccount, TLRPC.TL_error error, BaseFragment fragment, TLObject request, Object... args) {
@ -322,7 +324,39 @@ public class AlertsCreator {
return builder.show(); return builder.show();
} }
public static AlertDialog.Builder createLanguageAlert(LaunchActivity activity, final TLRPC.TL_langPackLanguage language) { private static SpannableStringBuilder mkTransSpan(String str, TLRPC.TL_langPackLanguage language, BottomBuilder builder) {
SpannableStringBuilder spanned = new SpannableStringBuilder(AndroidUtilities.replaceTags(str));
int start = TextUtils.indexOf(spanned, '[');
int end;
if (start != -1) {
end = TextUtils.indexOf(spanned, ']', start + 1);
if (start != -1 && end != -1) {
spanned.delete(end, end + 1);
spanned.delete(start, start + 1);
}
} else {
end = -1;
}
if (start != -1 && end != -1) {
spanned.setSpan(new URLSpanNoUnderline(language.translations_url) {
@Override
public void onClick(View widget) {
builder.dismiss();
super.onClick(widget);
}
}, start, end - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return spanned;
}
public static BottomSheet createLanguageAlert(LaunchActivity activity, final TLRPC.TL_langPackLanguage language) {
return createLanguageAlert(activity, language, null).create();
}
public static BottomBuilder createLanguageAlert(LaunchActivity activity, final TLRPC.TL_langPackLanguage language, Runnable callback) {
if (language == null) { if (language == null) {
return null; return null;
} }
@ -332,29 +366,31 @@ public class AlertsCreator {
language.base_lang_code = language.base_lang_code.replace('-', '_').toLowerCase(); language.base_lang_code = language.base_lang_code.replace('-', '_').toLowerCase();
} }
SpannableStringBuilder spanned; BottomBuilder builder = new BottomBuilder(activity);
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
LocaleController.LocaleInfo currentInfo = LocaleController.getInstance().getCurrentLocaleInfo(); LocaleController.LocaleInfo currentInfo = LocaleController.getInstance().getCurrentLocaleInfo();
String str;
if (currentInfo.shortName.equals(language.lang_code)) { if (currentInfo.shortName.equals(language.lang_code)) {
builder.setTitle(LocaleController.getString("Language", R.string.Language)); String str = LocaleController.formatString("LanguageSame", R.string.LanguageSame, language.name);
str = LocaleController.formatString("LanguageSame", R.string.LanguageSame, language.name); builder.addTitle(LocaleController.getString("Language", R.string.Language), mkTransSpan(str, language, builder));
builder.setNegativeButton(LocaleController.getString("OK", R.string.OK), null); builder.addCancelButton();
builder.setNeutralButton(LocaleController.getString("SETTINGS", R.string.SETTINGS), (dialog, which) -> activity.presentFragment(new LanguageSelectActivity())); builder.addButton(LocaleController.getString("SETTINGS", R.string.SETTINGS), (__) -> {
builder.dismiss();
activity.presentFragment(new LanguageSelectActivity());
return Unit.INSTANCE;
});
} else { } else {
if (language.strings_count == 0) { if (language.strings_count == 0) {
builder.setTitle(LocaleController.getString("LanguageUnknownTitle", R.string.LanguageUnknownTitle)); String str = LocaleController.formatString("LanguageUnknownCustomAlert", R.string.LanguageUnknownCustomAlert, language.name);
str = LocaleController.formatString("LanguageUnknownCustomAlert", R.string.LanguageUnknownCustomAlert, language.name); builder.addTitle(LocaleController.getString("LanguageUnknownTitle", R.string.LanguageUnknownTitle), mkTransSpan(str, language, builder));
builder.setNegativeButton(LocaleController.getString("OK", R.string.OK), null); builder.addCancelButton();
} else { } else {
builder.setTitle(LocaleController.getString("LanguageTitle", R.string.LanguageTitle)); String str;
if (language.official) { if (language.official) {
str = LocaleController.formatString("LanguageAlert", R.string.LanguageAlert, language.name, (int) Math.ceil(language.translated_count / (float) language.strings_count * 100)); str = LocaleController.formatString("LanguageAlert", R.string.LanguageAlert, language.name, (int) Math.ceil(language.translated_count / (float) language.strings_count * 100));
} else { } else {
str = LocaleController.formatString("LanguageCustomAlert", R.string.LanguageCustomAlert, language.name, (int) Math.ceil(language.translated_count / (float) language.strings_count * 100)); str = LocaleController.formatString("LanguageCustomAlert", R.string.LanguageCustomAlert, language.name, (int) Math.ceil(language.translated_count / (float) language.strings_count * 100));
} }
builder.setPositiveButton(LocaleController.getString("Change", R.string.Change), (dialogInterface, i) -> { builder.addTitle(LocaleController.getString("LanguageTitle", R.string.LanguageTitle), mkTransSpan(str, language, builder));
builder.addButton(LocaleController.getString("Change", R.string.Change), (it) -> {
String key; String key;
if (language.official) { if (language.official) {
key = "remote_" + language.lang_code; key = "remote_" + language.lang_code;
@ -376,47 +412,18 @@ public class AlertsCreator {
localeInfo.pathToFile = "unofficial"; localeInfo.pathToFile = "unofficial";
} }
} }
if (callback != null) {
callback.run();
}
LocaleController.getInstance().applyLanguage(localeInfo, true, false, false, true, UserConfig.selectedAccount); LocaleController.getInstance().applyLanguage(localeInfo, true, false, false, true, UserConfig.selectedAccount);
activity.rebuildAllFragments(true); activity.rebuildAllFragments(true);
builder.dismiss();
return Unit.INSTANCE;
}); });
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); builder.addCancelButton();
} }
} }
spanned = new SpannableStringBuilder(AndroidUtilities.replaceTags(str));
int start = TextUtils.indexOf(spanned, '[');
int end;
if (start != -1) {
end = TextUtils.indexOf(spanned, ']', start + 1);
if (start != -1 && end != -1) {
spanned.delete(end, end + 1);
spanned.delete(start, start + 1);
}
} else {
end = -1;
}
if (start != -1 && end != -1) {
spanned.setSpan(new URLSpanNoUnderline(language.translations_url) {
@Override
public void onClick(View widget) {
builder.getDismissRunnable().run();
super.onClick(widget);
}
}, start, end - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
final TextView message = new TextView(activity);
message.setText(spanned);
message.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
message.setLinkTextColor(Theme.getColor(Theme.key_dialogTextLink));
message.setHighlightColor(Theme.getColor(Theme.key_dialogLinkSelection));
message.setPadding(AndroidUtilities.dp(23), 0, AndroidUtilities.dp(23), 0);
message.setMovementMethod(new AndroidUtilities.LinkMovementMethodMy());
message.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
builder.setView(message);
return builder; return builder;
} }
@ -452,7 +459,7 @@ public class AlertsCreator {
return null; return null;
} }
AlertDialog.Builder builder = new AlertDialog.Builder(context); AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(title == null ? LocaleController.getString("AppName", R.string.AppName) : title); builder.setTitle(title == null ? LocaleController.getString("NekoX", R.string.NekoX) : title);
builder.setMessage(text); builder.setMessage(text);
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null); builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null);
return builder; return builder;
@ -582,11 +589,11 @@ public class AlertsCreator {
}; };
int[] icons = new int[]{ int[] icons = new int[]{
R.drawable.notifications_on, R.drawable.baseline_notifications_24,
R.drawable.notifications_mute1h, R.drawable.deproko_baseline_clock_24,
R.drawable.notifications_mute2d, R.drawable.deproko_baseline_clock_24,
R.drawable.notifications_settings, R.drawable.baseline_settings_24,
R.drawable.notifications_off R.drawable.baseline_notifications_off_24
}; };
final LinearLayout linearLayout = new LinearLayout(parentFragment.getParentActivity()); final LinearLayout linearLayout = new LinearLayout(parentFragment.getParentActivity());
@ -601,10 +608,10 @@ public class AlertsCreator {
Drawable drawable = parentFragment.getParentActivity().getResources().getDrawable(icons[a]); Drawable drawable = parentFragment.getParentActivity().getResources().getDrawable(icons[a]);
if (a == descriptions.length - 1) { if (a == descriptions.length - 1) {
textView.setTextColor(Theme.getColor(Theme.key_dialogTextRed)); textView.setTextColor(Theme.getColor(Theme.key_dialogTextRed));
drawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogRedIcon), PorterDuff.Mode.MULTIPLY)); drawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogRedIcon), PorterDuff.Mode.SRC_IN));
} else { } else {
textView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack)); textView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
drawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogIcon), PorterDuff.Mode.MULTIPLY)); drawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogIcon), PorterDuff.Mode.SRC_IN));
} }
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
textView.setLines(1); textView.setLines(1);

View File

@ -1580,9 +1580,9 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter
private void sendLogs() { private void sendLogs() {
File[] files = dir.listFiles(); File path = new File(EnvUtil.getTelegramPath(), "logs");
boolean[] finished = new boolean[1]; File logcatFile = new File(path, "NekoX-" + System.currentTimeMillis() + ".log");
FileUtil.delete(logcatFile); FileUtil.delete(logcatFile);
@ -1592,25 +1592,16 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter
IoUtil.copy(process, logcatFile); IoUtil.copy(process, logcatFile);
Intent i = new Intent(Intent.ACTION_SEND); RuntimeUtil.exec("logcat", "-c");
if (Build.VERSION.SDK_INT >= 24) {
i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); ShareUtil.shareFile(getParentActivity(), logcatFile);
}
i.setType("message/rfc822"); } catch (Exception e) {
i.putExtra(Intent.EXTRA_EMAIL, "");
i.putExtra(Intent.EXTRA_SUBJECT, "Logs from " + LocaleController.getInstance().formatterStats.format(System.currentTimeMillis())); AlertUtil.showToast(e);
i.putExtra(Intent.EXTRA_STREAM, uri);
if (getParentActivity() != null) { }
getParentActivity().startActivityForResult(Intent.createChooser(i, "Select email application."), 500);
}
} else {
Toast.makeText(getParentActivity(), LocaleController.getString("ErrorOccurred", R.string.ErrorOccurred), Toast.LENGTH_SHORT).show();
}
});
} catch (Exception e) {
e.printStackTrace();
}
});
} }
private class SearchAdapter extends RecyclerListView.SelectionAdapter { private class SearchAdapter extends RecyclerListView.SelectionAdapter {