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.PowerManager;
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.TLRPC;
import org.telegram.ui.Components.ForegroundDetector;
import java.io.File;
import java.lang.reflect.Method;
import java.util.Set;
import tw.nekomimi.nekogram.ExternalGcm;
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 {
@SuppressLint("StaticFieldLeak")
public static volatile Context applicationContext;
public static volatile NetworkInfo currentNetworkInfo;
public static volatile Handler applicationHandler;
@ -55,28 +68,144 @@ public class ApplicationLoader extends Application {
public static boolean hasPlayServices;
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
@Override public SharedPreferences getSharedPreferences(String name, int mode) {
return new WarppedPref(super.getSharedPreferences(name, mode));
}
public static File getFilesDirFixed() {
for (int a = 0; a < 10; a++) {
File path = ApplicationLoader.applicationContext.getFilesDir();
if (path != null) {
return path;
@Override
protected void attachBaseContext(Context base) {
if (SDK_INT >= Build.VERSION_CODES.P) {
Reflection.unseal(base);
}
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 {
ApplicationInfo info = applicationContext.getApplicationInfo();
File path = new File(info.dataDir, "files");
path.mkdirs();
return path;
} catch (Exception e) {
FileLog.e(e);
return new File(info.dataDir);
} catch (Exception ignored) {
}
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() {
@ -86,11 +215,22 @@ public class ApplicationLoader extends Application {
applicationInited = true;
try {
LocaleController.getInstance();
} catch (Exception e) {
e.printStackTrace();
}
UIUtil.runOnIoDispatcher(() -> {
try {
LocaleController.getInstance();
} catch (Exception e) {
e.printStackTrace();
}
try {
EnvUtil.doTest();
} catch (Exception e) {
FileLog.e("EnvUtil test Failed", e);
}
});
try {
connectivityManager = (ConnectivityManager) ApplicationLoader.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
@ -137,29 +277,50 @@ public class ApplicationLoader extends Application {
SharedConfig.loadConfig();
for (int a = 0; a < UserConfig.MAX_ACCOUNT_COUNT; a++) {
UserConfig.getInstance(a).loadConfig();
MessagesController.getInstance(a);
if (a == 0) {
SharedConfig.pushStringStatus = "__FIREBASE_GENERATING_SINCE_" + ConnectionsManager.getInstance(a).getCurrentTime() + "__";
} else {
ConnectionsManager.getInstance(a);
}
TLRPC.User user = UserConfig.getInstance(a).getCurrentUser();
if (user != null) {
MessagesController.getInstance(a).putUser(user, true);
SendMessagesHelper.getInstance(a).checkUnsentMessages();
final int finalA = a;
Runnable initRunnable = () -> {
UserConfig.getInstance(finalA).loadConfig();
MessagesController.getInstance(finalA);
if (finalA == 0) {
SharedConfig.pushStringStatus = "__FIREBASE_GENERATING_SINCE_" + ConnectionsManager.getInstance(finalA).getCurrentTime() + "__";
} else {
ConnectionsManager.getInstance(finalA);
}
TLRPC.User user = UserConfig.getInstance(finalA).getCurrentUser();
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;
ExternalGcm.initPlayServices();
if (BuildVars.LOGS_ENABLED) {
FileLog.d("app initied");
}
MediaController.getInstance();
for (int a = 0; a < UserConfig.MAX_ACCOUNT_COUNT; a++) {
ContactsController.getInstance(a).checkAppAccount();
DownloadController.getInstance(a);
final int finalA = 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
public void onCreate() {
try {
applicationContext = getApplicationContext();
} catch (Throwable ignore) {
}
super.onCreate();
@ -196,41 +357,64 @@ public class ApplicationLoader extends Application {
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
org.osmdroid.config.Configuration.getInstance().setUserAgentValue("Telegram-FOSS(F-Droid) "+BuildConfig.VERSION_NAME);
org.osmdroid.config.Configuration.getInstance().setOsmdroidBasePath(new File(getCacheDir(),"osmdroid"));
startPushService();
}
public static void startPushService() {
if (ExternalGcm.checkPlayServices() || (SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && isNotificationListenerEnabled())) {
return;
}
SharedPreferences preferences = MessagesController.getGlobalNotificationsSettings();
boolean enabled;
if (preferences.contains("pushService")) {
enabled = preferences.getBoolean("pushService", true);
if (SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
if (!preferences.getBoolean("pushConnection", true)) return;
}
} 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) {
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));
} else {
applicationContext.startService(new Intent(applicationContext, NotificationsService.class));
}
} catch (Throwable ignore) {
} catch (Throwable e) {
Log.d("TFOSS", "Failed to start push service");
}
} else {
applicationContext.stopService(new Intent(applicationContext, NotificationsService.class));
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);
}
}
public static boolean isNotificationListenerEnabled() {
Set<String> packageNames = NotificationManagerCompat.getEnabledListenerPackages(applicationContext);
if (packageNames.contains(applicationContext.getPackageName())) {
return true;
}
return false;
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
@ -242,7 +426,6 @@ public class ApplicationLoader extends Application {
}
}
private static void ensureCurrentNetworkGet(boolean force) {
if (force || currentNetworkInfo == null) {
try {

View File

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

View File

@ -30,6 +30,9 @@ public class BuildVars {
public static int TGX_APP_ID = 21724;
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 {
try {

View File

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

View File

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

View File

@ -17,228 +17,50 @@ import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.Locale;
import cn.hutool.core.lang.caller.CallerUtil;
import cn.hutool.core.lang.caller.StackTraceCaller;
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 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();
}
private final static StackTraceCaller caller = new StackTraceCaller();
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 "";
}
public static String getTonlibLogPath() {
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().tonlibFile = new File(dir, getInstance().dateFormat.format(System.currentTimeMillis()) + "_tonlib.txt");
return getInstance().tonlibFile.getAbsolutePath();
} catch (Throwable e) {
e.printStackTrace();
}
return "";
private static String mkTag() {
return caller.getCaller(3).getSimpleName();
}
private static String mkMessage(Throwable e) {
String message = e.getMessage();
if (message != null) return message;
return e.getClass().getSimpleName();
}
public static void e(final String message, final Throwable exception) {
if (!BuildVars.LOGS_ENABLED) {
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();
}
});
}
Log.e(mkTag(), message, exception);
}
public static void e(final String message) {
if (!BuildVars.LOGS_ENABLED) {
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();
}
});
}
Log.e(mkTag(), message);
}
public static void e(final Throwable e) {
if (!BuildVars.LOGS_ENABLED) {
return;
}
ensureInitied();
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();
}
Log.e(mkTag(),mkMessage(e),e);
}
public static void d(final String message) {
if (!BuildVars.LOGS_ENABLED) {
return;
}
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();
}
});
}
if (!BuildVars.LOGS_ENABLED) return;
Log.d(mkTag(), message);
}
public static void w(final String message) {
if (!BuildVars.LOGS_ENABLED) {
return;
}
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();
}
});
}
if (!BuildVars.LOGS_ENABLED) return;
Log.w(mkTag(), message);
}
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;
if (stream == null) {
File cacheFile = new File(uploadingFilePath);
if (AndroidUtilities.isInternalUri(Uri.fromFile(cacheFile))) {
throw new Exception("trying to upload internal file");
}
stream = new RandomAccessFile(cacheFile, "r");
if (estimatedSize != 0) {
totalFileSize = estimatedSize;

View File

@ -17,17 +17,16 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import androidx.exifinterface.media.ExifInterface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.SparseArray;
import androidx.exifinterface.media.ExifInterface;
import org.json.JSONArray;
import org.json.JSONObject;
import org.telegram.messenger.secretmedia.EncryptedFileInputStream;
@ -65,7 +64,8 @@ import java.util.Locale;
import java.util.Map;
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 {
@ -1781,79 +1781,67 @@ public class ImageLoader {
}
}
AndroidUtilities.createEmptyFile(new File(cachePath, ".nomedia"));
mediaDirs.put(FileLoader.MEDIA_DIR_CACHE, cachePath);
if (BuildVars.LOGS_ENABLED) {
FileLog.d("cache path = " + cachePath);
}
try {
if (NekoConfig.saveCacheToPrivateDirectory || Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
if (NekoConfig.saveCacheToPrivateDirectory) {
telegramPath = new File(ApplicationLoader.applicationContext.getFilesDir(), "Telegram");
} else {
telegramPath = new File(Environment.getExternalStorageDirectory(), "Telegram");
telegramPath = EnvUtil.getTelegramPath();
if (telegramPath.isDirectory()) {
try {
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 {
File imagePath = new File(telegramPath, "Telegram Images");
imagePath.mkdir();
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);
}
try {
File videoPath = new File(telegramPath, "videos");
FileUtil.initDir(videoPath);
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 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) {
FileLog.d("this Android can't rename files");
try {
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();

View File

@ -100,6 +100,14 @@ public class ImageLocation {
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) {
if (user == null || user.access_hash == 0 || user.photo == null) {
return null;

View File

@ -14,12 +14,15 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.Xml;
import android.view.Gravity;
import org.telegram.messenger.support.ArrayUtils;
import org.telegram.messenger.time.FastDateFormat;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLObject;
@ -30,6 +33,7 @@ import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Calendar;
@ -40,6 +44,7 @@ import java.util.Locale;
import java.util.TimeZone;
import tw.nekomimi.nekogram.NekoConfig;
import tw.nekomimi.nekogram.utils.FileUtil;
public class LocaleController {
@ -51,7 +56,13 @@ public class LocaleController {
static final int QUANTITY_MANY = 0x0010;
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 FastDateFormat formatterDay;
public FastDateFormat formatterWeek;
@ -109,6 +120,9 @@ public class LocaleController {
public boolean builtIn;
public int serverIndex;
public TLRPC.TL_langPackLanguage pack;
public boolean toInstall;
public String getSaveString() {
String langCode = baseLangCode == null ? "" : baseLangCode;
String pluralCode = TextUtils.isEmpty(pluralLangCode) ? shortName : pluralLangCode;
@ -151,17 +165,25 @@ public class LocaleController {
}
public File getPathToFile() {
File baseDir = new File(ApplicationLoader.getDataDirFixed(), "languages");
FileUtil.initDir(baseDir);
if (isRemote()) {
return new File(ApplicationLoader.getFilesDirFixed(), "remote_" + shortName + ".xml");
return new File(baseDir, "remote_" + shortName + ".xml");
} 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;
}
public File getPathToBaseFile() {
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;
}
@ -215,6 +237,7 @@ public class LocaleController {
private ArrayList<LocaleInfo> otherLanguages = new ArrayList<>();
private static volatile LocaleController Instance = null;
public static LocaleController getInstance() {
LocaleController localInstance = Instance;
if (localInstance == null) {
@ -225,6 +248,8 @@ public class LocaleController {
}
}
}
if (localInstance.formatterDay == null || localInstance.chatFullDate == null)
localInstance.recreateFormatters();
return localInstance;
}
@ -325,6 +350,20 @@ public class LocaleController {
languages.add(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.name = "瓜体中文 \uD83D\uDE36";
localeInfo.nameEnglish = "Duangified Chinese (Simplified)";
@ -336,23 +375,6 @@ public class LocaleController {
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.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.name = "正體中文";
@ -365,6 +387,9 @@ public class LocaleController {
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.name = "日本語";
@ -721,7 +746,7 @@ public class LocaleController {
}
}
editor.putString("unofficial", stringBuilder.toString());
editor.commit();
editor.apply();
}
public boolean deleteLanguage(LocaleInfo localeInfo, int currentAccount) {
@ -897,6 +922,7 @@ public class LocaleController {
saveOtherLanguages();
}
}
loadPrebuiltLocaleFile(localeInfo);
if ((localeInfo.isRemote() || localeInfo.isUnofficial()) && (force || !pathToFile.exists() || hasBase && !pathToBaseFile.exists())) {
if (BuildVars.LOGS_ENABLED) {
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.Editor editor = preferences.edit();
editor.putString("language", localeInfo.getKey());
editor.commit();
editor.apply();
}
if (pathToFile == null) {
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")) ||
lang.startsWith("ar_") || lang.startsWith("fa_") || lang.startsWith("he_") || lang.startsWith("iw_")
|| currentLocaleInfo != null && currentLocaleInfo.isRtl;
nameDisplayOrder = NekoConfig.nameOrder;
formatterDayMonth = createFormatter(locale, getStringInternal("formatterMonth", R.string.formatterMonth), "dd MMM");
formatterYear = createFormatter(locale, getStringInternal("formatterYear", R.string.formatterYear), "dd.MM.yy");
@ -1743,7 +1768,7 @@ public class LocaleController {
return getString("WithinAWeek", R.string.WithinAWeek);
} else if (user.status.expires == -102) {
return getString("WithinAMonth", R.string.WithinAMonth);
} else {
} else {
return formatDateOnline(user.status.expires);
}
}
@ -1859,7 +1884,7 @@ public class LocaleController {
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit();
editor.putString("language", localeInfo.getKey());
editor.commit();
editor.apply();
}
if (newLocale != null) {
localeValues = valuesToSet;
@ -1980,7 +2005,7 @@ public class LocaleController {
req.lang_pack = "";
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
if (response != null) {
AndroidUtilities.runOnUIThread(() -> saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount));
saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount);
}
}, ConnectionsManager.RequestFlagWithoutLogin);
}
@ -1989,7 +2014,7 @@ public class LocaleController {
req.lang_code = localeInfo.getBaseLangCode();
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (TLObject response, TLRPC.TL_error error) -> {
if (response != null) {
AndroidUtilities.runOnUIThread(() -> saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount));
saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount);
}
}, ConnectionsManager.RequestFlagWithoutLogin);
}
@ -2002,7 +2027,7 @@ public class LocaleController {
req.lang_pack = "";
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
if (response != null) {
AndroidUtilities.runOnUIThread(() -> saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount));
saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount);
}
}, ConnectionsManager.RequestFlagWithoutLogin);
} else {
@ -2013,13 +2038,54 @@ public class LocaleController {
req.lang_code = localeInfo.getLangCode();
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (TLObject response, TLRPC.TL_error error) -> {
if (response != null) {
AndroidUtilities.runOnUIThread(() -> saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount));
saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount);
}
}, 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) {
return getTranslitString(src, true, false);
}

View File

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

View File

@ -11,14 +11,10 @@ package org.telegram.messenger;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.os.Build;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import tw.nekomimi.nekogram.utils.FileUtil;
public class NativeLoader {
@ -34,7 +30,7 @@ public class NativeLoader {
File f = null;
if (context != null) {
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) {
th.printStackTrace();
}
@ -48,67 +44,6 @@ public class NativeLoader {
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")
public static synchronized void initNativeLibs(Context context) {
if (nativeLoaded) {
@ -116,93 +51,19 @@ public class NativeLoader {
}
try {
try {
System.loadLibrary(LIB_NAME);
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();
}
System.loadLibrary(LIB_NAME);
nativeLoaded = true;
if (BuildVars.LOGS_ENABLED) {
FileLog.e("Library not found, arch = " + folder);
FileLog.d("loaded normal lib");
}
if (loadFromZip(context, destDir, destLocalFile, folder)) {
return;
}
} catch (Throwable e) {
e.printStackTrace();
return;
} catch (Error e) {
FileLog.e(e);
}
try {
System.loadLibrary(LIB_NAME);
System.loadLibrary(FileUtil.extLib(LIB_NAME).getPath());
FileLog.d("loaded extracted lib");
nativeLoaded = true;
} catch (Error e) {
FileLog.e(e);

View File

@ -18,37 +18,36 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.IBinder;
import android.provider.Settings;
import androidx.core.app.NotificationCompat;
import org.telegram.ui.LaunchActivity;
import tw.nekomimi.nekogram.NekoConfig;
public class NotificationsService extends Service {
@Override
public void onCreate() {
super.onCreate();
ApplicationLoader.postInitApplication();
if (NekoConfig.residentNotification) {
Intent activityIntent = new Intent(this, LaunchActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, activityIntent, 0);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("nekogram", LocaleController.getString("NekogramRunning", R.string.NekogramRunning), NotificationManager.IMPORTANCE_DEFAULT);
channel.enableLights(false);
channel.enableVibration(false);
channel.setSound(null, null);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager != null) {
notificationManager.createNotificationChannel(channel);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String CHANNEL_ID = "push_service_channel";
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, LocaleController.getString("PlaceHolder", R.string.PlaceHolder), NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("NekoX - System");
channel.enableLights(false);
channel.enableVibration(false);
channel.setSound(null, null);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
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)
.setColor(0xff11acfa)
.setContentTitle(LocaleController.getString("NekogramRunning", R.string.NekogramRunning))
.setContentText(LocaleController.getString("TapToDisable",R.string.TapToDisable))
.setContentIntent(pendingIntent)
.setCategory(NotificationCompat.CATEGORY_STATUS)
.build();
@ -71,7 +70,12 @@ public class NotificationsService extends Service {
SharedPreferences preferences = MessagesController.getGlobalNotificationsSettings();
if (preferences.getBoolean("pushService", true)) {
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.concurrent.ConcurrentHashMap;
import tw.nekomimi.nekogram.utils.AlertUtil;
public class SecretChatHelper extends BaseController {
public static class TL_decryptedMessageHolder extends TLObject {
@ -1950,25 +1952,12 @@ public class SecretChatHelper extends BaseController {
});
} else {
delayedEncryptedChatUpdates.clear();
AndroidUtilities.runOnUIThread(() -> {
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);
}
});
AlertUtil.showToast(error);
}
}, ConnectionsManager.RequestFlagFailOnServerErrors);
} else {
delayedEncryptedChatUpdates.clear();
AlertUtil.showToast(error);
AndroidUtilities.runOnUIThread(() -> {
startingSecretChat = false;
if (!((Activity) context).isFinishing()) {

View File

@ -36,6 +36,8 @@ import android.widget.Toast;
import androidx.annotation.UiThread;
import androidx.core.view.inputmethod.InputContentInfoCompat;
import com.google.gson.Gson;
import org.telegram.messenger.audioinfo.AudioInfo;
import org.telegram.messenger.support.SparseLongArray;
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.AnimatedFileDrawable;
import org.telegram.ui.Components.Point;
import org.telegram.ui.PaymentFormActivity;
import java.io.File;
import java.io.FileInputStream;
@ -1842,7 +1843,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (!messageObject.isGif() && (videoEditedInfo == null || !videoEditedInfo.muted)) {
uploadedDocument.nosound_video = true;
if (BuildVars.DEBUG_VERSION) {
FileLog.d("nosound_video = true");
FileLog.e("nosound_video = true");
}
}
if (document.access_hash == 0) {
@ -2193,14 +2194,6 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
TLRPC.TL_urlAuthResultDefault res = (TLRPC.TL_urlAuthResultDefault) response;
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 {
TLRPC.TL_messages_botCallbackAnswer res = (TLRPC.TL_messages_botCallbackAnswer) response;
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) {
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();
TLRPC.TL_documentAttributeAudio attributeAudio = null;
String extension = null;
@ -6049,7 +6036,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (forceDocument) {
videoEditedInfo = null;
} else {
videoEditedInfo = info.videoEditedInfo != null ? info.videoEditedInfo : createCompressionSettings(info.path);
videoEditedInfo = info.videoEditedInfo;
}
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.content.Context;
import android.os.Build;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.FileLog;
@ -15,6 +14,8 @@ import java.util.Locale;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import tw.nekomimi.nekogram.utils.FileUtil;
public final class TgVoipNativeLoader {
private final static int LIB_REVISION = 1;
@ -37,149 +38,25 @@ public final class TgVoipNativeLoader {
@SuppressLint("UnsafeDynamicallyLoadedCode")
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 {
System.loadLibrary(libName);
if (BuildVars.LOGS_ENABLED) {
FileLog.d("loaded lib: " + libName);
FileLog.d("loaded normal lib: " + libName);
}
return true;
} catch (Error e) {
FileLog.e(e);
}
return false;
}
@SuppressLint({"UnsafeDynamicallyLoadedCode", "SetWorldReadable"})
private static boolean loadFromZip(Context context, File destDir, File destLocalFile, String folder, String libName) {
try {
for (File file : destDir.listFiles()) {
file.delete();
}
} catch (Exception e) {
System.load(FileUtil.extLib(libName).getPath());
FileLog.d("loaded extracted lib");
nativeLoaded = true;
} catch (Error 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;
}
}

View File

@ -365,7 +365,9 @@ public abstract class VoIPBaseService extends Service implements SensorEventList
sheet.show();
ViewGroup container=sheet.getSheetContainer();
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);
}
return;
@ -1414,7 +1416,7 @@ public abstract class VoIPBaseService extends Service implements SensorEventList
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))
.setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
.setIcon(Icon.createWithResource(this, R.mipmap.ic_launcher))
.setIcon(Icon.createWithResource(this, R.drawable.ic_launcher_foreground))
.setHighlightColor(0xff2ca5e0)
.addSupportedUriScheme("sip")
.build();

View File

@ -1,7 +1,6 @@
package org.telegram.tgnet;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.os.AsyncTask;
@ -10,14 +9,14 @@ import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Base64;
import org.json.JSONArray;
import org.json.JSONObject;
import com.v2ray.ang.util.Utils;
import org.telegram.messenger.AccountInstance;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BaseController;
import org.telegram.messenger.BuildConfig;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.EmuDetector;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.KeepAliveJob;
@ -29,18 +28,12 @@ import org.telegram.messenger.StatsController;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import tw.nekomimi.nekogram.NekoConfig;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
@ -55,6 +48,12 @@ import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
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 final static int ConnectionTypeGeneric = 1;
@ -120,24 +119,26 @@ public class ConnectionsManager extends BaseController {
private static class ResolvedDomain {
public ArrayList<String> addresses;
public InetAddress[] addresses;
long ttl;
public ResolvedDomain(ArrayList<String> a, long t) {
public ResolvedDomain(InetAddress[] a, long t) {
addresses = a;
ttl = t;
}
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 int lastClassGuid = 1;
private static volatile ConnectionsManager[] Instance = new ConnectionsManager[UserConfig.MAX_ACCOUNT_COUNT];
public static ConnectionsManager getInstance(int num) {
ConnectionsManager localInstance = Instance[num];
if (localInstance == null) {
@ -172,11 +173,6 @@ public class ConnectionsManager extends BaseController {
deviceModel = Build.MANUFACTURER + Build.MODEL;
PackageInfo pInfo = ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0);
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;
} catch (Exception e) {
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) {
final int requestToken = lastRequestToken.getAndIncrement();
Utilities.stageQueue.postRunnable(() -> {
UIUtil.runOnIoDispatcher(() -> {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("send request " + object + " with token = " + requestToken);
FileLog.d("send request " + object.getClass().getSimpleName() + " with token = " + requestToken);
}
try {
NativeByteBuffer buffer = new NativeByteBuffer(object.getObjectSize());
@ -278,14 +274,14 @@ public class ConnectionsManager extends BaseController {
error.code = errorCode;
error.text = errorText;
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) {
resp.networkType = networkType;
}
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 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) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
String proxyAddress = preferences.getString("proxy_ip", "");
String proxyUsername = preferences.getString("proxy_user", "");
String proxyPassword = preferences.getString("proxy_pass", "");
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);
if (SharedConfig.proxyEnabled && SharedConfig.currentProxy != null) {
native_setProxySettings(currentAccount, SharedConfig.currentProxy.address, SharedConfig.currentProxy.port, SharedConfig.currentProxy.username, SharedConfig.currentProxy.password, SharedConfig.currentProxy.secret);
}
native_init(currentAccount, version, layer, apiId, deviceModel, systemVersion, appVersion, langCode, systemLangCode, configPath, logPath, regId, cFingerprint, timezoneOffset, userId, enablePushConnection, ApplicationLoader.isNetworkOnline(), ApplicationLoader.getCurrentNetworkType());
checkConnection();
}
public static void setLangCode(String langCode) {
@ -387,7 +381,7 @@ public class ConnectionsManager extends BaseController {
public void switchBackend() {
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
preferences.edit().remove("language_showed2").commit();
preferences.edit().remove("language_showed2").apply();
native_switchBackend(currentAccount);
}
@ -534,54 +528,36 @@ public class ConnectionsManager extends BaseController {
public static void onRequestNewServerIpAndPort(final int second, final int currentAccount) {
Utilities.stageQueue.postRunnable(() -> {
if (currentTask != null || second == 0 && Math.abs(lastDnsRequestTime - System.currentTimeMillis()) < 10000 || !ApplicationLoader.isNetworkOnline()) {
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());
}
return;
}
lastDnsRequestTime = System.currentTimeMillis();
if (second == 3) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("start mozilla 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;
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;
});
}
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) {
AndroidUtilities.runOnUIThread(() -> {
ResolvedDomain resolvedDomain = dnsCache.get(hostName);
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 {
ResolveHostByNameTask task = resolvingHostnameTasks.get(hostName);
if (task == null) {
@ -590,7 +566,7 @@ public class ConnectionsManager extends BaseController {
task.executeOnExecutor(DNS_THREAD_POOL_EXECUTOR, null, null, null);
} catch (Throwable e) {
FileLog.e(e);
native_onHostNameResolved(hostName, address, "");
native_onHostNameResolved(hostName, address, "", false);
return;
}
resolvingHostnameTasks.put(hostName, task);
@ -652,34 +628,65 @@ public class ConnectionsManager extends BaseController {
}
public static native void native_switchBackend(int currentAccount);
public static native int native_isTestBackend(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_updateDcSettings(int currentAccount);
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 long native_getCurrentTimeMillis(int currentAccount);
public static native int native_getCurrentTime(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_cancelRequest(int currentAccount, int token, boolean notifyServer);
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_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_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 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_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_setRegId(int currentAccount, String regId);
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_setPushConnectionEnabled(int currentAccount, boolean value);
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 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() {
return lastClassGuid++;
@ -698,7 +705,7 @@ public class ConnectionsManager extends BaseController {
}
@SuppressLint("NewApi")
protected static boolean useIpv6Address() {
public static boolean useIpv6Address() {
if (Build.VERSION.SDK_INT < 19) {
return false;
}
@ -711,22 +718,13 @@ public class ConnectionsManager extends BaseController {
if (!networkInterface.isUp() || networkInterface.isLoopback() || networkInterface.getInterfaceAddresses().isEmpty()) {
continue;
}
if (BuildVars.LOGS_ENABLED) {
FileLog.d("valid interface: " + networkInterface);
}
List<InterfaceAddress> interfaceAddresses = networkInterface.getInterfaceAddresses();
for (int a = 0; a < interfaceAddresses.size(); a++) {
InterfaceAddress address = interfaceAddresses.get(a);
InetAddress inetAddress = address.getAddress();
if (BuildVars.LOGS_ENABLED) {
FileLog.d("address: " + inetAddress.getHostAddress());
}
if (inetAddress.isLinkLocalAddress() || inetAddress.isLoopbackAddress() || inetAddress.isMulticastAddress()) {
continue;
}
if (BuildVars.LOGS_ENABLED) {
FileLog.d("address is good");
}
}
}
} catch (Throwable e) {
@ -760,7 +758,7 @@ public class ConnectionsManager extends BaseController {
}
}
}
if(NekoConfig.useIPv6){
if (NekoConfig.useIPv6) {
return hasIpv6;
} else {
return !hasIpv4 && hasIpv6;
@ -790,75 +788,17 @@ public class ConnectionsManager extends BaseController {
}
protected ResolvedDomain doInBackground(Void... voids) {
ByteArrayOutputStream outbuf = null;
InputStream httpConnectionStream = null;
boolean done = false;
InetAddress[] result;
try {
URL downloadUrl = new URL("https://www.google.com/resolve?name=" + currentHostName + "&type=A");
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(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) {
}
result = DnsFactory.Companion.lookup(currentHostName).toArray(new InetAddress[0]);
} catch (Exception e) {
result = new InetAddress[0];
}
if (!done) {
try {
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;
return new ResolvedDomain(result, 10 * 60 * 1000L);
}
@Override
@ -866,11 +806,12 @@ public class ConnectionsManager extends BaseController {
if (result != null) {
dnsCache.put(currentHostName, result);
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 {
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);
@ -888,101 +829,30 @@ public class ConnectionsManager extends BaseController {
}
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;
}
@ -996,9 +866,9 @@ public class ConnectionsManager extends BaseController {
} else {
if (BuildVars.LOGS_ENABLED) {
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);
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 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) {
this(context, menu, backgroundColor, iconColor, false);
}
@ -149,7 +162,7 @@ public class ActionBarMenuItem extends FrameLayout {
iconView.setScaleType(ImageView.ScaleType.CENTER);
addView(iconView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
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) {
if (iconView != null) {
iconView.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
iconView.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
}
if (textView != null) {
textView.setTextColor(color);
}
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();
location = new int[2];
popupLayout = new ActionBarPopupWindow.ActionBarPopupWindowLayout(getContext());
popupLayout = new ActionBarPopupWindow.ActionBarPopupWindowLayout(getContext(), verticalScrollBarEnabled);
popupLayout.setOnTouchListener((v, event) -> {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
if (popupWindow != null && popupWindow.isShowing()) {
@ -402,7 +415,7 @@ public class ActionBarMenuItem extends FrameLayout {
}
public void redrawPopup(int color) {
if (popupLayout != null && popupLayout.getBackgroundColor() != color) {
if (popupLayout != null) {
popupLayout.setBackgroundColor(color);
if (popupWindow != null && popupWindow.isShowing()) {
popupLayout.invalidate();
@ -450,6 +463,26 @@ public class ActionBarMenuItem extends FrameLayout {
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() {
if (popupLayout == null || parentMenu != null && parentMenu.isActionMode && parentMenu.parentActionBar != null && !parentMenu.parentActionBar.isActionModeShowed()) {
return;
@ -844,7 +877,7 @@ public class ActionBarMenuItem extends FrameLayout {
}
};
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.setAlpha(0.0f);
clearButton.setRotation(45);
@ -946,7 +979,25 @@ public class ActionBarMenuItem extends FrameLayout {
private void updateOrShowPopup(boolean show, boolean update) {
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()*/;
} else {
float scaleY = getScaleY();
@ -958,7 +1009,33 @@ public class ActionBarMenuItem extends FrameLayout {
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;
if (subMenuOpenSide == 0) {
if (SharedConfig.smoothKeyboard) {

View File

@ -21,6 +21,9 @@ import android.graphics.drawable.Drawable;
import android.os.Build;
import androidx.annotation.Keep;
import androidx.core.view.ViewCompat;
import androidx.core.widget.ScrollerCompat;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
@ -51,6 +54,7 @@ public class ActionBarPopupWindow extends PopupWindow {
private AnimatorSet windowAnimatorSet;
private boolean animationEnabled = allowAnimation;
private int dismissAnimationDuration = 150;
static {
Field f = null;
try {
@ -92,9 +96,13 @@ public class ActionBarPopupWindow extends PopupWindow {
protected Drawable backgroundDrawable;
public ActionBarPopupWindowLayout(Context context) {
this(context,false);
}
public ActionBarPopupWindowLayout(Context context, boolean verticalScrollBarEnabled) {
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));
setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(8), AndroidUtilities.dp(8), AndroidUtilities.dp(8));
@ -102,7 +110,7 @@ public class ActionBarPopupWindow extends PopupWindow {
try {
scrollView = new ScrollView(context);
scrollView.setVerticalScrollBarEnabled(false);
scrollView.setVerticalScrollBarEnabled(verticalScrollBarEnabled);
addView(scrollView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
} catch (Throwable e) {
FileLog.e(e);
@ -111,7 +119,7 @@ public class ActionBarPopupWindow extends PopupWindow {
linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.VERTICAL);
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 {
addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
}
@ -131,7 +139,7 @@ public class ActionBarPopupWindow extends PopupWindow {
public void setBackgroundColor(int 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.setPivotY(0);
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();
int visibleCount = 0;
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.ofInt(content, "backAlpha", 0, 255));
windowAnimatorSet.setDuration(150 + 16 * visibleCount);
int finalCount = count;
windowAnimatorSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
@ -428,8 +443,7 @@ public class ActionBarPopupWindow extends PopupWindow {
public void onAnimationEnd(Animator animation) {
windowAnimatorSet = null;
ActionBarPopupWindowLayout content = (ActionBarPopupWindowLayout) getContentView();
int count = content.getItemsCount();
for (int a = 0; a < count; a++) {
for (int a = 0; a < finalCount; a++) {
View child = content.getItemAt(a);
child.setAlpha(1.0f);
}

View File

@ -25,11 +25,6 @@ import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
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.util.TypedValue;
import android.view.Gravity;
@ -44,11 +39,18 @@ import android.view.WindowManager;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
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.LocaleController;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
@ -119,8 +121,8 @@ public class BottomSheet extends Dialog {
protected int backgroundPaddingTop;
protected int backgroundPaddingLeft;
private boolean applyTopPadding = true;
private boolean applyBottomPadding = true;
private boolean applyTopPadding = false;
private boolean applyBottomPadding = false;
private ArrayList<BottomSheetCell> itemViews = new ArrayList<>();
@ -138,7 +140,7 @@ public class BottomSheet extends Dialog {
disableScroll = b;
}
protected class ContainerView extends FrameLayout implements NestedScrollingParent {
protected class ContainerView extends LinearLayout implements NestedScrollingParent {
private VelocityTracker velocityTracker = null;
private int startedTrackingX;
@ -429,7 +431,7 @@ public class BottomSheet extends Dialog {
continue;
}
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 height = child.getMeasuredHeight();
@ -544,7 +546,9 @@ public class BottomSheet extends Dialog {
public interface BottomSheetDelegateInterface {
void onOpenAnimationStart();
void onOpenAnimationEnd();
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 ImageView imageView;
@ -575,36 +579,41 @@ public class BottomSheet extends Dialog {
super(context);
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.setScaleType(ImageView.ScaleType.CENTER);
imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogIcon), PorterDuff.Mode.MULTIPLY));
addView(imageView, LayoutHelper.createFrame(56, 48, Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)));
imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogIcon), PorterDuff.Mode.SRC_IN));
addView(imageView, LayoutHelper.createLinear(56, 48));
textView = new TextView(context);
textView.setLines(1);
textView.setSingleLine(true);
textView.setGravity(Gravity.CENTER_HORIZONTAL);
textView.setEllipsize(TextUtils.TruncateAt.END);
if (type == 0) {
textView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
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) {
textView.setGravity(Gravity.CENTER);
textView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
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) {
textView.setGravity(Gravity.CENTER);
textView.setTextColor(Theme.getColor(Theme.key_featuredStickers_buttonText));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
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)));
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.setVisibility(VISIBLE);
if (bigTitle) {
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);
}
textView.setPadding(0, 0, 0, 0);
} else {
imageView.setVisibility(INVISIBLE);
textView.setPadding(AndroidUtilities.dp(bigTitle ? 21 : 16), 0, AndroidUtilities.dp(bigTitle ? 21 : 16), 0);
imageView.setVisibility(GONE);
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) {
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);
touchSlop = vc.getScaledTouchSlop();
Rect padding = new Rect();
shadowDrawable = context.getResources().getDrawable(R.drawable.sheet_shadow_round).mutate();
shadowDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogBackground), PorterDuff.Mode.MULTIPLY));
shadowDrawable = context.getResources().getDrawable(R.drawable.sheet_shadow).mutate();
shadowDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogBackground), PorterDuff.Mode.SRC_IN));
shadowDrawable.getPadding(padding);
backgroundPaddingLeft = padding.left;
backgroundPaddingTop = padding.top;
@ -736,7 +742,7 @@ public class BottomSheet extends Dialog {
}
if (containerView == null) {
containerView = new FrameLayout(getContext()) {
containerView = new LinearLayout(getContext()) {
@Override
public boolean hasOverlappingRendering() {
return false;
@ -747,6 +753,10 @@ public class BottomSheet extends Dialog {
super.setTranslationY(translationY);
onContainerTranslationYChanged(translationY);
}
{
setOrientation(VERTICAL);
}
};
containerView.setBackgroundDrawable(shadowDrawable);
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);
container.addView(containerView, 0, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM));
int topOffset = 0;
if (title != null) {
titleView = new TextView(getContext());
titleView.setLines(1);
titleView.setSingleLine(true);
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) {
titleView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
titleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
titleView.setSingleLine(true);
titleView.setEllipsize(TextUtils.TruncateAt.MIDDLE);
titleView.setTextColor(Theme.getColor(Theme.key_dialogTextBlue2));
titleView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
titleView.setPadding(AndroidUtilities.dp(21), AndroidUtilities.dp(6), AndroidUtilities.dp(21), AndroidUtilities.dp(8));
} else {
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);
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);
topOffset += 48;
}
if (customView != null) {
if (customView.getParent() != null) {
ViewGroup viewGroup = (ViewGroup) customView.getParent();
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 {
if (items != null) {
FrameLayout rowLayout = null;
int lastRowLayoutNum = 0;
FrameLayout rootView = new ScrollView(getContext());
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++) {
if (items[a] == null) {
continue;
}
BottomSheetCell cell = new BottomSheetCell(getContext(), 0);
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));
topOffset += 48;
rowView.addView(cell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 56, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 0));
cell.setTag(a);
cell.setOnClickListener(v -> dismissWithButtonClick((Integer) v.getTag()));
itemViews.add(cell);
@ -840,7 +850,7 @@ public class BottomSheet extends Dialog {
WindowManager.LayoutParams params = window.getAttributes();
if (focusable) {
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 {
params.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
params.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
@ -853,7 +863,7 @@ public class BottomSheet extends Dialog {
}
public void setBackgroundColor(int color) {
shadowDrawable.setColorFilter(color, PorterDuff.Mode.MULTIPLY);
shadowDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
@Override
@ -883,7 +893,7 @@ public class BottomSheet extends Dialog {
startAnimationRunnable = null;
startOpenAnimation();
}
}, 150);
});
} else {
startOpenAnimation();
}
@ -928,6 +938,7 @@ public class BottomSheet extends Dialog {
public void setTitle(CharSequence value, boolean big) {
title = value;
bigTitle = big;
setApplyTopPadding(true);
}
public void setApplyTopPadding(boolean value) {
@ -983,7 +994,6 @@ public class BottomSheet extends Dialog {
ObjectAnimator.ofFloat(containerView, View.TRANSLATION_Y, 0),
ObjectAnimator.ofInt(backDrawable, AnimationProperties.COLOR_DRAWABLE_ALPHA, dimBehind ? 51 : 0));
currentSheetAnimation.setDuration(400);
currentSheetAnimation.setStartDelay(20);
currentSheetAnimation.setInterpolator(openInterpolator);
currentSheetAnimation.addListener(new AnimatorListenerAdapter() {
@Override
@ -1024,7 +1034,7 @@ public class BottomSheet extends Dialog {
delegate = bottomSheetDelegate;
}
public FrameLayout getContainer() {
public LinearLayout getContainer() {
return container;
}
@ -1054,7 +1064,7 @@ public class BottomSheet extends Dialog {
}
BottomSheetCell cell = itemViews.get(item);
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) {

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 boolean autoNightScheduleByLocation;
public static float autoNightBrighnessThreshold = 0.25f;
@ -3829,24 +3829,28 @@ public class Theme {
ThemeInfo themeInfo = new ThemeInfo();
themeInfo.name = "Blue";
themeInfo.assetName = "bluebubbles.attheme";
themeInfo.previewBackgroundColor = 0xff95beec;
themeInfo.previewInColor = 0xffffffff;
themeInfo.previewOutColor = 0xffd0e6ff;
themeInfo.firstAccentIsDefault = true;
themeInfo.assetName = NekoConfig.useDefaultTheme ? "bluebubbles.attheme" : "nekox-indigo.attheme";
themeInfo.previewBackgroundColor = -657931;
themeInfo.previewInColor = NekoConfig.useDefaultTheme ? 0xffffffff : Color.parseColor("#c0ffffff");
themeInfo.previewOutColor = NekoConfig.useDefaultTheme ? 0xffd0e6ff: Color.parseColor("#3f51b5");
themeInfo.currentAccentId = DEFALT_THEME_ACCENT_ID;
themeInfo.sortIndex = 1;
themeInfo.setAccentColorOptions(
new int[] { 0xFF5890C5, 0xFF239853, 0xFFCE5E82, 0xFF7F63C3, 0xFF2491AD, 0xFF299C2F, 0xFF8854B4, 0xFF328ACF, 0xFF43ACC7, 0xFF52AC44, 0xFFCD5F93, 0xFFD28036, 0xFF8366CC, 0xFFCE4E57, 0xFFD3AE40, 0xFF7B88AB },
new int[] { 0xFFB8E18D, 0xFFFAFBCC, 0xFFFFF9DC, 0xFFC14F6E, 0xFFD1BD1B, 0xFFFFFAC9, 0xFFFCF6D8, 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[] { 0x00000000, 0xFFDFE2A0, 0xFFE2B991, 0xFFD7C1E9, 0xFFDCD1C0, 0xFFEFB576, 0xFFC0A2D1, 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[] { 99, 9, 10, 11, 12, 13, 14, 0, 1, 2, 3, 4, 5, 6, 7, 8 },
new String[] { "", "p-pXcflrmFIBAAAAvXYQk-mCwZU", "JqSUrO0-mFIBAAAAWwTvLzoWGQI", "O-wmAfBPSFADAAAA4zINVfD_bro", "RepJ5uE_SVABAAAAr4d0YhgB850", "-Xc-np9y2VMCAAAARKr0yNNPYW0", "dhf9pceaQVACAAAAbzdVo4SCiZA", "", "", "", "", "", "", "", "", "" },
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 }
);
if (NekoConfig.useDefaultTheme) {
themeInfo.firstAccentIsDefault = true;
themeInfo.setAccentColorOptions(
new int[]{0xFF5890C5, 0xFF239853, 0xFFCE5E82, 0xFF7F63C3, 0xFF2491AD, 0xFF299C2F, 0xFF8854B4, 0xFF328ACF, 0xFF43ACC7, 0xFF52AC44, 0xFFCD5F93, 0xFFD28036, 0xFF8366CC, 0xFFCE4E57, 0xFFD3AE40, 0xFF7B88AB},
new int[]{0xFFB8E18D, 0xFFFAFBCC, 0xFFFFF9DC, 0xFFC14F6E, 0xFFD1BD1B, 0xFFFFFAC9, 0xFFFCF6D8, 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[]{0x00000000, 0xFFDFE2A0, 0xFFE2B991, 0xFFD7C1E9, 0xFFDCD1C0, 0xFFEFB576, 0xFFC0A2D1, 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[]{99, 9, 10, 11, 12, 13, 14, 0, 1, 2, 3, 4, 5, 6, 7, 8},
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);
themesDict.put("Blue", themeInfo);
@ -3977,7 +3981,7 @@ public class Theme {
ThemeInfo applyingTheme = null;
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
try {
final ThemeInfo themeDarkBlue = themesDict.get("Dark Blue");
final ThemeInfo themeDarkBlue = themesDict.get("Night");
String theme = preferences.getString("theme", null);
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)) {
applyingTheme = themesDict.get("Blue");
applyingTheme.currentAccentId = DEFALT_THEME_ACCENT_ID;
@ -4202,7 +4206,7 @@ public class Theme {
currentNightTheme.setOverrideWallpaper(overrideWallpaper);
}
}
preferences.edit().remove("overrideThemeWallpaper").remove("selectedBackground2").commit();
preferences.edit().remove("overrideThemeWallpaper").remove("selectedBackground2").apply();
}
int switchToTheme = needSwitchToTheme();
@ -4265,11 +4269,11 @@ public class Theme {
Resources resources = context.getResources();
Drawable defaultDrawable = resources.getDrawable(resource).mutate();
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();
if (pressedColor != 0) {
pressedDrawable.setColorFilter(new PorterDuffColorFilter(pressedColor, PorterDuff.Mode.MULTIPLY));
pressedDrawable.setColorFilter(new PorterDuffColorFilter(pressedColor, PorterDuff.Mode.SRC_IN));
}
StateListDrawable stateListDrawable = new StateListDrawable() {
@Override
@ -4301,9 +4305,9 @@ public class Theme {
public static Drawable createEditTextDrawable(Context context, boolean alert) {
Resources resources = context.getResources();
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();
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() {
@Override
public boolean selectDrawable(int index) {
@ -4388,11 +4392,11 @@ public class Theme {
Resources resources = context.getResources();
Drawable defaultDrawable = resources.getDrawable(resource).mutate();
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();
if (pressedColor != 0) {
pressedDrawable.setColorFilter(new PorterDuffColorFilter(pressedColor, PorterDuff.Mode.MULTIPLY));
pressedDrawable.setColorFilter(new PorterDuffColorFilter(pressedColor, PorterDuff.Mode.SRC_IN));
}
StateListDrawable stateListDrawable = new StateListDrawable() {
@Override
@ -4481,7 +4485,7 @@ public class Theme {
if (drawable instanceof ColorDrawable) {
((ColorDrawable) drawable).setColor(color);
} 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;
}
if (themeInfo == currentNightTheme) {
currentNightTheme = themesDict.get("Dark Blue");
currentNightTheme = themesDict.get("Night");
}
themeInfo.removeObservers();
@ -5903,7 +5907,7 @@ public class Theme {
if (currentDayTheme == info) {
currentDayTheme = defaultTheme;
} else if (currentNightTheme == info) {
currentNightTheme = themesDict.get("Dark Blue");
currentNightTheme = themesDict.get("Night");
isNightTheme = true;
}
if (currentTheme == info) {
@ -6048,7 +6052,7 @@ public class Theme {
}
public static File getAssetFile(String assetName) {
File file = new File(ApplicationLoader.getFilesDirFixed(), assetName);
File file = new File(ApplicationLoader.getCacheDirFixed(), assetName);
long size;
try {
InputStream stream = ApplicationLoader.applicationContext.getAssets().open(assetName);
@ -6404,7 +6408,7 @@ public class Theme {
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[2] = resources.getDrawable(R.drawable.folders_private);
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_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));
applyCommonTheme();
}
}
@ -6542,7 +6546,7 @@ public class Theme {
dialogs_checkDrawable = 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_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_reorderDrawable = resources.getDrawable(R.drawable.list_reorder).mutate();
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_msgMediaHalfCheckDrawable = 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_msgOutSelectedClockDrawable = resources.getDrawable(R.drawable.msg_clock).mutate();
chat_msgInClockDrawable = resources.getDrawable(R.drawable.msg_clock).mutate();
chat_msgInSelectedClockDrawable = resources.getDrawable(R.drawable.msg_clock).mutate();
chat_msgMediaClockDrawable = resources.getDrawable(R.drawable.msg_clock).mutate();
chat_msgStickerClockDrawable = resources.getDrawable(R.drawable.msg_clock).mutate();
chat_msgOutClockDrawable = resources.getDrawable(R.drawable.deproko_baseline_clock_24).mutate();
chat_msgOutSelectedClockDrawable = resources.getDrawable(R.drawable.deproko_baseline_clock_24).mutate();
chat_msgInClockDrawable = resources.getDrawable(R.drawable.deproko_baseline_clock_24).mutate();
chat_msgInSelectedClockDrawable = resources.getDrawable(R.drawable.deproko_baseline_clock_24).mutate();
chat_msgMediaClockDrawable = resources.getDrawable(R.drawable.deproko_baseline_clock_24).mutate();
chat_msgStickerClockDrawable = resources.getDrawable(R.drawable.deproko_baseline_clock_24).mutate();
chat_msgInViewsDrawable = 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();
@ -6772,7 +6776,7 @@ public class Theme {
chat_pollCheckDrawable[a] = resources.getDrawable(R.drawable.poll_right).mutate();
chat_pollCrossDrawable[a] = resources.getDrawable(R.drawable.poll_wrong).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();
@ -6902,8 +6906,8 @@ public class Theme {
chat_photoStatesDrawables[12][0] = 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[1] = 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.baseline_person_24);
chat_locationDrawable[0] = 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) {
chat_actionBackgroundPaint.setColor(serviceColor);
colorFilter = new PorterDuffColorFilter(serviceColor, PorterDuff.Mode.MULTIPLY);
colorFilter2 = new PorterDuffColorFilter(serviceColor2, PorterDuff.Mode.MULTIPLY);
colorFilter = new PorterDuffColorFilter(serviceColor, PorterDuff.Mode.SRC_IN);
colorFilter2 = new PorterDuffColorFilter(serviceColor2, PorterDuff.Mode.SRC_IN);
currentColor = serviceColor;
if (chat_cornerOuter[0] != null) {
for (int a = 0; a < 4; a++) {
@ -7221,8 +7225,8 @@ public class Theme {
}
if (currentSelectedColor != servicePressedColor) {
currentSelectedColor = servicePressedColor;
colorPressedFilter = new PorterDuffColorFilter(servicePressedColor, PorterDuff.Mode.MULTIPLY);
colorPressedFilter2 = new PorterDuffColorFilter(servicePressedColor2, PorterDuff.Mode.MULTIPLY);
colorPressedFilter = new PorterDuffColorFilter(servicePressedColor, PorterDuff.Mode.SRC_IN);
colorPressedFilter2 = new PorterDuffColorFilter(servicePressedColor2, PorterDuff.Mode.SRC_IN);
}
}
@ -7249,13 +7253,13 @@ public class Theme {
if (selected) {
if (currentShareSelectedColorFilter == null || currentShareSelectedColorFilterColor != color) {
currentShareSelectedColorFilterColor = color;
currentShareSelectedColorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY);
currentShareSelectedColorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN);
}
return currentShareSelectedColorFilter;
} else {
if (currentShareColorFilter == null || currentShareColorFilterColor != color) {
currentShareColorFilterColor = color;
currentShareColorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY);
currentShareColorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN);
}
return currentShareColorFilter;
}
@ -7282,7 +7286,7 @@ public class Theme {
return null;
}
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;
}
@ -7477,7 +7481,7 @@ public class Theme {
} else if (drawable instanceof ScamDrawable) {
((ScamDrawable) drawable).setColor(color);
} 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) {
((ShapeDrawable) state).getPaint().setColor(color);
} else {
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
}
} else {
Drawable state = getStateDrawable(drawable, 1);
if (state instanceof ShapeDrawable) {
((ShapeDrawable) state).getPaint().setColor(color);
} else {
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
}
}
} catch (Throwable ignore) {
@ -7534,20 +7538,20 @@ public class Theme {
if (state instanceof ShapeDrawable) {
((ShapeDrawable) state).getPaint().setColor(color);
} else {
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
}
state = getStateDrawable(drawable, 1);
if (state instanceof ShapeDrawable) {
((ShapeDrawable) state).getPaint().setColor(color);
} else {
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
}
} else {
Drawable state = getStateDrawable(drawable, 2);
if (state instanceof ShapeDrawable) {
((ShapeDrawable) state).getPaint().setColor(color);
} else {
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
state.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
}
}
} catch (Throwable ignore) {
@ -7566,7 +7570,7 @@ public class Theme {
if (drawable1 instanceof ShapeDrawable) {
((ShapeDrawable) drawable1).getPaint().setColor(color);
} 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 kotlin.Unit;
import tw.nekomimi.nekogram.BottomBuilder;
@TargetApi(23)
public class ActionIntroActivity extends BaseFragment implements LocationController.LocationFetchCallback {
@ -544,11 +547,13 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
break;
}
case ACTION_TYPE_CHANGE_PHONE_NUMBER: {
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setTitle(LocaleController.getString("PhoneNumberChangeTitle", R.string.PhoneNumberChangeTitle));
builder.setMessage(LocaleController.getString("PhoneNumberAlert", R.string.PhoneNumberAlert));
builder.setPositiveButton(LocaleController.getString("Change", R.string.Change), (dialogInterface, i) -> presentFragment(new ChangePhoneActivity(), true));
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
BottomBuilder builder = new BottomBuilder(getParentActivity());
builder.addTitle(LocaleController.getString("PhoneNumberAlert", R.string.PhoneNumberAlert));
builder.addItem(LocaleController.getString("Change", R.string.Change), (i) -> {
presentFragment(new ChangePhoneActivity(), true);
return Unit.INSTANCE;
});
builder.addCancelItem();
showDialog(builder.create());
break;
}
@ -608,8 +613,8 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
subtitleTextView.setVisibility(View.VISIBLE);
drawable1 = context.getResources().getDrawable(R.drawable.sim_old);
drawable2 = context.getResources().getDrawable(R.drawable.sim_new);
drawable1.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_changephoneinfo_image), PorterDuff.Mode.MULTIPLY));
drawable2.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_changephoneinfo_image2), 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.SRC_IN));
imageView.setImageDrawable(new CombinedDrawable(drawable1, drawable2));
imageView.setScaleType(ImageView.ScaleType.CENTER);
UserConfig userConfig = getUserConfig();
@ -668,7 +673,7 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
return;
}
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.setNegativeButton(LocaleController.getString("PermissionOpenSettings", R.string.PermissionOpenSettings), (dialog, which) -> {
if (getParentActivity() == null) {
@ -722,7 +727,7 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
if (grantResults != null && grantResults.length != 0) {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
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.setNegativeButton(LocaleController.getString("PermissionOpenSettings", R.string.PermissionOpenSettings), (dialog, which) -> {
if (getParentActivity() == null) {
@ -747,7 +752,7 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
processOpenQrReader();
} else {
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.setNegativeButton(LocaleController.getString("PermissionOpenSettings", R.string.PermissionOpenSettings), (dialog, which) -> {
try {

View File

@ -14,19 +14,25 @@ import android.content.SharedPreferences;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserConfig;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.DrawerActionCell;
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.DrawerProfileCell;
import org.telegram.ui.Cells.DrawerUserCell;
import org.telegram.ui.Cells.EmptyCell;
import org.telegram.ui.Cells.DrawerProfileCell;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.SideMenultItemAnimator;
@ -34,12 +40,13 @@ import java.util.ArrayList;
import java.util.Collections;
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 ArrayList<Item> items = new ArrayList<>(11);
public ArrayList<Item> items = new ArrayList<>(11);
private ArrayList<Integer> accountNumbers = new ArrayList<>();
private boolean accountsShown;
private DrawerProfileCell profileCell;
@ -48,7 +55,7 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
public DrawerLayoutAdapter(Context context, SideMenultItemAnimator animator) {
mContext = context;
itemAnimator = animator;
accountsShown = UserConfig.getActivatedAccountsCount() > 1 && MessagesController.getGlobalMainSettings().getBoolean("accountsShown", true);
accountsShown = true;
Theme.createDialogsResources(context);
resetItems();
}
@ -78,7 +85,7 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
if (profileCell != null) {
profileCell.setAccountsShown(accountsShown, animated);
}
MessagesController.getGlobalMainSettings().edit().putBoolean("accountsShown", accountsShown).commit();
MessagesController.getGlobalMainSettings().edit().putBoolean("accountsShown", accountsShown).apply();
if (animated) {
itemAnimator.setShouldClipChildren(false);
if (accountsShown) {
@ -95,6 +102,11 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
return accountsShown;
}
@Override public void didReceivedNotification(int id, int account, Object... args) {
resetItems();
notifyDataSetChanged();
}
@Override
public void notifyDataSetChanged() {
resetItems();
@ -120,6 +132,9 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
case 3:
view = new DrawerActionCell(mContext);
break;
case 6:
view = new DrawerActionCheckCell(mContext);
break;
case 4:
view = new DrawerUserCell(mContext);
break;
@ -153,8 +168,19 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
drawerActionCell.setPadding(0, 0, 0, 0);
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: {
DrawerUserCell drawerUserCell = (DrawerUserCell) holder.itemView;
drawerUserCell.invalidate();
drawerUserCell.setAccount(accountNumbers.get(position - 2));
break;
}
@ -174,7 +200,7 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
return 4;
} else {
if (accountNumbers.size() < UserConfig.MAX_ACCOUNT_COUNT) {
if (i == accountNumbers.size()){
if (i == accountNumbers.size()) {
return 5;
} else if (i == accountNumbers.size() + 1) {
return 2;
@ -190,7 +216,7 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
if (items.get(i) == null) {
return 2;
}
return 3;
return items.get(i) instanceof CheckItem ? 6 : 3;
}
private void resetItems() {
@ -221,56 +247,23 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
return;
}
int eventType = Theme.getEventType();
int newGroupIcon;
int newSecretIcon;
int newChannelIcon;
int contactsIcon;
int callsIcon;
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));
int contactsIcon = R.drawable.baseline_perm_contact_calendar_24;
int savedIcon = R.drawable.baseline_bookmark_24;
int settingsIcon = R.drawable.baseline_settings_24;
int inviteIcon = R.drawable.baseline_person_add_24;
int helpIcon = R.drawable.baseline_help_24;
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(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(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) {
@ -285,7 +278,19 @@ public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter {
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 String text;
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() {
return accountNumbers.size();
}

View File

@ -38,7 +38,7 @@ public class DrawerAddCell extends FrameLayout {
textView.setMaxLines(1);
textView.setSingleLine(true);
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));
}
@ -54,7 +54,7 @@ public class DrawerAddCell extends FrameLayout {
textView.setText(LocaleController.getString("AddAccount", R.string.AddAccount));
Drawable drawable = getResources().getDrawable(R.drawable.account_add);
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);
}

View File

@ -15,22 +15,23 @@ import android.os.Build;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LayoutHelper;
import java.util.ArrayList;
public class HeaderCell extends FrameLayout {
public class HeaderCell extends LinearLayout {
private TextView textView;
private SimpleTextView textView2;
private TextView textView2;
private int height = 40;
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) {
this(context, textColorKey, padding, topMargin, text2, false);
}
public HeaderCell(Context context, String textColorKey, int padding, int topMargin, boolean text2,boolean bigTitle) {
super(context);
setOrientation(LinearLayout.VERTICAL);
setPadding(AndroidUtilities.dp(padding), AndroidUtilities.dp(topMargin), AndroidUtilities.dp(padding), 0);
textView = new TextView(getContext());
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.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
textView.setMinHeight(AndroidUtilities.dp(height - topMargin));
textView.setTextColor(Theme.getColor(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 SimpleTextView(getContext());
textView2.setTextSize(13);
textView2.setGravity((LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.TOP);
addView(textView2, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.TOP, padding, 21, padding, 0));
}
textView2 = new TextView(getContext());
textView2.setTextSize(13);
textView2.setMovementMethod(new AndroidUtilities.LinkMovementMethodMy());
textView2.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
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) {
@ -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) {
textView.setText(text);
}
public void setText2(CharSequence text) {
if (textView2 == null) {
return;
if (textView2.getVisibility() != View.VISIBLE) {
textView2.setVisibility(View.VISIBLE);
}
textView2.setText(text);
}
@ -93,8 +108,7 @@ public class HeaderCell extends FrameLayout {
public TextView getTextView() {
return textView;
}
public SimpleTextView getTextView2() {
public TextView getTextView2() {
return textView2;
}

View File

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

View File

@ -42,6 +42,9 @@ public class RadioColorCell extends FrameLayout {
textView.setSingleLine(true);
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));
setBackground(Theme.createSelectorDrawable(Theme.getColor(Theme.key_actionBarActionModeDefaultSelector), 3));
}
@Override

View File

@ -92,8 +92,8 @@ public class SessionCell extends FrameLayout {
detailTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
detailTextView.setLines(1);
detailTextView.setMaxLines(1);
detailTextView.setSingleLine(true);
detailTextView.setEllipsize(TextUtils.TruncateAt.END);
//detailTextView.setSingleLine(true);
//detailTextView.setEllipsize(TextUtils.TruncateAt.END);
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));

View File

@ -55,8 +55,9 @@ public class TextCell extends FrameLayout {
addView(valueTextView);
imageView = new ImageView(context);
imageView.setVisibility(GONE);
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);
valueImageView = new ImageView(context);
@ -132,7 +133,7 @@ public class TextCell extends FrameLayout {
textView.setTextColor(Theme.getColor(text));
textView.setTag(text);
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);
}
}
@ -150,11 +151,13 @@ public class TextCell extends FrameLayout {
public void setTextAndIcon(String text, int resId, boolean divider) {
textView.setText(text);
valueTextView.setText(null);
imageView.setImageResource(resId);
imageView.setVisibility(VISIBLE);
if (resId != 0) {
imageView.setImageResource(resId);
imageView.setVisibility(VISIBLE);
}
imageView.setPadding(0, AndroidUtilities.dp(7), 0, 0);
valueTextView.setVisibility(GONE);
valueImageView.setVisibility(GONE);
imageView.setPadding(0, AndroidUtilities.dp(7), 0, 0);
needDivider = divider;
setWillNotDraw(!needDivider);
}

View File

@ -14,7 +14,10 @@ import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.Property;
import android.util.TypedValue;
@ -25,13 +28,16 @@ import android.widget.FrameLayout;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimationProperties;
import org.telegram.ui.Components.CheckBoxSquare;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.Switch;
import org.telegram.ui.Components.ViewHelper;
import java.util.ArrayList;
@ -40,6 +46,7 @@ public class TextCheckCell extends FrameLayout {
private TextView textView;
private TextView valueTextView;
private Switch checkBox;
private CheckBoxSquare checkBoxSquare;
private boolean needDivider;
private boolean isMultiline;
private int height = 50;
@ -77,11 +84,7 @@ public class TextCheckCell extends FrameLayout {
textView = new TextView(context);
textView.setTextColor(Theme.getColor(dialog ? Theme.key_dialogTextBlack : Theme.key_windowBackgroundWhiteBlackText));
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.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));
valueTextView = new TextView(context);
@ -95,9 +98,18 @@ public class TextCheckCell extends FrameLayout {
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));
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));
if (!dialog) {
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);
}
@ -107,7 +119,7 @@ public class TextCheckCell extends FrameLayout {
if (isMultiline) {
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
} 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) {
textView.setText(text);
isMultiline = false;
checkBox.setChecked(checked, false);
if (checkBox != null) {
checkBox.setChecked(checked, false);
} else {
checkBoxSquare.setChecked(checked,false);
}
needDivider = divider;
valueTextView.setVisibility(GONE);
LayoutParams layoutParams = (LayoutParams) textView.getLayoutParams();
@ -150,7 +166,7 @@ public class TextCheckCell extends FrameLayout {
@Override
public void setPressed(boolean pressed) {
if (drawCheckRipple) {
if (drawCheckRipple && checkBox != null) {
checkBox.setDrawRipple(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) {
textView.setText(text);
valueTextView.setText(value);
checkBox.setChecked(checked, false);
if (checkBox != null) {
checkBox.setChecked(checked, false);
} else {
checkBoxSquare.setChecked(checked,false);
}
needDivider = divider;
valueTextView.setVisibility(VISIBLE);
isMultiline = multiline;
@ -187,13 +207,17 @@ public class TextCheckCell extends FrameLayout {
super.setEnabled(value);
if (animators != null) {
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) {
animators.add(ObjectAnimator.ofFloat(valueTextView, "alpha", value ? 1.0f : 0.5f));
}
} else {
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) {
valueTextView.setAlpha(value ? 1.0f : 0.5f);
}
@ -201,11 +225,15 @@ public class TextCheckCell extends FrameLayout {
}
public void setChecked(boolean checked) {
checkBox.setChecked(checked, true);
if (checkBox != null) {
checkBox.setChecked(checked, true);
} else {
checkBoxSquare.setChecked(checked,true);
}
}
public boolean isChecked() {
return checkBox.isChecked();
return checkBox != null ? checkBox.isChecked() : checkBoxSquare.isChecked();
}
@Override
@ -226,7 +254,9 @@ public class TextCheckCell extends FrameLayout {
if (animationPaint == null) {
animationPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
checkBox.setOverrideColor(checked ? 1 : 2);
if (checkBox != null) {
checkBox.setOverrideColor(checked ? 1 : 2);
}
animatedColorBackground = color;
animationPaint.setColor(animatedColorBackground);
animationProgress = 0.0f;
@ -262,7 +292,7 @@ public class TextCheckCell extends FrameLayout {
canvas.drawCircle(cx, cy, animatedRad, animationPaint);
}
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);
info.setClassName("android.widget.Switch");
info.setCheckable(true);
info.setChecked(checkBox.isChecked());
info.setContentDescription(checkBox.isChecked() ? LocaleController.getString("NotificationsOn", R.string.NotificationsOn) : LocaleController.getString("NotificationsOff", R.string.NotificationsOff));
info.setChecked(isChecked());
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.Components.LayoutHelper;
import cn.hutool.core.util.StrUtil;
public class TextDetailSettingsCell extends FrameLayout {
private TextView textView;
@ -58,7 +60,7 @@ public class TextDetailSettingsCell extends FrameLayout {
imageView = new ImageView(context);
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);
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) {
textView.setText(text);
if (StrUtil.isBlank(value)) {
valueTextView.setVisibility(GONE);
} else {
valueTextView.setVisibility(VISIBLE);
}
valueTextView.setText(value);
needDivider = divider;
imageView.setVisibility(GONE);

View File

@ -16,6 +16,7 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuffColorFilter;
import android.os.Bundle;
import android.os.Vibrator;
import android.text.Editable;
@ -70,6 +71,9 @@ import org.telegram.ui.Components.SizeNotifierFrameLayout;
import java.util.ArrayList;
import kotlin.Unit;
import tw.nekomimi.nekogram.BottomBuilder;
public class ChannelCreateActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate, ImageUpdater.ImageUpdaterDelegate {
private View doneButton;
@ -474,7 +478,9 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
}
};
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.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));
@ -569,7 +575,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
radioButtonCell1 = new RadioButtonCell(context);
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));
radioButtonCell1.setOnClickListener(v -> {
if (!isPrivate) {
@ -581,7 +587,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
radioButtonCell2 = new RadioButtonCell(context);
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));
radioButtonCell2.setOnClickListener(v -> {
if (isPrivate) {
@ -949,15 +955,13 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
AdminedChannelCell adminedChannelCell = new AdminedChannelCell(getParentActivity(), view -> {
AdminedChannelCell cell = (AdminedChannelCell) view.getParent();
final TLRPC.Chat channel = cell.getCurrentChannel();
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
BottomBuilder builder = new BottomBuilder(getParentActivity());
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 {
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.setPositiveButton(LocaleController.getString("RevokeButton", R.string.RevokeButton), (dialogInterface, i) -> {
builder.addItem(LocaleController.getString("RevokeButton", R.string.RevokeButton),R.drawable.baseline_delete_forever_24, (i) -> {
TLRPC.TL_channels_updateUsername req1 = new TLRPC.TL_channels_updateUsername();
req1.channel = MessagesController.getInputChannel(channel);
req1.username = "";
@ -972,7 +976,9 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
});
}
}, ConnectionsManager.RequestFlagInvokeAfter);
return Unit.INSTANCE;
});
builder.addCancelItem();
showDialog(builder.create());
});
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.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.FileLog;
@ -92,6 +91,9 @@ import java.util.List;
import java.util.Locale;
import java.util.concurrent.CountDownLatch;
import kotlin.Unit;
import tw.nekomimi.nekogram.BottomBuilder;
public class AlertsCreator {
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();
}
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) {
return null;
}
@ -332,29 +366,31 @@ public class AlertsCreator {
language.base_lang_code = language.base_lang_code.replace('-', '_').toLowerCase();
}
SpannableStringBuilder spanned;
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
BottomBuilder builder = new BottomBuilder(activity);
LocaleController.LocaleInfo currentInfo = LocaleController.getInstance().getCurrentLocaleInfo();
String str;
if (currentInfo.shortName.equals(language.lang_code)) {
builder.setTitle(LocaleController.getString("Language", R.string.Language));
str = LocaleController.formatString("LanguageSame", R.string.LanguageSame, language.name);
builder.setNegativeButton(LocaleController.getString("OK", R.string.OK), null);
builder.setNeutralButton(LocaleController.getString("SETTINGS", R.string.SETTINGS), (dialog, which) -> activity.presentFragment(new LanguageSelectActivity()));
String str = LocaleController.formatString("LanguageSame", R.string.LanguageSame, language.name);
builder.addTitle(LocaleController.getString("Language", R.string.Language), mkTransSpan(str, language, builder));
builder.addCancelButton();
builder.addButton(LocaleController.getString("SETTINGS", R.string.SETTINGS), (__) -> {
builder.dismiss();
activity.presentFragment(new LanguageSelectActivity());
return Unit.INSTANCE;
});
} else {
if (language.strings_count == 0) {
builder.setTitle(LocaleController.getString("LanguageUnknownTitle", R.string.LanguageUnknownTitle));
str = LocaleController.formatString("LanguageUnknownCustomAlert", R.string.LanguageUnknownCustomAlert, language.name);
builder.setNegativeButton(LocaleController.getString("OK", R.string.OK), null);
String str = LocaleController.formatString("LanguageUnknownCustomAlert", R.string.LanguageUnknownCustomAlert, language.name);
builder.addTitle(LocaleController.getString("LanguageUnknownTitle", R.string.LanguageUnknownTitle), mkTransSpan(str, language, builder));
builder.addCancelButton();
} else {
builder.setTitle(LocaleController.getString("LanguageTitle", R.string.LanguageTitle));
String str;
if (language.official) {
str = LocaleController.formatString("LanguageAlert", R.string.LanguageAlert, language.name, (int) Math.ceil(language.translated_count / (float) language.strings_count * 100));
} else {
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;
if (language.official) {
key = "remote_" + language.lang_code;
@ -376,47 +412,18 @@ public class AlertsCreator {
localeInfo.pathToFile = "unofficial";
}
}
if (callback != null) {
callback.run();
}
LocaleController.getInstance().applyLanguage(localeInfo, true, false, false, true, UserConfig.selectedAccount);
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;
}
@ -452,7 +459,7 @@ public class AlertsCreator {
return null;
}
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.setPositiveButton(LocaleController.getString("OK", R.string.OK), null);
return builder;
@ -582,11 +589,11 @@ public class AlertsCreator {
};
int[] icons = new int[]{
R.drawable.notifications_on,
R.drawable.notifications_mute1h,
R.drawable.notifications_mute2d,
R.drawable.notifications_settings,
R.drawable.notifications_off
R.drawable.baseline_notifications_24,
R.drawable.deproko_baseline_clock_24,
R.drawable.deproko_baseline_clock_24,
R.drawable.baseline_settings_24,
R.drawable.baseline_notifications_off_24
};
final LinearLayout linearLayout = new LinearLayout(parentFragment.getParentActivity());
@ -601,10 +608,10 @@ public class AlertsCreator {
Drawable drawable = parentFragment.getParentActivity().getResources().getDrawable(icons[a]);
if (a == descriptions.length - 1) {
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 {
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.setLines(1);

View File

@ -1580,9 +1580,9 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter
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);
@ -1592,25 +1592,16 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter
IoUtil.copy(process, logcatFile);
Intent i = new Intent(Intent.ACTION_SEND);
if (Build.VERSION.SDK_INT >= 24) {
i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_EMAIL, "");
i.putExtra(Intent.EXTRA_SUBJECT, "Logs from " + LocaleController.getInstance().formatterStats.format(System.currentTimeMillis()));
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();
}
});
RuntimeUtil.exec("logcat", "-c");
ShareUtil.shareFile(getParentActivity(), logcatFile);
} catch (Exception e) {
AlertUtil.showToast(e);
}
}
private class SearchAdapter extends RecyclerListView.SelectionAdapter {