diff --git a/TMessagesProj/build.gradle b/TMessagesProj/build.gradle index 1f144ec19..e5696e530 100644 --- a/TMessagesProj/build.gradle +++ b/TMessagesProj/build.gradle @@ -80,7 +80,7 @@ android { defaultConfig { minSdkVersion 8 targetSdkVersion 21 - versionCode 397 - versionName "2.0.5" + versionCode 403 + versionName "2.1.0" } } diff --git a/TMessagesProj/config/debug/AndroidManifest.xml b/TMessagesProj/config/debug/AndroidManifest.xml index dc448b5fa..7836674f2 100644 --- a/TMessagesProj/config/debug/AndroidManifest.xml +++ b/TMessagesProj/config/debug/AndroidManifest.xml @@ -23,7 +23,7 @@ android:icon="@drawable/ic_launcher" android:label="@string/AppName" android:theme="@style/Theme.TMessages.Start" - android:name="org.telegram.ui.ApplicationLoader" + android:name=".ApplicationLoader" android:hardwareAccelerated="true" android:largeHeap="true"> diff --git a/TMessagesProj/config/foss/AndroidManifest.xml b/TMessagesProj/config/foss/AndroidManifest.xml index 17b3445ef..df2d1e24b 100644 --- a/TMessagesProj/config/foss/AndroidManifest.xml +++ b/TMessagesProj/config/foss/AndroidManifest.xml @@ -8,7 +8,7 @@ android:icon="@drawable/ic_launcher" android:label="@string/AppName" android:theme="@style/Theme.TMessages.Start" - android:name="org.telegram.ui.ApplicationLoader" + android:name=".ApplicationLoader" android:hardwareAccelerated="true" android:largeHeap="true"> diff --git a/TMessagesProj/config/release/AndroidManifest.xml b/TMessagesProj/config/release/AndroidManifest.xml index 463616384..17c2c2458 100644 --- a/TMessagesProj/config/release/AndroidManifest.xml +++ b/TMessagesProj/config/release/AndroidManifest.xml @@ -23,7 +23,7 @@ android:icon="@drawable/ic_launcher" android:label="@string/AppName" android:theme="@style/Theme.TMessages.Start" - android:name="org.telegram.ui.ApplicationLoader" + android:name=".ApplicationLoader" android:hardwareAccelerated="true" android:largeHeap="true"> diff --git a/TMessagesProj/jni/Android.mk b/TMessagesProj/jni/Android.mk index 5c2a6c040..bd2a81f05 100755 --- a/TMessagesProj/jni/Android.mk +++ b/TMessagesProj/jni/Android.mk @@ -2,7 +2,7 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_PRELINK_MODULE := false -LOCAL_MODULE := tmessages.3 +LOCAL_MODULE := tmessages.4 LOCAL_CFLAGS := -w -std=gnu99 -O2 -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 LOCAL_CFLAGS += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -fno-math-errno LOCAL_CFLAGS += -DANDROID_NDK -DDISABLE_IMPORTGL -fno-strict-aliasing -fprefetch-loop-arrays -DAVOID_TABLES -DANDROID_TILE_BASED_DECODE -DANDROID_ARMV6_IDCT -DHAVE_STRCHRNUL=0 diff --git a/TMessagesProj/jni/gif.c b/TMessagesProj/jni/gif.c index 06b7a6283..c47cdbd95 100644 --- a/TMessagesProj/jni/gif.c +++ b/TMessagesProj/jni/gif.c @@ -589,7 +589,7 @@ static jint open(GifFileType *GifFileIn, int Error, int startPos, JNIEnv *env, j return (jint)(Error == 0 ? info : NULL); } -JNIEXPORT jlong JNICALL Java_org_telegram_ui_Views_GifDrawable_getAllocationByteCount(JNIEnv *env, jclass class, jobject gifInfo) { +JNIEXPORT jlong JNICALL Java_org_telegram_ui_Components_GifDrawable_getAllocationByteCount(JNIEnv *env, jclass class, jobject gifInfo) { GifInfo *info = (GifInfo *)gifInfo; if (info == NULL) { return 0; @@ -602,7 +602,7 @@ JNIEXPORT jlong JNICALL Java_org_telegram_ui_Views_GifDrawable_getAllocationByte return sum; } -JNIEXPORT void JNICALL Java_org_telegram_ui_Views_GifDrawable_reset(JNIEnv *env, jclass class, jobject gifInfo) { +JNIEXPORT void JNICALL Java_org_telegram_ui_Components_GifDrawable_reset(JNIEnv *env, jclass class, jobject gifInfo) { GifInfo *info = (GifInfo *)gifInfo; if (info == NULL) { return; @@ -610,7 +610,7 @@ JNIEXPORT void JNICALL Java_org_telegram_ui_Views_GifDrawable_reset(JNIEnv *env, reset(info); } -JNIEXPORT void JNICALL Java_org_telegram_ui_Views_GifDrawable_setSpeedFactor(JNIEnv *env, jclass class, jobject gifInfo, jfloat factor) { +JNIEXPORT void JNICALL Java_org_telegram_ui_Components_GifDrawable_setSpeedFactor(JNIEnv *env, jclass class, jobject gifInfo, jfloat factor) { GifInfo *info = (GifInfo *)gifInfo; if (info == NULL) { return; @@ -618,7 +618,7 @@ JNIEXPORT void JNICALL Java_org_telegram_ui_Views_GifDrawable_setSpeedFactor(JNI info->speedFactor = factor; } -JNIEXPORT void JNICALL Java_org_telegram_ui_Views_GifDrawable_seekToTime(JNIEnv *env, jclass class, jobject gifInfo, jint desiredPos, jintArray jPixels) { +JNIEXPORT void JNICALL Java_org_telegram_ui_Components_GifDrawable_seekToTime(JNIEnv *env, jclass class, jobject gifInfo, jint desiredPos, jintArray jPixels) { GifInfo *info = (GifInfo *)gifInfo; if (info == NULL || jPixels == NULL) { return; @@ -665,7 +665,7 @@ JNIEXPORT void JNICALL Java_org_telegram_ui_Views_GifDrawable_seekToTime(JNIEnv } } -JNIEXPORT void JNICALL Java_org_telegram_ui_Views_GifDrawable_seekToFrame(JNIEnv *env, jclass class, jobject gifInfo, jint desiredIdx, jintArray jPixels) { +JNIEXPORT void JNICALL Java_org_telegram_ui_Components_GifDrawable_seekToFrame(JNIEnv *env, jclass class, jobject gifInfo, jint desiredIdx, jintArray jPixels) { GifInfo *info = (GifInfo *)gifInfo; if (info == NULL|| jPixels==NULL) { return; @@ -701,7 +701,7 @@ JNIEXPORT void JNICALL Java_org_telegram_ui_Views_GifDrawable_seekToFrame(JNIEnv } } -JNIEXPORT void JNICALL Java_org_telegram_ui_Views_GifDrawable_renderFrame(JNIEnv *env, jclass class, jintArray jPixels, jobject gifInfo, jintArray metaData) { +JNIEXPORT void JNICALL Java_org_telegram_ui_Components_GifDrawable_renderFrame(JNIEnv *env, jclass class, jintArray jPixels, jobject gifInfo, jintArray metaData) { GifInfo *info = (GifInfo *)gifInfo; if (info == NULL || jPixels == NULL) { return; @@ -752,7 +752,7 @@ JNIEXPORT void JNICALL Java_org_telegram_ui_Views_GifDrawable_renderFrame(JNIEnv (*env)->ReleaseIntArrayElements(env, metaData, rawMetaData, 0); } -JNIEXPORT void JNICALL Java_org_telegram_ui_Views_GifDrawable_free(JNIEnv *env, jclass class, jobject gifInfo) { +JNIEXPORT void JNICALL Java_org_telegram_ui_Components_GifDrawable_free(JNIEnv *env, jclass class, jobject gifInfo) { if (gifInfo == NULL) { return; } @@ -765,7 +765,7 @@ JNIEXPORT void JNICALL Java_org_telegram_ui_Views_GifDrawable_free(JNIEnv *env, cleanUp(info); } -JNIEXPORT jstring JNICALL Java_org_telegram_ui_Views_GifDrawable_getComment(JNIEnv *env, jclass class, jobject gifInfo) { +JNIEXPORT jstring JNICALL Java_org_telegram_ui_Components_GifDrawable_getComment(JNIEnv *env, jclass class, jobject gifInfo) { if (gifInfo == NULL) { return NULL; } @@ -773,14 +773,14 @@ JNIEXPORT jstring JNICALL Java_org_telegram_ui_Views_GifDrawable_getComment(JNIE return (*env)->NewStringUTF(env, info->comment); } -JNIEXPORT jint JNICALL Java_org_telegram_ui_Views_GifDrawable_getLoopCount(JNIEnv *env, jclass class, jobject gifInfo) { +JNIEXPORT jint JNICALL Java_org_telegram_ui_Components_GifDrawable_getLoopCount(JNIEnv *env, jclass class, jobject gifInfo) { if (gifInfo == NULL) { return 0; } return ((GifInfo *)gifInfo)->loopCount; } -JNIEXPORT jint JNICALL Java_org_telegram_ui_Views_GifDrawable_getDuration(JNIEnv *env, jclass class, jobject gifInfo) { +JNIEXPORT jint JNICALL Java_org_telegram_ui_Components_GifDrawable_getDuration(JNIEnv *env, jclass class, jobject gifInfo) { GifInfo *info = (GifInfo *)gifInfo; if (info == NULL) { return 0; @@ -793,7 +793,7 @@ JNIEXPORT jint JNICALL Java_org_telegram_ui_Views_GifDrawable_getDuration(JNIEnv return sum; } -JNIEXPORT jint JNICALL Java_org_telegram_ui_Views_GifDrawable_getCurrentPosition(JNIEnv *env, jclass class, jobject gifInfo) { +JNIEXPORT jint JNICALL Java_org_telegram_ui_Components_GifDrawable_getCurrentPosition(JNIEnv *env, jclass class, jobject gifInfo) { GifInfo *info = (GifInfo *)gifInfo; if (info == NULL) { return 0; @@ -811,7 +811,7 @@ JNIEXPORT jint JNICALL Java_org_telegram_ui_Views_GifDrawable_getCurrentPosition return (int) (sum + remainder); } -JNIEXPORT void JNICALL Java_org_telegram_ui_Views_GifDrawable_saveRemainder(JNIEnv *env, jclass class, jobject gifInfo) { +JNIEXPORT void JNICALL Java_org_telegram_ui_Components_GifDrawable_saveRemainder(JNIEnv *env, jclass class, jobject gifInfo) { GifInfo *info = (GifInfo *)gifInfo; if (info == NULL) { return; @@ -819,7 +819,7 @@ JNIEXPORT void JNICALL Java_org_telegram_ui_Views_GifDrawable_saveRemainder(JNIE info->lastFrameReaminder = getRealTime() - info->nextStartTime; } -JNIEXPORT void JNICALL Java_org_telegram_ui_Views_GifDrawable_restoreRemainder(JNIEnv *env, jclass class, jobject gifInfo) { +JNIEXPORT void JNICALL Java_org_telegram_ui_Components_GifDrawable_restoreRemainder(JNIEnv *env, jclass class, jobject gifInfo) { GifInfo *info = (GifInfo *)gifInfo; if (info == NULL || info->lastFrameReaminder == ULONG_MAX) { return; @@ -828,7 +828,7 @@ JNIEXPORT void JNICALL Java_org_telegram_ui_Views_GifDrawable_restoreRemainder(J info->lastFrameReaminder = ULONG_MAX; } -JNIEXPORT jint JNICALL Java_org_telegram_ui_Views_GifDrawable_openFile(JNIEnv *env, jclass class, jintArray metaData, jstring jfname) { +JNIEXPORT jint JNICALL Java_org_telegram_ui_Components_GifDrawable_openFile(JNIEnv *env, jclass class, jintArray metaData, jstring jfname) { if (jfname == NULL) { setMetaData(0, 0, 0, D_GIF_ERR_OPEN_FAILED, env, metaData); return (jint) NULL; diff --git a/TMessagesProj/libs/armeabi-v7a/libtmessages.3.so b/TMessagesProj/libs/armeabi-v7a/libtmessages.4.so similarity index 89% rename from TMessagesProj/libs/armeabi-v7a/libtmessages.3.so rename to TMessagesProj/libs/armeabi-v7a/libtmessages.4.so index 6d9c8366b..c38583ba5 100755 Binary files a/TMessagesProj/libs/armeabi-v7a/libtmessages.3.so and b/TMessagesProj/libs/armeabi-v7a/libtmessages.4.so differ diff --git a/TMessagesProj/libs/armeabi/libtmessages.3.so b/TMessagesProj/libs/armeabi/libtmessages.4.so similarity index 85% rename from TMessagesProj/libs/armeabi/libtmessages.3.so rename to TMessagesProj/libs/armeabi/libtmessages.4.so index 98fb21768..25188ed13 100755 Binary files a/TMessagesProj/libs/armeabi/libtmessages.3.so and b/TMessagesProj/libs/armeabi/libtmessages.4.so differ diff --git a/TMessagesProj/libs/x86/libtmessages.3.so b/TMessagesProj/libs/x86/libtmessages.4.so similarity index 76% rename from TMessagesProj/libs/x86/libtmessages.3.so rename to TMessagesProj/libs/x86/libtmessages.4.so index 61ccbf61f..e0f20794e 100755 Binary files a/TMessagesProj/libs/x86/libtmessages.3.so and b/TMessagesProj/libs/x86/libtmessages.4.so differ diff --git a/TMessagesProj/src/main/AndroidManifest.xml b/TMessagesProj/src/main/AndroidManifest.xml index a5fb34f8a..a85bdd038 100644 --- a/TMessagesProj/src/main/AndroidManifest.xml +++ b/TMessagesProj/src/main/AndroidManifest.xml @@ -4,10 +4,10 @@ android:installLocation="auto"> @@ -41,20 +41,20 @@ + android:largeHeap="true" + android:theme="@style/Theme.TMessages.Start"> + android:windowSoftInputMode="adjustPan"> @@ -95,6 +95,19 @@ + + + + + + + + + + + + + + android:theme="@style/Theme.TMessages.PopupNotification" + android:windowSoftInputMode="adjustResize|stateHidden"> @@ -116,8 +129,7 @@ - + @@ -125,8 +137,7 @@ android:resource="@xml/auth"/> - + diff --git a/TMessagesProj/src/main/java/org/telegram/PhoneFormat/PhoneFormat.java b/TMessagesProj/src/main/java/org/telegram/PhoneFormat/PhoneFormat.java index 512b962a0..a6dbff0ac 100644 --- a/TMessagesProj/src/main/java/org/telegram/PhoneFormat/PhoneFormat.java +++ b/TMessagesProj/src/main/java/org/telegram/PhoneFormat/PhoneFormat.java @@ -24,7 +24,7 @@ package org.telegram.PhoneFormat; -import org.telegram.ui.ApplicationLoader; +import org.telegram.messenger.ApplicationLoader; import java.io.ByteArrayOutputStream; import java.io.InputStream; diff --git a/TMessagesProj/src/main/java/org/telegram/SQLite/SQLiteDatabase.java b/TMessagesProj/src/main/java/org/telegram/SQLite/SQLiteDatabase.java index 451673154..0aecf4b23 100755 --- a/TMessagesProj/src/main/java/org/telegram/SQLite/SQLiteDatabase.java +++ b/TMessagesProj/src/main/java/org/telegram/SQLite/SQLiteDatabase.java @@ -9,7 +9,7 @@ package org.telegram.SQLite; import org.telegram.messenger.FileLog; -import org.telegram.ui.ApplicationLoader; +import org.telegram.messenger.ApplicationLoader; public class SQLiteDatabase { private final int sqliteHandle; diff --git a/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java b/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java index 9e8afe33f..944f1d7ac 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java +++ b/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java @@ -20,6 +20,9 @@ import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Environment; +import android.text.Spannable; +import android.text.SpannableStringBuilder; +import android.text.Spanned; import android.util.StateSet; import android.view.Display; import android.view.Surface; @@ -35,12 +38,14 @@ import android.widget.TextView; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; -import org.telegram.ui.ApplicationLoader; -import org.telegram.ui.Views.NumberPicker; +import org.telegram.messenger.ApplicationLoader; +import org.telegram.ui.Components.NumberPicker; +import org.telegram.ui.Components.TypefaceSpan; import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.Hashtable; public class AndroidUtilities { @@ -389,7 +394,7 @@ public class AndroidUtilities { encryptedChat.ttl = 60 * 60 * 24 * 7; } if (oldValue != encryptedChat.ttl) { - SendMessagesHelper.getInstance().sendTTLMessage(encryptedChat, null); + SecretChatHelper.getInstance().sendTTLMessage(encryptedChat, null); MessagesStorage.getInstance().updateEncryptedChatTTL(encryptedChat); } } @@ -502,4 +507,21 @@ public class AndroidUtilities { } } } + + public static Spannable replaceBold(String str) { + int start; + ArrayList bolds = new ArrayList(); + while ((start = str.indexOf("")) != -1) { + int end = str.indexOf("") - 3; + str = str.replaceFirst("", "").replaceFirst("", ""); + bolds.add(start); + bolds.add(end); + } + SpannableStringBuilder stringBuilder = new SpannableStringBuilder(str); + for (int a = 0; a < bolds.size() / 2; a++) { + TypefaceSpan span = new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + stringBuilder.setSpan(span, bolds.get(a * 2), bolds.get(a * 2 + 1), Spanned.SPAN_INCLUSIVE_INCLUSIVE); + } + return stringBuilder; + } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/AppStartReceiver.java b/TMessagesProj/src/main/java/org/telegram/android/AppStartReceiver.java index 5368465c1..49bfe9f0b 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/AppStartReceiver.java +++ b/TMessagesProj/src/main/java/org/telegram/android/AppStartReceiver.java @@ -12,7 +12,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import org.telegram.ui.ApplicationLoader; +import org.telegram.messenger.ApplicationLoader; public class AppStartReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { diff --git a/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java b/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java index 8fe61f985..5135657eb 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java @@ -31,7 +31,7 @@ import org.telegram.messenger.TLObject; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; -import org.telegram.ui.ApplicationLoader; +import org.telegram.messenger.ApplicationLoader; import java.util.ArrayList; import java.util.Collections; diff --git a/TMessagesProj/src/main/java/org/telegram/android/Emoji.java b/TMessagesProj/src/main/java/org/telegram/android/Emoji.java index 4287ae6eb..49745d6c2 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/Emoji.java +++ b/TMessagesProj/src/main/java/org/telegram/android/Emoji.java @@ -29,7 +29,7 @@ import android.widget.TextView; import org.telegram.messenger.FileLog; import org.telegram.messenger.Utilities; -import org.telegram.ui.ApplicationLoader; +import org.telegram.messenger.ApplicationLoader; public class Emoji { private static HashMap rects = new HashMap(); diff --git a/TMessagesProj/src/main/java/org/telegram/android/GcmBroadcastReceiver.java b/TMessagesProj/src/main/java/org/telegram/android/GcmBroadcastReceiver.java index 7b33e2c6c..f0a133beb 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/GcmBroadcastReceiver.java +++ b/TMessagesProj/src/main/java/org/telegram/android/GcmBroadcastReceiver.java @@ -16,7 +16,7 @@ import android.content.Intent; import org.json.JSONObject; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; -import org.telegram.ui.ApplicationLoader; +import org.telegram.messenger.ApplicationLoader; public class GcmBroadcastReceiver extends BroadcastReceiver { diff --git a/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java b/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java index b2030a68f..f3d7be2d1 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java @@ -31,7 +31,7 @@ import org.telegram.messenger.FileLog; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; -import org.telegram.ui.ApplicationLoader; +import org.telegram.messenger.ApplicationLoader; import java.io.ByteArrayOutputStream; import java.io.File; diff --git a/TMessagesProj/src/main/java/org/telegram/android/LocaleController.java b/TMessagesProj/src/main/java/org/telegram/android/LocaleController.java index ce0f24729..0aae84ab0 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/LocaleController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/LocaleController.java @@ -24,7 +24,7 @@ import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.messenger.Utilities; -import org.telegram.ui.ApplicationLoader; +import org.telegram.messenger.ApplicationLoader; import org.xmlpull.v1.XmlPullParser; import java.io.File; diff --git a/TMessagesProj/src/main/java/org/telegram/android/MediaController.java b/TMessagesProj/src/main/java/org/telegram/android/MediaController.java index b87fa1760..b7b25b8cb 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MediaController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MediaController.java @@ -52,9 +52,9 @@ import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; -import org.telegram.ui.ApplicationLoader; +import org.telegram.messenger.ApplicationLoader; import org.telegram.ui.Cells.ChatMediaCell; -import org.telegram.ui.Views.GifDrawable; +import org.telegram.ui.Components.GifDrawable; import java.io.File; import java.io.FileInputStream; @@ -809,7 +809,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel } } if (send) { - SendMessagesHelper.getInstance().sendScreenshotMessage(lastSecretChat, lastSecretChatVisibleMessages, null); + SecretChatHelper.getInstance().sendScreenshotMessage(lastSecretChat, lastSecretChatVisibleMessages, null); } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java b/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java index d3cc37878..f3b155fd6 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java @@ -25,7 +25,7 @@ import org.telegram.messenger.FileLog; import org.telegram.messenger.TLRPC; import org.telegram.messenger.R; import org.telegram.messenger.UserConfig; -import org.telegram.ui.Views.URLSpanNoUnderline; +import org.telegram.ui.Components.URLSpanNoUnderline; import java.util.AbstractMap; import java.util.ArrayList; @@ -452,6 +452,60 @@ public class MessageObject { return ""; } + private boolean containsUrls(String message) { + if (message == null || message.length() < 3 || message.length() > 1024 * 20) { + return false; + } + + boolean containsSomething = false; + + int length = message.length(); + + int digitsInRow = 0; + int schemeSequence = 0; + int dotSequence = 0; + + char lastChar = 0; + + for (int i = 0; i < length; i++) { + char c = message.charAt(i); + + if (c >= '0' && c <= '9') { + digitsInRow++; + if (digitsInRow >= 6) { + return true; + } + schemeSequence = 0; + dotSequence = 0; + } else if (c == ':') { + if (schemeSequence == 0) { + schemeSequence = 1; + } else { + schemeSequence = 0; + } + } else if (c == '/') { + if (schemeSequence == 2) { + return true; + } + if (schemeSequence == 1) { + schemeSequence++; + } else { + schemeSequence = 0; + } + } else if (c == '.') { + if (dotSequence == 0 && lastChar != ' ') { + dotSequence++; + } else { + dotSequence = 0; + } + } else if (c != ' ' && lastChar == '.' && dotSequence == 1) { + return true; + } + lastChar = c; + } + return false; + } + private void generateLayout() { if (type != 0 || messageOwner.to_id == null || messageText == null || messageText.length() == 0) { return; @@ -459,11 +513,11 @@ public class MessageObject { textLayoutBlocks = new ArrayList(); - if (messageText instanceof Spannable) { - if (messageOwner.message != null && messageOwner.message.contains(".") && (messageOwner.message.contains(".com") || messageOwner.message.contains("http") || messageOwner.message.contains(".ru") || messageOwner.message.contains(".org") || messageOwner.message.contains(".net"))) { - Linkify.addLinks((Spannable)messageText, Linkify.WEB_URLS); - } else if (messageText.length() < 100) { - Linkify.addLinks((Spannable)messageText, Linkify.WEB_URLS | Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS); + if (messageText instanceof Spannable && containsUrls(messageOwner.message)) { + if (messageOwner.message.length() < 100) { + Linkify.addLinks((Spannable) messageText, Linkify.WEB_URLS | Linkify.PHONE_NUMBERS); + } else { + Linkify.addLinks((Spannable) messageText, Linkify.WEB_URLS); } } @@ -576,10 +630,7 @@ public class MessageObject { } if (lineWidth > maxWidth + 100) { - int start = block.textLayout.getLineStart(n); - int end = block.textLayout.getLineEnd(n); - CharSequence text = block.textLayout.getText().subSequence(start, end); - continue; + lineWidth = maxWidth; } try { diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java index 21c5c2307..c47932bc8 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java @@ -9,32 +9,23 @@ package org.telegram.android; import android.app.Activity; -import android.app.AlertDialog; -import android.app.ProgressDialog; -import android.content.Context; -import android.content.DialogInterface; import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.os.Build; import android.text.Html; import android.util.SparseArray; -import org.telegram.messenger.BuffersStorage; -import org.telegram.messenger.ByteBufferDesc; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; -import org.telegram.messenger.MessageKeyData; import org.telegram.messenger.R; import org.telegram.messenger.RPCRequest; -import org.telegram.messenger.TLClassStore; import org.telegram.messenger.TLObject; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; -import org.telegram.ui.ApplicationLoader; +import org.telegram.messenger.ApplicationLoader; -import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -44,6 +35,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Semaphore; public class MessagesController implements NotificationCenter.NotificationCenterDelegate { + private ConcurrentHashMap chats = new ConcurrentHashMap(100, 1.0f, 2); private ConcurrentHashMap encryptedChats = new ConcurrentHashMap(10, 1.0f, 2); private ConcurrentHashMap users = new ConcurrentHashMap(100, 1.0f, 2); @@ -61,19 +53,13 @@ public class MessagesController implements NotificationCenter.NotificationCenter public boolean loadingBlockedUsers = false; public ArrayList blockedUsers = new ArrayList(); - private HashMap acceptingChats = new HashMap(); private ArrayList updatesQueue = new ArrayList(); - private ArrayList pendingEncMessagesToDelete = new ArrayList(); private long updatesStartWaitTime = 0; - public ArrayList delayedEncryptedChatUpdates = new ArrayList(); - private boolean startingSecretChat = false; private ArrayList loadingFullUsers = new ArrayList(); private ArrayList loadedFullUsers = new ArrayList(); private ArrayList loadingFullChats = new ArrayList(); private ArrayList loadedFullChats = new ArrayList(); - private HashMap> secretHolesQueue = new HashMap>(); - private boolean gettingNewDeleteTask = false; private int currentDeletingTaskTime = 0; private ArrayList currentDeletingTaskMids = null; @@ -113,7 +99,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter public static final int UPDATE_MASK_USER_PHONE = 128; public static final int UPDATE_MASK_READ_DIALOG_MESSAGE = 256; public static final int UPDATE_MASK_SELECT_DIALOG = 512; - public static final int UPDATE_MASK_ALL = UPDATE_MASK_AVATAR | UPDATE_MASK_STATUS | UPDATE_MASK_NAME | UPDATE_MASK_CHAT_AVATAR | UPDATE_MASK_CHAT_NAME | UPDATE_MASK_CHAT_MEMBERS | UPDATE_MASK_USER_PRINT | UPDATE_MASK_USER_PHONE | UPDATE_MASK_READ_DIALOG_MESSAGE; + public static final int UPDATE_MASK_PHONE = 1024; + public static final int UPDATE_MASK_ALL = UPDATE_MASK_AVATAR | UPDATE_MASK_STATUS | UPDATE_MASK_NAME | UPDATE_MASK_CHAT_AVATAR | UPDATE_MASK_CHAT_NAME | UPDATE_MASK_CHAT_MEMBERS | UPDATE_MASK_USER_PRINT | UPDATE_MASK_USER_PHONE | UPDATE_MASK_READ_DIALOG_MESSAGE | UPDATE_MASK_PHONE; public static class PrintingUser { public long lastTime; @@ -307,11 +294,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter MediaController.getInstance().cleanup(); NotificationsController.getInstance().cleanup(); SendMessagesHelper.getInstance().cleanUp(); + SecretChatHelper.getInstance().cleanUp(); dialogs_dict.clear(); dialogs.clear(); dialogsServerOnly.clear(); - acceptingChats.clear(); users.clear(); chats.clear(); dialogMessage.clear(); @@ -321,15 +308,12 @@ public class MessagesController implements NotificationCenter.NotificationCenter totalDialogsCount = 0; lastPrintingStringCount = 0; updatesQueue.clear(); - pendingEncMessagesToDelete.clear(); - delayedEncryptedChatUpdates.clear(); blockedUsers.clear(); sendingTypings.clear(); loadingFullUsers.clear(); loadedFullUsers.clear(); loadingFullUsers.clear(); loadedFullUsers.clear(); - secretHolesQueue.clear(); updatesStartWaitTime = 0; currentDeletingTaskTime = 0; @@ -346,7 +330,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter offlineSent = false; registeringForPush = false; uploadingAvatar = null; - startingSecretChat = false; statusRequest = 0; statusSettingState = 0; @@ -1038,7 +1021,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesDeleted, messages); if (randoms != null && encryptedChat != null && !randoms.isEmpty()) { - SendMessagesHelper.getInstance().sendMessagesDeleteMessage(encryptedChat, randoms, null); + SecretChatHelper.getInstance().sendMessagesDeleteMessage(encryptedChat, randoms, null); } ArrayList toSend = new ArrayList(); @@ -1133,9 +1116,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter }); } else { if (onlyHistory) { - SendMessagesHelper.getInstance().sendClearHistoryMessage(getEncryptedChat(high_id), null); + SecretChatHelper.getInstance().sendClearHistoryMessage(getEncryptedChat(high_id), null); } else { - declineSecretChat(high_id); + SecretChatHelper.getInstance().declineSecretChat(high_id); } } } @@ -1707,8 +1690,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter putChats(dialogsRes.chats, isCache); if (encChats != null) { for (TLRPC.EncryptedChat encryptedChat : encChats) { - if (encryptedChat instanceof TLRPC.TL_encryptedChat && AndroidUtilities.getMyLayerVersion(encryptedChat.layer) < SendMessagesHelper.CURRENT_SECRET_CHAT_LAYER) { - SendMessagesHelper.getInstance().sendNotifyLayerMessage(encryptedChat, null); + if (encryptedChat instanceof TLRPC.TL_encryptedChat && AndroidUtilities.getMyLayerVersion(encryptedChat.layer) < SecretChatHelper.CURRENT_SECRET_CHAT_LAYER) { + SecretChatHelper.getInstance().sendNotifyLayerMessage(encryptedChat, null); } putEncryptedChat(encryptedChat, true); } @@ -1789,7 +1772,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } ArrayList random_ids = new ArrayList(); random_ids.add(random_id); - SendMessagesHelper.getInstance().sendMessagesReadMessage(chat, random_ids, null); + SecretChatHelper.getInstance().sendMessagesReadMessage(chat, random_ids, null); int time = ConnectionsManager.getInstance().getCurrentTime(); MessagesStorage.getInstance().createTaskForSecretChat(chat.id, time, time, 0, random_ids); } @@ -1912,14 +1895,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } - private void processPendingEncMessages() { - if (!pendingEncMessagesToDelete.isEmpty()) { - ArrayList arr = new ArrayList(pendingEncMessagesToDelete); - MessagesStorage.getInstance().markMessagesAsDeletedByRandoms(arr); - pendingEncMessagesToDelete.clear(); - } - } - public long createChat(String title, ArrayList selectedContacts, final TLRPC.InputFile uploadedAvatar, boolean isBroadcast) { if (isBroadcast) { TLRPC.TL_chat chat = new TLRPC.TL_chat(); @@ -2577,7 +2552,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (!res.new_messages.isEmpty() || !res.new_encrypted_messages.isEmpty()) { final HashMap> messages = new HashMap>(); for (TLRPC.EncryptedMessage encryptedMessage : res.new_encrypted_messages) { - ArrayList decryptedMessages = decryptMessage(encryptedMessage); + ArrayList decryptedMessages = SecretChatHelper.getInstance().decryptMessage(encryptedMessage); if (decryptedMessages != null && !decryptedMessages.isEmpty()) { for (TLRPC.Message message : decryptedMessages) { res.new_messages.add(message); @@ -2623,7 +2598,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter arr.add(obj); } - processPendingEncMessages(); + SecretChatHelper.getInstance().processPendingEncMessages(); AndroidUtilities.runOnUIThread(new Runnable() { @Override @@ -3085,6 +3060,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter interfaceUpdateMask |= UPDATE_MASK_AVATAR; MessagesStorage.getInstance().clearUserPhotos(update.user_id); updatesOnMainThread.add(update); + } else if (update instanceof TLRPC.TL_updateUserPhone) { + interfaceUpdateMask |= UPDATE_MASK_PHONE; + updatesOnMainThread.add(update); } else if (update instanceof TLRPC.TL_updateContactRegistered) { if (enableJoined && usersDict.containsKey(update.user_id)) { TLRPC.TL_messageService newMessage = new TLRPC.TL_messageService(); @@ -3155,7 +3133,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter //DEPRECATED } else if (update instanceof TLRPC.TL_updateNewEncryptedMessage) { MessagesStorage.lastQtsValue = update.qts; - ArrayList decryptedMessages = decryptMessage(((TLRPC.TL_updateNewEncryptedMessage)update).message); + ArrayList decryptedMessages = SecretChatHelper.getInstance().decryptMessage(((TLRPC.TL_updateNewEncryptedMessage)update).message); if (decryptedMessages != null && !decryptedMessages.isEmpty()) { int cid = ((TLRPC.TL_updateNewEncryptedMessage)update).message.chat_id; long uid = ((long) cid) << 32; @@ -3208,84 +3186,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } else if (update instanceof TLRPC.TL_updateDcOptions) { ConnectionsManager.getInstance().updateDcSettings(0); } else if (update instanceof TLRPC.TL_updateEncryption) { - final TLRPC.EncryptedChat newChat = update.chat; - long dialog_id = ((long)newChat.id) << 32; - TLRPC.EncryptedChat existingChat = getEncryptedChatDB(newChat.id); - - if (newChat instanceof TLRPC.TL_encryptedChatRequested && existingChat == null) { - int user_id = newChat.participant_id; - if (user_id == UserConfig.getClientUserId()) { - user_id = newChat.admin_id; - } - TLRPC.User user = getUser(user_id); - if (user == null) { - user = usersDict.get(user_id); - } - newChat.user_id = user_id; - final TLRPC.TL_dialog dialog = new TLRPC.TL_dialog(); - dialog.id = dialog_id; - dialog.unread_count = 0; - dialog.top_message = 0; - dialog.last_message_date = update.date; - - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - dialogs_dict.put(dialog.id, dialog); - dialogs.add(dialog); - dialogsServerOnly.clear(); - putEncryptedChat(newChat, false); - Collections.sort(dialogs, new Comparator() { - @Override - public int compare(TLRPC.TL_dialog tl_dialog, TLRPC.TL_dialog tl_dialog2) { - if (tl_dialog.last_message_date == tl_dialog2.last_message_date) { - return 0; - } else if (tl_dialog.last_message_date < tl_dialog2.last_message_date) { - return 1; - } else { - return -1; - } - } - }); - for (TLRPC.TL_dialog d : dialogs) { - int high_id = (int)(d.id >> 32); - if ((int)d.id != 0 && high_id != 1) { - dialogsServerOnly.add(d); - } - } - NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); - } - }); - MessagesStorage.getInstance().putEncryptedChat(newChat, user, dialog); - acceptSecretChat(newChat); - } else if (newChat instanceof TLRPC.TL_encryptedChat) { - if (existingChat != null && existingChat instanceof TLRPC.TL_encryptedChatWaiting && (existingChat.auth_key == null || existingChat.auth_key.length == 1)) { - newChat.a_or_b = existingChat.a_or_b; - newChat.user_id = existingChat.user_id; - processAcceptedSecretChat(newChat); - } else if (existingChat == null && startingSecretChat) { - delayedEncryptedChatUpdates.add(update); - } - } else { - final TLRPC.EncryptedChat exist = existingChat; - if (exist != null) { - newChat.user_id = exist.user_id; - newChat.auth_key = exist.auth_key; - newChat.ttl = exist.ttl; - newChat.seq_in = exist.seq_in; - newChat.seq_out = exist.seq_out; - } - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - if (exist != null) { - putEncryptedChat(newChat, false); - } - MessagesStorage.getInstance().updateEncryptedChat(newChat); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.encryptedChatUpdated, newChat); - } - }); - } + SecretChatHelper.getInstance().processUpdateEncryption((TLRPC.TL_updateEncryption) update, usersDict); } else if (update instanceof TLRPC.TL_updateUserBlocked) { final TLRPC.TL_updateUserBlocked finalUpdate = (TLRPC.TL_updateUserBlocked)update; if (finalUpdate.blocked) { @@ -3358,7 +3259,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter final int interfaceUpdateMaskFinal = interfaceUpdateMask; final boolean printChangedArg = printChanged; - processPendingEncMessages(); + SecretChatHelper.getInstance().processPendingEncMessages(); if (!contactsIds.isEmpty()) { ContactsController.getInstance().processContactsUpdates(contactsIds, usersDict); @@ -3393,9 +3294,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter ArrayList dbUsersStatus = new ArrayList(); SharedPreferences.Editor editor = null; for (TLRPC.Update update : updatesOnMainThread) { - TLRPC.User toDbUser = new TLRPC.User(); + final TLRPC.User toDbUser = new TLRPC.User(); toDbUser.id = update.user_id; - TLRPC.User currentUser = getUser(update.user_id); + final TLRPC.User currentUser = getUser(update.user_id); if (update instanceof TLRPC.TL_updatePrivacy) { if (update.key instanceof TLRPC.TL_privacyKeyStatusTimestamp) { ContactsController.getInstance().setPrivacyRules(update.rules); @@ -3431,6 +3332,18 @@ public class MessagesController implements NotificationCenter.NotificationCenter avatarsUpdate = true; toDbUser.photo = update.photo; dbUsers.add(toDbUser); + } else if (update instanceof TLRPC.TL_updateUserPhone) { + if (currentUser != null) { + currentUser.phone = update.phone; + Utilities.photoBookQueue.postRunnable(new Runnable() { + @Override + public void run() { + ContactsController.getInstance().addContactToPhoneBook(currentUser, true); + } + }); + } + toDbUser.phone = update.phone; + dbUsers.add(toDbUser); } else if (update instanceof TLRPC.TL_updateNotifySettings) { if (update.notify_settings instanceof TLRPC.TL_peerNotifySettings && update.peer instanceof TLRPC.TL_notifyPeer) { if (editor == null) { @@ -3688,724 +3601,4 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } } - - public TLRPC.Message processDecryptedObject(final TLRPC.EncryptedChat chat, final TLRPC.EncryptedFile file, int date, long random_id, TLObject object) { - if (object != null) { - int from_id = chat.admin_id; - if (from_id == UserConfig.getClientUserId()) { - from_id = chat.participant_id; - } - - if (object instanceof TLRPC.TL_decryptedMessage) { - TLRPC.TL_decryptedMessage decryptedMessage = (TLRPC.TL_decryptedMessage)object; - TLRPC.TL_message newMessage = null; - if (AndroidUtilities.getPeerLayerVersion(chat.layer) >= 17) { - newMessage = new TLRPC.TL_message_secret(); - newMessage.ttl = decryptedMessage.ttl; - } else { - newMessage = new TLRPC.TL_message(); - newMessage.ttl = chat.ttl; - } - newMessage.message = decryptedMessage.message; - newMessage.date = date; - newMessage.local_id = newMessage.id = UserConfig.getNewMessageId(); - UserConfig.saveConfig(false); - newMessage.from_id = from_id; - newMessage.to_id = new TLRPC.TL_peerUser(); - newMessage.random_id = random_id; - newMessage.to_id.user_id = UserConfig.getClientUserId(); - newMessage.flags = TLRPC.MESSAGE_FLAG_UNREAD; - newMessage.dialog_id = ((long)chat.id) << 32; - if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaEmpty) { - newMessage.media = new TLRPC.TL_messageMediaEmpty(); - } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaContact) { - newMessage.media = new TLRPC.TL_messageMediaContact(); - newMessage.media.last_name = decryptedMessage.media.last_name; - newMessage.media.first_name = decryptedMessage.media.first_name; - newMessage.media.phone_number = decryptedMessage.media.phone_number; - newMessage.media.user_id = decryptedMessage.media.user_id; - } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaGeoPoint) { - newMessage.media = new TLRPC.TL_messageMediaGeo(); - newMessage.media.geo = new TLRPC.TL_geoPoint(); - newMessage.media.geo.lat = decryptedMessage.media.lat; - newMessage.media.geo._long = decryptedMessage.media._long; - } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaPhoto) { - if (decryptedMessage.media.key == null || decryptedMessage.media.key.length != 32 || decryptedMessage.media.iv == null || decryptedMessage.media.iv.length != 32) { - return null; - } - newMessage.media = new TLRPC.TL_messageMediaPhoto(); - newMessage.media.photo = new TLRPC.TL_photo(); - newMessage.media.photo.user_id = newMessage.from_id; - newMessage.media.photo.date = newMessage.date; - newMessage.media.photo.caption = ""; - newMessage.media.photo.geo = new TLRPC.TL_geoPointEmpty(); - if (decryptedMessage.media.thumb.length != 0 && decryptedMessage.media.thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) { - TLRPC.TL_photoCachedSize small = new TLRPC.TL_photoCachedSize(); - small.w = decryptedMessage.media.thumb_w; - small.h = decryptedMessage.media.thumb_h; - small.bytes = decryptedMessage.media.thumb; - small.type = "s"; - small.location = new TLRPC.TL_fileLocationUnavailable(); - newMessage.media.photo.sizes.add(small); - } - - TLRPC.TL_photoSize big = new TLRPC.TL_photoSize(); - big.w = decryptedMessage.media.w; - big.h = decryptedMessage.media.h; - big.type = "x"; - big.size = file.size; - big.location = new TLRPC.TL_fileEncryptedLocation(); - big.location.key = decryptedMessage.media.key; - big.location.iv = decryptedMessage.media.iv; - big.location.dc_id = file.dc_id; - big.location.volume_id = file.id; - big.location.secret = file.access_hash; - big.location.local_id = file.key_fingerprint; - newMessage.media.photo.sizes.add(big); - } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaVideo) { - if (decryptedMessage.media.key == null || decryptedMessage.media.key.length != 32 || decryptedMessage.media.iv == null || decryptedMessage.media.iv.length != 32) { - return null; - } - newMessage.media = new TLRPC.TL_messageMediaVideo(); - newMessage.media.video = new TLRPC.TL_videoEncrypted(); - if (decryptedMessage.media.thumb.length != 0 && decryptedMessage.media.thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) { - newMessage.media.video.thumb = new TLRPC.TL_photoCachedSize(); - newMessage.media.video.thumb.bytes = decryptedMessage.media.thumb; - newMessage.media.video.thumb.w = decryptedMessage.media.thumb_w; - newMessage.media.video.thumb.h = decryptedMessage.media.thumb_h; - newMessage.media.video.thumb.type = "s"; - newMessage.media.video.thumb.location = new TLRPC.TL_fileLocationUnavailable(); - } else { - newMessage.media.video.thumb = new TLRPC.TL_photoSizeEmpty(); - newMessage.media.video.thumb.type = "s"; - } - newMessage.media.video.duration = decryptedMessage.media.duration; - newMessage.media.video.dc_id = file.dc_id; - newMessage.media.video.w = decryptedMessage.media.w; - newMessage.media.video.h = decryptedMessage.media.h; - newMessage.media.video.date = date; - newMessage.media.video.caption = ""; - newMessage.media.video.user_id = from_id; - newMessage.media.video.size = file.size; - newMessage.media.video.id = file.id; - newMessage.media.video.access_hash = file.access_hash; - newMessage.media.video.key = decryptedMessage.media.key; - newMessage.media.video.iv = decryptedMessage.media.iv; - newMessage.media.video.mime_type = decryptedMessage.media.mime_type; - if (newMessage.ttl != 0) { - newMessage.ttl = Math.max(newMessage.media.video.duration + 1, newMessage.ttl); - } - if (newMessage.media.video.mime_type == null) { - newMessage.media.video.mime_type = "video/mp4"; - } - } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaDocument) { - if (decryptedMessage.media.key == null || decryptedMessage.media.key.length != 32 || decryptedMessage.media.iv == null || decryptedMessage.media.iv.length != 32) { - return null; - } - newMessage.media = new TLRPC.TL_messageMediaDocument(); - newMessage.media.document = new TLRPC.TL_documentEncrypted(); - newMessage.media.document.id = file.id; - newMessage.media.document.access_hash = file.access_hash; - newMessage.media.document.user_id = decryptedMessage.media.user_id; - newMessage.media.document.date = date; - newMessage.media.document.file_name = decryptedMessage.media.file_name; - newMessage.media.document.mime_type = decryptedMessage.media.mime_type; - newMessage.media.document.size = file.size; - newMessage.media.document.key = decryptedMessage.media.key; - newMessage.media.document.iv = decryptedMessage.media.iv; - if (decryptedMessage.media.thumb.length != 0 && decryptedMessage.media.thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) { - newMessage.media.document.thumb = new TLRPC.TL_photoCachedSize(); - newMessage.media.document.thumb.bytes = decryptedMessage.media.thumb; - newMessage.media.document.thumb.w = decryptedMessage.media.thumb_w; - newMessage.media.document.thumb.h = decryptedMessage.media.thumb_h; - newMessage.media.document.thumb.type = "s"; - newMessage.media.document.thumb.location = new TLRPC.TL_fileLocationUnavailable(); - } else { - newMessage.media.document.thumb = new TLRPC.TL_photoSizeEmpty(); - newMessage.media.document.thumb.type = "s"; - } - newMessage.media.document.dc_id = file.dc_id; - } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaAudio) { - if (decryptedMessage.media.key == null || decryptedMessage.media.key.length != 32 || decryptedMessage.media.iv == null || decryptedMessage.media.iv.length != 32) { - return null; - } - newMessage.media = new TLRPC.TL_messageMediaAudio(); - newMessage.media.audio = new TLRPC.TL_audioEncrypted(); - newMessage.media.audio.id = file.id; - newMessage.media.audio.access_hash = file.access_hash; - newMessage.media.audio.user_id = from_id; - newMessage.media.audio.date = date; - newMessage.media.audio.size = file.size; - newMessage.media.audio.key = decryptedMessage.media.key; - newMessage.media.audio.iv = decryptedMessage.media.iv; - newMessage.media.audio.dc_id = file.dc_id; - newMessage.media.audio.duration = decryptedMessage.media.duration; - newMessage.media.audio.mime_type = decryptedMessage.media.mime_type; - if (newMessage.ttl != 0) { - newMessage.ttl = Math.max(newMessage.media.audio.duration + 1, newMessage.ttl); - } - if (newMessage.media.audio.mime_type == null) { - newMessage.media.audio.mime_type = "audio/ogg"; - } - } else { - return null; - } - return newMessage; - } else if (object instanceof TLRPC.TL_decryptedMessageService) { - final TLRPC.TL_decryptedMessageService serviceMessage = (TLRPC.TL_decryptedMessageService)object; - if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL || serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages) { - TLRPC.TL_messageService newMessage = new TLRPC.TL_messageService(); - if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) { - newMessage.action = new TLRPC.TL_messageEncryptedAction(); - if (serviceMessage.action.ttl_seconds < 0 || serviceMessage.action.ttl_seconds > 60 * 60 * 24 * 365) { - serviceMessage.action.ttl_seconds = 60 * 60 * 24 * 365; - } - chat.ttl = serviceMessage.action.ttl_seconds; - newMessage.action.encryptedAction = serviceMessage.action; - MessagesStorage.getInstance().updateEncryptedChatTTL(chat); - } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages) { - newMessage.action = new TLRPC.TL_messageEncryptedAction(); - newMessage.action.encryptedAction = serviceMessage.action; - } - newMessage.local_id = newMessage.id = UserConfig.getNewMessageId(); - UserConfig.saveConfig(false); - newMessage.flags = TLRPC.MESSAGE_FLAG_UNREAD; - newMessage.date = date; - newMessage.from_id = from_id; - newMessage.to_id = new TLRPC.TL_peerUser(); - newMessage.to_id.user_id = UserConfig.getClientUserId(); - newMessage.dialog_id = ((long)chat.id) << 32; - return newMessage; - } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionFlushHistory) { - final long did = ((long)chat.id) << 32; - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - TLRPC.TL_dialog dialog = dialogs_dict.get(did); - if (dialog != null) { - dialog.unread_count = 0; - dialogMessage.remove(dialog.top_message); - } - MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { - @Override - public void run() { - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - NotificationsController.getInstance().processReadMessages(null, did, 0, Integer.MAX_VALUE, false); - HashMap dialogsToUpdate = new HashMap(); - dialogsToUpdate.put(did, 0); - NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate); - } - }); - } - }); - MessagesStorage.getInstance().deleteDialog(did, true); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.removeAllMessagesFromDialog, did); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); - } - }); - return null; - } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionDeleteMessages) { - if (!serviceMessage.action.random_ids.isEmpty()) { - pendingEncMessagesToDelete.addAll(serviceMessage.action.random_ids); - } - return null; - } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionReadMessages) { - if (!serviceMessage.action.random_ids.isEmpty()) { - MessagesStorage.getInstance().createTaskForSecretChat(chat.id, ConnectionsManager.getInstance().getCurrentTime(), ConnectionsManager.getInstance().getCurrentTime(), 1, serviceMessage.action.random_ids); - } - } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionNotifyLayer) { - int currentPeerLayer = AndroidUtilities.getPeerLayerVersion(chat.layer); - chat.layer = 0; - chat.layer = AndroidUtilities.setPeerLayerVersion(chat.layer, serviceMessage.action.layer); - MessagesStorage.getInstance().updateEncryptedChatLayer(chat); - if (currentPeerLayer < 17) { - SendMessagesHelper.getInstance().sendNotifyLayerMessage(chat, null); - } - } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionResend) { - - } else { - return null; - } - } else { - FileLog.e("tmessages", "unkown message " + object); - } - } else { - FileLog.e("tmessages", "unkown TLObject"); - } - return null; - } - - public void checkSecretHoles(TLRPC.EncryptedChat chat, ArrayList messages) { - ArrayList holes = secretHolesQueue.get(chat.id); - if (holes == null) { - return; - } - Collections.sort(holes, new Comparator() { - @Override - public int compare(TLRPC.TL_decryptedMessageHolder lhs, TLRPC.TL_decryptedMessageHolder rhs) { - if (lhs.layer.out_seq_no > rhs.layer.out_seq_no) { - return 1; - } else if (lhs.layer.out_seq_no < rhs.layer.out_seq_no) { - return -1; - } - return 0; - } - }); - - boolean update = false; - for (int a = 0; a < holes.size(); a++) { - TLRPC.TL_decryptedMessageHolder holder = holes.get(a); - if (holder.layer.out_seq_no == chat.seq_in || chat.seq_in == holder.layer.out_seq_no - 2) { - chat.seq_in = holder.layer.out_seq_no; - holes.remove(a); - a--; - update = true; - - TLRPC.Message message = processDecryptedObject(chat, holder.file, holder.date, holder.random_id, holder.layer.message); - if (message != null) { - messages.add(message); - } - } else { - break; - } - } - if (holes.isEmpty()) { - secretHolesQueue.remove(chat.id); - } - if (update) { - MessagesStorage.getInstance().updateEncryptedChatSeq(chat); - } - } - - public ArrayList decryptMessage(TLRPC.EncryptedMessage message) { - final TLRPC.EncryptedChat chat = getEncryptedChatDB(message.chat_id); - if (chat == null || chat instanceof TLRPC.TL_encryptedChatDiscarded) { - return null; - } - ByteBufferDesc is = BuffersStorage.getInstance().getFreeBuffer(message.bytes.length); - is.writeRaw(message.bytes); - is.position(0); - long fingerprint = is.readInt64(); - if (chat.key_fingerprint == fingerprint) { - byte[] messageKey = is.readData(16); - MessageKeyData keyData = Utilities.generateMessageKeyData(chat.auth_key, messageKey, false); - - Utilities.aesIgeEncryption(is.buffer, keyData.aesKey, keyData.aesIv, false, false, 24, is.limit() - 24); - - int len = is.readInt32(); - TLObject object = TLClassStore.Instance().TLdeserialize(is, is.readInt32()); - BuffersStorage.getInstance().reuseFreeBuffer(is); - if (object instanceof TLRPC.TL_decryptedMessageLayer) { - final TLRPC.TL_decryptedMessageLayer layer = (TLRPC.TL_decryptedMessageLayer)object; - if (chat.seq_in == 0 && chat.seq_out == 0) { - if (chat.admin_id == UserConfig.getClientUserId()) { - chat.seq_out = 1; - } else { - chat.seq_in = 1; - } - } - if (layer.out_seq_no < chat.seq_in) { - return null; - } - if (chat.seq_in != layer.out_seq_no && chat.seq_in != layer.out_seq_no - 2) { - ArrayList arr = secretHolesQueue.get(chat.id); - if (arr == null) { - arr = new ArrayList(); - secretHolesQueue.put(chat.id, arr); - } - if (arr.size() >= 10) { - secretHolesQueue.remove(chat.id); - final TLRPC.TL_encryptedChatDiscarded newChat = new TLRPC.TL_encryptedChatDiscarded(); - newChat.id = chat.id; - newChat.user_id = chat.user_id; - newChat.auth_key = chat.auth_key; - newChat.seq_in = chat.seq_in; - newChat.seq_out = chat.seq_out; - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - putEncryptedChat(newChat, false); - MessagesStorage.getInstance().updateEncryptedChat(newChat); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.encryptedChatUpdated, newChat); - } - }); - declineSecretChat(chat.id); - return null; - } - - TLRPC.TL_decryptedMessageHolder holder = new TLRPC.TL_decryptedMessageHolder(); - holder.layer = layer; - holder.file = message.file; - holder.random_id = message.random_id; - holder.date = message.date; - arr.add(holder); - return null; - } - chat.seq_in = layer.out_seq_no; - MessagesStorage.getInstance().updateEncryptedChatSeq(chat); - object = layer.message; - } - ArrayList messages = new ArrayList(); - TLRPC.Message decryptedMessage = processDecryptedObject(chat, message.file, message.date, message.random_id, object); - if (decryptedMessage != null) { - messages.add(decryptedMessage); - } - checkSecretHoles(chat, messages); - return messages; - } else { - BuffersStorage.getInstance().reuseFreeBuffer(is); - FileLog.e("tmessages", "fingerprint mismatch"); - } - return null; - } - - public void processAcceptedSecretChat(final TLRPC.EncryptedChat encryptedChat) { - BigInteger p = new BigInteger(1, MessagesStorage.secretPBytes); - BigInteger i_authKey = new BigInteger(1, encryptedChat.g_a_or_b); - - if (!Utilities.isGoodGaAndGb(i_authKey, p)) { - declineSecretChat(encryptedChat.id); - return; - } - - i_authKey = i_authKey.modPow(new BigInteger(1, encryptedChat.a_or_b), p); - - byte[] authKey = i_authKey.toByteArray(); - if (authKey.length > 256) { - byte[] correctedAuth = new byte[256]; - System.arraycopy(authKey, authKey.length - 256, correctedAuth, 0, 256); - authKey = correctedAuth; - } else if (authKey.length < 256) { - byte[] correctedAuth = new byte[256]; - System.arraycopy(authKey, 0, correctedAuth, 256 - authKey.length, authKey.length); - for (int a = 0; a < 256 - authKey.length; a++) { - authKey[a] = 0; - } - authKey = correctedAuth; - } - byte[] authKeyHash = Utilities.computeSHA1(authKey); - byte[] authKeyId = new byte[8]; - System.arraycopy(authKeyHash, authKeyHash.length - 8, authKeyId, 0, 8); - long fingerprint = Utilities.bytesToLong(authKeyId); - if (encryptedChat.key_fingerprint == fingerprint) { - encryptedChat.auth_key = authKey; - encryptedChat.seq_in = 0; - encryptedChat.seq_out = 1; - MessagesStorage.getInstance().updateEncryptedChat(encryptedChat); - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - putEncryptedChat(encryptedChat, false); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.encryptedChatUpdated, encryptedChat); - SendMessagesHelper.getInstance().sendNotifyLayerMessage(encryptedChat, null); - } - }); - } else { - final TLRPC.TL_encryptedChatDiscarded newChat = new TLRPC.TL_encryptedChatDiscarded(); - newChat.id = encryptedChat.id; - newChat.user_id = encryptedChat.user_id; - newChat.auth_key = encryptedChat.auth_key; - newChat.seq_in = encryptedChat.seq_in; - newChat.seq_out = encryptedChat.seq_out; - MessagesStorage.getInstance().updateEncryptedChat(newChat); - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - putEncryptedChat(newChat, false); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.encryptedChatUpdated, newChat); - } - }); - declineSecretChat(encryptedChat.id); - } - } - - public void declineSecretChat(int chat_id) { - TLRPC.TL_messages_discardEncryption req = new TLRPC.TL_messages_discardEncryption(); - req.chat_id = chat_id; - ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { - @Override - public void run(TLObject response, TLRPC.TL_error error) { - - } - }); - } - - public void acceptSecretChat(final TLRPC.EncryptedChat encryptedChat) { - if (acceptingChats.get(encryptedChat.id) != null) { - return; - } - acceptingChats.put(encryptedChat.id, encryptedChat); - TLRPC.TL_messages_getDhConfig req = new TLRPC.TL_messages_getDhConfig(); - req.random_length = 256; - req.version = MessagesStorage.lastSecretVersion; - ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { - @Override - public void run(TLObject response, TLRPC.TL_error error) { - if (error == null) { - TLRPC.messages_DhConfig res = (TLRPC.messages_DhConfig) response; - if (response instanceof TLRPC.TL_messages_dhConfig) { - if (!Utilities.isGoodPrime(res.p, res.g)) { - acceptingChats.remove(encryptedChat.id); - declineSecretChat(encryptedChat.id); - return; - } - - MessagesStorage.secretPBytes = res.p; - MessagesStorage.secretG = res.g; - MessagesStorage.lastSecretVersion = res.version; - MessagesStorage.getInstance().saveSecretParams(MessagesStorage.lastSecretVersion, MessagesStorage.secretG, MessagesStorage.secretPBytes); - } - byte[] salt = new byte[256]; - for (int a = 0; a < 256; a++) { - salt[a] = (byte) ((byte) (Utilities.random.nextDouble() * 256) ^ res.random[a]); - } - encryptedChat.a_or_b = salt; - encryptedChat.seq_in = 1; - encryptedChat.seq_out = 0; - BigInteger p = new BigInteger(1, MessagesStorage.secretPBytes); - BigInteger g_b = BigInteger.valueOf(MessagesStorage.secretG); - g_b = g_b.modPow(new BigInteger(1, salt), p); - BigInteger g_a = new BigInteger(1, encryptedChat.g_a); - - if (!Utilities.isGoodGaAndGb(g_a, p)) { - acceptingChats.remove(encryptedChat.id); - declineSecretChat(encryptedChat.id); - return; - } - - byte[] g_b_bytes = g_b.toByteArray(); - if (g_b_bytes.length > 256) { - byte[] correctedAuth = new byte[256]; - System.arraycopy(g_b_bytes, 1, correctedAuth, 0, 256); - g_b_bytes = correctedAuth; - } - - g_a = g_a.modPow(new BigInteger(1, salt), p); - - byte[] authKey = g_a.toByteArray(); - if (authKey.length > 256) { - byte[] correctedAuth = new byte[256]; - System.arraycopy(authKey, authKey.length - 256, correctedAuth, 0, 256); - authKey = correctedAuth; - } else if (authKey.length < 256) { - byte[] correctedAuth = new byte[256]; - System.arraycopy(authKey, 0, correctedAuth, 256 - authKey.length, authKey.length); - for (int a = 0; a < 256 - authKey.length; a++) { - authKey[a] = 0; - } - authKey = correctedAuth; - } - byte[] authKeyHash = Utilities.computeSHA1(authKey); - byte[] authKeyId = new byte[8]; - System.arraycopy(authKeyHash, authKeyHash.length - 8, authKeyId, 0, 8); - encryptedChat.auth_key = authKey; - - TLRPC.TL_messages_acceptEncryption req2 = new TLRPC.TL_messages_acceptEncryption(); - req2.g_b = g_b_bytes; - req2.peer = new TLRPC.TL_inputEncryptedChat(); - req2.peer.chat_id = encryptedChat.id; - req2.peer.access_hash = encryptedChat.access_hash; - req2.key_fingerprint = Utilities.bytesToLong(authKeyId); - ConnectionsManager.getInstance().performRpc(req2, new RPCRequest.RPCRequestDelegate() { - @Override - public void run(TLObject response, TLRPC.TL_error error) { - acceptingChats.remove(encryptedChat.id); - if (error == null) { - final TLRPC.EncryptedChat newChat = (TLRPC.EncryptedChat) response; - newChat.auth_key = encryptedChat.auth_key; - newChat.user_id = encryptedChat.user_id; - newChat.seq_in = encryptedChat.seq_in; - newChat.seq_out = encryptedChat.seq_out; - MessagesStorage.getInstance().updateEncryptedChat(newChat); - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - putEncryptedChat(newChat, false); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.encryptedChatUpdated, newChat); - SendMessagesHelper.getInstance().sendNotifyLayerMessage(newChat, null); - } - }); - } - } - }); - } else { - acceptingChats.remove(encryptedChat.id); - } - } - }); - } - - public void startSecretChat(final Context context, final TLRPC.User user) { - if (user == null) { - return; - } - startingSecretChat = true; - final ProgressDialog progressDialog = new ProgressDialog(context); - progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading)); - progressDialog.setCanceledOnTouchOutside(false); - progressDialog.setCancelable(false); - TLRPC.TL_messages_getDhConfig req = new TLRPC.TL_messages_getDhConfig(); - req.random_length = 256; - req.version = MessagesStorage.lastSecretVersion; - final long reqId = ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { - @Override - public void run(TLObject response, TLRPC.TL_error error) { - if (error == null) { - TLRPC.messages_DhConfig res = (TLRPC.messages_DhConfig) response; - if (response instanceof TLRPC.TL_messages_dhConfig) { - if (!Utilities.isGoodPrime(res.p, res.g)) { - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - try { - if (!((Activity) context).isFinishing()) { - progressDialog.dismiss(); - } - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } - }); - return; - } - MessagesStorage.secretPBytes = res.p; - MessagesStorage.secretG = res.g; - MessagesStorage.lastSecretVersion = res.version; - MessagesStorage.getInstance().saveSecretParams(MessagesStorage.lastSecretVersion, MessagesStorage.secretG, MessagesStorage.secretPBytes); - } - final byte[] salt = new byte[256]; - for (int a = 0; a < 256; a++) { - salt[a] = (byte) ((byte) (Utilities.random.nextDouble() * 256) ^ res.random[a]); - } - - BigInteger i_g_a = BigInteger.valueOf(MessagesStorage.secretG); - i_g_a = i_g_a.modPow(new BigInteger(1, salt), new BigInteger(1, MessagesStorage.secretPBytes)); - byte[] g_a = i_g_a.toByteArray(); - if (g_a.length > 256) { - byte[] correctedAuth = new byte[256]; - System.arraycopy(g_a, 1, correctedAuth, 0, 256); - g_a = correctedAuth; - } - - TLRPC.TL_messages_requestEncryption req2 = new TLRPC.TL_messages_requestEncryption(); - req2.g_a = g_a; - req2.user_id = getInputUser(user); - req2.random_id = Utilities.random.nextInt(); - ConnectionsManager.getInstance().performRpc(req2, new RPCRequest.RPCRequestDelegate() { - @Override - public void run(final TLObject response, TLRPC.TL_error error) { - if (error == null) { - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - startingSecretChat = false; - if (!((Activity) context).isFinishing()) { - try { - progressDialog.dismiss(); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } - TLRPC.EncryptedChat chat = (TLRPC.EncryptedChat) response; - chat.user_id = chat.participant_id; - chat.seq_in = 0; - chat.seq_out = 1; - chat.a_or_b = salt; - putEncryptedChat(chat, false); - TLRPC.TL_dialog dialog = new TLRPC.TL_dialog(); - dialog.id = ((long) chat.id) << 32; - dialog.unread_count = 0; - dialog.top_message = 0; - dialog.last_message_date = ConnectionsManager.getInstance().getCurrentTime(); - dialogs_dict.put(dialog.id, dialog); - dialogs.add(dialog); - dialogsServerOnly.clear(); - Collections.sort(dialogs, new Comparator() { - @Override - public int compare(TLRPC.TL_dialog tl_dialog, TLRPC.TL_dialog tl_dialog2) { - if (tl_dialog.last_message_date == tl_dialog2.last_message_date) { - return 0; - } else if (tl_dialog.last_message_date < tl_dialog2.last_message_date) { - return 1; - } else { - return -1; - } - } - }); - for (TLRPC.TL_dialog d : dialogs) { - int high_id = (int)(d.id >> 32); - if ((int)d.id != 0 && high_id != 1) { - dialogsServerOnly.add(d); - } - } - MessagesStorage.getInstance().putEncryptedChat(chat, user, dialog); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.encryptedChatCreated, chat); - Utilities.stageQueue.postRunnable(new Runnable() { - @Override - public void run() { - if (!delayedEncryptedChatUpdates.isEmpty()) { - processUpdateArray(delayedEncryptedChatUpdates, null, null); - delayedEncryptedChatUpdates.clear(); - } - } - }); - } - }); - } else { - delayedEncryptedChatUpdates.clear(); - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - if (!((Activity) context).isFinishing()) { - startingSecretChat = false; - try { - progressDialog.dismiss(); - } catch (Exception e) { - FileLog.e("tmessages", 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); - } - } - }); - } - } - }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors); - } else { - delayedEncryptedChatUpdates.clear(); - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - startingSecretChat = false; - if (!((Activity) context).isFinishing()) { - try { - progressDialog.dismiss(); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } - } - }); - } - } - }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors); - progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, LocaleController.getString("Cancel", R.string.Cancel), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - ConnectionsManager.getInstance().cancelRpc(reqId, true); - try { - dialog.dismiss(); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } - }); - progressDialog.show(); - } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java b/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java index 8a98a2067..2199f5c44 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java @@ -28,7 +28,7 @@ import org.telegram.messenger.TLObject; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; -import org.telegram.ui.ApplicationLoader; +import org.telegram.messenger.ApplicationLoader; import java.io.File; import java.util.ArrayList; @@ -104,7 +104,7 @@ public class MessagesStorage { database.executeFast("CREATE TABLE users(uid INTEGER PRIMARY KEY, name TEXT, status INTEGER, data BLOB)").stepThis().dispose(); database.executeFast("CREATE TABLE messages(mid INTEGER PRIMARY KEY, uid INTEGER, read_state INTEGER, send_state INTEGER, date INTEGER, data BLOB, out INTEGER, ttl INTEGER, media INTEGER)").stepThis().dispose(); database.executeFast("CREATE TABLE chats(uid INTEGER PRIMARY KEY, name TEXT, data BLOB)").stepThis().dispose(); - database.executeFast("CREATE TABLE enc_chats(uid INTEGER PRIMARY KEY, user INTEGER, name TEXT, data BLOB, g BLOB, authkey BLOB, ttl INTEGER, layer INTEGER, seq_in INTEGER, seq_out INTEGER)").stepThis().dispose(); + database.executeFast("CREATE TABLE enc_chats(uid INTEGER PRIMARY KEY, user INTEGER, name TEXT, data BLOB, g BLOB, authkey BLOB, ttl INTEGER, layer INTEGER, seq_in INTEGER, seq_out INTEGER, use_count INTEGER, exchange_id INTEGER, key_date INTEGER, fprint INTEGER, fauthkey BLOB, khash BLOB)").stepThis().dispose(); database.executeFast("CREATE TABLE dialogs(did INTEGER PRIMARY KEY, date INTEGER, unread_count INTEGER, last_mid INTEGER)").stepThis().dispose(); database.executeFast("CREATE TABLE chat_settings(uid INTEGER PRIMARY KEY, participants BLOB)").stepThis().dispose(); database.executeFast("CREATE TABLE contacts(uid INTEGER PRIMARY KEY, mutual INTEGER)").stepThis().dispose(); @@ -156,7 +156,7 @@ public class MessagesStorage { database.executeFast("CREATE INDEX IF NOT EXISTS seq_idx_messages_seq ON messages_seq(seq_in, seq_out);").stepThis().dispose(); - database.executeFast("PRAGMA user_version = 7").stepThis().dispose(); + database.executeFast("PRAGMA user_version = 10").stepThis().dispose(); } else { try { SQLiteCursor cursor = database.queryFinalized("SELECT seq, pts, date, qts, lsv, sg, pbytes FROM params WHERE id = 1"); @@ -188,7 +188,7 @@ public class MessagesStorage { } int version = database.executeInt("PRAGMA user_version"); - if (version < 9) { + if (version < 10) { updateDbToLastVersion(version); } } @@ -329,6 +329,16 @@ public class MessagesStorage { database.executeFast("PRAGMA user_version = 9").stepThis().dispose(); version = 9; }*/ + if ((version == 7 || version == 8 || version == 9) && version < 10) { + database.executeFast("ALTER TABLE enc_chats ADD COLUMN use_count INTEGER default 0").stepThis().dispose(); + database.executeFast("ALTER TABLE enc_chats ADD COLUMN exchange_id INTEGER default 0").stepThis().dispose(); + database.executeFast("ALTER TABLE enc_chats ADD COLUMN key_date INTEGER default 0").stepThis().dispose(); + database.executeFast("ALTER TABLE enc_chats ADD COLUMN fprint INTEGER default 0").stepThis().dispose(); + database.executeFast("ALTER TABLE enc_chats ADD COLUMN fauthkey BLOB default NULL").stepThis().dispose(); + database.executeFast("ALTER TABLE enc_chats ADD COLUMN khash BLOB default NULL").stepThis().dispose(); + database.executeFast("PRAGMA user_version = 10").stepThis().dispose(); + version = 10; + } } catch (Exception e) { FileLog.e("tmessages", e); } @@ -1329,9 +1339,6 @@ public class MessagesStorage { StringBuilder uids = new StringBuilder(); while (cursor.next()) { int user_id = cursor.intValue(0); - if (user_id == UserConfig.getClientUserId()) { - continue; - } TLRPC.TL_contact contact = new TLRPC.TL_contact(); contact.user_id = user_id; contact.mutual = cursor.intValue(1) == 1; @@ -2008,10 +2015,11 @@ public class MessagesStorage { public void run() { SQLitePreparedStatement state = null; try { - state = database.executeFast("UPDATE enc_chats SET seq_in = ?, seq_out = ? WHERE uid = ?"); + state = database.executeFast("UPDATE enc_chats SET seq_in = ?, seq_out = ?, use_count = ? WHERE uid = ?"); state.bindInteger(1, chat.seq_in); state.bindInteger(2, chat.seq_out); - state.bindInteger(3, chat.id); + state.bindInteger(3, (int)chat.key_use_count_in << 16 | chat.key_use_count_out); + state.bindInteger(4, chat.id); state.step(); } catch (Exception e) { FileLog.e("tmessages", e); @@ -2081,10 +2089,18 @@ public class MessagesStorage { public void run() { SQLitePreparedStatement state = null; try { - state = database.executeFast("UPDATE enc_chats SET data = ?, g = ?, authkey = ?, ttl = ?, layer = ?, seq_in = ?, seq_out = ? WHERE uid = ?"); + if ((chat.key_hash == null || chat.key_hash.length != 16) && chat.auth_key != null) { + byte[] sha1 = Utilities.computeSHA1(chat.auth_key); + chat.key_hash = new byte[16]; + System.arraycopy(sha1, 0, chat.key_hash, 0, chat.key_hash.length); + } + + state = database.executeFast("UPDATE enc_chats SET data = ?, g = ?, authkey = ?, ttl = ?, layer = ?, seq_in = ?, seq_out = ?, use_count = ?, exchange_id = ?, key_date = ?, fprint = ?, fauthkey = ?, khash = ? WHERE uid = ?"); ByteBufferDesc data = buffersStorage.getFreeBuffer(chat.getObjectSize()); ByteBufferDesc data2 = buffersStorage.getFreeBuffer(chat.a_or_b != null ? chat.a_or_b.length : 1); ByteBufferDesc data3 = buffersStorage.getFreeBuffer(chat.auth_key != null ? chat.auth_key.length : 1); + ByteBufferDesc data4 = buffersStorage.getFreeBuffer(chat.future_auth_key != null ? chat.future_auth_key.length : 1); + ByteBufferDesc data5 = buffersStorage.getFreeBuffer(chat.key_hash != null ? chat.key_hash.length : 1); chat.serializeToStream(data); state.bindByteBuffer(1, data.buffer); if (chat.a_or_b != null) { @@ -2093,17 +2109,32 @@ public class MessagesStorage { if (chat.auth_key != null) { data3.writeRaw(chat.auth_key); } + if (chat.future_auth_key != null) { + data4.writeRaw(chat.future_auth_key); + } + if (chat.key_hash != null) { + data5.writeRaw(chat.key_hash); + } state.bindByteBuffer(2, data2.buffer); state.bindByteBuffer(3, data3.buffer); state.bindInteger(4, chat.ttl); state.bindInteger(5, chat.layer); state.bindInteger(6, chat.seq_in); state.bindInteger(7, chat.seq_out); - state.bindInteger(8, chat.id); + state.bindInteger(8, (int)chat.key_use_count_in << 16 | chat.key_use_count_out); + state.bindLong(9, chat.exchange_id); + state.bindInteger(10, chat.key_create_date); + state.bindLong(11, chat.future_key_fingerprint); + state.bindByteBuffer(12, data4.buffer); + state.bindByteBuffer(13, data5.buffer); + state.bindInteger(14, chat.id); + state.step(); buffersStorage.reuseFreeBuffer(data); buffersStorage.reuseFreeBuffer(data2); buffersStorage.reuseFreeBuffer(data3); + buffersStorage.reuseFreeBuffer(data4); + buffersStorage.reuseFreeBuffer(data5); } catch (Exception e) { FileLog.e("tmessages", e); } finally { @@ -2151,10 +2182,17 @@ public class MessagesStorage { @Override public void run() { try { - SQLitePreparedStatement state = database.executeFast("REPLACE INTO enc_chats VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + if ((chat.key_hash == null || chat.key_hash.length != 16) && chat.auth_key != null) { + byte[] sha1 = Utilities.computeSHA1(chat.auth_key); + chat.key_hash = new byte[16]; + System.arraycopy(sha1, 0, chat.key_hash, 0, chat.key_hash.length); + } + SQLitePreparedStatement state = database.executeFast("REPLACE INTO enc_chats VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); ByteBufferDesc data = buffersStorage.getFreeBuffer(chat.getObjectSize()); ByteBufferDesc data2 = buffersStorage.getFreeBuffer(chat.a_or_b != null ? chat.a_or_b.length : 1); ByteBufferDesc data3 = buffersStorage.getFreeBuffer(chat.auth_key != null ? chat.auth_key.length : 1); + ByteBufferDesc data4 = buffersStorage.getFreeBuffer(chat.future_auth_key != null ? chat.future_auth_key.length : 1); + ByteBufferDesc data5 = buffersStorage.getFreeBuffer(chat.key_hash != null ? chat.key_hash.length : 1); chat.serializeToStream(data); state.bindInteger(1, chat.id); @@ -2167,17 +2205,32 @@ public class MessagesStorage { if (chat.auth_key != null) { data3.writeRaw(chat.auth_key); } + if (chat.future_auth_key != null) { + data4.writeRaw(chat.future_auth_key); + } + if (chat.key_hash != null) { + data5.writeRaw(chat.key_hash); + } state.bindByteBuffer(5, data2.buffer); state.bindByteBuffer(6, data3.buffer); state.bindInteger(7, chat.ttl); state.bindInteger(8, chat.layer); state.bindInteger(9, chat.seq_in); state.bindInteger(10, chat.seq_out); + state.bindInteger(11, (int)chat.key_use_count_in << 16 | chat.key_use_count_out); + state.bindLong(12, chat.exchange_id); + state.bindInteger(13, chat.key_create_date); + state.bindLong(14, chat.future_key_fingerprint); + state.bindByteBuffer(15, data4.buffer); + state.bindByteBuffer(16, data5.buffer); + state.step(); state.dispose(); buffersStorage.reuseFreeBuffer(data); buffersStorage.reuseFreeBuffer(data2); buffersStorage.reuseFreeBuffer(data3); + buffersStorage.reuseFreeBuffer(data4); + buffersStorage.reuseFreeBuffer(data5); if (dialog != null) { state = database.executeFast("REPLACE INTO dialogs(did, date, unread_count, last_mid) VALUES(?, ?, ?, ?)"); @@ -2317,8 +2370,8 @@ public class MessagesStorage { if (chatsToLoad == null || chatsToLoad.length() == 0 || result == null) { return; } - - SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl, layer, seq_in, seq_out FROM enc_chats WHERE uid IN(%s)", chatsToLoad)); + //use_count INTEGER, exchange_id INTEGER, key_date INTEGER, fprint INTEGER, fauthkey BLOB + SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl, layer, seq_in, seq_out, use_count, exchange_id, key_date, fprint, fauthkey, khash FROM enc_chats WHERE uid IN(%s)", chatsToLoad)); while (cursor.next()) { try { ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0)); @@ -2335,6 +2388,14 @@ public class MessagesStorage { chat.layer = cursor.intValue(5); chat.seq_in = cursor.intValue(6); chat.seq_out = cursor.intValue(7); + int use_count = cursor.intValue(8); + chat.key_use_count_in = (short)(use_count >> 16); + chat.key_use_count_out = (short)(use_count); + chat.exchange_id = cursor.longValue(9); + chat.key_create_date = cursor.intValue(10); + chat.future_key_fingerprint = cursor.longValue(11); + chat.future_auth_key = cursor.byteArrayValue(12); + chat.key_hash = cursor.byteArrayValue(13); result.add(chat); } } @@ -2994,6 +3055,8 @@ public class MessagesStorage { user.username = updateUser.username; } else if (updateUser.photo != null) { user.photo = updateUser.photo; + } else if (updateUser.phone != null) { + user.phone = updateUser.phone; } } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/NativeLoader.java b/TMessagesProj/src/main/java/org/telegram/android/NativeLoader.java index a4716d283..0aa1b69d9 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/NativeLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/android/NativeLoader.java @@ -23,7 +23,7 @@ import java.util.zip.ZipFile; public class NativeLoader { - private final static int LIB_VERSION = 3; + private final static int LIB_VERSION = 4; private final static String LIB_NAME = "tmessages." + LIB_VERSION; private final static String LIB_SO_NAME = "lib" + LIB_NAME + ".so"; private final static String LOCALE_LIB_SO_NAME = "lib" + LIB_NAME + "loc.so"; diff --git a/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java b/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java index 4d4840a69..a6c346e69 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java @@ -33,7 +33,7 @@ import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; -import org.telegram.ui.ApplicationLoader; +import org.telegram.messenger.ApplicationLoader; import org.telegram.ui.LaunchActivity; import org.telegram.ui.PopupNotificationActivity; diff --git a/TMessagesProj/src/main/java/org/telegram/android/NotificationsService.java b/TMessagesProj/src/main/java/org/telegram/android/NotificationsService.java index a790c7983..91f90efba 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/NotificationsService.java +++ b/TMessagesProj/src/main/java/org/telegram/android/NotificationsService.java @@ -14,7 +14,7 @@ import android.content.SharedPreferences; import android.os.IBinder; import org.telegram.messenger.FileLog; -import org.telegram.ui.ApplicationLoader; +import org.telegram.messenger.ApplicationLoader; public class NotificationsService extends Service { diff --git a/TMessagesProj/src/main/java/org/telegram/android/ScreenReceiver.java b/TMessagesProj/src/main/java/org/telegram/android/ScreenReceiver.java index 7a357627d..e6b6c7572 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/ScreenReceiver.java +++ b/TMessagesProj/src/main/java/org/telegram/android/ScreenReceiver.java @@ -14,7 +14,7 @@ import android.content.Intent; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; -import org.telegram.ui.ApplicationLoader; +import org.telegram.messenger.ApplicationLoader; public class ScreenReceiver extends BroadcastReceiver { @Override diff --git a/TMessagesProj/src/main/java/org/telegram/android/SecretChatHelper.java b/TMessagesProj/src/main/java/org/telegram/android/SecretChatHelper.java new file mode 100644 index 000000000..857a28c51 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/android/SecretChatHelper.java @@ -0,0 +1,1756 @@ +/* + * This is the source code of Telegram for Android v. 2.0.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2014. + */ + +package org.telegram.android; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.DialogInterface; + +import org.telegram.messenger.BuffersStorage; +import org.telegram.messenger.ByteBufferDesc; +import org.telegram.messenger.ConnectionsManager; +import org.telegram.messenger.FileLoader; +import org.telegram.messenger.FileLog; +import org.telegram.messenger.MessageKeyData; +import org.telegram.messenger.R; +import org.telegram.messenger.RPCRequest; +import org.telegram.messenger.TLClassStore; +import org.telegram.messenger.TLObject; +import org.telegram.messenger.TLRPC; +import org.telegram.messenger.UserConfig; +import org.telegram.messenger.Utilities; + +import java.io.File; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; + +public class SecretChatHelper { + + public static final int CURRENT_SECRET_CHAT_LAYER = 20; + + private ArrayList sendingNotifyLayer = new ArrayList(); + private HashMap> secretHolesQueue = new HashMap>(); + private HashMap acceptingChats = new HashMap(); + public ArrayList delayedEncryptedChatUpdates = new ArrayList(); + private ArrayList pendingEncMessagesToDelete = new ArrayList(); + private boolean startingSecretChat = false; + + private static volatile SecretChatHelper Instance = null; + public static SecretChatHelper getInstance() { + SecretChatHelper localInstance = Instance; + if (localInstance == null) { + synchronized (SecretChatHelper.class) { + localInstance = Instance; + if (localInstance == null) { + Instance = localInstance = new SecretChatHelper(); + } + } + } + return localInstance; + } + + public void cleanUp() { + sendingNotifyLayer.clear(); + acceptingChats.clear(); + secretHolesQueue.clear(); + delayedEncryptedChatUpdates.clear(); + pendingEncMessagesToDelete.clear(); + + startingSecretChat = false; + } + + protected void processPendingEncMessages() { + if (!pendingEncMessagesToDelete.isEmpty()) { + ArrayList arr = new ArrayList(pendingEncMessagesToDelete); + MessagesStorage.getInstance().markMessagesAsDeletedByRandoms(arr); + pendingEncMessagesToDelete.clear(); + } + } + + private TLRPC.TL_messageService createServiceSecretMessage(final TLRPC.EncryptedChat encryptedChat, TLRPC.DecryptedMessageAction decryptedMessage) { + TLRPC.TL_messageService newMsg = new TLRPC.TL_messageService(); + + newMsg.action = new TLRPC.TL_messageEncryptedAction(); + newMsg.action.encryptedAction = decryptedMessage; + newMsg.local_id = newMsg.id = UserConfig.getNewMessageId(); + newMsg.from_id = UserConfig.getClientUserId(); + newMsg.flags = TLRPC.MESSAGE_FLAG_UNREAD | TLRPC.MESSAGE_FLAG_OUT; + newMsg.dialog_id = ((long)encryptedChat.id) << 32; + newMsg.to_id = new TLRPC.TL_peerUser(); + newMsg.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING; + if (encryptedChat.participant_id == UserConfig.getClientUserId()) { + newMsg.to_id.user_id = encryptedChat.admin_id; + } else { + newMsg.to_id.user_id = encryptedChat.participant_id; + } + if (decryptedMessage instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages || decryptedMessage instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) { + newMsg.date = ConnectionsManager.getInstance().getCurrentTime(); + } else { + newMsg.date = 0; + } + newMsg.random_id = SendMessagesHelper.getInstance().getNextRandomId(); + UserConfig.saveConfig(false); + + ArrayList arr = new ArrayList(); + arr.add(newMsg); + MessagesStorage.getInstance().putMessages(arr, false, true, true, 0); + + return newMsg; + } + + public void sendMessagesReadMessage(TLRPC.EncryptedChat encryptedChat, ArrayList random_ids, TLRPC.Message resendMessage) { + if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) { + return; + } + TLRPC.TL_decryptedMessageService reqSend = null; + if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { + reqSend = new TLRPC.TL_decryptedMessageService(); + } else { + reqSend = new TLRPC.TL_decryptedMessageService_old(); + reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; + Utilities.random.nextBytes(reqSend.random_bytes); + } + + TLRPC.Message message = null; + + if (resendMessage != null) { + message = resendMessage; + reqSend.action = message.action.encryptedAction; + } else { + reqSend.action = new TLRPC.TL_decryptedMessageActionReadMessages(); + reqSend.action.random_ids = random_ids; + message = createServiceSecretMessage(encryptedChat, reqSend.action); + } + reqSend.random_id = message.random_id; + + performSendEncryptedRequest(reqSend, message, encryptedChat, null, null); + } + + protected void processUpdateEncryption(TLRPC.TL_updateEncryption update, ConcurrentHashMap usersDict) { + final TLRPC.EncryptedChat newChat = update.chat; + long dialog_id = ((long)newChat.id) << 32; + TLRPC.EncryptedChat existingChat = MessagesController.getInstance().getEncryptedChatDB(newChat.id); + + if (newChat instanceof TLRPC.TL_encryptedChatRequested && existingChat == null) { + int user_id = newChat.participant_id; + if (user_id == UserConfig.getClientUserId()) { + user_id = newChat.admin_id; + } + TLRPC.User user = MessagesController.getInstance().getUser(user_id); + if (user == null) { + user = usersDict.get(user_id); + } + newChat.user_id = user_id; + final TLRPC.TL_dialog dialog = new TLRPC.TL_dialog(); + dialog.id = dialog_id; + dialog.unread_count = 0; + dialog.top_message = 0; + dialog.last_message_date = update.date; + + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + MessagesController.getInstance().dialogs_dict.put(dialog.id, dialog); + MessagesController.getInstance().dialogs.add(dialog); + MessagesController.getInstance().putEncryptedChat(newChat, false); + Collections.sort(MessagesController.getInstance().dialogs, new Comparator() { + @Override + public int compare(TLRPC.TL_dialog tl_dialog, TLRPC.TL_dialog tl_dialog2) { + if (tl_dialog.last_message_date == tl_dialog2.last_message_date) { + return 0; + } else if (tl_dialog.last_message_date < tl_dialog2.last_message_date) { + return 1; + } else { + return -1; + } + } + }); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); + } + }); + MessagesStorage.getInstance().putEncryptedChat(newChat, user, dialog); + SecretChatHelper.getInstance().acceptSecretChat(newChat); + } else if (newChat instanceof TLRPC.TL_encryptedChat) { + if (existingChat != null && existingChat instanceof TLRPC.TL_encryptedChatWaiting && (existingChat.auth_key == null || existingChat.auth_key.length == 1)) { + newChat.a_or_b = existingChat.a_or_b; + newChat.user_id = existingChat.user_id; + SecretChatHelper.getInstance().processAcceptedSecretChat(newChat); + } else if (existingChat == null && startingSecretChat) { + delayedEncryptedChatUpdates.add(update); + } + } else { + final TLRPC.EncryptedChat exist = existingChat; + if (exist != null) { + newChat.user_id = exist.user_id; + newChat.auth_key = exist.auth_key; + newChat.key_create_date = exist.key_create_date; + newChat.key_use_count_in = exist.key_use_count_in; + newChat.key_use_count_out = exist.key_use_count_out; + newChat.ttl = exist.ttl; + newChat.seq_in = exist.seq_in; + newChat.seq_out = exist.seq_out; + } + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (exist != null) { + MessagesController.getInstance().putEncryptedChat(newChat, false); + } + MessagesStorage.getInstance().updateEncryptedChat(newChat); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.encryptedChatUpdated, newChat); + } + }); + } + } + + public void sendMessagesDeleteMessage(TLRPC.EncryptedChat encryptedChat, ArrayList random_ids, TLRPC.Message resendMessage) { + if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) { + return; + } + TLRPC.TL_decryptedMessageService reqSend = null; + if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { + reqSend = new TLRPC.TL_decryptedMessageService(); + } else { + reqSend = new TLRPC.TL_decryptedMessageService_old(); + reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; + Utilities.random.nextBytes(reqSend.random_bytes); + } + + TLRPC.Message message = null; + + if (resendMessage != null) { + message = resendMessage; + reqSend.action = message.action.encryptedAction; + } else { + reqSend.action = new TLRPC.TL_decryptedMessageActionDeleteMessages(); + reqSend.action.random_ids = random_ids; + message = createServiceSecretMessage(encryptedChat, reqSend.action); + } + reqSend.random_id = message.random_id; + + performSendEncryptedRequest(reqSend, message, encryptedChat, null, null); + } + + public void sendClearHistoryMessage(TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) { + if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) { + return; + } + TLRPC.TL_decryptedMessageService reqSend = null; + if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { + reqSend = new TLRPC.TL_decryptedMessageService(); + } else { + reqSend = new TLRPC.TL_decryptedMessageService_old(); + reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; + Utilities.random.nextBytes(reqSend.random_bytes); + } + + TLRPC.Message message = null; + + if (resendMessage != null) { + message = resendMessage; + reqSend.action = message.action.encryptedAction; + } else { + reqSend.action = new TLRPC.TL_decryptedMessageActionFlushHistory(); + message = createServiceSecretMessage(encryptedChat, reqSend.action); + } + reqSend.random_id = message.random_id; + + performSendEncryptedRequest(reqSend, message, encryptedChat, null, null); + } + + public void sendNotifyLayerMessage(final TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) { + if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) { + return; + } + if (sendingNotifyLayer.contains(encryptedChat.id)) { + return; + } + sendingNotifyLayer.add(encryptedChat.id); + TLRPC.TL_decryptedMessageService reqSend = null; + if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { + reqSend = new TLRPC.TL_decryptedMessageService(); + } else { + reqSend = new TLRPC.TL_decryptedMessageService_old(); + reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; + Utilities.random.nextBytes(reqSend.random_bytes); + } + + TLRPC.Message message = null; + + if (resendMessage != null) { + message = resendMessage; + reqSend.action = message.action.encryptedAction; + } else { + reqSend.action = new TLRPC.TL_decryptedMessageActionNotifyLayer(); + reqSend.action.layer = CURRENT_SECRET_CHAT_LAYER; + message = createServiceSecretMessage(encryptedChat, reqSend.action); + } + reqSend.random_id = message.random_id; + + performSendEncryptedRequest(reqSend, message, encryptedChat, null, null); + } + + public void sendRequestKeyMessage(final TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) { + if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) { + return; + } + + TLRPC.TL_decryptedMessageService reqSend = null; + if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { + reqSend = new TLRPC.TL_decryptedMessageService(); + } else { + reqSend = new TLRPC.TL_decryptedMessageService_old(); + reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; + Utilities.random.nextBytes(reqSend.random_bytes); + } + + TLRPC.Message message = null; + + if (resendMessage != null) { + message = resendMessage; + reqSend.action = message.action.encryptedAction; + } else { + reqSend.action = new TLRPC.TL_decryptedMessageActionRequestKey(); + reqSend.action.exchange_id = encryptedChat.exchange_id; + reqSend.action.g_a = encryptedChat.g_a; + + message = createServiceSecretMessage(encryptedChat, reqSend.action); + } + reqSend.random_id = message.random_id; + + performSendEncryptedRequest(reqSend, message, encryptedChat, null, null); + } + + public void sendAcceptKeyMessage(final TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) { + if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) { + return; + } + + TLRPC.TL_decryptedMessageService reqSend = null; + if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { + reqSend = new TLRPC.TL_decryptedMessageService(); + } else { + reqSend = new TLRPC.TL_decryptedMessageService_old(); + reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; + Utilities.random.nextBytes(reqSend.random_bytes); + } + + TLRPC.Message message = null; + + if (resendMessage != null) { + message = resendMessage; + reqSend.action = message.action.encryptedAction; + } else { + reqSend.action = new TLRPC.TL_decryptedMessageActionAcceptKey(); + reqSend.action.exchange_id = encryptedChat.exchange_id; + reqSend.action.key_fingerprint = encryptedChat.future_key_fingerprint; + reqSend.action.g_b = encryptedChat.g_a_or_b; + + message = createServiceSecretMessage(encryptedChat, reqSend.action); + } + reqSend.random_id = message.random_id; + + performSendEncryptedRequest(reqSend, message, encryptedChat, null, null); + } + + public void sendCommitKeyMessage(final TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) { + if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) { + return; + } + + TLRPC.TL_decryptedMessageService reqSend = null; + if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { + reqSend = new TLRPC.TL_decryptedMessageService(); + } else { + reqSend = new TLRPC.TL_decryptedMessageService_old(); + reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; + Utilities.random.nextBytes(reqSend.random_bytes); + } + + TLRPC.Message message = null; + + if (resendMessage != null) { + message = resendMessage; + reqSend.action = message.action.encryptedAction; + } else { + reqSend.action = new TLRPC.TL_decryptedMessageActionCommitKey(); + reqSend.action.exchange_id = encryptedChat.exchange_id; + reqSend.action.key_fingerprint = encryptedChat.future_key_fingerprint; + + message = createServiceSecretMessage(encryptedChat, reqSend.action); + } + reqSend.random_id = message.random_id; + + performSendEncryptedRequest(reqSend, message, encryptedChat, null, null); + } + + public void sendAbortKeyMessage(final TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage, long excange_id) { + if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) { + return; + } + + TLRPC.TL_decryptedMessageService reqSend = null; + if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { + reqSend = new TLRPC.TL_decryptedMessageService(); + } else { + reqSend = new TLRPC.TL_decryptedMessageService_old(); + reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; + Utilities.random.nextBytes(reqSend.random_bytes); + } + + TLRPC.Message message = null; + + if (resendMessage != null) { + message = resendMessage; + reqSend.action = message.action.encryptedAction; + } else { + reqSend.action = new TLRPC.TL_decryptedMessageActionAbortKey(); + reqSend.action.exchange_id = excange_id; + + message = createServiceSecretMessage(encryptedChat, reqSend.action); + } + reqSend.random_id = message.random_id; + + performSendEncryptedRequest(reqSend, message, encryptedChat, null, null); + } + + public void sendNoopMessage(final TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) { + if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) { + return; + } + + TLRPC.TL_decryptedMessageService reqSend = null; + if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { + reqSend = new TLRPC.TL_decryptedMessageService(); + } else { + reqSend = new TLRPC.TL_decryptedMessageService_old(); + reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; + Utilities.random.nextBytes(reqSend.random_bytes); + } + + TLRPC.Message message = null; + + if (resendMessage != null) { + message = resendMessage; + reqSend.action = message.action.encryptedAction; + } else { + reqSend.action = new TLRPC.TL_decryptedMessageActionNoop(); + message = createServiceSecretMessage(encryptedChat, reqSend.action); + } + reqSend.random_id = message.random_id; + + performSendEncryptedRequest(reqSend, message, encryptedChat, null, null); + } + + public void sendTTLMessage(TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) { + if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) { + return; + } + + TLRPC.TL_decryptedMessageService reqSend = null; + if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { + reqSend = new TLRPC.TL_decryptedMessageService(); + } else { + reqSend = new TLRPC.TL_decryptedMessageService_old(); + reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; + Utilities.random.nextBytes(reqSend.random_bytes); + } + + TLRPC.Message message = null; + + if (resendMessage != null) { + message = resendMessage; + reqSend.action = message.action.encryptedAction; + } else { + reqSend.action = new TLRPC.TL_decryptedMessageActionSetMessageTTL(); + reqSend.action.ttl_seconds = encryptedChat.ttl; + message = createServiceSecretMessage(encryptedChat, reqSend.action); + + MessageObject newMsgObj = new MessageObject(message, null); + newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING; + ArrayList objArr = new ArrayList(); + objArr.add(newMsgObj); + MessagesController.getInstance().updateInterfaceWithMessages(message.dialog_id, objArr); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); + } + reqSend.random_id = message.random_id; + + performSendEncryptedRequest(reqSend, message, encryptedChat, null, null); + } + + public void sendScreenshotMessage(TLRPC.EncryptedChat encryptedChat, ArrayList random_ids, TLRPC.Message resendMessage) { + if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) { + return; + } + + TLRPC.TL_decryptedMessageService reqSend = null; + if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { + reqSend = new TLRPC.TL_decryptedMessageService(); + } else { + reqSend = new TLRPC.TL_decryptedMessageService_old(); + reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; + Utilities.random.nextBytes(reqSend.random_bytes); + } + + TLRPC.Message message = null; + + if (resendMessage != null) { + message = resendMessage; + reqSend.action = message.action.encryptedAction; + } else { + reqSend.action = new TLRPC.TL_decryptedMessageActionScreenshotMessages(); + reqSend.action.random_ids = random_ids; + message = createServiceSecretMessage(encryptedChat, reqSend.action); + + MessageObject newMsgObj = new MessageObject(message, null); + newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING; + ArrayList objArr = new ArrayList(); + objArr.add(newMsgObj); + MessagesController.getInstance().updateInterfaceWithMessages(message.dialog_id, objArr); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); + } + reqSend.random_id = message.random_id; + + performSendEncryptedRequest(reqSend, message, encryptedChat, null, null); + } + + private void processSentMessage(TLRPC.Message newMsg, TLRPC.EncryptedFile file, TLRPC.DecryptedMessage decryptedMessage, String originalPath) { + if (file != null) { + if (newMsg.media instanceof TLRPC.TL_messageMediaPhoto && newMsg.media.photo != null) { + TLRPC.PhotoSize size = newMsg.media.photo.sizes.get(newMsg.media.photo.sizes.size() - 1); + String fileName = size.location.volume_id + "_" + size.location.local_id; + size.location = new TLRPC.TL_fileEncryptedLocation(); + size.location.key = decryptedMessage.media.key; + size.location.iv = decryptedMessage.media.iv; + size.location.dc_id = file.dc_id; + size.location.volume_id = file.id; + size.location.secret = file.access_hash; + size.location.local_id = file.key_fingerprint; + String fileName2 = size.location.volume_id + "_" + size.location.local_id; + File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName + ".jpg"); + File cacheFile2 = FileLoader.getPathToAttach(size); + cacheFile.renameTo(cacheFile2); + ImageLoader.getInstance().replaceImageInCache(fileName, fileName2); + ArrayList arr = new ArrayList(); + arr.add(newMsg); + MessagesStorage.getInstance().putMessages(arr, false, true, false, 0); + + MessagesStorage.getInstance().putSentFile(originalPath, newMsg.media.photo, 3); + } else if (newMsg.media instanceof TLRPC.TL_messageMediaVideo && newMsg.media.video != null) { + TLRPC.Video video = newMsg.media.video; + newMsg.media.video = new TLRPC.TL_videoEncrypted(); + newMsg.media.video.duration = video.duration; + newMsg.media.video.thumb = video.thumb; + newMsg.media.video.dc_id = file.dc_id; + newMsg.media.video.w = video.w; + newMsg.media.video.h = video.h; + newMsg.media.video.date = video.date; + newMsg.media.video.caption = ""; + newMsg.media.video.user_id = video.user_id; + newMsg.media.video.size = file.size; + newMsg.media.video.id = file.id; + newMsg.media.video.access_hash = file.access_hash; + newMsg.media.video.key = decryptedMessage.media.key; + newMsg.media.video.iv = decryptedMessage.media.iv; + newMsg.media.video.mime_type = video.mime_type; + + if (newMsg.attachPath != null && newMsg.attachPath.startsWith(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE).getAbsolutePath())) { + File cacheFile = new File(newMsg.attachPath); + File cacheFile2 = FileLoader.getPathToAttach(newMsg.media.video); + if (cacheFile.renameTo(cacheFile2)) { + newMsg.attachPath = ""; + } + } + + ArrayList arr = new ArrayList(); + arr.add(newMsg); + MessagesStorage.getInstance().putMessages(arr, false, true, false, 0); + + MessagesStorage.getInstance().putSentFile(originalPath, newMsg.media.video, 5); + } else if (newMsg.media instanceof TLRPC.TL_messageMediaDocument && newMsg.media.document != null) { + TLRPC.Document document = newMsg.media.document; + newMsg.media.document = new TLRPC.TL_documentEncrypted(); + newMsg.media.document.id = file.id; + newMsg.media.document.access_hash = file.access_hash; + newMsg.media.document.user_id = document.user_id; + newMsg.media.document.date = document.date; + newMsg.media.document.file_name = document.file_name; + newMsg.media.document.mime_type = document.mime_type; + newMsg.media.document.size = file.size; + newMsg.media.document.key = decryptedMessage.media.key; + newMsg.media.document.iv = decryptedMessage.media.iv; + newMsg.media.document.thumb = document.thumb; + newMsg.media.document.dc_id = file.dc_id; + + if (newMsg.attachPath != null && newMsg.attachPath.startsWith(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE).getAbsolutePath())) { + File cacheFile = new File(newMsg.attachPath); + File cacheFile2 = FileLoader.getPathToAttach(newMsg.media.document); + if (cacheFile.renameTo(cacheFile2)) { + newMsg.attachPath = ""; + } + } + + ArrayList arr = new ArrayList(); + arr.add(newMsg); + MessagesStorage.getInstance().putMessages(arr, false, true, false, 0); + + MessagesStorage.getInstance().putSentFile(originalPath, newMsg.media.document, 4); + } else if (newMsg.media instanceof TLRPC.TL_messageMediaAudio && newMsg.media.audio != null) { + TLRPC.Audio audio = newMsg.media.audio; + newMsg.media.audio = new TLRPC.TL_audioEncrypted(); + newMsg.media.audio.id = file.id; + newMsg.media.audio.access_hash = file.access_hash; + newMsg.media.audio.user_id = audio.user_id; + newMsg.media.audio.date = audio.date; + newMsg.media.audio.duration = audio.duration; + newMsg.media.audio.size = file.size; + newMsg.media.audio.dc_id = file.dc_id; + newMsg.media.audio.key = decryptedMessage.media.key; + newMsg.media.audio.iv = decryptedMessage.media.iv; + newMsg.media.audio.mime_type = audio.mime_type; + + String fileName = audio.dc_id + "_" + audio.id + ".ogg"; + String fileName2 = newMsg.media.audio.dc_id + "_" + newMsg.media.audio.id + ".ogg"; + if (!fileName.equals(fileName2)) { + File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName); + File cacheFile2 = FileLoader.getPathToAttach(newMsg.media.audio); + if (cacheFile.renameTo(cacheFile2)) { + newMsg.attachPath = ""; + } + } + + ArrayList arr = new ArrayList(); + arr.add(newMsg); + MessagesStorage.getInstance().putMessages(arr, false, true, false, 0); + } + } + } + + public static boolean isSecretVisibleMessage(TLRPC.Message message) { + return message.action instanceof TLRPC.TL_messageEncryptedAction && (message.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages || message.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL); + } + + public static boolean isSecretInvisibleMessage(TLRPC.Message message) { + return message.action instanceof TLRPC.TL_messageEncryptedAction && !(message.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages || message.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL); + } + + protected void performSendEncryptedRequest(final TLRPC.DecryptedMessage req, final TLRPC.Message newMsgObj, final TLRPC.EncryptedChat chat, final TLRPC.InputEncryptedFile encryptedFile, final String originalPath) { + if (req == null || chat.auth_key == null || chat instanceof TLRPC.TL_encryptedChatRequested || chat instanceof TLRPC.TL_encryptedChatWaiting) { + return; + } + Utilities.stageQueue.postRunnable(new Runnable() { + @Override + public void run() { + TLObject toEncryptObject = null; + if (AndroidUtilities.getPeerLayerVersion(chat.layer) >= 17) { + TLRPC.TL_decryptedMessageLayer layer = new TLRPC.TL_decryptedMessageLayer(); + layer.layer = AndroidUtilities.getPeerLayerVersion(chat.layer); + layer.message = req; + layer.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; + Utilities.random.nextBytes(layer.random_bytes); + toEncryptObject = layer; + + if (chat.seq_in == 0 && chat.seq_out == 0) { + if (chat.admin_id == UserConfig.getClientUserId()) { + chat.seq_out = 1; + } else { + chat.seq_in = 1; + } + } + + if (newMsgObj.seq_in == 0 && newMsgObj.seq_out == 0) { + layer.in_seq_no = chat.seq_in; + layer.out_seq_no = chat.seq_out; + chat.seq_out += 2; + if (AndroidUtilities.getPeerLayerVersion(chat.layer) >= 20) { + if (chat.key_create_date == 0) { + chat.key_create_date = ConnectionsManager.getInstance().getCurrentTime(); + } + chat.key_use_count_out++; + if ((chat.key_use_count_out >= 100 || chat.key_create_date < ConnectionsManager.getInstance().getCurrentTime() - 60 * 60 * 24 * 7) && chat.exchange_id == 0) { + requestNewSecretChatKey(chat); + } + } + MessagesStorage.getInstance().updateEncryptedChatSeq(chat); + if (newMsgObj != null) { + newMsgObj.seq_in = layer.in_seq_no; + newMsgObj.seq_out = layer.out_seq_no; + MessagesStorage.getInstance().setMessageSeq(newMsgObj.id, newMsgObj.seq_in, newMsgObj.seq_out); + } + } else { + layer.in_seq_no = newMsgObj.seq_in; + layer.out_seq_no = newMsgObj.seq_out; + } + } else { + toEncryptObject = req; + } + + int len = toEncryptObject.getObjectSize(); + ByteBufferDesc toEncrypt = BuffersStorage.getInstance().getFreeBuffer(4 + len); + toEncrypt.writeInt32(len); + toEncryptObject.serializeToStream(toEncrypt); + + byte[] messageKeyFull = Utilities.computeSHA1(toEncrypt.buffer); + byte[] messageKey = new byte[16]; + System.arraycopy(messageKeyFull, messageKeyFull.length - 16, messageKey, 0, 16); + + MessageKeyData keyData = Utilities.generateMessageKeyData(chat.auth_key, messageKey, false); + + len = toEncrypt.length(); + int extraLen = len % 16 != 0 ? 16 - len % 16 : 0; + ByteBufferDesc dataForEncryption = BuffersStorage.getInstance().getFreeBuffer(len + extraLen); + toEncrypt.position(0); + dataForEncryption.writeRaw(toEncrypt); + if (extraLen != 0) { + byte[] b = new byte[extraLen]; + Utilities.random.nextBytes(b); + dataForEncryption.writeRaw(b); + } + BuffersStorage.getInstance().reuseFreeBuffer(toEncrypt); + + Utilities.aesIgeEncryption(dataForEncryption.buffer, keyData.aesKey, keyData.aesIv, true, false, 0, dataForEncryption.limit()); + + ByteBufferDesc data = BuffersStorage.getInstance().getFreeBuffer(8 + messageKey.length + dataForEncryption.length()); + dataForEncryption.position(0); + data.writeInt64(chat.key_fingerprint); + data.writeRaw(messageKey); + data.writeRaw(dataForEncryption); + BuffersStorage.getInstance().reuseFreeBuffer(dataForEncryption); + data.position(0); + + TLObject reqToSend = null; + + if (encryptedFile == null) { + if (req instanceof TLRPC.TL_decryptedMessageService) { + TLRPC.TL_messages_sendEncryptedService req2 = new TLRPC.TL_messages_sendEncryptedService(); + req2.data = data; + req2.random_id = req.random_id; + req2.peer = new TLRPC.TL_inputEncryptedChat(); + req2.peer.chat_id = chat.id; + req2.peer.access_hash = chat.access_hash; + reqToSend = req2; + } else { + TLRPC.TL_messages_sendEncrypted req2 = new TLRPC.TL_messages_sendEncrypted(); + req2.data = data; + req2.random_id = req.random_id; + req2.peer = new TLRPC.TL_inputEncryptedChat(); + req2.peer.chat_id = chat.id; + req2.peer.access_hash = chat.access_hash; + reqToSend = req2; + } + } else { + TLRPC.TL_messages_sendEncryptedFile req2 = new TLRPC.TL_messages_sendEncryptedFile(); + req2.data = data; + req2.random_id = req.random_id; + req2.peer = new TLRPC.TL_inputEncryptedChat(); + req2.peer.chat_id = chat.id; + req2.peer.access_hash = chat.access_hash; + req2.file = encryptedFile; + reqToSend = req2; + } + ConnectionsManager.getInstance().performRpc(reqToSend, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, TLRPC.TL_error error) { + if (error == null) { + if (req.action instanceof TLRPC.TL_decryptedMessageActionNotifyLayer) { + TLRPC.EncryptedChat currentChat = MessagesController.getInstance().getEncryptedChat(chat.id); + sendingNotifyLayer.remove((Integer)currentChat.id); + currentChat.layer = AndroidUtilities.setMyLayerVersion(currentChat.layer, CURRENT_SECRET_CHAT_LAYER); + MessagesStorage.getInstance().updateEncryptedChatLayer(currentChat); + } + } + if (newMsgObj != null) { + if (error == null) { + final String attachPath = newMsgObj.attachPath; + final TLRPC.messages_SentEncryptedMessage res = (TLRPC.messages_SentEncryptedMessage) response; + if (isSecretVisibleMessage(newMsgObj)) { + newMsgObj.date = res.date; + } + if (res.file instanceof TLRPC.TL_encryptedFile) { + processSentMessage(newMsgObj, res.file, req, originalPath); + } + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { + @Override + public void run() { + if (isSecretInvisibleMessage(newMsgObj)) { + res.date = 0; + } + MessagesStorage.getInstance().updateMessageStateAndId(newMsgObj.random_id, newMsgObj.id, newMsgObj.id, res.date, false); + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + newMsgObj.send_state = MessageObject.MESSAGE_SEND_STATE_SENT; + NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, newMsgObj.id, newMsgObj.id, newMsgObj); + SendMessagesHelper.getInstance().processSentMessage(newMsgObj.id); + if (newMsgObj.media instanceof TLRPC.TL_messageMediaVideo) { + SendMessagesHelper.getInstance().stopVideoService(attachPath); + } + } + }); + } + }); + } else { + MessagesStorage.getInstance().markMessageAsSendError(newMsgObj.id); + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + newMsgObj.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR; + NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, newMsgObj.id); + SendMessagesHelper.getInstance().processSentMessage(newMsgObj.id); + if (newMsgObj.media instanceof TLRPC.TL_messageMediaVideo) { + SendMessagesHelper.getInstance().stopVideoService(newMsgObj.attachPath); + } + } + }); + } + } + } + }); + } + }); + } + + public TLRPC.Message processDecryptedObject(final TLRPC.EncryptedChat chat, final TLRPC.EncryptedFile file, int date, long random_id, TLObject object, boolean new_key_used) { + if (object != null) { + int from_id = chat.admin_id; + if (from_id == UserConfig.getClientUserId()) { + from_id = chat.participant_id; + } + + if (AndroidUtilities.getPeerLayerVersion(chat.layer) >= 20 && chat.exchange_id == 0 && chat.future_key_fingerprint == 0 && chat.key_use_count_in >= 120) { + requestNewSecretChatKey(chat); + } + + if (chat.exchange_id == 0 && chat.future_key_fingerprint != 0 && !new_key_used) { + chat.future_auth_key = new byte[256]; + chat.future_key_fingerprint = 0; + MessagesStorage.getInstance().updateEncryptedChat(chat); + } else if (chat.exchange_id != 0 && new_key_used) { + chat.key_fingerprint = chat.future_key_fingerprint; + chat.auth_key = chat.future_auth_key; + chat.key_create_date = ConnectionsManager.getInstance().getCurrentTime(); + chat.future_auth_key = new byte[256]; + chat.future_key_fingerprint = 0; + chat.key_use_count_in = 0; + chat.key_use_count_out = 0; + chat.exchange_id = 0; + + MessagesStorage.getInstance().updateEncryptedChat(chat); + } + + if (object instanceof TLRPC.TL_decryptedMessage) { + TLRPC.TL_decryptedMessage decryptedMessage = (TLRPC.TL_decryptedMessage)object; + TLRPC.TL_message newMessage = null; + if (AndroidUtilities.getPeerLayerVersion(chat.layer) >= 17) { + newMessage = new TLRPC.TL_message_secret(); + newMessage.ttl = decryptedMessage.ttl; + } else { + newMessage = new TLRPC.TL_message(); + newMessage.ttl = chat.ttl; + } + newMessage.message = decryptedMessage.message; + newMessage.date = date; + newMessage.local_id = newMessage.id = UserConfig.getNewMessageId(); + UserConfig.saveConfig(false); + newMessage.from_id = from_id; + newMessage.to_id = new TLRPC.TL_peerUser(); + newMessage.random_id = random_id; + newMessage.to_id.user_id = UserConfig.getClientUserId(); + newMessage.flags = TLRPC.MESSAGE_FLAG_UNREAD; + newMessage.dialog_id = ((long)chat.id) << 32; + if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaEmpty) { + newMessage.media = new TLRPC.TL_messageMediaEmpty(); + } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaContact) { + newMessage.media = new TLRPC.TL_messageMediaContact(); + newMessage.media.last_name = decryptedMessage.media.last_name; + newMessage.media.first_name = decryptedMessage.media.first_name; + newMessage.media.phone_number = decryptedMessage.media.phone_number; + newMessage.media.user_id = decryptedMessage.media.user_id; + } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaGeoPoint) { + newMessage.media = new TLRPC.TL_messageMediaGeo(); + newMessage.media.geo = new TLRPC.TL_geoPoint(); + newMessage.media.geo.lat = decryptedMessage.media.lat; + newMessage.media.geo._long = decryptedMessage.media._long; + } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaPhoto) { + if (decryptedMessage.media.key == null || decryptedMessage.media.key.length != 32 || decryptedMessage.media.iv == null || decryptedMessage.media.iv.length != 32) { + return null; + } + newMessage.media = new TLRPC.TL_messageMediaPhoto(); + newMessage.media.photo = new TLRPC.TL_photo(); + newMessage.media.photo.user_id = newMessage.from_id; + newMessage.media.photo.date = newMessage.date; + newMessage.media.photo.caption = ""; + newMessage.media.photo.geo = new TLRPC.TL_geoPointEmpty(); + if (decryptedMessage.media.thumb.length != 0 && decryptedMessage.media.thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) { + TLRPC.TL_photoCachedSize small = new TLRPC.TL_photoCachedSize(); + small.w = decryptedMessage.media.thumb_w; + small.h = decryptedMessage.media.thumb_h; + small.bytes = decryptedMessage.media.thumb; + small.type = "s"; + small.location = new TLRPC.TL_fileLocationUnavailable(); + newMessage.media.photo.sizes.add(small); + } + + TLRPC.TL_photoSize big = new TLRPC.TL_photoSize(); + big.w = decryptedMessage.media.w; + big.h = decryptedMessage.media.h; + big.type = "x"; + big.size = file.size; + big.location = new TLRPC.TL_fileEncryptedLocation(); + big.location.key = decryptedMessage.media.key; + big.location.iv = decryptedMessage.media.iv; + big.location.dc_id = file.dc_id; + big.location.volume_id = file.id; + big.location.secret = file.access_hash; + big.location.local_id = file.key_fingerprint; + newMessage.media.photo.sizes.add(big); + } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaVideo) { + if (decryptedMessage.media.key == null || decryptedMessage.media.key.length != 32 || decryptedMessage.media.iv == null || decryptedMessage.media.iv.length != 32) { + return null; + } + newMessage.media = new TLRPC.TL_messageMediaVideo(); + newMessage.media.video = new TLRPC.TL_videoEncrypted(); + if (decryptedMessage.media.thumb.length != 0 && decryptedMessage.media.thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) { + newMessage.media.video.thumb = new TLRPC.TL_photoCachedSize(); + newMessage.media.video.thumb.bytes = decryptedMessage.media.thumb; + newMessage.media.video.thumb.w = decryptedMessage.media.thumb_w; + newMessage.media.video.thumb.h = decryptedMessage.media.thumb_h; + newMessage.media.video.thumb.type = "s"; + newMessage.media.video.thumb.location = new TLRPC.TL_fileLocationUnavailable(); + } else { + newMessage.media.video.thumb = new TLRPC.TL_photoSizeEmpty(); + newMessage.media.video.thumb.type = "s"; + } + newMessage.media.video.duration = decryptedMessage.media.duration; + newMessage.media.video.dc_id = file.dc_id; + newMessage.media.video.w = decryptedMessage.media.w; + newMessage.media.video.h = decryptedMessage.media.h; + newMessage.media.video.date = date; + newMessage.media.video.caption = ""; + newMessage.media.video.user_id = from_id; + newMessage.media.video.size = file.size; + newMessage.media.video.id = file.id; + newMessage.media.video.access_hash = file.access_hash; + newMessage.media.video.key = decryptedMessage.media.key; + newMessage.media.video.iv = decryptedMessage.media.iv; + newMessage.media.video.mime_type = decryptedMessage.media.mime_type; + if (newMessage.ttl != 0) { + newMessage.ttl = Math.max(newMessage.media.video.duration + 1, newMessage.ttl); + } + if (newMessage.media.video.mime_type == null) { + newMessage.media.video.mime_type = "video/mp4"; + } + } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaDocument) { + if (decryptedMessage.media.key == null || decryptedMessage.media.key.length != 32 || decryptedMessage.media.iv == null || decryptedMessage.media.iv.length != 32) { + return null; + } + newMessage.media = new TLRPC.TL_messageMediaDocument(); + newMessage.media.document = new TLRPC.TL_documentEncrypted(); + newMessage.media.document.id = file.id; + newMessage.media.document.access_hash = file.access_hash; + newMessage.media.document.user_id = decryptedMessage.media.user_id; + newMessage.media.document.date = date; + newMessage.media.document.file_name = decryptedMessage.media.file_name; + newMessage.media.document.mime_type = decryptedMessage.media.mime_type; + newMessage.media.document.size = file.size; + newMessage.media.document.key = decryptedMessage.media.key; + newMessage.media.document.iv = decryptedMessage.media.iv; + if (decryptedMessage.media.thumb.length != 0 && decryptedMessage.media.thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) { + newMessage.media.document.thumb = new TLRPC.TL_photoCachedSize(); + newMessage.media.document.thumb.bytes = decryptedMessage.media.thumb; + newMessage.media.document.thumb.w = decryptedMessage.media.thumb_w; + newMessage.media.document.thumb.h = decryptedMessage.media.thumb_h; + newMessage.media.document.thumb.type = "s"; + newMessage.media.document.thumb.location = new TLRPC.TL_fileLocationUnavailable(); + } else { + newMessage.media.document.thumb = new TLRPC.TL_photoSizeEmpty(); + newMessage.media.document.thumb.type = "s"; + } + newMessage.media.document.dc_id = file.dc_id; + } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaAudio) { + if (decryptedMessage.media.key == null || decryptedMessage.media.key.length != 32 || decryptedMessage.media.iv == null || decryptedMessage.media.iv.length != 32) { + return null; + } + newMessage.media = new TLRPC.TL_messageMediaAudio(); + newMessage.media.audio = new TLRPC.TL_audioEncrypted(); + newMessage.media.audio.id = file.id; + newMessage.media.audio.access_hash = file.access_hash; + newMessage.media.audio.user_id = from_id; + newMessage.media.audio.date = date; + newMessage.media.audio.size = file.size; + newMessage.media.audio.key = decryptedMessage.media.key; + newMessage.media.audio.iv = decryptedMessage.media.iv; + newMessage.media.audio.dc_id = file.dc_id; + newMessage.media.audio.duration = decryptedMessage.media.duration; + newMessage.media.audio.mime_type = decryptedMessage.media.mime_type; + if (newMessage.ttl != 0) { + newMessage.ttl = Math.max(newMessage.media.audio.duration + 1, newMessage.ttl); + } + if (newMessage.media.audio.mime_type == null) { + newMessage.media.audio.mime_type = "audio/ogg"; + } + } else { + return null; + } + return newMessage; + } else if (object instanceof TLRPC.TL_decryptedMessageService) { + final TLRPC.TL_decryptedMessageService serviceMessage = (TLRPC.TL_decryptedMessageService)object; + if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL || serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages) { + TLRPC.TL_messageService newMessage = new TLRPC.TL_messageService(); + if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) { + newMessage.action = new TLRPC.TL_messageEncryptedAction(); + if (serviceMessage.action.ttl_seconds < 0 || serviceMessage.action.ttl_seconds > 60 * 60 * 24 * 365) { + serviceMessage.action.ttl_seconds = 60 * 60 * 24 * 365; + } + chat.ttl = serviceMessage.action.ttl_seconds; + newMessage.action.encryptedAction = serviceMessage.action; + MessagesStorage.getInstance().updateEncryptedChatTTL(chat); + } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages) { + newMessage.action = new TLRPC.TL_messageEncryptedAction(); + newMessage.action.encryptedAction = serviceMessage.action; + } + newMessage.local_id = newMessage.id = UserConfig.getNewMessageId(); + UserConfig.saveConfig(false); + newMessage.flags = TLRPC.MESSAGE_FLAG_UNREAD; + newMessage.date = date; + newMessage.from_id = from_id; + newMessage.to_id = new TLRPC.TL_peerUser(); + newMessage.to_id.user_id = UserConfig.getClientUserId(); + newMessage.dialog_id = ((long)chat.id) << 32; + return newMessage; + } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionFlushHistory) { + final long did = ((long)chat.id) << 32; + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(did); + if (dialog != null) { + dialog.unread_count = 0; + MessagesController.getInstance().dialogMessage.remove(dialog.top_message); + } + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { + @Override + public void run() { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + NotificationsController.getInstance().processReadMessages(null, did, 0, Integer.MAX_VALUE, false); + HashMap dialogsToUpdate = new HashMap(); + dialogsToUpdate.put(did, 0); + NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate); + } + }); + } + }); + MessagesStorage.getInstance().deleteDialog(did, true); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.removeAllMessagesFromDialog, did); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); + } + }); + return null; + } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionDeleteMessages) { + if (!serviceMessage.action.random_ids.isEmpty()) { + pendingEncMessagesToDelete.addAll(serviceMessage.action.random_ids); + } + return null; + } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionReadMessages) { + if (!serviceMessage.action.random_ids.isEmpty()) { + MessagesStorage.getInstance().createTaskForSecretChat(chat.id, ConnectionsManager.getInstance().getCurrentTime(), ConnectionsManager.getInstance().getCurrentTime(), 1, serviceMessage.action.random_ids); + } + } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionNotifyLayer) { + int currentPeerLayer = AndroidUtilities.getPeerLayerVersion(chat.layer); + chat.layer = 0; + chat.layer = AndroidUtilities.setPeerLayerVersion(chat.layer, serviceMessage.action.layer); + MessagesStorage.getInstance().updateEncryptedChatLayer(chat); + if (currentPeerLayer < CURRENT_SECRET_CHAT_LAYER) { + sendNotifyLayerMessage(chat, null); + } + } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionRequestKey) { + if (chat.exchange_id != 0) { + if (chat.exchange_id > serviceMessage.action.exchange_id) { + FileLog.e("tmessages", "we already have request key with higher exchange_id"); + return null; + } else { + sendAbortKeyMessage(chat, null, chat.exchange_id); + } + } + + byte[] salt = new byte[256]; + for (int a = 0; a < 256; a++) { + salt[a] = (byte) (Utilities.random.nextDouble() * 256); + } + + BigInteger p = new BigInteger(1, MessagesStorage.secretPBytes); + BigInteger g_b = BigInteger.valueOf(MessagesStorage.secretG); + g_b = g_b.modPow(new BigInteger(1, salt), p); + BigInteger g_a = new BigInteger(1, serviceMessage.action.g_a); + + if (!Utilities.isGoodGaAndGb(g_a, p)) { + sendAbortKeyMessage(chat, null, serviceMessage.action.exchange_id); + return null; + } + + byte[] g_b_bytes = g_b.toByteArray(); + if (g_b_bytes.length > 256) { + byte[] correctedAuth = new byte[256]; + System.arraycopy(g_b_bytes, 1, correctedAuth, 0, 256); + g_b_bytes = correctedAuth; + } + + g_a = g_a.modPow(new BigInteger(1, salt), p); + + byte[] authKey = g_a.toByteArray(); + if (authKey.length > 256) { + byte[] correctedAuth = new byte[256]; + System.arraycopy(authKey, authKey.length - 256, correctedAuth, 0, 256); + authKey = correctedAuth; + } else if (authKey.length < 256) { + byte[] correctedAuth = new byte[256]; + System.arraycopy(authKey, 0, correctedAuth, 256 - authKey.length, authKey.length); + for (int a = 0; a < 256 - authKey.length; a++) { + authKey[a] = 0; + } + authKey = correctedAuth; + } + byte[] authKeyHash = Utilities.computeSHA1(authKey); + byte[] authKeyId = new byte[8]; + System.arraycopy(authKeyHash, authKeyHash.length - 8, authKeyId, 0, 8); + + chat.exchange_id = serviceMessage.action.exchange_id; + chat.future_auth_key = authKey; + chat.future_key_fingerprint = Utilities.bytesToLong(authKeyId); + chat.g_a_or_b = g_b_bytes; + + MessagesStorage.getInstance().updateEncryptedChat(chat); + + sendAcceptKeyMessage(chat, null); + } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionAcceptKey) { + if (chat.exchange_id == serviceMessage.action.exchange_id) { + + BigInteger p = new BigInteger(1, MessagesStorage.secretPBytes); + BigInteger i_authKey = new BigInteger(1, serviceMessage.action.g_b); + + if (!Utilities.isGoodGaAndGb(i_authKey, p)) { + chat.future_auth_key = new byte[256]; + chat.future_key_fingerprint = 0; + chat.exchange_id = 0; + MessagesStorage.getInstance().updateEncryptedChat(chat); + + sendAbortKeyMessage(chat, null, serviceMessage.action.exchange_id); + return null; + } + + i_authKey = i_authKey.modPow(new BigInteger(1, chat.a_or_b), p); + + byte[] authKey = i_authKey.toByteArray(); + if (authKey.length > 256) { + byte[] correctedAuth = new byte[256]; + System.arraycopy(authKey, authKey.length - 256, correctedAuth, 0, 256); + authKey = correctedAuth; + } else if (authKey.length < 256) { + byte[] correctedAuth = new byte[256]; + System.arraycopy(authKey, 0, correctedAuth, 256 - authKey.length, authKey.length); + for (int a = 0; a < 256 - authKey.length; a++) { + authKey[a] = 0; + } + authKey = correctedAuth; + } + byte[] authKeyHash = Utilities.computeSHA1(authKey); + byte[] authKeyId = new byte[8]; + System.arraycopy(authKeyHash, authKeyHash.length - 8, authKeyId, 0, 8); + long fingerprint = Utilities.bytesToLong(authKeyId); + if (serviceMessage.action.key_fingerprint == fingerprint) { + chat.future_auth_key = authKey; + chat.future_key_fingerprint = fingerprint; + + MessagesStorage.getInstance().updateEncryptedChat(chat); + } else { + chat.future_auth_key = new byte[256]; + chat.future_key_fingerprint = 0; + chat.exchange_id = 0; + MessagesStorage.getInstance().updateEncryptedChat(chat); + sendAbortKeyMessage(chat, null, serviceMessage.action.exchange_id); + } + + sendCommitKeyMessage(chat, null); + } else { + chat.future_auth_key = new byte[256]; + chat.future_key_fingerprint = 0; + chat.exchange_id = 0; + MessagesStorage.getInstance().updateEncryptedChat(chat); + sendAbortKeyMessage(chat, null, serviceMessage.action.exchange_id); + } + } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionCommitKey) { + if (chat.exchange_id == serviceMessage.action.exchange_id && chat.future_key_fingerprint == serviceMessage.action.key_fingerprint) { + long old_fingerpring = chat.key_fingerprint; + byte[] old_key = chat.auth_key; + chat.key_fingerprint = chat.future_key_fingerprint; + chat.auth_key = chat.future_auth_key; + chat.key_create_date = ConnectionsManager.getInstance().getCurrentTime(); + chat.future_auth_key = old_key; + chat.future_key_fingerprint = old_fingerpring; + chat.key_use_count_in = 0; + chat.key_use_count_out = 0; + chat.exchange_id = 0; + + MessagesStorage.getInstance().updateEncryptedChat(chat); + + sendNoopMessage(chat, null); + } else { + chat.future_auth_key = new byte[256]; + chat.future_key_fingerprint = 0; + chat.exchange_id = 0; + MessagesStorage.getInstance().updateEncryptedChat(chat); + sendAbortKeyMessage(chat, null, serviceMessage.action.exchange_id); + } + } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionAbortKey) { + if (chat.exchange_id == serviceMessage.action.exchange_id) { + chat.future_auth_key = new byte[256]; + chat.future_key_fingerprint = 0; + chat.exchange_id = 0; + MessagesStorage.getInstance().updateEncryptedChat(chat); + } + } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionNoop) { + //do nothing + } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionResend) { + + } else { + return null; + } + } else { + FileLog.e("tmessages", "unknown message " + object); + } + } else { + FileLog.e("tmessages", "unknown TLObject"); + } + return null; + } + + public void checkSecretHoles(TLRPC.EncryptedChat chat, ArrayList messages) { + ArrayList holes = secretHolesQueue.get(chat.id); + if (holes == null) { + return; + } + Collections.sort(holes, new Comparator() { + @Override + public int compare(TLRPC.TL_decryptedMessageHolder lhs, TLRPC.TL_decryptedMessageHolder rhs) { + if (lhs.layer.out_seq_no > rhs.layer.out_seq_no) { + return 1; + } else if (lhs.layer.out_seq_no < rhs.layer.out_seq_no) { + return -1; + } + return 0; + } + }); + + boolean update = false; + for (int a = 0; a < holes.size(); a++) { + TLRPC.TL_decryptedMessageHolder holder = holes.get(a); + if (holder.layer.out_seq_no == chat.seq_in || chat.seq_in == holder.layer.out_seq_no - 2) { + chat.seq_in = holder.layer.out_seq_no; + holes.remove(a); + a--; + update = true; + + TLRPC.Message message = processDecryptedObject(chat, holder.file, holder.date, holder.random_id, holder.layer.message, holder.new_key_used); + if (message != null) { + messages.add(message); + } + } else { + break; + } + } + if (holes.isEmpty()) { + secretHolesQueue.remove(chat.id); + } + if (update) { + MessagesStorage.getInstance().updateEncryptedChatSeq(chat); + } + } + + protected ArrayList decryptMessage(TLRPC.EncryptedMessage message) { + final TLRPC.EncryptedChat chat = MessagesController.getInstance().getEncryptedChatDB(message.chat_id); + if (chat == null || chat instanceof TLRPC.TL_encryptedChatDiscarded) { + return null; + } + ByteBufferDesc is = BuffersStorage.getInstance().getFreeBuffer(message.bytes.length); + is.writeRaw(message.bytes); + is.position(0); + long fingerprint = is.readInt64(); + byte[] keyToDecrypt = null; + boolean new_key_used = false; + if (chat.key_fingerprint == fingerprint) { + keyToDecrypt = chat.auth_key; + } else if (chat.future_key_fingerprint != 0 && chat.future_key_fingerprint == fingerprint) { + keyToDecrypt = chat.future_auth_key; + new_key_used = true; + } + + if (keyToDecrypt != null) { + byte[] messageKey = is.readData(16); + MessageKeyData keyData = Utilities.generateMessageKeyData(keyToDecrypt, messageKey, false); + + Utilities.aesIgeEncryption(is.buffer, keyData.aesKey, keyData.aesIv, false, false, 24, is.limit() - 24); + + int len = is.readInt32(); + TLObject object = TLClassStore.Instance().TLdeserialize(is, is.readInt32()); + BuffersStorage.getInstance().reuseFreeBuffer(is); + if (!new_key_used && AndroidUtilities.getPeerLayerVersion(chat.layer) >= 20) { + chat.key_use_count_in++; + } + if (object instanceof TLRPC.TL_decryptedMessageLayer) { + final TLRPC.TL_decryptedMessageLayer layer = (TLRPC.TL_decryptedMessageLayer)object; + if (chat.seq_in == 0 && chat.seq_out == 0) { + if (chat.admin_id == UserConfig.getClientUserId()) { + chat.seq_out = 1; + } else { + chat.seq_in = 1; + } + } + if (layer.out_seq_no < chat.seq_in) { + return null; + } + if (chat.seq_in != layer.out_seq_no && chat.seq_in != layer.out_seq_no - 2) { + ArrayList arr = secretHolesQueue.get(chat.id); + if (arr == null) { + arr = new ArrayList(); + secretHolesQueue.put(chat.id, arr); + } + if (arr.size() >= 10) { + secretHolesQueue.remove(chat.id); + final TLRPC.TL_encryptedChatDiscarded newChat = new TLRPC.TL_encryptedChatDiscarded(); + newChat.id = chat.id; + newChat.user_id = chat.user_id; + newChat.auth_key = chat.auth_key; + newChat.key_create_date = chat.key_create_date; + newChat.key_use_count_in = chat.key_use_count_in; + newChat.key_use_count_out = chat.key_use_count_out; + newChat.seq_in = chat.seq_in; + newChat.seq_out = chat.seq_out; + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + MessagesController.getInstance().putEncryptedChat(newChat, false); + MessagesStorage.getInstance().updateEncryptedChat(newChat); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.encryptedChatUpdated, newChat); + } + }); + declineSecretChat(chat.id); + return null; + } + + TLRPC.TL_decryptedMessageHolder holder = new TLRPC.TL_decryptedMessageHolder(); + holder.layer = layer; + holder.file = message.file; + holder.random_id = message.random_id; + holder.date = message.date; + holder.new_key_used = new_key_used; + arr.add(holder); + return null; + } + chat.seq_in = layer.out_seq_no; + MessagesStorage.getInstance().updateEncryptedChatSeq(chat); + object = layer.message; + } + ArrayList messages = new ArrayList(); + TLRPC.Message decryptedMessage = processDecryptedObject(chat, message.file, message.date, message.random_id, object, new_key_used); + if (decryptedMessage != null) { + messages.add(decryptedMessage); + } + checkSecretHoles(chat, messages); + return messages; + } else { + BuffersStorage.getInstance().reuseFreeBuffer(is); + FileLog.e("tmessages", "fingerprint mismatch " + fingerprint); + } + return null; + } + + public void requestNewSecretChatKey(final TLRPC.EncryptedChat encryptedChat) { + if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) < 20) { + return; + } + final byte[] salt = new byte[256]; + for (int a = 0; a < 256; a++) { + salt[a] = (byte) (Utilities.random.nextDouble() * 256); + } + + BigInteger i_g_a = BigInteger.valueOf(MessagesStorage.secretG); + i_g_a = i_g_a.modPow(new BigInteger(1, salt), new BigInteger(1, MessagesStorage.secretPBytes)); + byte[] g_a = i_g_a.toByteArray(); + if (g_a.length > 256) { + byte[] correctedAuth = new byte[256]; + System.arraycopy(g_a, 1, correctedAuth, 0, 256); + g_a = correctedAuth; + } + + encryptedChat.exchange_id = SendMessagesHelper.getInstance().getNextRandomId(); + encryptedChat.a_or_b = salt; + encryptedChat.g_a = g_a; + + MessagesStorage.getInstance().updateEncryptedChat(encryptedChat); + + sendRequestKeyMessage(encryptedChat, null); + } + + public void processAcceptedSecretChat(final TLRPC.EncryptedChat encryptedChat) { + BigInteger p = new BigInteger(1, MessagesStorage.secretPBytes); + BigInteger i_authKey = new BigInteger(1, encryptedChat.g_a_or_b); + + if (!Utilities.isGoodGaAndGb(i_authKey, p)) { + declineSecretChat(encryptedChat.id); + return; + } + + i_authKey = i_authKey.modPow(new BigInteger(1, encryptedChat.a_or_b), p); + + byte[] authKey = i_authKey.toByteArray(); + if (authKey.length > 256) { + byte[] correctedAuth = new byte[256]; + System.arraycopy(authKey, authKey.length - 256, correctedAuth, 0, 256); + authKey = correctedAuth; + } else if (authKey.length < 256) { + byte[] correctedAuth = new byte[256]; + System.arraycopy(authKey, 0, correctedAuth, 256 - authKey.length, authKey.length); + for (int a = 0; a < 256 - authKey.length; a++) { + authKey[a] = 0; + } + authKey = correctedAuth; + } + byte[] authKeyHash = Utilities.computeSHA1(authKey); + byte[] authKeyId = new byte[8]; + System.arraycopy(authKeyHash, authKeyHash.length - 8, authKeyId, 0, 8); + long fingerprint = Utilities.bytesToLong(authKeyId); + if (encryptedChat.key_fingerprint == fingerprint) { + encryptedChat.auth_key = authKey; + encryptedChat.key_create_date = ConnectionsManager.getInstance().getCurrentTime(); + encryptedChat.seq_in = 0; + encryptedChat.seq_out = 1; + MessagesStorage.getInstance().updateEncryptedChat(encryptedChat); + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + MessagesController.getInstance().putEncryptedChat(encryptedChat, false); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.encryptedChatUpdated, encryptedChat); + sendNotifyLayerMessage(encryptedChat, null); + } + }); + } else { + final TLRPC.TL_encryptedChatDiscarded newChat = new TLRPC.TL_encryptedChatDiscarded(); + newChat.id = encryptedChat.id; + newChat.user_id = encryptedChat.user_id; + newChat.auth_key = encryptedChat.auth_key; + newChat.key_create_date = encryptedChat.key_create_date; + newChat.key_use_count_in = encryptedChat.key_use_count_in; + newChat.key_use_count_out = encryptedChat.key_use_count_out; + newChat.seq_in = encryptedChat.seq_in; + newChat.seq_out = encryptedChat.seq_out; + MessagesStorage.getInstance().updateEncryptedChat(newChat); + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + MessagesController.getInstance().putEncryptedChat(newChat, false); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.encryptedChatUpdated, newChat); + } + }); + declineSecretChat(encryptedChat.id); + } + } + + public void declineSecretChat(int chat_id) { + TLRPC.TL_messages_discardEncryption req = new TLRPC.TL_messages_discardEncryption(); + req.chat_id = chat_id; + ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, TLRPC.TL_error error) { + + } + }); + } + + public void acceptSecretChat(final TLRPC.EncryptedChat encryptedChat) { + if (acceptingChats.get(encryptedChat.id) != null) { + return; + } + acceptingChats.put(encryptedChat.id, encryptedChat); + TLRPC.TL_messages_getDhConfig req = new TLRPC.TL_messages_getDhConfig(); + req.random_length = 256; + req.version = MessagesStorage.lastSecretVersion; + ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, TLRPC.TL_error error) { + if (error == null) { + TLRPC.messages_DhConfig res = (TLRPC.messages_DhConfig) response; + if (response instanceof TLRPC.TL_messages_dhConfig) { + if (!Utilities.isGoodPrime(res.p, res.g)) { + acceptingChats.remove(encryptedChat.id); + declineSecretChat(encryptedChat.id); + return; + } + + MessagesStorage.secretPBytes = res.p; + MessagesStorage.secretG = res.g; + MessagesStorage.lastSecretVersion = res.version; + MessagesStorage.getInstance().saveSecretParams(MessagesStorage.lastSecretVersion, MessagesStorage.secretG, MessagesStorage.secretPBytes); + } + byte[] salt = new byte[256]; + for (int a = 0; a < 256; a++) { + salt[a] = (byte) ((byte) (Utilities.random.nextDouble() * 256) ^ res.random[a]); + } + encryptedChat.a_or_b = salt; + encryptedChat.seq_in = 1; + encryptedChat.seq_out = 0; + BigInteger p = new BigInteger(1, MessagesStorage.secretPBytes); + BigInteger g_b = BigInteger.valueOf(MessagesStorage.secretG); + g_b = g_b.modPow(new BigInteger(1, salt), p); + BigInteger g_a = new BigInteger(1, encryptedChat.g_a); + + if (!Utilities.isGoodGaAndGb(g_a, p)) { + acceptingChats.remove(encryptedChat.id); + declineSecretChat(encryptedChat.id); + return; + } + + byte[] g_b_bytes = g_b.toByteArray(); + if (g_b_bytes.length > 256) { + byte[] correctedAuth = new byte[256]; + System.arraycopy(g_b_bytes, 1, correctedAuth, 0, 256); + g_b_bytes = correctedAuth; + } + + g_a = g_a.modPow(new BigInteger(1, salt), p); + + byte[] authKey = g_a.toByteArray(); + if (authKey.length > 256) { + byte[] correctedAuth = new byte[256]; + System.arraycopy(authKey, authKey.length - 256, correctedAuth, 0, 256); + authKey = correctedAuth; + } else if (authKey.length < 256) { + byte[] correctedAuth = new byte[256]; + System.arraycopy(authKey, 0, correctedAuth, 256 - authKey.length, authKey.length); + for (int a = 0; a < 256 - authKey.length; a++) { + authKey[a] = 0; + } + authKey = correctedAuth; + } + byte[] authKeyHash = Utilities.computeSHA1(authKey); + byte[] authKeyId = new byte[8]; + System.arraycopy(authKeyHash, authKeyHash.length - 8, authKeyId, 0, 8); + encryptedChat.auth_key = authKey; + encryptedChat.key_create_date = ConnectionsManager.getInstance().getCurrentTime(); + + TLRPC.TL_messages_acceptEncryption req2 = new TLRPC.TL_messages_acceptEncryption(); + req2.g_b = g_b_bytes; + req2.peer = new TLRPC.TL_inputEncryptedChat(); + req2.peer.chat_id = encryptedChat.id; + req2.peer.access_hash = encryptedChat.access_hash; + req2.key_fingerprint = Utilities.bytesToLong(authKeyId); + ConnectionsManager.getInstance().performRpc(req2, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, TLRPC.TL_error error) { + acceptingChats.remove(encryptedChat.id); + if (error == null) { + final TLRPC.EncryptedChat newChat = (TLRPC.EncryptedChat) response; + newChat.auth_key = encryptedChat.auth_key; + newChat.user_id = encryptedChat.user_id; + newChat.seq_in = encryptedChat.seq_in; + newChat.seq_out = encryptedChat.seq_out; + newChat.key_create_date = encryptedChat.key_create_date; + newChat.key_use_count_in = encryptedChat.key_use_count_in; + newChat.key_use_count_out = encryptedChat.key_use_count_out; + MessagesStorage.getInstance().updateEncryptedChat(newChat); + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + MessagesController.getInstance().putEncryptedChat(newChat, false); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.encryptedChatUpdated, newChat); + sendNotifyLayerMessage(newChat, null); + } + }); + } + } + }); + } else { + acceptingChats.remove(encryptedChat.id); + } + } + }); + } + + public void startSecretChat(final Context context, final TLRPC.User user) { + if (user == null) { + return; + } + startingSecretChat = true; + final ProgressDialog progressDialog = new ProgressDialog(context); + progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.setCancelable(false); + TLRPC.TL_messages_getDhConfig req = new TLRPC.TL_messages_getDhConfig(); + req.random_length = 256; + req.version = MessagesStorage.lastSecretVersion; + final long reqId = ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, TLRPC.TL_error error) { + if (error == null) { + TLRPC.messages_DhConfig res = (TLRPC.messages_DhConfig) response; + if (response instanceof TLRPC.TL_messages_dhConfig) { + if (!Utilities.isGoodPrime(res.p, res.g)) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + try { + if (!((Activity) context).isFinishing()) { + progressDialog.dismiss(); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + return; + } + MessagesStorage.secretPBytes = res.p; + MessagesStorage.secretG = res.g; + MessagesStorage.lastSecretVersion = res.version; + MessagesStorage.getInstance().saveSecretParams(MessagesStorage.lastSecretVersion, MessagesStorage.secretG, MessagesStorage.secretPBytes); + } + final byte[] salt = new byte[256]; + for (int a = 0; a < 256; a++) { + salt[a] = (byte) ((byte) (Utilities.random.nextDouble() * 256) ^ res.random[a]); + } + + BigInteger i_g_a = BigInteger.valueOf(MessagesStorage.secretG); + i_g_a = i_g_a.modPow(new BigInteger(1, salt), new BigInteger(1, MessagesStorage.secretPBytes)); + byte[] g_a = i_g_a.toByteArray(); + if (g_a.length > 256) { + byte[] correctedAuth = new byte[256]; + System.arraycopy(g_a, 1, correctedAuth, 0, 256); + g_a = correctedAuth; + } + + TLRPC.TL_messages_requestEncryption req2 = new TLRPC.TL_messages_requestEncryption(); + req2.g_a = g_a; + req2.user_id = MessagesController.getInputUser(user); + req2.random_id = Utilities.random.nextInt(); + ConnectionsManager.getInstance().performRpc(req2, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(final TLObject response, TLRPC.TL_error error) { + if (error == null) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + startingSecretChat = false; + if (!((Activity) context).isFinishing()) { + try { + progressDialog.dismiss(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + TLRPC.EncryptedChat chat = (TLRPC.EncryptedChat) response; + chat.user_id = chat.participant_id; + chat.seq_in = 0; + chat.seq_out = 1; + chat.a_or_b = salt; + MessagesController.getInstance().putEncryptedChat(chat, false); + TLRPC.TL_dialog dialog = new TLRPC.TL_dialog(); + dialog.id = ((long) chat.id) << 32; + dialog.unread_count = 0; + dialog.top_message = 0; + dialog.last_message_date = ConnectionsManager.getInstance().getCurrentTime(); + MessagesController.getInstance().dialogs_dict.put(dialog.id, dialog); + MessagesController.getInstance().dialogs.add(dialog); + Collections.sort(MessagesController.getInstance().dialogs, new Comparator() { + @Override + public int compare(TLRPC.TL_dialog tl_dialog, TLRPC.TL_dialog tl_dialog2) { + if (tl_dialog.last_message_date == tl_dialog2.last_message_date) { + return 0; + } else if (tl_dialog.last_message_date < tl_dialog2.last_message_date) { + return 1; + } else { + return -1; + } + } + }); + MessagesStorage.getInstance().putEncryptedChat(chat, user, dialog); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.encryptedChatCreated, chat); + Utilities.stageQueue.postRunnable(new Runnable() { + @Override + public void run() { + if (!delayedEncryptedChatUpdates.isEmpty()) { + MessagesController.getInstance().processUpdateArray(delayedEncryptedChatUpdates, null, null); + delayedEncryptedChatUpdates.clear(); + } + } + }); + } + }); + } else { + delayedEncryptedChatUpdates.clear(); + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (!((Activity) context).isFinishing()) { + startingSecretChat = false; + try { + progressDialog.dismiss(); + } catch (Exception e) { + FileLog.e("tmessages", 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); + } + } + }); + } + } + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors); + } else { + delayedEncryptedChatUpdates.clear(); + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + startingSecretChat = false; + if (!((Activity) context).isFinishing()) { + try { + progressDialog.dismiss(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + } + }); + } + } + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors); + progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, LocaleController.getString("Cancel", R.string.Cancel), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + ConnectionsManager.getInstance().cancelRpc(reqId, true); + try { + dialog.dismiss(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + progressDialog.show(); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java b/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java index 8b9f37d86..e57717104 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java @@ -18,19 +18,16 @@ import android.provider.MediaStore; import android.webkit.MimeTypeMap; import android.widget.Toast; -import org.telegram.messenger.BuffersStorage; -import org.telegram.messenger.ByteBufferDesc; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; -import org.telegram.messenger.MessageKeyData; import org.telegram.messenger.R; import org.telegram.messenger.RPCRequest; import org.telegram.messenger.TLObject; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; -import org.telegram.ui.ApplicationLoader; +import org.telegram.messenger.ApplicationLoader; import java.io.File; import java.util.ArrayList; @@ -38,12 +35,9 @@ import java.util.HashMap; public class SendMessagesHelper implements NotificationCenter.NotificationCenterDelegate { - public static final int CURRENT_SECRET_CHAT_LAYER = 17; - private TLRPC.ChatParticipants currentChatInfo = null; private HashMap> delayedMessages = new HashMap>(); private HashMap unsentMessages = new HashMap(); - private ArrayList sendingNotifyLayer = new ArrayList(); private class DelayedMessage { public TLObject sendRequest; @@ -82,7 +76,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter public void cleanUp() { delayedMessages.clear(); - sendingNotifyLayer.clear(); unsentMessages.clear(); currentChatInfo = null; } @@ -149,7 +142,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter } else if (encryptedFile != null && message.sendEncryptedRequest != null) { message.sendEncryptedRequest.media.key = encryptedFile.key; message.sendEncryptedRequest.media.iv = encryptedFile.iv; - performSendEncryptedRequest(message.sendEncryptedRequest, message.obj.messageOwner, message.encryptedChat, encryptedFile, message.originalPath); + SecretChatHelper.getInstance().performSendEncryptedRequest(message.sendEncryptedRequest, message.obj.messageOwner, message.encryptedChat, encryptedFile, message.originalPath); arr.remove(a); a--; } @@ -301,17 +294,17 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter return false; } if (messageObject.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) { - sendTTLMessage(encryptedChat, messageObject.messageOwner); + SecretChatHelper.getInstance().sendTTLMessage(encryptedChat, messageObject.messageOwner); } else if (messageObject.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionDeleteMessages) { - sendMessagesDeleteMessage(encryptedChat, null, messageObject.messageOwner); + SecretChatHelper.getInstance().sendMessagesDeleteMessage(encryptedChat, null, messageObject.messageOwner); } else if (messageObject.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionFlushHistory) { - sendClearHistoryMessage(encryptedChat, messageObject.messageOwner); + SecretChatHelper.getInstance().sendClearHistoryMessage(encryptedChat, messageObject.messageOwner); } else if (messageObject.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionNotifyLayer) { - sendNotifyLayerMessage(encryptedChat, messageObject.messageOwner); + SecretChatHelper.getInstance().sendNotifyLayerMessage(encryptedChat, messageObject.messageOwner); } else if (messageObject.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionReadMessages) { - sendMessagesReadMessage(encryptedChat, null, messageObject.messageOwner); + SecretChatHelper.getInstance().sendMessagesReadMessage(encryptedChat, null, messageObject.messageOwner); } else if (messageObject.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages) { - sendScreenshotMessage(encryptedChat, null, messageObject.messageOwner); + SecretChatHelper.getInstance().sendScreenshotMessage(encryptedChat, null, messageObject.messageOwner); } else if (messageObject.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionTyping) { } else if (messageObject.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionResend) { @@ -326,7 +319,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter return true; } - public void processSentMessage(int id) { + protected void processSentMessage(int id) { int prevSize = unsentMessages.size(); unsentMessages.remove(id); if (prevSize != 0 && unsentMessages.size() == 0) { @@ -677,7 +670,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter reqSend.random_id = newMsg.random_id; reqSend.message = message; reqSend.media = new TLRPC.TL_decryptedMessageMediaEmpty(); - performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, null, null); + SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, null, null); } } else if (type >= 1 && type <= 3 || type >= 5 && type <= 8) { if (encryptedChat == null) { @@ -838,7 +831,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter reqSend.media = new TLRPC.TL_decryptedMessageMediaGeoPoint(); reqSend.media.lat = lat; reqSend.media._long = lon; - performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, null, null); + SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, null, null); } else if (type == 2) { TLRPC.PhotoSize small = photo.sizes.get(0); TLRPC.PhotoSize big = photo.sizes.get(photo.sizes.size() - 1); @@ -864,7 +857,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter encryptedFile.access_hash = big.location.secret; reqSend.media.key = big.location.key; reqSend.media.iv = big.location.iv; - performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, encryptedFile, null); + SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, encryptedFile, null); } } else if (type == 3) { if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { @@ -895,7 +888,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter encryptedFile.access_hash = video.access_hash; reqSend.media.key = video.key; reqSend.media.iv = video.iv; - performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, encryptedFile, null); + SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, encryptedFile, null); } } else if (type == 6) { reqSend.media = new TLRPC.TL_decryptedMessageMediaContact(); @@ -903,7 +896,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter reqSend.media.first_name = user.first_name; reqSend.media.last_name = user.last_name; reqSend.media.user_id = user.id; - performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, null, null); + SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, null, null); } else if (type == 7) { reqSend.media = new TLRPC.TL_decryptedMessageMediaDocument(); reqSend.media.size = document.size; @@ -933,7 +926,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter encryptedFile.access_hash = document.access_hash; reqSend.media.key = document.key; reqSend.media.iv = document.iv; - performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, encryptedFile, null); + SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, encryptedFile, null); } } else if (type == 8) { if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { @@ -1065,7 +1058,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter } } - private void stopVideoService(final String path) { + protected void stopVideoService(final String path) { MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { @@ -1098,7 +1091,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter TLRPC.messages_StatedMessage res = (TLRPC.messages_StatedMessage) response; sentMessages.add(res.message); newMsgObj.id = res.message.id; - processSentMessage(newMsgObj, res.message, null, null, originalPath); + processSentMessage(newMsgObj, res.message, originalPath); MessagesController.getInstance().processNewDifferenceParams(res.seq, res.pts, res.message.date); } else if (response instanceof TLRPC.messages_StatedMessages) { TLRPC.messages_StatedMessages res = (TLRPC.messages_StatedMessages) response; @@ -1108,7 +1101,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter if (!isBroadcast) { newMsgObj.id = message.id; } - processSentMessage(newMsgObj, message, null, null, originalPath); + processSentMessage(newMsgObj, message, originalPath); } MessagesController.getInstance().processNewDifferenceParams(res.seq, res.pts, -1); } @@ -1175,621 +1168,125 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter }), true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassCanCompress, ConnectionsManager.DEFAULT_DATACENTER_ID); } - private void performSendEncryptedRequest(final TLRPC.DecryptedMessage req, final TLRPC.Message newMsgObj, final TLRPC.EncryptedChat chat, final TLRPC.InputEncryptedFile encryptedFile, final String originalPath) { - if (req == null || chat.auth_key == null || chat instanceof TLRPC.TL_encryptedChatRequested || chat instanceof TLRPC.TL_encryptedChatWaiting) { + private void processSentMessage(TLRPC.Message newMsg, TLRPC.Message sentMessage, String originalPath) { + if (sentMessage == null) { return; } - Utilities.stageQueue.postRunnable(new Runnable() { - @Override - public void run() { - TLObject toEncryptObject = null; - if (AndroidUtilities.getPeerLayerVersion(chat.layer) >= 17) { - TLRPC.TL_decryptedMessageLayer layer = new TLRPC.TL_decryptedMessageLayer(); - layer.layer = CURRENT_SECRET_CHAT_LAYER; - layer.message = req; - layer.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; - Utilities.random.nextBytes(layer.random_bytes); - toEncryptObject = layer; + if (sentMessage.media instanceof TLRPC.TL_messageMediaPhoto && sentMessage.media.photo != null && newMsg.media instanceof TLRPC.TL_messageMediaPhoto && newMsg.media.photo != null) { + MessagesStorage.getInstance().putSentFile(originalPath, sentMessage.media.photo, 0); - if (chat.seq_in == 0 && chat.seq_out == 0) { - if (chat.admin_id == UserConfig.getClientUserId()) { - chat.seq_out = 1; - } else { - chat.seq_in = 1; - } - } - - if (newMsgObj.seq_in == 0 && newMsgObj.seq_out == 0) { - layer.in_seq_no = chat.seq_in; - layer.out_seq_no = chat.seq_out; - chat.seq_out += 2; - MessagesStorage.getInstance().updateEncryptedChatSeq(chat); - if (newMsgObj != null) { - newMsgObj.seq_in = layer.in_seq_no; - newMsgObj.seq_out = layer.out_seq_no; - MessagesStorage.getInstance().setMessageSeq(newMsgObj.id, newMsgObj.seq_in, newMsgObj.seq_out); - } - } else { - layer.in_seq_no = newMsgObj.seq_in; - layer.out_seq_no = newMsgObj.seq_out; - } - } else { - toEncryptObject = req; + for (TLRPC.PhotoSize size : sentMessage.media.photo.sizes) { + if (size instanceof TLRPC.TL_photoSizeEmpty) { + continue; } - - int len = toEncryptObject.getObjectSize(); - ByteBufferDesc toEncrypt = BuffersStorage.getInstance().getFreeBuffer(4 + len); - toEncrypt.writeInt32(len); - toEncryptObject.serializeToStream(toEncrypt); - - byte[] messageKeyFull = Utilities.computeSHA1(toEncrypt.buffer); - byte[] messageKey = new byte[16]; - System.arraycopy(messageKeyFull, messageKeyFull.length - 16, messageKey, 0, 16); - - MessageKeyData keyData = Utilities.generateMessageKeyData(chat.auth_key, messageKey, false); - - len = toEncrypt.length(); - int extraLen = len % 16 != 0 ? 16 - len % 16 : 0; - ByteBufferDesc dataForEncryption = BuffersStorage.getInstance().getFreeBuffer(len + extraLen); - toEncrypt.position(0); - dataForEncryption.writeRaw(toEncrypt); - if (extraLen != 0) { - byte[] b = new byte[extraLen]; - Utilities.random.nextBytes(b); - dataForEncryption.writeRaw(b); - } - BuffersStorage.getInstance().reuseFreeBuffer(toEncrypt); - - Utilities.aesIgeEncryption(dataForEncryption.buffer, keyData.aesKey, keyData.aesIv, true, false, 0, dataForEncryption.limit()); - - ByteBufferDesc data = BuffersStorage.getInstance().getFreeBuffer(8 + messageKey.length + dataForEncryption.length()); - dataForEncryption.position(0); - data.writeInt64(chat.key_fingerprint); - data.writeRaw(messageKey); - data.writeRaw(dataForEncryption); - BuffersStorage.getInstance().reuseFreeBuffer(dataForEncryption); - data.position(0); - - TLObject reqToSend = null; - - if (encryptedFile == null) { - if (req instanceof TLRPC.TL_decryptedMessageService) { - TLRPC.TL_messages_sendEncryptedService req2 = new TLRPC.TL_messages_sendEncryptedService(); - req2.data = data; - req2.random_id = req.random_id; - req2.peer = new TLRPC.TL_inputEncryptedChat(); - req2.peer.chat_id = chat.id; - req2.peer.access_hash = chat.access_hash; - reqToSend = req2; - } else { - TLRPC.TL_messages_sendEncrypted req2 = new TLRPC.TL_messages_sendEncrypted(); - req2.data = data; - req2.random_id = req.random_id; - req2.peer = new TLRPC.TL_inputEncryptedChat(); - req2.peer.chat_id = chat.id; - req2.peer.access_hash = chat.access_hash; - reqToSend = req2; - } - } else { - TLRPC.TL_messages_sendEncryptedFile req2 = new TLRPC.TL_messages_sendEncryptedFile(); - req2.data = data; - req2.random_id = req.random_id; - req2.peer = new TLRPC.TL_inputEncryptedChat(); - req2.peer.chat_id = chat.id; - req2.peer.access_hash = chat.access_hash; - req2.file = encryptedFile; - reqToSend = req2; - } - ConnectionsManager.getInstance().performRpc(reqToSend, new RPCRequest.RPCRequestDelegate() { - @Override - public void run(TLObject response, TLRPC.TL_error error) { - if (error == null) { - if (req.action instanceof TLRPC.TL_decryptedMessageActionNotifyLayer) { - TLRPC.EncryptedChat currentChat = MessagesController.getInstance().getEncryptedChat(chat.id); - sendingNotifyLayer.remove((Integer)currentChat.id); - currentChat.layer = AndroidUtilities.setMyLayerVersion(currentChat.layer, CURRENT_SECRET_CHAT_LAYER); - MessagesStorage.getInstance().updateEncryptedChatLayer(currentChat); - } - } - if (newMsgObj != null) { - if (error == null) { - final String attachPath = newMsgObj.attachPath; - final TLRPC.messages_SentEncryptedMessage res = (TLRPC.messages_SentEncryptedMessage) response; - if (newMsgObj.action instanceof TLRPC.TL_messageEncryptedAction) { - if (newMsgObj.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages || newMsgObj.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) { - newMsgObj.date = res.date; - } - } - if (res.file instanceof TLRPC.TL_encryptedFile) { - processSentMessage(newMsgObj, null, res.file, req, originalPath); - } - MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { - @Override - public void run() { - if (newMsgObj.action instanceof TLRPC.TL_messageEncryptedAction) { - if (!(newMsgObj.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages || newMsgObj.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL)) { - res.date = 0; - } - } - MessagesStorage.getInstance().updateMessageStateAndId(newMsgObj.random_id, newMsgObj.id, newMsgObj.id, res.date, false); - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - newMsgObj.send_state = MessageObject.MESSAGE_SEND_STATE_SENT; - NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, newMsgObj.id, newMsgObj.id, newMsgObj); - processSentMessage(newMsgObj.id); - if (newMsgObj.media instanceof TLRPC.TL_messageMediaVideo) { - stopVideoService(attachPath); - } - } - }); - } - }); - } else { - MessagesStorage.getInstance().markMessageAsSendError(newMsgObj.id); - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - newMsgObj.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR; - NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, newMsgObj.id); - processSentMessage(newMsgObj.id); - if (newMsgObj.media instanceof TLRPC.TL_messageMediaVideo) { - stopVideoService(newMsgObj.attachPath); - } - } - }); - } - } - } - }); - } - }); - } - - private void processSentMessage(TLRPC.Message newMsg, TLRPC.Message sentMessage, TLRPC.EncryptedFile file, TLRPC.DecryptedMessage decryptedMessage, String originalPath) { - if (sentMessage != null) { - if (sentMessage.media instanceof TLRPC.TL_messageMediaPhoto && sentMessage.media.photo != null && newMsg.media instanceof TLRPC.TL_messageMediaPhoto && newMsg.media.photo != null) { - MessagesStorage.getInstance().putSentFile(originalPath, sentMessage.media.photo, 0); - - for (TLRPC.PhotoSize size : sentMessage.media.photo.sizes) { - if (size instanceof TLRPC.TL_photoSizeEmpty) { - continue; - } - for (TLRPC.PhotoSize size2 : newMsg.media.photo.sizes) { - if (size.type.equals(size2.type)) { - String fileName = size2.location.volume_id + "_" + size2.location.local_id; - String fileName2 = size.location.volume_id + "_" + size.location.local_id; - if (fileName.equals(fileName2)) { - break; - } - File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName + ".jpg"); - File cacheFile2 = null; - if (sentMessage.media.photo.sizes.size() == 1 || size.w > 80 || size.h > 80) { - cacheFile2 = FileLoader.getPathToAttach(size); - } else { - cacheFile2 = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName2 + ".jpg"); - } - cacheFile.renameTo(cacheFile2); - ImageLoader.getInstance().replaceImageInCache(fileName, fileName2); - size2.location = size.location; + for (TLRPC.PhotoSize size2 : newMsg.media.photo.sizes) { + if (size.type.equals(size2.type)) { + String fileName = size2.location.volume_id + "_" + size2.location.local_id; + String fileName2 = size.location.volume_id + "_" + size.location.local_id; + if (fileName.equals(fileName2)) { break; } - } - } - sentMessage.message = newMsg.message; - sentMessage.attachPath = newMsg.attachPath; - newMsg.media.photo.id = sentMessage.media.photo.id; - newMsg.media.photo.access_hash = sentMessage.media.photo.access_hash; - } else if (sentMessage.media instanceof TLRPC.TL_messageMediaVideo && sentMessage.media.video != null && newMsg.media instanceof TLRPC.TL_messageMediaVideo && newMsg.media.video != null) { - MessagesStorage.getInstance().putSentFile(originalPath, sentMessage.media.video, 2); - - TLRPC.PhotoSize size2 = newMsg.media.video.thumb; - TLRPC.PhotoSize size = sentMessage.media.video.thumb; - if (size2.location != null && size.location != null && !(size instanceof TLRPC.TL_photoSizeEmpty) && !(size2 instanceof TLRPC.TL_photoSizeEmpty)) { - String fileName = size2.location.volume_id + "_" + size2.location.local_id; - String fileName2 = size.location.volume_id + "_" + size.location.local_id; - if (!fileName.equals(fileName2)) { File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName + ".jpg"); - File cacheFile2 = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName2 + ".jpg"); + File cacheFile2 = null; + if (sentMessage.media.photo.sizes.size() == 1 || size.w > 80 || size.h > 80) { + cacheFile2 = FileLoader.getPathToAttach(size); + } else { + cacheFile2 = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName2 + ".jpg"); + } cacheFile.renameTo(cacheFile2); ImageLoader.getInstance().replaceImageInCache(fileName, fileName2); size2.location = size.location; + break; } } + } + sentMessage.message = newMsg.message; + sentMessage.attachPath = newMsg.attachPath; + newMsg.media.photo.id = sentMessage.media.photo.id; + newMsg.media.photo.access_hash = sentMessage.media.photo.access_hash; + } else if (sentMessage.media instanceof TLRPC.TL_messageMediaVideo && sentMessage.media.video != null && newMsg.media instanceof TLRPC.TL_messageMediaVideo && newMsg.media.video != null) { + MessagesStorage.getInstance().putSentFile(originalPath, sentMessage.media.video, 2); - sentMessage.message = newMsg.message; - newMsg.media.video.dc_id = sentMessage.media.video.dc_id; - newMsg.media.video.id = sentMessage.media.video.id; - newMsg.media.video.access_hash = sentMessage.media.video.access_hash; + TLRPC.PhotoSize size2 = newMsg.media.video.thumb; + TLRPC.PhotoSize size = sentMessage.media.video.thumb; + if (size2.location != null && size.location != null && !(size instanceof TLRPC.TL_photoSizeEmpty) && !(size2 instanceof TLRPC.TL_photoSizeEmpty)) { + String fileName = size2.location.volume_id + "_" + size2.location.local_id; + String fileName2 = size.location.volume_id + "_" + size.location.local_id; + if (!fileName.equals(fileName2)) { + File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName + ".jpg"); + File cacheFile2 = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName2 + ".jpg"); + cacheFile.renameTo(cacheFile2); + ImageLoader.getInstance().replaceImageInCache(fileName, fileName2); + size2.location = size.location; + } + } - if (newMsg.attachPath != null && newMsg.attachPath.startsWith(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE).getAbsolutePath())) { - File cacheFile = new File(newMsg.attachPath); - File cacheFile2 = FileLoader.getPathToAttach(newMsg.media.video); - if (!cacheFile.renameTo(cacheFile2)) { - sentMessage.attachPath = newMsg.attachPath; - } - } else { + sentMessage.message = newMsg.message; + newMsg.media.video.dc_id = sentMessage.media.video.dc_id; + newMsg.media.video.id = sentMessage.media.video.id; + newMsg.media.video.access_hash = sentMessage.media.video.access_hash; + + if (newMsg.attachPath != null && newMsg.attachPath.startsWith(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE).getAbsolutePath())) { + File cacheFile = new File(newMsg.attachPath); + File cacheFile2 = FileLoader.getPathToAttach(newMsg.media.video); + if (!cacheFile.renameTo(cacheFile2)) { sentMessage.attachPath = newMsg.attachPath; } - } else if (sentMessage.media instanceof TLRPC.TL_messageMediaDocument && sentMessage.media.document != null && newMsg.media instanceof TLRPC.TL_messageMediaDocument && newMsg.media.document != null) { - MessagesStorage.getInstance().putSentFile(originalPath, sentMessage.media.document, 1); + } else { + sentMessage.attachPath = newMsg.attachPath; + } + } else if (sentMessage.media instanceof TLRPC.TL_messageMediaDocument && sentMessage.media.document != null && newMsg.media instanceof TLRPC.TL_messageMediaDocument && newMsg.media.document != null) { + MessagesStorage.getInstance().putSentFile(originalPath, sentMessage.media.document, 1); - TLRPC.PhotoSize size2 = newMsg.media.document.thumb; - TLRPC.PhotoSize size = sentMessage.media.document.thumb; - if (size2.location != null && size.location != null && !(size instanceof TLRPC.TL_photoSizeEmpty) && !(size2 instanceof TLRPC.TL_photoSizeEmpty)) { - String fileName = size2.location.volume_id + "_" + size2.location.local_id; - String fileName2 = size.location.volume_id + "_" + size.location.local_id; - if (!fileName.equals(fileName2)) { - File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName + ".jpg"); - File cacheFile2 = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName2 + ".jpg"); - cacheFile.renameTo(cacheFile2); - ImageLoader.getInstance().replaceImageInCache(fileName, fileName2); - size2.location = size.location; - } + TLRPC.PhotoSize size2 = newMsg.media.document.thumb; + TLRPC.PhotoSize size = sentMessage.media.document.thumb; + if (size2.location != null && size.location != null && !(size instanceof TLRPC.TL_photoSizeEmpty) && !(size2 instanceof TLRPC.TL_photoSizeEmpty)) { + String fileName = size2.location.volume_id + "_" + size2.location.local_id; + String fileName2 = size.location.volume_id + "_" + size.location.local_id; + if (!fileName.equals(fileName2)) { + File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName + ".jpg"); + File cacheFile2 = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName2 + ".jpg"); + cacheFile.renameTo(cacheFile2); + ImageLoader.getInstance().replaceImageInCache(fileName, fileName2); + size2.location = size.location; } + } - newMsg.media.document.dc_id = sentMessage.media.document.dc_id; - newMsg.media.document.id = sentMessage.media.document.id; - newMsg.media.document.access_hash = sentMessage.media.document.access_hash; + newMsg.media.document.dc_id = sentMessage.media.document.dc_id; + newMsg.media.document.id = sentMessage.media.document.id; + newMsg.media.document.access_hash = sentMessage.media.document.access_hash; - if (newMsg.attachPath != null && newMsg.attachPath.startsWith(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE).getAbsolutePath())) { - File cacheFile = new File(newMsg.attachPath); - File cacheFile2 = FileLoader.getPathToAttach(sentMessage.media.document); - if (!cacheFile.renameTo(cacheFile2)) { - sentMessage.attachPath = newMsg.attachPath; - sentMessage.message = newMsg.message; - } else { - newMsg.attachPath = ""; - } - } else { + if (newMsg.attachPath != null && newMsg.attachPath.startsWith(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE).getAbsolutePath())) { + File cacheFile = new File(newMsg.attachPath); + File cacheFile2 = FileLoader.getPathToAttach(sentMessage.media.document); + if (!cacheFile.renameTo(cacheFile2)) { sentMessage.attachPath = newMsg.attachPath; sentMessage.message = newMsg.message; + } else { + newMsg.attachPath = ""; } - } else if (sentMessage.media instanceof TLRPC.TL_messageMediaAudio && sentMessage.media.audio != null && newMsg.media instanceof TLRPC.TL_messageMediaAudio && newMsg.media.audio != null) { + } else { + sentMessage.attachPath = newMsg.attachPath; sentMessage.message = newMsg.message; + } + } else if (sentMessage.media instanceof TLRPC.TL_messageMediaAudio && sentMessage.media.audio != null && newMsg.media instanceof TLRPC.TL_messageMediaAudio && newMsg.media.audio != null) { + sentMessage.message = newMsg.message; - String fileName = newMsg.media.audio.dc_id + "_" + newMsg.media.audio.id + ".ogg"; - newMsg.media.audio.dc_id = sentMessage.media.audio.dc_id; - newMsg.media.audio.id = sentMessage.media.audio.id; - newMsg.media.audio.access_hash = sentMessage.media.audio.access_hash; - String fileName2 = sentMessage.media.audio.dc_id + "_" + sentMessage.media.audio.id + ".ogg"; - if (!fileName.equals(fileName2)) { - File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName); - File cacheFile2 = FileLoader.getPathToAttach(sentMessage.media.audio); - if (!cacheFile.renameTo(cacheFile2)) { - sentMessage.attachPath = newMsg.attachPath; - } + String fileName = newMsg.media.audio.dc_id + "_" + newMsg.media.audio.id + ".ogg"; + newMsg.media.audio.dc_id = sentMessage.media.audio.dc_id; + newMsg.media.audio.id = sentMessage.media.audio.id; + newMsg.media.audio.access_hash = sentMessage.media.audio.access_hash; + String fileName2 = sentMessage.media.audio.dc_id + "_" + sentMessage.media.audio.id + ".ogg"; + if (!fileName.equals(fileName2)) { + File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName); + File cacheFile2 = FileLoader.getPathToAttach(sentMessage.media.audio); + if (!cacheFile.renameTo(cacheFile2)) { + sentMessage.attachPath = newMsg.attachPath; } } - } else if (file != null) { - if (newMsg.media instanceof TLRPC.TL_messageMediaPhoto && newMsg.media.photo != null) { - TLRPC.PhotoSize size = newMsg.media.photo.sizes.get(newMsg.media.photo.sizes.size() - 1); - String fileName = size.location.volume_id + "_" + size.location.local_id; - size.location = new TLRPC.TL_fileEncryptedLocation(); - size.location.key = decryptedMessage.media.key; - size.location.iv = decryptedMessage.media.iv; - size.location.dc_id = file.dc_id; - size.location.volume_id = file.id; - size.location.secret = file.access_hash; - size.location.local_id = file.key_fingerprint; - String fileName2 = size.location.volume_id + "_" + size.location.local_id; - File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName + ".jpg"); - File cacheFile2 = FileLoader.getPathToAttach(size); - cacheFile.renameTo(cacheFile2); - ImageLoader.getInstance().replaceImageInCache(fileName, fileName2); - ArrayList arr = new ArrayList(); - arr.add(newMsg); - MessagesStorage.getInstance().putMessages(arr, false, true, false, 0); - - MessagesStorage.getInstance().putSentFile(originalPath, newMsg.media.photo, 3); - } else if (newMsg.media instanceof TLRPC.TL_messageMediaVideo && newMsg.media.video != null) { - TLRPC.Video video = newMsg.media.video; - newMsg.media.video = new TLRPC.TL_videoEncrypted(); - newMsg.media.video.duration = video.duration; - newMsg.media.video.thumb = video.thumb; - newMsg.media.video.dc_id = file.dc_id; - newMsg.media.video.w = video.w; - newMsg.media.video.h = video.h; - newMsg.media.video.date = video.date; - newMsg.media.video.caption = ""; - newMsg.media.video.user_id = video.user_id; - newMsg.media.video.size = file.size; - newMsg.media.video.id = file.id; - newMsg.media.video.access_hash = file.access_hash; - newMsg.media.video.key = decryptedMessage.media.key; - newMsg.media.video.iv = decryptedMessage.media.iv; - newMsg.media.video.mime_type = video.mime_type; - - if (newMsg.attachPath != null && newMsg.attachPath.startsWith(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE).getAbsolutePath())) { - File cacheFile = new File(newMsg.attachPath); - File cacheFile2 = FileLoader.getPathToAttach(newMsg.media.video); - if (cacheFile.renameTo(cacheFile2)) { - newMsg.attachPath = ""; - } - } - - ArrayList arr = new ArrayList(); - arr.add(newMsg); - MessagesStorage.getInstance().putMessages(arr, false, true, false, 0); - - MessagesStorage.getInstance().putSentFile(originalPath, newMsg.media.video, 5); - } else if (newMsg.media instanceof TLRPC.TL_messageMediaDocument && newMsg.media.document != null) { - TLRPC.Document document = newMsg.media.document; - newMsg.media.document = new TLRPC.TL_documentEncrypted(); - newMsg.media.document.id = file.id; - newMsg.media.document.access_hash = file.access_hash; - newMsg.media.document.user_id = document.user_id; - newMsg.media.document.date = document.date; - newMsg.media.document.file_name = document.file_name; - newMsg.media.document.mime_type = document.mime_type; - newMsg.media.document.size = file.size; - newMsg.media.document.key = decryptedMessage.media.key; - newMsg.media.document.iv = decryptedMessage.media.iv; - newMsg.media.document.thumb = document.thumb; - newMsg.media.document.dc_id = file.dc_id; - - if (newMsg.attachPath != null && newMsg.attachPath.startsWith(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE).getAbsolutePath())) { - File cacheFile = new File(newMsg.attachPath); - File cacheFile2 = FileLoader.getPathToAttach(newMsg.media.document); - if (cacheFile.renameTo(cacheFile2)) { - newMsg.attachPath = ""; - } - } - - ArrayList arr = new ArrayList(); - arr.add(newMsg); - MessagesStorage.getInstance().putMessages(arr, false, true, false, 0); - - MessagesStorage.getInstance().putSentFile(originalPath, newMsg.media.document, 4); - } else if (newMsg.media instanceof TLRPC.TL_messageMediaAudio && newMsg.media.audio != null) { - TLRPC.Audio audio = newMsg.media.audio; - newMsg.media.audio = new TLRPC.TL_audioEncrypted(); - newMsg.media.audio.id = file.id; - newMsg.media.audio.access_hash = file.access_hash; - newMsg.media.audio.user_id = audio.user_id; - newMsg.media.audio.date = audio.date; - newMsg.media.audio.duration = audio.duration; - newMsg.media.audio.size = file.size; - newMsg.media.audio.dc_id = file.dc_id; - newMsg.media.audio.key = decryptedMessage.media.key; - newMsg.media.audio.iv = decryptedMessage.media.iv; - newMsg.media.audio.mime_type = audio.mime_type; - - String fileName = audio.dc_id + "_" + audio.id + ".ogg"; - String fileName2 = newMsg.media.audio.dc_id + "_" + newMsg.media.audio.id + ".ogg"; - if (!fileName.equals(fileName2)) { - File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName); - File cacheFile2 = FileLoader.getPathToAttach(newMsg.media.audio); - if (cacheFile.renameTo(cacheFile2)) { - newMsg.attachPath = ""; - } - } - - ArrayList arr = new ArrayList(); - arr.add(newMsg); - MessagesStorage.getInstance().putMessages(arr, false, true, false, 0); - } } } - private TLRPC.TL_messageService createServiceSecretMessage(final TLRPC.EncryptedChat encryptedChat, TLRPC.DecryptedMessageAction decryptedMessage) { - TLRPC.TL_messageService newMsg = new TLRPC.TL_messageService(); - - newMsg.action = new TLRPC.TL_messageEncryptedAction(); - newMsg.action.encryptedAction = decryptedMessage; - newMsg.local_id = newMsg.id = UserConfig.getNewMessageId(); - newMsg.from_id = UserConfig.getClientUserId(); - newMsg.flags = TLRPC.MESSAGE_FLAG_UNREAD | TLRPC.MESSAGE_FLAG_OUT; - newMsg.dialog_id = ((long)encryptedChat.id) << 32; - newMsg.to_id = new TLRPC.TL_peerUser(); - newMsg.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING; - if (encryptedChat.participant_id == UserConfig.getClientUserId()) { - newMsg.to_id.user_id = encryptedChat.admin_id; - } else { - newMsg.to_id.user_id = encryptedChat.participant_id; - } - if (decryptedMessage instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages || decryptedMessage instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) { - newMsg.date = ConnectionsManager.getInstance().getCurrentTime(); - } else { - newMsg.date = 0; - } - newMsg.random_id = getNextRandomId(); - UserConfig.saveConfig(false); - - ArrayList arr = new ArrayList(); - arr.add(newMsg); - MessagesStorage.getInstance().putMessages(arr, false, true, true, 0); - - return newMsg; - } - - public void sendMessagesReadMessage(TLRPC.EncryptedChat encryptedChat, ArrayList random_ids, TLRPC.Message resendMessage) { - if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) { - return; - } - TLRPC.TL_decryptedMessageService reqSend = null; - if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { - reqSend = new TLRPC.TL_decryptedMessageService(); - } else { - reqSend = new TLRPC.TL_decryptedMessageService_old(); - reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; - Utilities.random.nextBytes(reqSend.random_bytes); - } - - TLRPC.Message message = null; - - if (resendMessage != null) { - message = resendMessage; - reqSend.action = message.action.encryptedAction; - } else { - reqSend.action = new TLRPC.TL_decryptedMessageActionReadMessages(); - reqSend.action.random_ids = random_ids; - message = createServiceSecretMessage(encryptedChat, reqSend.action); - } - reqSend.random_id = message.random_id; - - performSendEncryptedRequest(reqSend, message, encryptedChat, null, null); - } - - public void sendMessagesDeleteMessage(TLRPC.EncryptedChat encryptedChat, ArrayList random_ids, TLRPC.Message resendMessage) { - if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) { - return; - } - TLRPC.TL_decryptedMessageService reqSend = null; - if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { - reqSend = new TLRPC.TL_decryptedMessageService(); - } else { - reqSend = new TLRPC.TL_decryptedMessageService_old(); - reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; - Utilities.random.nextBytes(reqSend.random_bytes); - } - - TLRPC.Message message = null; - - if (resendMessage != null) { - message = resendMessage; - reqSend.action = message.action.encryptedAction; - } else { - reqSend.action = new TLRPC.TL_decryptedMessageActionDeleteMessages(); - reqSend.action.random_ids = random_ids; - message = createServiceSecretMessage(encryptedChat, reqSend.action); - } - reqSend.random_id = message.random_id; - - performSendEncryptedRequest(reqSend, message, encryptedChat, null, null); - } - - public void sendClearHistoryMessage(TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) { - if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) { - return; - } - TLRPC.TL_decryptedMessageService reqSend = null; - if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { - reqSend = new TLRPC.TL_decryptedMessageService(); - } else { - reqSend = new TLRPC.TL_decryptedMessageService_old(); - reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; - Utilities.random.nextBytes(reqSend.random_bytes); - } - - TLRPC.Message message = null; - - if (resendMessage != null) { - message = resendMessage; - reqSend.action = message.action.encryptedAction; - } else { - reqSend.action = new TLRPC.TL_decryptedMessageActionFlushHistory(); - message = createServiceSecretMessage(encryptedChat, reqSend.action); - } - reqSend.random_id = message.random_id; - - performSendEncryptedRequest(reqSend, message, encryptedChat, null, null); - } - - public void sendNotifyLayerMessage(final TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) { - if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) { - return; - } - if (sendingNotifyLayer.contains(encryptedChat.id)) { - return; - } - sendingNotifyLayer.add(encryptedChat.id); - TLRPC.TL_decryptedMessageService reqSend = null; - if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { - reqSend = new TLRPC.TL_decryptedMessageService(); - } else { - reqSend = new TLRPC.TL_decryptedMessageService_old(); - reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; - Utilities.random.nextBytes(reqSend.random_bytes); - } - - TLRPC.Message message = null; - - if (resendMessage != null) { - message = resendMessage; - reqSend.action = message.action.encryptedAction; - } else { - reqSend.action = new TLRPC.TL_decryptedMessageActionNotifyLayer(); - reqSend.action.layer = CURRENT_SECRET_CHAT_LAYER; - message = createServiceSecretMessage(encryptedChat, reqSend.action); - } - reqSend.random_id = message.random_id; - - performSendEncryptedRequest(reqSend, message, encryptedChat, null, null); - } - - public void sendTTLMessage(TLRPC.EncryptedChat encryptedChat, TLRPC.Message resendMessage) { - if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) { - return; - } - - TLRPC.TL_decryptedMessageService reqSend = null; - if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { - reqSend = new TLRPC.TL_decryptedMessageService(); - } else { - reqSend = new TLRPC.TL_decryptedMessageService_old(); - reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; - Utilities.random.nextBytes(reqSend.random_bytes); - } - - TLRPC.Message message = null; - - if (resendMessage != null) { - message = resendMessage; - reqSend.action = message.action.encryptedAction; - } else { - reqSend.action = new TLRPC.TL_decryptedMessageActionSetMessageTTL(); - reqSend.action.ttl_seconds = encryptedChat.ttl; - message = createServiceSecretMessage(encryptedChat, reqSend.action); - - MessageObject newMsgObj = new MessageObject(message, null); - newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING; - ArrayList objArr = new ArrayList(); - objArr.add(newMsgObj); - MessagesController.getInstance().updateInterfaceWithMessages(message.dialog_id, objArr); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); - } - reqSend.random_id = message.random_id; - - performSendEncryptedRequest(reqSend, message, encryptedChat, null, null); - } - - public void sendScreenshotMessage(TLRPC.EncryptedChat encryptedChat, ArrayList random_ids, TLRPC.Message resendMessage) { - if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) { - return; - } - - TLRPC.TL_decryptedMessageService reqSend = null; - if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { - reqSend = new TLRPC.TL_decryptedMessageService(); - } else { - reqSend = new TLRPC.TL_decryptedMessageService_old(); - reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; - Utilities.random.nextBytes(reqSend.random_bytes); - } - - TLRPC.Message message = null; - - if (resendMessage != null) { - message = resendMessage; - reqSend.action = message.action.encryptedAction; - } else { - reqSend.action = new TLRPC.TL_decryptedMessageActionScreenshotMessages(); - reqSend.action.random_ids = random_ids; - message = createServiceSecretMessage(encryptedChat, reqSend.action); - - MessageObject newMsgObj = new MessageObject(message, null); - newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING; - ArrayList objArr = new ArrayList(); - objArr.add(newMsgObj); - MessagesController.getInstance().updateInterfaceWithMessages(message.dialog_id, objArr); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); - } - reqSend.random_id = message.random_id; - - performSendEncryptedRequest(reqSend, message, encryptedChat, null, null); - } - private void putToDelayedMessages(String location, DelayedMessage message) { ArrayList arrayList = delayedMessages.get(location); if (arrayList == null) { @@ -1799,7 +1296,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter arrayList.add(message); } - private long getNextRandomId() { + protected long getNextRandomId() { long val = 0; while (val == 0) { val = Utilities.random.nextLong(); diff --git a/TMessagesProj/src/main/java/org/telegram/android/VideoEncodingService.java b/TMessagesProj/src/main/java/org/telegram/android/VideoEncodingService.java index e057c682a..734fbf202 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/VideoEncodingService.java +++ b/TMessagesProj/src/main/java/org/telegram/android/VideoEncodingService.java @@ -16,7 +16,7 @@ import android.support.v4.app.NotificationManagerCompat; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; -import org.telegram.ui.ApplicationLoader; +import org.telegram.messenger.ApplicationLoader; public class VideoEncodingService extends Service implements NotificationCenter.NotificationCenterDelegate { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ApplicationLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java similarity index 97% rename from TMessagesProj/src/main/java/org/telegram/ui/ApplicationLoader.java rename to TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java index 54cc2472d..b788712c3 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ApplicationLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013. */ -package org.telegram.ui; +package org.telegram.messenger; import android.app.AlarmManager; import android.app.Application; @@ -34,15 +34,10 @@ import org.telegram.android.ContactsController; import org.telegram.android.MediaController; import org.telegram.android.NotificationsService; import org.telegram.android.SendMessagesHelper; -import org.telegram.messenger.BuildVars; -import org.telegram.messenger.ConnectionsManager; -import org.telegram.messenger.FileLog; import org.telegram.android.LocaleController; import org.telegram.android.MessagesController; import org.telegram.android.NativeLoader; import org.telegram.android.ScreenReceiver; -import org.telegram.messenger.UserConfig; -import org.telegram.messenger.Utilities; import java.util.concurrent.atomic.AtomicInteger; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java b/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java index dc7201798..ed620901a 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java @@ -21,7 +21,6 @@ import org.telegram.android.ContactsController; import org.telegram.android.LocaleController; import org.telegram.android.MessagesController; import org.telegram.android.NotificationCenter; -import org.telegram.ui.ApplicationLoader; import java.io.File; import java.util.ArrayList; @@ -418,7 +417,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. pushSessionId = Utilities.random.nextLong(); } if (currentDatacenterId == 0) { - currentDatacenterId = 1; + currentDatacenterId = 2; } saveSession(); } @@ -432,12 +431,12 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. if (isTestBackend == 0) { Datacenter datacenter = new Datacenter(); datacenter.datacenterId = 1; - datacenter.addAddressAndPort("173.240.5.1", 443); + datacenter.addAddressAndPort("149.154.175.50", 443); datacenters.put(datacenter.datacenterId, datacenter); datacenter = new Datacenter(); datacenter.datacenterId = 2; - datacenter.addAddressAndPort("149.154.167.50", 443); + datacenter.addAddressAndPort("149.154.167.51", 443); datacenters.put(datacenter.datacenterId, datacenter); datacenter = new Datacenter(); @@ -447,7 +446,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. datacenter = new Datacenter(); datacenter.datacenterId = 4; - datacenter.addAddressAndPort("149.154.167.90", 443); + datacenter.addAddressAndPort("149.154.167.91", 443); datacenters.put(datacenter.datacenterId, datacenter); datacenter = new Datacenter(); @@ -473,7 +472,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } else if (datacenters.size() == 1) { Datacenter datacenter = new Datacenter(); datacenter.datacenterId = 2; - datacenter.addAddressAndPort("149.154.167.50", 443); + datacenter.addAddressAndPort("149.154.167.51", 443); datacenters.put(datacenter.datacenterId, datacenter); datacenter = new Datacenter(); @@ -483,12 +482,12 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. datacenter = new Datacenter(); datacenter.datacenterId = 4; - datacenter.addAddressAndPort("31.210.235.12", 443); + datacenter.addAddressAndPort("149.154.167.91", 443); datacenters.put(datacenter.datacenterId, datacenter); datacenter = new Datacenter(); datacenter.datacenterId = 5; - datacenter.addAddressAndPort("116.51.22.2", 443); + datacenter.addAddressAndPort("149.154.171.5", 443); datacenters.put(datacenter.datacenterId, datacenter); } } @@ -1113,13 +1112,13 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. request.retryCount++; - if ((request.flags & RPCRequest.RPCRequestClassDownloadMedia) != 0) { + if (!request.salt && (request.flags & RPCRequest.RPCRequestClassDownloadMedia) != 0) { int retryMax = 10; if ((request.flags & RPCRequest.RPCRequestClassForceDownload) == 0) { if (request.wait) { retryMax = 1; } else { - retryMax = 3; + retryMax = 6; } } if (request.retryCount >= retryMax) { @@ -2244,6 +2243,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } if (request.respondsToMessageId(resultMid)) { request.retryCount = 0; + request.salt = true; + break; } } } @@ -2568,7 +2569,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. if (message == null) { FileLog.e("tmessages", "***** Error parsing message: " + constructor); } else { - FileLog.e("tmessages", "received object " + message); + FileLog.d("tmessages", "received object " + message); processMessage(message, messageId, messageSeqNo, messageServerSalt, connection, 0, 0); connection.addProcessedMessageId(messageId); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/Datacenter.java b/TMessagesProj/src/main/java/org/telegram/messenger/Datacenter.java index 4c1914128..36823ed79 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/Datacenter.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/Datacenter.java @@ -11,8 +11,6 @@ package org.telegram.messenger; import android.content.Context; import android.content.SharedPreferences; -import org.telegram.ui.ApplicationLoader; - import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java index 6ac2cbc9f..ceee714f6 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java @@ -12,7 +12,6 @@ import android.net.Uri; import android.util.Log; import org.telegram.android.time.FastDateFormat; -import org.telegram.ui.ApplicationLoader; import java.io.File; import java.io.FileOutputStream; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java index 96e6c7d68..157103bec 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java @@ -11,8 +11,6 @@ package org.telegram.messenger; import android.app.Activity; import android.content.SharedPreferences; -import org.telegram.ui.ApplicationLoader; - import java.io.File; import java.io.FileInputStream; import java.math.BigInteger; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java b/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java index 84fa468cb..4e7454e07 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java @@ -37,6 +37,7 @@ public class RPCRequest { int serverFailureCount; int flags; boolean wait = false; + boolean salt = false; protected int retryCount = 0; protected int lastResendTime = 0; protected boolean completed = false; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/TLClassStore.java b/TMessagesProj/src/main/java/org/telegram/messenger/TLClassStore.java index 9a5bfdc68..0247b881e 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/TLClassStore.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/TLClassStore.java @@ -359,6 +359,13 @@ public class TLClassStore { classStore.put(TLRPC.TL_inputPhotoCrop.constructor, TLRPC.TL_inputPhotoCrop.class); classStore.put(TLRPC.TL_messages_dialogs.constructor, TLRPC.TL_messages_dialogs.class); classStore.put(TLRPC.TL_messages_dialogsSlice.constructor, TLRPC.TL_messages_dialogsSlice.class); + classStore.put(TLRPC.TL_account_sentChangePhoneCode.constructor, TLRPC.TL_account_sentChangePhoneCode.class); + classStore.put(TLRPC.TL_updateUserPhone.constructor, TLRPC.TL_updateUserPhone.class); + classStore.put(TLRPC.TL_decryptedMessageActionRequestKey.constructor, TLRPC.TL_decryptedMessageActionRequestKey.class); + classStore.put(TLRPC.TL_decryptedMessageActionAcceptKey.constructor, TLRPC.TL_decryptedMessageActionAcceptKey.class); + classStore.put(TLRPC.TL_decryptedMessageActionCommitKey.constructor, TLRPC.TL_decryptedMessageActionCommitKey.class); + classStore.put(TLRPC.TL_decryptedMessageActionAbortKey.constructor, TLRPC.TL_decryptedMessageActionAbortKey.class); + classStore.put(TLRPC.TL_decryptedMessageActionNoop.constructor, TLRPC.TL_decryptedMessageActionNoop.class); classStore.put(TLRPC.TL_msg_container.constructor, TLRPC.TL_msg_container.class); classStore.put(TLRPC.TL_fileEncryptedLocation.constructor, TLRPC.TL_fileEncryptedLocation.class); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java b/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java index b00dd1534..21310e0ca 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java @@ -3675,6 +3675,7 @@ public class TLRPC { public long random_id; public ArrayList dc_options = new ArrayList(); public ChatParticipants participants; + public String phone; public TL_privacyKeyStatusTimestamp key; public ArrayList rules = new ArrayList(); public EncryptedChat chat; @@ -4009,6 +4010,22 @@ public class TLRPC { } } + public static class TL_updateUserPhone extends Update { + public static int constructor = 0x12b9417b; + + + public void readParams(AbsSerializedData stream) { + user_id = stream.readInt32(); + phone = stream.readString(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(user_id); + stream.writeString(phone); + } + } + public static class TL_updatePrivacy extends Update { public static int constructor = 0xee3b272a; @@ -4329,10 +4346,14 @@ public class TLRPC { public static class DecryptedMessageAction extends TLObject { public int start_seq_no; public int end_seq_no; - public int layer; public int ttl_seconds; + public int layer; public ArrayList random_ids = new ArrayList(); + public long exchange_id; + public long key_fingerprint; + public byte[] g_b; public SendMessageAction action; + public byte[] g_a; } public static class TL_decryptedMessageActionSetMessageTTL extends DecryptedMessageAction { @@ -4356,6 +4377,24 @@ public class TLRPC { } } + public static class TL_decryptedMessageActionAcceptKey extends DecryptedMessageAction { + public static int constructor = 0x6fe1735b; + + + public void readParams(AbsSerializedData stream) { + exchange_id = stream.readInt64(); + g_b = stream.readByteArray(); + key_fingerprint = stream.readInt64(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt64(exchange_id); + stream.writeByteArray(g_b); + stream.writeInt64(key_fingerprint); + } + } + public static class TL_decryptedMessageActionResend extends DecryptedMessageAction { public static int constructor = 0x511110b0; @@ -4409,6 +4448,22 @@ public class TLRPC { } } + public static class TL_decryptedMessageActionRequestKey extends DecryptedMessageAction { + public static int constructor = 0xf3c9611b; + + + public void readParams(AbsSerializedData stream) { + exchange_id = stream.readInt64(); + g_a = stream.readByteArray(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt64(exchange_id); + stream.writeByteArray(g_a); + } + } + public static class TL_decryptedMessageActionTyping extends DecryptedMessageAction { public static int constructor = 0xccb27641; @@ -5019,6 +5074,69 @@ public class TLRPC { } } + public static class TL_contacts_resolveUsername extends TLObject { + public static int constructor = 0xbf0131c; + + public String username; + + public Class responseClass () { + return User.class; + } + + public void readParams(AbsSerializedData stream) { + username = stream.readString(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeString(username); + } + } + + public static class TL_account_sendChangePhoneCode extends TLObject { + public static int constructor = 0xa407a8f4; + + public String phone_number; + + public Class responseClass () { + return TL_account_sentChangePhoneCode.class; + } + + public void readParams(AbsSerializedData stream) { + phone_number = stream.readString(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeString(phone_number); + } + } + + public static class TL_account_changePhone extends TLObject { + public static int constructor = 0x70c32edb; + + public String phone_number; + public String phone_code_hash; + public String phone_code; + + public Class responseClass () { + return User.class; + } + + public void readParams(AbsSerializedData stream) { + phone_number = stream.readString(); + phone_code_hash = stream.readString(); + phone_code = stream.readString(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeString(phone_number); + stream.writeString(phone_code_hash); + stream.writeString(phone_code); + } + } + public static class InputAudio extends TLObject { public long id; public long access_hash; @@ -5900,6 +6018,24 @@ public class TLRPC { } } + public static class TL_account_sentChangePhoneCode extends TLObject { + public static int constructor = 0xa4f58c4c; + + public String phone_code_hash; + public int send_call_timeout; + + public void readParams(AbsSerializedData stream) { + phone_code_hash = stream.readString(); + send_call_timeout = stream.readInt32(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeString(phone_code_hash); + stream.writeInt32(send_call_timeout); + } + } + public static class InputFile extends TLObject { public long id; public int parts; @@ -8819,6 +8955,7 @@ public class TLRPC { public int date; public TL_decryptedMessageLayer layer; public EncryptedFile file; + public boolean new_key_used; public void readParams(AbsSerializedData stream) { random_id = stream.readInt64(); @@ -8827,6 +8964,7 @@ public class TLRPC { if (stream.readBool()) { file = (EncryptedFile) TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); } + new_key_used = stream.readBool(); } public void serializeToStream(AbsSerializedData stream) { @@ -8838,6 +8976,7 @@ public class TLRPC { if (file != null) { file.serializeToStream(stream); } + stream.writeBool(new_key_used); } } @@ -9990,6 +10129,13 @@ public class TLRPC { public int layer; public int seq_in; public int seq_out; + public byte[] key_hash; + public short key_use_count_in; + public short key_use_count_out; + public long exchange_id; + public int key_create_date; + public long future_key_fingerprint; + public byte[] future_auth_key; } public static class FileLocation extends TLObject { @@ -10290,7 +10436,7 @@ public class TLRPC { public static class invokeWithLayer extends TLObject { public static int constructor = 0xda9b0d0d; - public int layer = 19; + public int layer = 20; public TLObject query; public void serializeToStream(AbsSerializedData stream) { @@ -10406,6 +10552,45 @@ public class TLRPC { } } + public static class TL_decryptedMessageActionCommitKey extends DecryptedMessageAction { + public static int constructor = 0xec2e0b9b; + + + public void readParams(AbsSerializedData stream) { + exchange_id = stream.readInt64(); + key_fingerprint = stream.readInt64(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt64(exchange_id); + stream.writeInt64(key_fingerprint); + } + } + + public static class TL_decryptedMessageActionAbortKey extends DecryptedMessageAction { + public static int constructor = 0xdd05ec6b; + + + public void readParams(AbsSerializedData stream) { + exchange_id = stream.readInt64(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt64(exchange_id); + } + } + + public static class TL_decryptedMessageActionNoop extends DecryptedMessageAction { + public static int constructor = 0xa82fdd63; + + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + } + } + public static class TL_decryptedMessageActionScreenshotMessages extends DecryptedMessageAction { public static int constructor = 0x8ac1f475; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java index f27723f54..6ec36580c 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java @@ -13,7 +13,6 @@ import android.content.SharedPreferences; import android.util.Base64; import org.telegram.android.MessagesStorage; -import org.telegram.ui.ApplicationLoader; import java.io.File; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java b/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java index 9eedf8627..f7e44667f 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java @@ -28,8 +28,6 @@ import net.hockeyapp.android.CrashManager; import net.hockeyapp.android.CrashManagerListener; import net.hockeyapp.android.UpdateManager; -import org.telegram.ui.ApplicationLoader; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenuItem.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenuItem.java index f417a5664..fc29f1ae2 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenuItem.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenuItem.java @@ -55,6 +55,7 @@ public class ActionBarMenuItem extends ImageView { private Runnable showMenuRunnable; private boolean showFromBottom; private int menuHeight = AndroidUtilities.dp(16); + private boolean needOffset = Build.VERSION.SDK_INT >= 21; public ActionBarMenuItem(Context context, ActionBarMenu menu, int background) { super(context); @@ -135,6 +136,10 @@ public class ActionBarMenuItem extends ImageView { showFromBottom = value; } + public void setNeedOffset(boolean value) { + needOffset = Build.VERSION.SDK_INT >= 21 && value; + } + public TextView addSubItem(int id, String text, int icon) { if (popupLayout == null) { rect = new Rect(); @@ -247,29 +252,33 @@ public class ActionBarMenuItem extends ImageView { popupWindow.setFocusable(true); if (popupLayout.getMeasuredWidth() == 0) { if (showFromBottom) { - popupWindow.showAsDropDown(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth() + AndroidUtilities.dp(14), getBottomOffsetY()); - popupWindow.update(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth() + AndroidUtilities.dp(14), getBottomOffsetY(), -1, -1); + popupWindow.showAsDropDown(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth() + AndroidUtilities.dp(14), getOffsetY()); + popupWindow.update(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth() + AndroidUtilities.dp(14), getOffsetY(), -1, -1); } else { - popupWindow.showAsDropDown(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), -getMeasuredHeight()); - popupWindow.update(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), -getMeasuredHeight(), -1, -1); + popupWindow.showAsDropDown(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), getOffsetY()); + popupWindow.update(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), getOffsetY(), -1, -1); } } else { if (showFromBottom) { - popupWindow.showAsDropDown(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth() + AndroidUtilities.dp(14), getBottomOffsetY()); + popupWindow.showAsDropDown(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth() + AndroidUtilities.dp(14), getOffsetY()); } else { - popupWindow.showAsDropDown(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), -getMeasuredHeight()); + popupWindow.showAsDropDown(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), getOffsetY()); } } } - private int getBottomOffsetY() { - getLocationOnScreen(location); - int diff = location[1] - AndroidUtilities.statusBarHeight + getMeasuredHeight() - menuHeight; - int y = AndroidUtilities.dp(8) - menuHeight; - if (diff < 0) { - y -= diff; + private int getOffsetY() { + if (showFromBottom) { + getLocationOnScreen(location); + int diff = location[1] - AndroidUtilities.statusBarHeight + getMeasuredHeight() - menuHeight; + int y = AndroidUtilities.dp(8) - menuHeight; + if (diff < 0) { + y -= diff; + } + return y - (needOffset ? AndroidUtilities.statusBarHeight : 0); + } else { + return -getMeasuredHeight() - (needOffset ? AndroidUtilities.statusBarHeight : 0); } - return y; } public boolean toggleSearch() { @@ -415,9 +424,9 @@ public class ActionBarMenuItem extends ImageView { super.onLayout(changed, left, top, right, bottom); if (popupWindow != null && popupWindow.isShowing()) { if (showFromBottom) { - popupWindow.update(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth() + AndroidUtilities.dp(14), getBottomOffsetY(), -1, -1); + popupWindow.update(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth() + AndroidUtilities.dp(14), getOffsetY(), -1, -1); } else { - popupWindow.update(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), -getMeasuredHeight(), -1, -1); + popupWindow.update(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), getOffsetY(), -1, -1); } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarPopupWindow.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarPopupWindow.java index c6f960c0e..e67c9c640 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarPopupWindow.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarPopupWindow.java @@ -11,10 +11,12 @@ package org.telegram.ui.ActionBar; import android.content.Context; +import android.os.Build; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.View; import android.view.ViewTreeObserver; +import android.view.WindowManager; import android.widget.LinearLayout; import android.widget.PopupWindow; @@ -23,6 +25,7 @@ import org.telegram.messenger.FileLog; import java.lang.reflect.Field; public class ActionBarPopupWindow extends PopupWindow { + private static final Field superListenerField; static { Field f = null; @@ -132,6 +135,15 @@ public class ActionBarPopupWindow extends PopupWindow { mSuperScrollListener = null; } } + if (Build.VERSION.SDK_INT >= 21) { + try { + Field field = PopupWindow.class.getDeclaredField("mWindowLayoutType"); + field.setAccessible(true); + field.set(this, WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); + } catch (Exception e) { + /* ignored */ + } + } } private void unregisterListener() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/DrawerLayoutContainer.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/DrawerLayoutContainer.java index e14b10258..1c607dd5f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/DrawerLayoutContainer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/DrawerLayoutContainer.java @@ -34,7 +34,7 @@ public class DrawerLayoutContainer extends FrameLayout { private static final int MIN_DRAWER_MARGIN = 64; - private View drawerLayout; + private ViewGroup drawerLayout; private ActionBarLayout parentActionBarLayout; private boolean maybeStartTracking = false; @@ -55,7 +55,7 @@ public class DrawerLayoutContainer extends FrameLayout { private Drawable shadowLeft; private boolean allowOpenDrawer; - private int drawerPosition = 0; + private float drawerPosition = 0; private boolean drawerOpened = false; public DrawerLayoutContainer(Context context) { @@ -125,7 +125,7 @@ public class DrawerLayoutContainer extends FrameLayout { requestLayout(); } - public void setDrawerLayout(View layout) { + public void setDrawerLayout(ViewGroup layout) { drawerLayout = layout; addView(drawerLayout); if (Build.VERSION.SDK_INT >= 21) { @@ -133,11 +133,11 @@ public class DrawerLayoutContainer extends FrameLayout { } } - public void moveDrawerByX(int dx) { + public void moveDrawerByX(float dx) { setDrawerPosition(drawerPosition + dx); } - public void setDrawerPosition(int value) { + public void setDrawerPosition(float value) { drawerPosition = value; if (drawerPosition > drawerLayout.getMeasuredWidth()) { drawerPosition = drawerLayout.getMeasuredWidth(); @@ -150,10 +150,10 @@ public class DrawerLayoutContainer extends FrameLayout { if (drawerLayout.getVisibility() != newVisibility) { drawerLayout.setVisibility(newVisibility); } - setScrimOpacity((float)drawerPosition / (float)drawerLayout.getMeasuredWidth()); + setScrimOpacity(drawerPosition / (float)drawerLayout.getMeasuredWidth()); } - public int getDrawerPosition() { + public float getDrawerPosition() { return drawerPosition; } @@ -171,7 +171,7 @@ public class DrawerLayoutContainer extends FrameLayout { cancelCurrentAnimation(); AnimatorSetProxy animatorSet = new AnimatorSetProxy(); animatorSet.playTogether( - ObjectAnimatorProxy.ofInt(this, "drawerPosition", drawerLayout.getMeasuredWidth()) + ObjectAnimatorProxy.ofFloat(this, "drawerPosition", drawerLayout.getMeasuredWidth()) ); animatorSet.setInterpolator(new DecelerateInterpolator()); if (fast) { @@ -198,7 +198,7 @@ public class DrawerLayoutContainer extends FrameLayout { cancelCurrentAnimation(); AnimatorSetProxy animatorSet = new AnimatorSetProxy(); animatorSet.playTogether( - ObjectAnimatorProxy.ofInt(this, "drawerPosition", 0) + ObjectAnimatorProxy.ofFloat(this, "drawerPosition", 0) ); animatorSet.setInterpolator(new DecelerateInterpolator()); if (fast) { @@ -291,12 +291,13 @@ public class DrawerLayoutContainer extends FrameLayout { if (velocityTracker == null) { velocityTracker = VelocityTracker.obtain(); } - int dx = (int) (ev.getX() - startedTrackingX); - int dy = Math.abs((int) ev.getY() - startedTrackingY); + float dx = (int) (ev.getX() - startedTrackingX); + float dy = Math.abs((int) ev.getY() - startedTrackingY); velocityTracker.addMovement(ev); - if (maybeStartTracking && !startedTracking && Math.abs(dx) / 3 > Math.abs(dy) && (dx < 0 || dx > 0 && dx > AndroidUtilities.dp(10))) { + if (maybeStartTracking && !startedTracking && (dx > 0 && dx / 3.0f > Math.abs(dy) || dx < 0 && Math.abs(dx) >= Math.abs(dy) && Math.abs(dx) >= AndroidUtilities.dp(10))) { prepareForDrawerOpen(ev); startedTrackingX = (int) ev.getX(); + requestDisallowInterceptTouchEvent(true); } else if (startedTracking) { if (!beginTrackingSent) { if (((Activity)getContext()).getCurrentFocus() != null) { @@ -312,10 +313,10 @@ public class DrawerLayoutContainer extends FrameLayout { velocityTracker = VelocityTracker.obtain(); } velocityTracker.computeCurrentVelocity(1000); - if (!startedTracking) { + /*if (!startedTracking) { float velX = velocityTracker.getXVelocity(); float velY = velocityTracker.getYVelocity(); - if (Math.abs(velX) >= 1500 && Math.abs(velX) > Math.abs(velY)) { + if (Math.abs(velX) >= 3500 && Math.abs(velX) > Math.abs(velY)) { prepareForDrawerOpen(ev); if (!beginTrackingSent) { if (((Activity)getContext()).getCurrentFocus() != null) { @@ -324,15 +325,15 @@ public class DrawerLayoutContainer extends FrameLayout { beginTrackingSent = true; } } - } + }*/ if (startedTracking || drawerPosition != 0 && drawerPosition != drawerLayout.getMeasuredWidth()) { float velX = velocityTracker.getXVelocity(); float velY = velocityTracker.getYVelocity(); - boolean backAnimation = drawerPosition < drawerLayout.getMeasuredWidth() / 2.0f && (velX < 1500 || Math.abs(velX) < Math.abs(velY)) || velX < 0 && Math.abs(velX) >= 1500; + boolean backAnimation = drawerPosition < drawerLayout.getMeasuredWidth() / 2.0f && (velX < 3500 || Math.abs(velX) < Math.abs(velY)) || velX < 0 && Math.abs(velX) >= 3500; if (!backAnimation) { - openDrawer(!drawerOpened && Math.abs(velX) >= 1500); + openDrawer(!drawerOpened && Math.abs(velX) >= 3500); } else { - closeDrawer(drawerOpened && Math.abs(velX) >= 1500); + closeDrawer(drawerOpened && Math.abs(velX) >= 3500); } startedTracking = false; } else { @@ -357,7 +358,9 @@ public class DrawerLayoutContainer extends FrameLayout { @Override public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { - onTouchEvent(null); + if (maybeStartTracking && !startedTracking) { + onTouchEvent(null); + } super.requestDisallowInterceptTouchEvent(disallowIntercept); } @@ -378,7 +381,7 @@ public class DrawerLayoutContainer extends FrameLayout { if (drawerLayout != child) { child.layout(lp.leftMargin, lp.topMargin, lp.leftMargin + child.getMeasuredWidth(), lp.topMargin + child.getMeasuredHeight()); } else { - child.layout(-child.getMeasuredWidth() + drawerPosition, lp.topMargin, drawerPosition, lp.topMargin + child.getMeasuredHeight()); + child.layout(-child.getMeasuredWidth() + (int)drawerPosition, lp.topMargin, (int)drawerPosition, lp.topMargin + child.getMeasuredHeight()); } } inLayout = false; @@ -462,9 +465,9 @@ public class DrawerLayoutContainer extends FrameLayout { scrimPaint.setColor((int) (((0x99000000 & 0xff000000) >>> 24) * scrimOpacity) << 24); canvas.drawRect(clipLeft, 0, clipRight, getHeight(), scrimPaint); } else if (shadowLeft != null) { - final float alpha = Math.max(0, Math.min((float) drawerPosition / AndroidUtilities.dp(20), 1.0f)); + final float alpha = Math.max(0, Math.min(drawerPosition / AndroidUtilities.dp(20), 1.0f)); if (alpha != 0) { - shadowLeft.setBounds(drawerPosition, child.getTop(), drawerPosition + shadowLeft.getIntrinsicWidth(), child.getBottom()); + shadowLeft.setBounds((int)drawerPosition, child.getTop(), (int)drawerPosition + shadowLeft.getIntrinsicWidth(), child.getBottom()); shadowLeft.setAlpha((int) (0xff * alpha)); shadowLeft.draw(canvas); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/CountryAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/CountryAdapter.java index 389d17b80..9c7010c1d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/CountryAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/CountryAdapter.java @@ -15,7 +15,7 @@ import android.view.ViewGroup; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; import org.telegram.messenger.FileLog; -import org.telegram.ui.ApplicationLoader; +import org.telegram.messenger.ApplicationLoader; import org.telegram.ui.Cells.DividerCell; import org.telegram.ui.Cells.LetterSectionCell; import org.telegram.ui.Cells.TextSettingsCell; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsSearchAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsSearchAdapter.java index 79c194fd8..c5c2ca11b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsSearchAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsSearchAdapter.java @@ -10,6 +10,7 @@ package org.telegram.ui.Adapters; import android.content.Context; import android.text.Html; +import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; @@ -36,10 +37,15 @@ import org.telegram.ui.Cells.LoadingCell; import org.telegram.ui.Cells.ProfileSearchCell; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Locale; import java.util.Timer; import java.util.TimerTask; public class DialogsSearchAdapter extends BaseContactsSearchAdapter { + private Context mContext; private Timer searchTimer; private ArrayList searchResult = new ArrayList(); @@ -54,6 +60,12 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { private String lastMessagesSearchString; private int lastSearchId = 0; + private class DialogSearchResult { + public TLObject object; + public int date; + public CharSequence name; + } + public static interface MessagesActivitySearchAdapterDelegate { public abstract void searchStateChanged(boolean searching); } @@ -143,19 +155,211 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { @Override public void run() { try { - FileLog.e("tmessages", "trigger search"); - ArrayList encUsers = new ArrayList(); String q = query.trim().toLowerCase(); if (q.length() == 0) { lastSearchId = -1; updateSearchResults(new ArrayList(), new ArrayList(), new ArrayList(), lastSearchId); return; } + + ArrayList usersToLoad = new ArrayList(); + ArrayList chatsToLoad = new ArrayList(); + ArrayList encryptedToLoad = new ArrayList(); + ArrayList encUsers = new ArrayList(); + int resultCount = 0; + + HashMap dialogsResult = new HashMap(); + SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT did, date FROM dialogs ORDER BY date DESC LIMIT 200")); + while (cursor.next()) { + long id = cursor.longValue(0); + DialogSearchResult dialogSearchResult = new DialogSearchResult(); + dialogSearchResult.date = cursor.intValue(1); + dialogsResult.put(id, dialogSearchResult); + + int lower_id = (int)id; + int high_id = (int)(id >> 32); + if (lower_id != 0) { + if (high_id == 1) { + if (!serverOnly && !chatsToLoad.contains(lower_id)) { + chatsToLoad.add(lower_id); + } + } else { + if (lower_id > 0) { + if (!usersToLoad.contains(lower_id)) { + usersToLoad.add(lower_id); + } + } else { + if (!chatsToLoad.contains(-lower_id)) { + chatsToLoad.add(-lower_id); + } + } + } + } else if (!serverOnly) { + if (!encryptedToLoad.contains(high_id)) { + encryptedToLoad.add(high_id); + } + } + } + cursor.dispose(); + + if (!usersToLoad.isEmpty()) { + cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, status, name FROM users WHERE uid IN(%s)", TextUtils.join(",", usersToLoad))); + while (cursor.next()) { + String name = cursor.stringValue(2); + String username = null; + int usernamePos = name.lastIndexOf(";;;"); + if (usernamePos != -1) { + username = name.substring(usernamePos + 3); + } + int found = 0; + if (name.startsWith(q) || name.contains(" " + q)) { + found = 1; + } else if (username != null && username.startsWith(q)) { + found = 2; + } + if (found != 0) { + ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0)); + if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { + TLRPC.User user = (TLRPC.User) TLClassStore.Instance().TLdeserialize(data, data.readInt32()); + if (user.id != UserConfig.getClientUserId()) { + DialogSearchResult dialogSearchResult = dialogsResult.get((long)user.id); + if (user.status != null) { + user.status.expires = cursor.intValue(1); + } + if (found == 1) { + dialogSearchResult.name = Utilities.generateSearchName(user.first_name, user.last_name, q); + } else { + dialogSearchResult.name = Utilities.generateSearchName("@" + user.username, null, "@" + q); + } + dialogSearchResult.object = user; + resultCount++; + } + } + MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data); + } + } + cursor.dispose(); + } + + if (!chatsToLoad.isEmpty()) { + cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, name FROM chats WHERE uid IN(%s)", TextUtils.join(",", chatsToLoad))); + while (cursor.next()) { + String name = cursor.stringValue(1); + String[] args = name.split(" "); + if (name.startsWith(q) || name.contains(" " + q)) { + ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0)); + if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { + TLRPC.Chat chat = (TLRPC.Chat) TLClassStore.Instance().TLdeserialize(data, data.readInt32()); + long dialog_id; + if (chat.id > 0) { + dialog_id = -chat.id; + } else { + dialog_id = AndroidUtilities.makeBroadcastId(chat.id); + } + DialogSearchResult dialogSearchResult = dialogsResult.get(dialog_id); + dialogSearchResult.name = Utilities.generateSearchName(chat.title, null, q); + dialogSearchResult.object = chat; + resultCount++; + } + MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data); + } + } + cursor.dispose(); + } + + if (!encryptedToLoad.isEmpty()) { + cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT q.data, u.name, q.user, q.g, q.authkey, q.ttl, u.data, u.status, q.layer, q.seq_in, q.seq_out, q.use_count, q.exchange_id, q.key_date, q.fprint, q.fauthkey, q.khash FROM enc_chats as q INNER JOIN users as u ON q.user = u.uid WHERE q.uid IN(%s)", TextUtils.join(",", encryptedToLoad))); + while (cursor.next()) { + String name = cursor.stringValue(1); + + String username = null; + int usernamePos = name.lastIndexOf(";;;"); + if (usernamePos != -1) { + username = name.substring(usernamePos + 2); + } + int found = 0; + if (name.startsWith(q) || name.contains(" " + q)) { + found = 1; + } else if (username != null && username.startsWith(q)) { + found = 2; + } + + if (found != 0) { + ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0)); + ByteBufferDesc data2 = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(6)); + if (data != null && cursor.byteBufferValue(0, data.buffer) != 0 && cursor.byteBufferValue(6, data2.buffer) != 0) { + TLRPC.EncryptedChat chat = (TLRPC.EncryptedChat) TLClassStore.Instance().TLdeserialize(data, data.readInt32()); + DialogSearchResult dialogSearchResult = dialogsResult.get((long)chat.id << 32); + + chat.user_id = cursor.intValue(2); + chat.a_or_b = cursor.byteArrayValue(3); + chat.auth_key = cursor.byteArrayValue(4); + chat.ttl = cursor.intValue(5); + chat.layer = cursor.intValue(8); + chat.seq_in = cursor.intValue(9); + chat.seq_out = cursor.intValue(10); + int use_count = cursor.intValue(11); + chat.key_use_count_in = (short)(use_count >> 16); + chat.key_use_count_out = (short)(use_count); + chat.exchange_id = cursor.longValue(12); + chat.key_create_date = cursor.intValue(13); + chat.future_key_fingerprint = cursor.longValue(14); + chat.future_auth_key = cursor.byteArrayValue(15); + chat.key_hash = cursor.byteArrayValue(16); + + TLRPC.User user = (TLRPC.User)TLClassStore.Instance().TLdeserialize(data2, data2.readInt32()); + if (user.status != null) { + user.status.expires = cursor.intValue(7); + } + if (found == 1) { + dialogSearchResult.name = Html.fromHtml("" + ContactsController.formatName(user.first_name, user.last_name) + ""); + } else { + dialogSearchResult.name = Utilities.generateSearchName("@" + user.username, null, "@" + q); + } + dialogSearchResult.object = chat; + encUsers.add(user); + resultCount++; + } + MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data); + MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data2); + } + } + cursor.dispose(); + } + + ArrayList searchResults = new ArrayList(resultCount); + for (DialogSearchResult dialogSearchResult : dialogsResult.values()) { + if (dialogSearchResult.object != null && dialogSearchResult.name != null) { + searchResults.add(dialogSearchResult); + } + } + + Collections.sort(searchResults, new Comparator() { + @Override + public int compare(DialogSearchResult lhs, DialogSearchResult rhs) { + if (lhs.date < rhs.date) { + return 1; + } else if (lhs.date > rhs.date) { + return -1; + } + return 0; + } + }); + ArrayList resultArray = new ArrayList(); ArrayList resultArrayNames = new ArrayList(); - SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT u.data, u.status, u.name FROM users as u INNER JOIN contacts as c ON u.uid = c.uid"); + for (DialogSearchResult dialogSearchResult : searchResults) { + resultArray.add(dialogSearchResult.object); + resultArrayNames.add(dialogSearchResult.name); + } + + cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT u.data, u.status, u.name, u.uid FROM users as u INNER JOIN contacts as c ON u.uid = c.uid"); while (cursor.next()) { + int uid = cursor.intValue(3); + if (dialogsResult.containsKey((long)uid)) { + continue; + } String name = cursor.stringValue(2); String username = null; int usernamePos = name.lastIndexOf(";;;"); @@ -189,73 +393,6 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { } cursor.dispose(); - if (!serverOnly) { - cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT q.data, u.name, q.user, q.g, q.authkey, q.ttl, u.data, u.status, q.layer, q.seq_in, q.seq_out FROM enc_chats as q INNER JOIN dialogs as d ON (q.uid << 32) = d.did INNER JOIN users as u ON q.user = u.uid"); - while (cursor.next()) { - String name = cursor.stringValue(1); - - String username = null; - int usernamePos = name.lastIndexOf(";;;"); - if (usernamePos != -1) { - username = name.substring(usernamePos + 2); - } - int found = 0; - if (name.startsWith(q) || name.contains(" " + q)) { - found = 1; - } else if (username != null && username.startsWith(q)) { - found = 2; - } - - if (found != 0) { - ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0)); - ByteBufferDesc data2 = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(6)); - if (data != null && cursor.byteBufferValue(0, data.buffer) != 0 && cursor.byteBufferValue(6, data2.buffer) != 0) { - TLRPC.EncryptedChat chat = (TLRPC.EncryptedChat) TLClassStore.Instance().TLdeserialize(data, data.readInt32()); - chat.user_id = cursor.intValue(2); - chat.a_or_b = cursor.byteArrayValue(3); - chat.auth_key = cursor.byteArrayValue(4); - chat.ttl = cursor.intValue(5); - chat.layer = cursor.intValue(8); - chat.seq_in = cursor.intValue(9); - chat.seq_out = cursor.intValue(10); - - TLRPC.User user = (TLRPC.User)TLClassStore.Instance().TLdeserialize(data2, data2.readInt32()); - if (user.status != null) { - user.status.expires = cursor.intValue(7); - } - if (found == 1) { - resultArrayNames.add(Html.fromHtml("" + ContactsController.formatName(user.first_name, user.last_name) + "")); - } else { - resultArrayNames.add(Utilities.generateSearchName("@" + user.username, null, "@" + q)); - } - resultArray.add(chat); - encUsers.add(user); - } - MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data); - MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data2); - } - } - cursor.dispose(); - } - - cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT data, name FROM chats"); - while (cursor.next()) { - String name = cursor.stringValue(1); - String[] args = name.split(" "); - if (name.startsWith(q) || name.contains(" " + q)) { - ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0)); - if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { - TLRPC.Chat chat = (TLRPC.Chat) TLClassStore.Instance().TLdeserialize(data, data.readInt32()); - if (serverOnly && chat.id < 0) { - continue; - } - resultArrayNames.add(Utilities.generateSearchName(chat.title, null, q)); - resultArray.add(chat); - } - MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data); - } - } - cursor.dispose(); updateSearchResults(resultArray, resultArrayNames, encUsers, searchId); } catch (Exception e) { FileLog.e("tmessages", e); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatActionCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatActionCell.java index c7e20f198..c0764d16b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatActionCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatActionCell.java @@ -31,7 +31,7 @@ import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; import org.telegram.ui.PhotoViewer; -import org.telegram.ui.Views.AvatarDrawable; +import org.telegram.ui.Components.AvatarDrawable; public class ChatActionCell extends BaseCell { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatAudioCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatAudioCell.java index 9ab00e61f..f01d20b7e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatAudioCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatAudioCell.java @@ -25,9 +25,9 @@ import org.telegram.android.MessagesController; import org.telegram.messenger.R; import org.telegram.android.MessageObject; import org.telegram.android.ImageReceiver; -import org.telegram.ui.Views.AvatarDrawable; -import org.telegram.ui.Views.ProgressView; -import org.telegram.ui.Views.SeekBar; +import org.telegram.ui.Components.AvatarDrawable; +import org.telegram.ui.Components.ProgressView; +import org.telegram.ui.Components.SeekBar; import java.io.File; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java index 0440eb258..c2e1376af 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java @@ -28,7 +28,7 @@ import org.telegram.android.MessagesController; import org.telegram.messenger.R; import org.telegram.android.MessageObject; import org.telegram.android.ImageReceiver; -import org.telegram.ui.Views.AvatarDrawable; +import org.telegram.ui.Components.AvatarDrawable; public class ChatBaseCell extends BaseCell { @@ -482,7 +482,7 @@ public class ChatBaseCell extends BaseCell { if (drawName && nameLayout != null) { canvas.save(); canvas.translate(currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(19) - nameOffsetX, AndroidUtilities.dp(10)); - namePaint.setColor(AvatarDrawable.getColorForId(currentUser.id)); + namePaint.setColor(AvatarDrawable.getNameColorForId(currentUser.id)); nameLayout.draw(canvas); canvas.restore(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatContactCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatContactCell.java index c7b316f19..13edf97c4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatContactCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatContactCell.java @@ -28,7 +28,7 @@ import org.telegram.android.MessagesController; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; -import org.telegram.ui.Views.AvatarDrawable; +import org.telegram.ui.Components.AvatarDrawable; public class ChatContactCell extends ChatBaseCell { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java index 17b790a09..bd53d1c64 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java @@ -21,7 +21,6 @@ import android.text.TextPaint; import android.text.TextUtils; import android.view.MotionEvent; import android.view.SoundEffectConstants; -import android.view.animation.DecelerateInterpolator; import org.telegram.android.AndroidUtilities; import org.telegram.android.ImageLoader; @@ -33,8 +32,9 @@ import org.telegram.messenger.R; import org.telegram.messenger.Utilities; import org.telegram.android.MessageObject; import org.telegram.android.PhotoObject; +import org.telegram.ui.Components.RadialProgress; import org.telegram.ui.PhotoViewer; -import org.telegram.ui.Views.GifDrawable; +import org.telegram.ui.Components.GifDrawable; import org.telegram.android.ImageReceiver; import java.io.File; @@ -58,11 +58,10 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD private static MessageObject lastDownloadedGifMessage = null; private static TextPaint namePaint; private static Paint docBackPaint; - private static Paint progressPaint; private static Paint deleteProgressPaint; - private static DecelerateInterpolator decelerateInterpolator; private GifDrawable gifDrawable = null; + private RadialProgress radialProgress; private int photoWidth; private int photoHeight; @@ -71,7 +70,6 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD private String currentUrl; private String currentPhotoFilter; private ImageReceiver photoImage; - private boolean progressVisible = false; private boolean photoNotSet = false; private boolean cancelLoading = false; @@ -96,17 +94,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD private String currentNameString; private ChatMediaCellDelegate mediaDelegate = null; - - private float currentProgress = 0; - private RectF progressRect = new RectF(); - private long lastUpdateTime = 0; - private boolean animationStarted = false; - private float radOffset = 0; - private float animatedProgressValue = 0; - private long currentProgressTime = 0; - private float animationProgressStart = 0; private RectF deleteProgressRect = new RectF(); - private int lastSecretSecondsLeft = 0; public ChatMediaCell(Context context) { super(context); @@ -141,26 +129,21 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD docBackPaint = new Paint(); - progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - progressPaint.setStyle(Paint.Style.STROKE); - progressPaint.setStrokeCap(Paint.Cap.ROUND); - progressPaint.setStrokeWidth(AndroidUtilities.dp(2)); - deleteProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG); deleteProgressPaint.setColor(0xffe4e2e0); - - decelerateInterpolator = new DecelerateInterpolator(); } TAG = MediaController.getInstance().generateObserverTag(); photoImage = new ImageReceiver(this); + radialProgress = new RadialProgress(this); } public void clearGifImage() { if (currentMessageObject != null && currentMessageObject.type == 8) { gifDrawable = null; buttonState = 2; + radialProgress.setBackground(getDrawableForCurrentState(), false, false); invalidate(); } } @@ -228,7 +211,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD if (event.getAction() == MotionEvent.ACTION_UP) { buttonPressed = 0; playSoundEffect(SoundEffectConstants.CLICK); - didPressedButton(); + didPressedButton(false); invalidate(); } else if (event.getAction() == MotionEvent.ACTION_CANCEL) { buttonPressed = 0; @@ -295,7 +278,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD mediaDelegate.didClickedImage(this); } } else if (buttonState == 0) { - didPressedButton(); + didPressedButton(false); } } else if (currentMessageObject.type == 8) { if (buttonState == -1) { @@ -303,13 +286,14 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD if (gifDrawable != null) { gifDrawable.pause(); } + radialProgress.setBackground(getDrawableForCurrentState(), false, false); invalidate(); } else if (buttonState == 2 || buttonState == 0) { - didPressedButton(); + didPressedButton(false); } } else if (currentMessageObject.type == 3) { if (buttonState == 0 || buttonState == 3) { - didPressedButton(); + didPressedButton(false); } } else if (currentMessageObject.type == 4) { if (mediaDelegate != null) { @@ -324,7 +308,31 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD } } - private void didPressedButton() { + private Drawable getDrawableForCurrentState() { + if (buttonState >= 0 && buttonState < 4) { + Drawable currentButtonDrawable = null; + if (currentMessageObject.type == 9 && gifDrawable == null) { + if (buttonState == 1 && !currentMessageObject.isSending()) { + return buttonStatesDrawablesDoc[2][currentMessageObject.isOut() ? 1 : 0]; + } else { + return buttonStatesDrawablesDoc[buttonState][currentMessageObject.isOut() ? 1 : 0]; + } + } else { + if (buttonState == 1 && !currentMessageObject.isSending()) { + return buttonStatesDrawables[4]; + } else { + return buttonStatesDrawables[buttonState]; + } + } + } else if (buttonState == -1) { + if (currentMessageObject.type == 9 && gifDrawable == null) { + return currentMessageObject.isOut() ? placeholderDocOutDrawable : placeholderDocInDrawable; + } + } + return null; + } + + private void didPressedButton(boolean animated) { if (buttonState == 0) { cancelLoading = false; if (currentMessageObject.type == 1) { @@ -339,9 +347,8 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD } else if (currentMessageObject.type == 3) { FileLoader.getInstance().loadFile(currentMessageObject.messageOwner.media.video, true); } - progressVisible = true; - startAnimation(); buttonState = 1; + radialProgress.setBackground(getDrawableForCurrentState(), true, animated); invalidate(); } else if (buttonState == 1) { if (currentMessageObject.isOut() && currentMessageObject.isSending()) { @@ -360,9 +367,8 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD } else if (currentMessageObject.type == 3) { FileLoader.getInstance().cancelLoadFile(currentMessageObject.messageOwner.media.video); } - progressVisible = false; - stopAnimation(); buttonState = 0; + radialProgress.setBackground(getDrawableForCurrentState(), false, animated); invalidate(); } } else if (buttonState == 2) { @@ -373,7 +379,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD gifDrawable.start(); gifDrawable.invalidateSelf(); buttonState = -1; - invalidate(); + radialProgress.setBackground(getDrawableForCurrentState(), false, animated); } } else if (buttonState == 3) { if (mediaDelegate != null) { @@ -407,11 +413,11 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD @Override public void setMessageObject(MessageObject messageObject) { media = messageObject.type != 9; - if (currentMessageObject != messageObject || isPhotoDataChanged(messageObject) || isUserDataChanged()) { + boolean dataChanged = currentMessageObject == messageObject && (isUserDataChanged() || photoNotSet); + if (currentMessageObject != messageObject || isPhotoDataChanged(messageObject) || dataChanged) { super.setMessageObject(messageObject); cancelLoading = false; - progressVisible = false; buttonState = -1; gifDrawable = null; currentPhotoObject = null; @@ -630,14 +636,14 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD invalidate(); } - updateButtonState(); + updateButtonState(dataChanged); } public ImageReceiver getPhotoImage() { return photoImage; } - public void updateButtonState() { + public void updateButtonState(boolean animated) { String fileName = null; File cacheFile = null; if (currentMessageObject.type == 1) { @@ -660,16 +666,16 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD } } if (fileName == null) { + radialProgress.setBackground(null, false, false); return; } if (currentMessageObject.isOut() && currentMessageObject.isSending()) { if (currentMessageObject.messageOwner.attachPath != null) { MediaController.getInstance().addLoadingFileObserver(currentMessageObject.messageOwner.attachPath, this); - progressVisible = true; - startAnimation(); buttonState = 1; + radialProgress.setBackground(getDrawableForCurrentState(), true, animated); Float progress = FileLoader.getInstance().getFileProgress(currentMessageObject.messageOwner.attachPath); - setProgress(progress != null ? progress : 0, false); + radialProgress.setProgress(progress != null ? progress : 0, false); invalidate(); } } else { @@ -681,29 +687,26 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD } if (!cacheFile.exists()) { MediaController.getInstance().addLoadingFileObserver(fileName, this); + float setProgress = 0; + boolean progressVisible = false; if (!FileLoader.getInstance().isLoadingFile(fileName)) { if (cancelLoading || currentMessageObject.type != 1 || !MediaController.getInstance().canDownloadMedia(MediaController.AUTODOWNLOAD_MASK_PHOTO)) { buttonState = 0; - progressVisible = false; - stopAnimation(); } else { - buttonState = 1; progressVisible = true; - startAnimation(); + buttonState = 1; } - setProgress(0, false); } else { - buttonState = 1; progressVisible = true; - startAnimation(); + buttonState = 1; Float progress = FileLoader.getInstance().getFileProgress(fileName); - setProgress(progress != null ? progress : 0, false); + setProgress = progress != null ? progress : 0; } + radialProgress.setBackground(getDrawableForCurrentState(), progressVisible, animated); + radialProgress.setProgress(setProgress, false); invalidate(); } else { MediaController.getInstance().removeLoadingFileObserver(this); - progressVisible = false; - stopAnimation(); if (currentMessageObject.type == 8 && (gifDrawable == null || gifDrawable != null && !gifDrawable.isRunning())) { buttonState = 2; } else if (currentMessageObject.type == 3) { @@ -711,59 +714,12 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD } else { buttonState = -1; } + radialProgress.setBackground(getDrawableForCurrentState(), false, animated); invalidate(); } } } - private void updateAnimation() { - long newTime = System.currentTimeMillis(); - long dt = newTime - lastUpdateTime; - lastUpdateTime = newTime; - - radOffset += 360 * dt / 3000.0f; - float progressDiff = currentProgress - animationProgressStart; - if (progressDiff > 0) { - currentProgressTime += dt; - if (currentProgressTime >= 300) { - animatedProgressValue = currentProgress; - animationProgressStart = currentProgress; - currentProgressTime = 0; - } else { - animatedProgressValue = animationProgressStart + progressDiff * decelerateInterpolator.getInterpolation(currentProgressTime / 300.0f); - } - } - - invalidateProgress(); - } - - private void startAnimation() { - lastUpdateTime = System.currentTimeMillis(); - animationStarted = true; - invalidateProgress(); - } - - private void setProgress(float value, boolean animated) { - if (!animated) { - animatedProgressValue = value; - animationProgressStart = value; - } else { - animationProgressStart = animatedProgressValue; - } - currentProgress = value; - currentProgressTime = 0; - } - - private void invalidateProgress() { - int offset = AndroidUtilities.dp(2); - invalidate((int)progressRect.left - offset, (int)progressRect.top - offset, (int)progressRect.right + offset * 2, (int)progressRect.bottom + offset * 2); - } - - private void stopAnimation() { - radOffset = 0; - animationStarted = false; - } - @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), photoHeight + AndroidUtilities.dp(14)); @@ -791,7 +747,8 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD int size = AndroidUtilities.dp(48); buttonX = (int)(x + (photoWidth - size) / 2.0f); buttonY = (int)(AndroidUtilities.dp(7) + (photoHeight - size) / 2.0f); - progressRect.set(buttonX + AndroidUtilities.dp(1), buttonY + AndroidUtilities.dp(1), buttonX + AndroidUtilities.dp(47), buttonY + AndroidUtilities.dp(47)); + + radialProgress.setProgressRect(buttonX, buttonY, buttonX + AndroidUtilities.dp(48), buttonY + AndroidUtilities.dp(48)); deleteProgressRect.set(buttonX + AndroidUtilities.dp(3), buttonY + AndroidUtilities.dp(3), buttonX + AndroidUtilities.dp(45), buttonY + AndroidUtilities.dp(45)); } @@ -841,6 +798,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD drawTime = photoImage.getVisible(); } + radialProgress.setHideCurrentDrawable(false); if (currentMessageObject.type == 9) { Drawable menuDrawable = null; @@ -857,44 +815,37 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD setDrawableBounds(menuDrawable, photoImage.getImageX() + backgroundWidth - AndroidUtilities.dp(44), AndroidUtilities.dp(10)); menuDrawable.draw(canvas); + if (buttonState >= 0 && buttonState < 4) { + if (!imageDrawn) { + if (buttonState == 1 && !currentMessageObject.isSending()) { + radialProgress.swapBackground(buttonStatesDrawablesDoc[2][currentMessageObject.isOut() ? 1 : 0]); + } else { + radialProgress.swapBackground(buttonStatesDrawablesDoc[buttonState][currentMessageObject.isOut() ? 1 : 0]); + } + } else { + if (buttonState == 1 && !currentMessageObject.isSending()) { + radialProgress.swapBackground(buttonStatesDrawables[4]); + } else { + radialProgress.swapBackground(buttonStatesDrawables[buttonState]); + } + } + } + if (!imageDrawn) { canvas.drawRect(photoImage.getImageX(), photoImage.getImageY(), photoImage.getImageX() + photoImage.getImageWidth(), photoImage.getImageY() + photoImage.getImageHeight(), docBackPaint); - - if (buttonState == -1) { - Drawable drawable = currentMessageObject.isOut() ? placeholderDocOutDrawable : placeholderDocInDrawable; - setDrawableBounds(drawable, photoImage.getImageX() + AndroidUtilities.dp(19), photoImage.getImageY() + AndroidUtilities.dp(19)); - drawable.draw(canvas); - } if (currentMessageObject.isOut()) { - progressPaint.setColor(0xff81bd72); - + radialProgress.setProgressColor(0xff81bd72); } else { - progressPaint.setColor(0xffadbdcc); + radialProgress.setProgressColor(0xffadbdcc); } } else { - progressPaint.setColor(0xffffffff); + if (buttonState == -1) { + radialProgress.setHideCurrentDrawable(true); + } + radialProgress.setProgressColor(0xffffffff); } } else { - progressPaint.setColor(0xffffffff); - } - - if (buttonState >= 0 && buttonState < 4) { - Drawable currentButtonDrawable = null; - if (currentMessageObject.type == 9 && !imageDrawn) { - if (buttonState == 1 && !currentMessageObject.isSending()) { - currentButtonDrawable = buttonStatesDrawablesDoc[2][currentMessageObject.isOut() ? 1 : 0]; - } else { - currentButtonDrawable = buttonStatesDrawablesDoc[buttonState][currentMessageObject.isOut() ? 1 : 0]; - } - } else { - if (buttonState == 1 && !currentMessageObject.isSending()) { - currentButtonDrawable = buttonStatesDrawables[4]; - } else { - currentButtonDrawable = buttonStatesDrawables[buttonState]; - } - } - setDrawableBounds(currentButtonDrawable, buttonX, buttonY); - currentButtonDrawable.draw(canvas); + radialProgress.setProgressColor(0xffffffff); } if (buttonState == -1 && currentMessageObject.isSecretPhoto()) { @@ -920,9 +871,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD } } - if (progressVisible) { - canvas.drawArc(progressRect, -90 + radOffset, Math.max(4, 360 * animatedProgressValue), false, progressPaint); - } + radialProgress.onDraw(canvas); if (nameLayout != null) { canvas.save(); @@ -951,22 +900,21 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD infoLayout.draw(canvas); canvas.restore(); } - - if (animationStarted) { - updateAnimation(); - } } @Override public void onFailedDownload(String fileName) { - updateButtonState(); + updateButtonState(false); } @Override public void onSuccessDownload(String fileName) { - updateButtonState(); - if (currentMessageObject.type == 8 && lastDownloadedGifMessage != null && lastDownloadedGifMessage.messageOwner.id == currentMessageObject.messageOwner.id && buttonState == 2) { - didPressedButton(); + radialProgress.setProgress(1, true); + if (currentMessageObject.type == 8 && lastDownloadedGifMessage != null && lastDownloadedGifMessage.messageOwner.id == currentMessageObject.messageOwner.id) { + buttonState = 2; + didPressedButton(true); + } else if (!photoNotSet) { + updateButtonState(true); } if (photoNotSet) { setMessageObject(currentMessageObject); @@ -975,18 +923,15 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD @Override public void onProgressDownload(String fileName, float progress) { - progressVisible = true; - setProgress(progress, true); + radialProgress.setProgress(progress, true); if (buttonState != 1) { - updateButtonState(); + updateButtonState(true); } - invalidateProgress(); } @Override public void onProgressUpload(String fileName, float progress, boolean isEncrypted) { - setProgress(progress, true); - invalidateProgress(); + radialProgress.setProgress(progress, true); } @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java index 639d34a47..ef2814c84 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java @@ -147,10 +147,10 @@ public class ChatMessageCell extends ChatBaseCell { } } else { if (isChat && !messageObject.isOut()) { - maxWidth = AndroidUtilities.displaySize.x - AndroidUtilities.dp(122); + maxWidth = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) - AndroidUtilities.dp(122); drawName = true; } else { - maxWidth = AndroidUtilities.displaySize.x - AndroidUtilities.dp(80); + maxWidth = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) - AndroidUtilities.dp(80); drawName = false; } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java index ebbe032f1..027b8cbfb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java @@ -30,7 +30,7 @@ import org.telegram.android.MessagesController; import org.telegram.messenger.R; import org.telegram.messenger.UserConfig; import org.telegram.android.ImageReceiver; -import org.telegram.ui.Views.AvatarDrawable; +import org.telegram.ui.Components.AvatarDrawable; public class DialogCell extends BaseCell { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DrawerProfileCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DrawerProfileCell.java index d9f5199fb..f1dfbb2e5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DrawerProfileCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DrawerProfileCell.java @@ -19,8 +19,8 @@ import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.AndroidUtilities; import org.telegram.android.ContactsController; import org.telegram.messenger.TLRPC; -import org.telegram.ui.Views.AvatarDrawable; -import org.telegram.ui.Views.BackupImageView; +import org.telegram.ui.Components.AvatarDrawable; +import org.telegram.ui.Components.BackupImageView; public class DrawerProfileCell extends FrameLayout { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java index 40ac40264..47b4773b3 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java @@ -27,7 +27,7 @@ import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; -import org.telegram.ui.Views.AvatarDrawable; +import org.telegram.ui.Components.AvatarDrawable; public class ProfileSearchCell extends BaseCell { private static TextPaint namePaint; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextCheckCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextCheckCell.java index 5dc3b4ed3..4e5da0292 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextCheckCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextCheckCell.java @@ -18,8 +18,8 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; -import org.telegram.ui.Views.FrameLayoutFixed; -import org.telegram.ui.Views.Switch; +import org.telegram.ui.Components.FrameLayoutFixed; +import org.telegram.ui.Components.Switch; public class TextCheckCell extends FrameLayoutFixed { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextDetailDocumentsCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextDetailDocumentsCell.java index 437001511..89d0b8a85 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextDetailDocumentsCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextDetailDocumentsCell.java @@ -18,8 +18,8 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; -import org.telegram.ui.Views.BackupImageView; -import org.telegram.ui.Views.CheckBox; +import org.telegram.ui.Components.BackupImageView; +import org.telegram.ui.Components.CheckBox; public class TextDetailDocumentsCell extends FrameLayout { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextDetailSettingsCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextDetailSettingsCell.java index 033306956..4d62db658 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextDetailSettingsCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextDetailSettingsCell.java @@ -17,7 +17,7 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; -import org.telegram.ui.Views.FrameLayoutFixed; +import org.telegram.ui.Components.FrameLayoutFixed; public class TextDetailSettingsCell extends FrameLayoutFixed { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/UserCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/UserCell.java index 4d49a33a2..50f1ead88 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/UserCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/UserCell.java @@ -24,9 +24,9 @@ import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; -import org.telegram.ui.Views.AvatarDrawable; -import org.telegram.ui.Views.BackupImageView; -import org.telegram.ui.Views.CheckBox; +import org.telegram.ui.Components.AvatarDrawable; +import org.telegram.ui.Components.BackupImageView; +import org.telegram.ui.Components.CheckBox; public class UserCell extends FrameLayout { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChangeChatNameActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangeChatNameActivity.java index b5711b2a6..ddecb6b5a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChangeChatNameActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangeChatNameActivity.java @@ -26,6 +26,7 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.TLRPC; import org.telegram.android.MessagesController; import org.telegram.messenger.R; @@ -79,7 +80,7 @@ public class ChangeChatNameActivity extends BaseFragment { TLRPC.Chat currentChat = MessagesController.getInstance().getChat(chat_id); - fragmentView = new LinearLayout(inflater.getContext()); + fragmentView = new LinearLayout(getParentActivity()); fragmentView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); ((LinearLayout) fragmentView).setOrientation(LinearLayout.VERTICAL); fragmentView.setOnTouchListener(new View.OnTouchListener() { @@ -89,7 +90,7 @@ public class ChangeChatNameActivity extends BaseFragment { } }); - firstNameField = new EditText(inflater.getContext()); + firstNameField = new EditText(getParentActivity()); firstNameField.setText(currentChat.title); firstNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); firstNameField.setHintTextColor(0xff979797); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChangeNameActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangeNameActivity.java index 667de8842..666525aa4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChangeNameActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangeNameActivity.java @@ -25,6 +25,7 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.TLObject; import org.telegram.messenger.TLRPC; import org.telegram.messenger.ConnectionsManager; @@ -74,7 +75,7 @@ public class ChangeNameActivity extends BaseFragment { user = UserConfig.getCurrentUser(); } - fragmentView = new LinearLayout(inflater.getContext()); + fragmentView = new LinearLayout(getParentActivity()); fragmentView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); ((LinearLayout) fragmentView).setOrientation(LinearLayout.VERTICAL); fragmentView.setOnTouchListener(new View.OnTouchListener() { @@ -84,7 +85,7 @@ public class ChangeNameActivity extends BaseFragment { } }); - firstNameField = new EditText(inflater.getContext()); + firstNameField = new EditText(getParentActivity()); firstNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); firstNameField.setHintTextColor(0xff979797); firstNameField.setTextColor(0xff212121); @@ -116,7 +117,7 @@ public class ChangeNameActivity extends BaseFragment { } }); - lastNameField = new EditText(inflater.getContext()); + lastNameField = new EditText(getParentActivity()); lastNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); lastNameField.setHintTextColor(0xff979797); lastNameField.setTextColor(0xff212121); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java new file mode 100644 index 000000000..d0dc19b26 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java @@ -0,0 +1,1089 @@ +/* + * This is the source code of Telegram for Android v. 2.0.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2014. + */ + +package org.telegram.ui; + +import android.app.AlertDialog; +import android.app.ProgressDialog; +import android.content.Context; +import android.os.Bundle; +import android.telephony.TelephonyManager; +import android.text.Editable; +import android.text.InputFilter; +import android.text.InputType; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.view.animation.AccelerateDecelerateInterpolator; +import android.view.inputmethod.EditorInfo; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.ScrollView; +import android.widget.TextView; + +import org.telegram.PhoneFormat.PhoneFormat; +import org.telegram.android.AndroidUtilities; +import org.telegram.android.LocaleController; +import org.telegram.android.MessagesController; +import org.telegram.android.MessagesStorage; +import org.telegram.android.NotificationCenter; +import org.telegram.messenger.ApplicationLoader; +import org.telegram.messenger.BuildVars; +import org.telegram.messenger.ConnectionsManager; +import org.telegram.messenger.FileLog; +import org.telegram.messenger.R; +import org.telegram.messenger.RPCRequest; +import org.telegram.messenger.TLObject; +import org.telegram.messenger.TLRPC; +import org.telegram.messenger.UserConfig; +import org.telegram.ui.ActionBar.ActionBar; +import org.telegram.ui.ActionBar.ActionBarMenu; +import org.telegram.ui.ActionBar.BaseFragment; +import org.telegram.ui.AnimationCompat.AnimatorListenerAdapterProxy; +import org.telegram.ui.AnimationCompat.AnimatorSetProxy; +import org.telegram.ui.AnimationCompat.ObjectAnimatorProxy; +import org.telegram.ui.AnimationCompat.ViewProxy; +import org.telegram.ui.Components.SlideView; +import org.telegram.ui.Components.TypefaceSpan; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Locale; +import java.util.Timer; +import java.util.TimerTask; + +public class ChangePhoneActivity extends BaseFragment { + + private int currentViewNum = 0; + private SlideView[] views = new SlideView[2]; + private ProgressDialog progressDialog; + + private final static int done_button = 1; + + @Override + public void onFragmentDestroy() { + super.onFragmentDestroy(); + for (SlideView v : views) { + if (v != null) { + v.onDestroyActivity(); + } + } + if (progressDialog != null) { + try { + progressDialog.dismiss(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + progressDialog = null; + } + if (!AndroidUtilities.isTablet() && getParentActivity() != null) { + getParentActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); + } + } + + @Override + public View createView(LayoutInflater inflater, ViewGroup container) { + if (fragmentView == null) { + actionBar.setTitle(LocaleController.getString("AppName", R.string.AppName)); + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == done_button) { + views[currentViewNum].onNextPressed(); + } else if (id == -1) { + finishFragment(); + } + } + }); + + ActionBarMenu menu = actionBar.createMenu(); + menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + + fragmentView = new ScrollView(getParentActivity()); + ScrollView scrollView = (ScrollView) fragmentView; + scrollView.setFillViewport(true); + + FrameLayout frameLayout = new FrameLayout(getParentActivity()); + scrollView.addView(frameLayout); + ScrollView.LayoutParams layoutParams = (ScrollView.LayoutParams) frameLayout.getLayoutParams(); + layoutParams.width = ScrollView.LayoutParams.MATCH_PARENT; + layoutParams.height = ScrollView.LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + frameLayout.setLayoutParams(layoutParams); + + views[0] = new PhoneView(getParentActivity()); + views[0].setVisibility(View.VISIBLE); + frameLayout.addView(views[0]); + FrameLayout.LayoutParams layoutParams1 = (FrameLayout.LayoutParams) views[0].getLayoutParams(); + layoutParams1.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams1.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams1.leftMargin = AndroidUtilities.dp(16); + layoutParams1.rightMargin = AndroidUtilities.dp(16); + layoutParams1.topMargin = AndroidUtilities.dp(30); + layoutParams1.gravity = Gravity.TOP | Gravity.LEFT; + views[0].setLayoutParams(layoutParams1); + + views[1] = new LoginActivitySmsView(getParentActivity()); + views[1].setVisibility(View.GONE); + frameLayout.addView(views[1]); + layoutParams1 = (FrameLayout.LayoutParams) views[1].getLayoutParams(); + layoutParams1.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams1.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams1.leftMargin = AndroidUtilities.dp(16); + layoutParams1.rightMargin = AndroidUtilities.dp(16); + layoutParams1.topMargin = AndroidUtilities.dp(30); + layoutParams1.gravity = Gravity.TOP | Gravity.LEFT; + views[1].setLayoutParams(layoutParams1); + + try { + if (views[0] == null || views[1] == null) { + FrameLayout parent = (FrameLayout)((ScrollView) fragmentView).getChildAt(0); + for (int a = 0; a < views.length; a++) { + if (views[a] == null) { + views[a] = (SlideView)parent.getChildAt(a); + } + } + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + + actionBar.setTitle(views[0].getHeaderName()); + } else { + ViewGroup parent = (ViewGroup)fragmentView.getParent(); + if (parent != null) { + parent.removeView(fragmentView); + } + } + return fragmentView; + } + + @Override + public void onResume() { + super.onResume(); + if (!AndroidUtilities.isTablet()) { + getParentActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + } + } + + @Override + public boolean onBackPressed() { + if (currentViewNum == 0) { + for (SlideView v : views) { + if (v != null) { + v.onDestroyActivity(); + } + } + return true; + } else if (currentViewNum == 1) { + setPage(0, true, null, true); + } + return false; + } + + @Override + public void onOpenAnimationEnd() { + super.onOpenAnimationEnd(); + views[currentViewNum].onShow(); + } + + public void needShowAlert(final String text) { + if (text == null || getParentActivity() == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setMessage(text); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null); + showAlertDialog(builder); + } + + public void needShowProgress() { + if (getParentActivity() == null || getParentActivity().isFinishing() || progressDialog != null) { + return; + } + progressDialog = new ProgressDialog(getParentActivity()); + progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.setCancelable(false); + progressDialog.show(); + } + + public void needHideProgress() { + if (progressDialog == null) { + return; + } + try { + progressDialog.dismiss(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + progressDialog = null; + } + + public void setPage(int page, boolean animated, Bundle params, boolean back) { + if(android.os.Build.VERSION.SDK_INT > 10) { + final SlideView outView = views[currentViewNum]; + final SlideView newView = views[page]; + currentViewNum = page; + + newView.setParams(params); + actionBar.setTitle(newView.getHeaderName()); + newView.onShow(); + ViewProxy.setX(newView, back ? -AndroidUtilities.displaySize.x : AndroidUtilities.displaySize.x); + + AnimatorSetProxy animatorSet = new AnimatorSetProxy(); + animatorSet.setInterpolator(new AccelerateDecelerateInterpolator()); + animatorSet.setDuration(300); + animatorSet.playTogether( + ObjectAnimatorProxy.ofFloat(outView, "translationX", back ? AndroidUtilities.displaySize.x : -AndroidUtilities.displaySize.x), + ObjectAnimatorProxy.ofFloat(newView, "translationX", 0)); + animatorSet.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationStart(Object animation) { + newView.setVisibility(View.VISIBLE); + } + + @Override + public void onAnimationEnd(Object animation) { + outView.setVisibility(View.GONE); + outView.setX(0); + } + }); + animatorSet.start(); + } else { + views[currentViewNum].setVisibility(View.GONE); + currentViewNum = page; + views[page].setParams(params); + views[page].setVisibility(View.VISIBLE); + actionBar.setTitle(views[page].getHeaderName()); + views[page].onShow(); + } + } + + public class PhoneView extends SlideView implements AdapterView.OnItemSelectedListener { + + private EditText codeField; + private EditText phoneField; + private TextView countryButton; + + private int countryState = 0; + + private ArrayList countriesArray = new ArrayList(); + private HashMap countriesMap = new HashMap(); + private HashMap codesMap = new HashMap(); + + private boolean ignoreSelection = false; + private boolean ignoreOnTextChange = false; + private boolean ignoreOnPhoneChange = false; + private boolean nextPressed = false; + + public PhoneView(Context context) { + super(context); + + setOrientation(VERTICAL); + + countryButton = new TextView(context); + countryButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + countryButton.setPadding(AndroidUtilities.dp(12), AndroidUtilities.dp(10), AndroidUtilities.dp(12), 0); + countryButton.setTextColor(0xff212121); + countryButton.setMaxLines(1); + countryButton.setSingleLine(true); + countryButton.setEllipsize(TextUtils.TruncateAt.END); + countryButton.setGravity(Gravity.LEFT | Gravity.CENTER_HORIZONTAL); + countryButton.setBackgroundResource(R.drawable.spinner_states); + addView(countryButton); + LayoutParams layoutParams = (LayoutParams) countryButton.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = AndroidUtilities.dp(36); + layoutParams.leftMargin = AndroidUtilities.dp(20); + layoutParams.rightMargin = AndroidUtilities.dp(20); + layoutParams.bottomMargin = AndroidUtilities.dp(14); + countryButton.setLayoutParams(layoutParams); + countryButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + CountrySelectActivity fragment = new CountrySelectActivity(); + fragment.setCountrySelectActivityDelegate(new CountrySelectActivity.CountrySelectActivityDelegate() { + @Override + public void didSelectCountry(String name) { + selectCountry(name); + phoneField.requestFocus(); + } + }); + presentFragment(fragment); + } + }); + + View view = new View(context); + view.setPadding(AndroidUtilities.dp(12), 0, AndroidUtilities.dp(12), 0); + view.setBackgroundColor(0xffdbdbdb); + addView(view); + layoutParams = (LayoutParams) view.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = 1; + layoutParams.leftMargin = AndroidUtilities.dp(24); + layoutParams.rightMargin = AndroidUtilities.dp(24); + layoutParams.topMargin = AndroidUtilities.dp(-17.5f); + view.setLayoutParams(layoutParams); + + LinearLayout linearLayout = new LinearLayout(context); + linearLayout.setOrientation(HORIZONTAL); + addView(linearLayout); + layoutParams = (LayoutParams) linearLayout.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.topMargin = AndroidUtilities.dp(20); + linearLayout.setLayoutParams(layoutParams); + + TextView textView = new TextView(context); + textView.setText("+"); + textView.setTextColor(0xff212121); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + linearLayout.addView(textView); + layoutParams = (LayoutParams) textView.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.leftMargin = AndroidUtilities.dp(24); + textView.setLayoutParams(layoutParams); + + codeField = new EditText(context); + codeField.setInputType(InputType.TYPE_CLASS_PHONE); + codeField.setTextColor(0xff212121); + AndroidUtilities.clearCursorDrawable(codeField); + codeField.setPadding(AndroidUtilities.dp(10), 0, 0, 0); + codeField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + codeField.setMaxLines(1); + codeField.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL); + codeField.setImeOptions(EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NO_EXTRACT_UI); + InputFilter[] inputFilters = new InputFilter[1]; + inputFilters[0] = new InputFilter.LengthFilter(4); + codeField.setFilters(inputFilters); + linearLayout.addView(codeField); + layoutParams = (LayoutParams) codeField.getLayoutParams(); + layoutParams.width = AndroidUtilities.dp(55); + layoutParams.height = AndroidUtilities.dp(36); + layoutParams.rightMargin = AndroidUtilities.dp(16); + layoutParams.leftMargin = AndroidUtilities.dp(-9); + codeField.setLayoutParams(layoutParams); + codeField.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { + + } + + @Override + public void afterTextChanged(Editable editable) { + if (ignoreOnTextChange) { + ignoreOnTextChange = false; + return; + } + ignoreOnTextChange = true; + String text = PhoneFormat.stripExceptNumbers(codeField.getText().toString()); + codeField.setText(text); + if (text.length() == 0) { + countryButton.setText(LocaleController.getString("ChooseCountry", R.string.ChooseCountry)); + countryState = 1; + } else { + String country = codesMap.get(text); + if (country != null) { + int index = countriesArray.indexOf(country); + if (index != -1) { + ignoreSelection = true; + countryButton.setText(countriesArray.get(index)); + + updatePhoneField(); + countryState = 0; + } else { + countryButton.setText(LocaleController.getString("WrongCountry", R.string.WrongCountry)); + countryState = 2; + } + } else { + countryButton.setText(LocaleController.getString("WrongCountry", R.string.WrongCountry)); + countryState = 2; + } + codeField.setSelection(codeField.getText().length()); + } + } + }); + codeField.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { + if (i == EditorInfo.IME_ACTION_NEXT) { + phoneField.requestFocus(); + return true; + } + return false; + } + }); + + phoneField = new EditText(context); + phoneField.setInputType(InputType.TYPE_CLASS_PHONE); + phoneField.setTextColor(0xff212121); + phoneField.setHintTextColor(0xff979797); + phoneField.setPadding(0, 0, 0, 0); + AndroidUtilities.clearCursorDrawable(phoneField); + phoneField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + phoneField.setMaxLines(1); + phoneField.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL); + phoneField.setImeOptions(EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NO_EXTRACT_UI); + linearLayout.addView(phoneField); + layoutParams = (LayoutParams) phoneField.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = AndroidUtilities.dp(36); + layoutParams.rightMargin = AndroidUtilities.dp(24); + phoneField.setLayoutParams(layoutParams); + phoneField.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + if (ignoreOnPhoneChange) { + return; + } + if (count == 1 && after == 0 && s.length() > 1) { + String phoneChars = "0123456789"; + String str = s.toString(); + String substr = str.substring(start, start + 1); + if (!phoneChars.contains(substr)) { + ignoreOnPhoneChange = true; + StringBuilder builder = new StringBuilder(str); + int toDelete = 0; + for (int a = start; a >= 0; a--) { + substr = str.substring(a, a + 1); + if(phoneChars.contains(substr)) { + break; + } + toDelete++; + } + builder.delete(Math.max(0, start - toDelete), start + 1); + str = builder.toString(); + if (PhoneFormat.strip(str).length() == 0) { + phoneField.setText(""); + } else { + phoneField.setText(str); + updatePhoneField(); + } + ignoreOnPhoneChange = false; + } + } + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + public void afterTextChanged(Editable s) { + if (ignoreOnPhoneChange) { + return; + } + updatePhoneField(); + } + }); + phoneField.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { + if (i == EditorInfo.IME_ACTION_NEXT) { + onNextPressed(); + return true; + } + return false; + } + }); + + textView = new TextView(context); + textView.setText(LocaleController.getString("StartText", R.string.StartText)); + textView.setTextColor(0xff757575); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + textView.setGravity(Gravity.LEFT); + textView.setLineSpacing(AndroidUtilities.dp(2), 1.0f); + addView(textView); + layoutParams = (LayoutParams) textView.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.leftMargin = AndroidUtilities.dp(24); + layoutParams.rightMargin = AndroidUtilities.dp(24); + layoutParams.topMargin = AndroidUtilities.dp(28); + layoutParams.bottomMargin = AndroidUtilities.dp(10); + layoutParams.gravity = Gravity.LEFT; + textView.setLayoutParams(layoutParams); + + HashMap languageMap = new HashMap(); + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(getResources().getAssets().open("countries.txt"))); + String line; + while ((line = reader.readLine()) != null) { + String[] args = line.split(";"); + countriesArray.add(0, args[2]); + countriesMap.put(args[2], args[0]); + codesMap.put(args[0], args[2]); + languageMap.put(args[1], args[2]); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + + Collections.sort(countriesArray, new Comparator() { + @Override + public int compare(String lhs, String rhs) { + return lhs.compareTo(rhs); + } + }); + + String country = null; + + try { + TelephonyManager telephonyManager = (TelephonyManager)ApplicationLoader.applicationContext.getSystemService(Context.TELEPHONY_SERVICE); + if (telephonyManager != null) { + country = telephonyManager.getSimCountryIso().toUpperCase(); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + + if (country != null) { + String countryName = languageMap.get(country); + if (countryName != null) { + int index = countriesArray.indexOf(countryName); + if (index != -1) { + codeField.setText(countriesMap.get(countryName)); + countryState = 0; + } + } + } + if (codeField.length() == 0) { + countryButton.setText(LocaleController.getString("ChooseCountry", R.string.ChooseCountry)); + countryState = 1; + } + + if (codeField.length() != 0) { + AndroidUtilities.showKeyboard(phoneField); + phoneField.requestFocus(); + } else { + AndroidUtilities.showKeyboard(codeField); + codeField.requestFocus(); + } + } + + public void selectCountry(String name) { + int index = countriesArray.indexOf(name); + if (index != -1) { + ignoreOnTextChange = true; + codeField.setText(countriesMap.get(name)); + countryButton.setText(name); + countryState = 0; + } + } + + private void updatePhoneField() { + ignoreOnPhoneChange = true; + try { + String codeText = codeField.getText().toString(); + String phone = PhoneFormat.getInstance().format("+" + codeText + phoneField.getText().toString()); + int idx = phone.indexOf(" "); + if (idx != -1) { + String resultCode = PhoneFormat.stripExceptNumbers(phone.substring(0, idx)); + if (!codeText.equals(resultCode)) { + phone = PhoneFormat.getInstance().format(phoneField.getText().toString()).trim(); + phoneField.setText(phone); + int len = phoneField.length(); + phoneField.setSelection(phoneField.length()); + } else { + phoneField.setText(phone.substring(idx).trim()); + int len = phoneField.length(); + phoneField.setSelection(phoneField.length()); + } + } else { + phoneField.setSelection(phoneField.length()); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + ignoreOnPhoneChange = false; + } + + @Override + public void onItemSelected(AdapterView adapterView, View view, int i, long l) { + if (ignoreSelection) { + ignoreSelection = false; + return; + } + ignoreOnTextChange = true; + String str = countriesArray.get(i); + codeField.setText(countriesMap.get(str)); + updatePhoneField(); + } + + @Override + public void onNothingSelected(AdapterView adapterView) { + + } + + @Override + public void onNextPressed() { + if (nextPressed) { + return; + } + if (countryState == 1) { + needShowAlert(LocaleController.getString("ChooseCountry", R.string.ChooseCountry)); + return; + } else if (countryState == 2 && !BuildVars.DEBUG_VERSION) { + needShowAlert(LocaleController.getString("WrongCountry", R.string.WrongCountry)); + return; + } + if (codeField.length() == 0) { + needShowAlert(LocaleController.getString("InvalidPhoneNumber", R.string.InvalidPhoneNumber)); + return; + } + TLRPC.TL_account_sendChangePhoneCode req = new TLRPC.TL_account_sendChangePhoneCode(); + String phone = PhoneFormat.stripExceptNumbers("" + codeField.getText() + phoneField.getText()); + req.phone_number = phone; + final String phone2 = "+" + codeField.getText() + " " + phoneField.getText(); + + final Bundle params = new Bundle(); + params.putString("phone", phone2); + params.putString("phoneFormated", phone); + nextPressed = true; + needShowProgress(); + ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(final TLObject response, final TLRPC.TL_error error) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + nextPressed = false; + if (error == null) { + TLRPC.TL_account_sentChangePhoneCode res = (TLRPC.TL_account_sentChangePhoneCode)response; + params.putString("phoneHash", res.phone_code_hash); + params.putInt("calltime", res.send_call_timeout * 1000); + setPage(1, true, params, false); + } else { + if (error.text != null) { + if (error.text.contains("PHONE_NUMBER_INVALID")) { + needShowAlert(LocaleController.getString("InvalidPhoneNumber", R.string.InvalidPhoneNumber)); + } else if (error.text.contains("PHONE_CODE_EMPTY") || error.text.contains("PHONE_CODE_INVALID")) { + needShowAlert(LocaleController.getString("InvalidCode", R.string.InvalidCode)); + } else if (error.text.contains("PHONE_CODE_EXPIRED")) { + needShowAlert(LocaleController.getString("CodeExpired", R.string.CodeExpired)); + } else if (error.text.startsWith("FLOOD_WAIT")) { + needShowAlert(LocaleController.getString("FloodWait", R.string.FloodWait)); + } else if (error.text.startsWith("PHONE_NUMBER_OCCUPIED")) { + needShowAlert(LocaleController.formatString("ChangePhoneNumberOccupied", R.string.ChangePhoneNumberOccupied, phone2)); + } else { + needShowAlert(LocaleController.getString("ErrorOccurred", R.string.ErrorOccurred)); + } + } + } + needHideProgress(); + } + }); + } + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors); + } + + @Override + public void onShow() { + super.onShow(); + if (phoneField != null) { + AndroidUtilities.showKeyboard(phoneField); + phoneField.setSelection(phoneField.length()); + } + } + + @Override + public String getHeaderName() { + return LocaleController.getString("ChangePhoneNewNumber", R.string.ChangePhoneNewNumber); + } + } + + public class LoginActivitySmsView extends SlideView implements NotificationCenter.NotificationCenterDelegate { + + private String phoneHash; + private String requestPhone; + private EditText codeField; + private TextView confirmTextView; + private TextView timeText; + private Bundle currentParams; + + private Timer timeTimer; + private Timer codeTimer; + private final Object timerSync = new Object(); + private volatile int time = 60000; + private volatile int codeTime = 15000; + private double lastCurrentTime; + private double lastCodeTime; + private boolean waitingForSms = false; + private boolean nextPressed = false; + private String lastError = ""; + + public LoginActivitySmsView(Context context) { + super(context); + + setOrientation(VERTICAL); + + confirmTextView = new TextView(context); + confirmTextView.setTextColor(0xff757575); + confirmTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + confirmTextView.setGravity(Gravity.LEFT); + confirmTextView.setLineSpacing(AndroidUtilities.dp(2), 1.0f); + addView(confirmTextView); + LayoutParams layoutParams = (LayoutParams) confirmTextView.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.LEFT; + layoutParams.leftMargin = AndroidUtilities.dp(24); + layoutParams.rightMargin = AndroidUtilities.dp(24); + confirmTextView.setLayoutParams(layoutParams); + + codeField = new EditText(context); + codeField.setTextColor(0xff212121); + codeField.setHint(LocaleController.getString("Code", R.string.Code)); + AndroidUtilities.clearCursorDrawable(codeField); + codeField.setHintTextColor(0xff979797); + codeField.setImeOptions(EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NO_EXTRACT_UI); + codeField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + codeField.setInputType(InputType.TYPE_CLASS_PHONE); + codeField.setMaxLines(1); + codeField.setPadding(0, 0, 0, 0); + addView(codeField); + layoutParams = (LayoutParams) codeField.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = AndroidUtilities.dp(36); + layoutParams.gravity = Gravity.CENTER_HORIZONTAL; + layoutParams.topMargin = AndroidUtilities.dp(20); + layoutParams.leftMargin = AndroidUtilities.dp(24); + layoutParams.rightMargin = AndroidUtilities.dp(24); + codeField.setLayoutParams(layoutParams); + codeField.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { + if (i == EditorInfo.IME_ACTION_NEXT) { + onNextPressed(); + return true; + } + return false; + } + }); + + timeText = new TextView(context); + timeText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + timeText.setTextColor(0xff757575); + timeText.setLineSpacing(AndroidUtilities.dp(2), 1.0f); + timeText.setGravity(Gravity.LEFT); + addView(timeText); + layoutParams = (LayoutParams) timeText.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.LEFT; + layoutParams.topMargin = AndroidUtilities.dp(30); + layoutParams.leftMargin = AndroidUtilities.dp(24); + layoutParams.rightMargin = AndroidUtilities.dp(24); + timeText.setLayoutParams(layoutParams); + + LinearLayout linearLayout = new LinearLayout(context); + linearLayout.setGravity(Gravity.BOTTOM | Gravity.CENTER_VERTICAL); + addView(linearLayout); + layoutParams = (LayoutParams) linearLayout.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = LayoutParams.MATCH_PARENT; + linearLayout.setLayoutParams(layoutParams); + + TextView wrongNumber = new TextView(context); + wrongNumber.setGravity(Gravity.LEFT | Gravity.CENTER_HORIZONTAL); + wrongNumber.setTextColor(0xff4d83b3); + wrongNumber.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + wrongNumber.setLineSpacing(AndroidUtilities.dp(2), 1.0f); + wrongNumber.setPadding(0, AndroidUtilities.dp(24), 0, 0); + linearLayout.addView(wrongNumber); + layoutParams = (LayoutParams) wrongNumber.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.BOTTOM | Gravity.LEFT; + layoutParams.bottomMargin = AndroidUtilities.dp(10); + layoutParams.leftMargin = AndroidUtilities.dp(24); + layoutParams.rightMargin = AndroidUtilities.dp(24); + wrongNumber.setLayoutParams(layoutParams); + wrongNumber.setText(LocaleController.getString("WrongNumber", R.string.WrongNumber)); + wrongNumber.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + onBackPressed(); + setPage(0, true, null, true); + } + }); + } + + @Override + public String getHeaderName() { + return LocaleController.getString("YourCode", R.string.YourCode); + } + + @Override + public void setParams(Bundle params) { + if (params == null) { + return; + } + codeField.setText(""); + AndroidUtilities.setWaitingForSms(true); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.didReceiveSmsCode); + currentParams = params; + waitingForSms = true; + String phone = params.getString("phone"); + requestPhone = params.getString("phoneFormated"); + phoneHash = params.getString("phoneHash"); + time = params.getInt("calltime"); + + if (phone == null) { + return; + } + + String number = PhoneFormat.getInstance().format(phone); + String str = String.format(Locale.US, LocaleController.getString("SentSmsCode", R.string.SentSmsCode) + " %s", number); + try { + SpannableStringBuilder stringBuilder = new SpannableStringBuilder(str); + TypefaceSpan span = new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + int idx = str.indexOf(number); + stringBuilder.setSpan(span, idx, idx + number.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); + confirmTextView.setText(stringBuilder); + } catch (Exception e) { + FileLog.e("tmessages", e); + confirmTextView.setText(str); + } + + AndroidUtilities.showKeyboard(codeField); + codeField.requestFocus(); + + destroyTimer(); + destroyCodeTimer(); + timeText.setText(LocaleController.formatString("CallText", R.string.CallText, 1, 0)); + lastCurrentTime = System.currentTimeMillis(); + + createTimer(); + } + + private void createCodeTimer() { + if (codeTimer != null) { + return; + } + codeTime = 15000; + codeTimer = new Timer(); + lastCodeTime = System.currentTimeMillis(); + codeTimer.schedule(new TimerTask() { + @Override + public void run() { + double currentTime = System.currentTimeMillis(); + double diff = currentTime - lastCodeTime; + codeTime -= diff; + lastCodeTime = currentTime; + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (codeTime <= 1000) { + destroyCodeTimer(); + } + } + }); + } + }, 0, 1000); + } + + private void destroyCodeTimer() { + try { + synchronized(timerSync) { + if (codeTimer != null) { + codeTimer.cancel(); + codeTimer = null; + } + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + + private void createTimer() { + if (timeTimer != null) { + return; + } + timeTimer = new Timer(); + timeTimer.schedule(new TimerTask() { + @Override + public void run() { + double currentTime = System.currentTimeMillis(); + double diff = currentTime - lastCurrentTime; + time -= diff; + lastCurrentTime = currentTime; + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (time >= 1000) { + int minutes = time / 1000 / 60; + int seconds = time / 1000 - minutes * 60; + timeText.setText(LocaleController.formatString("CallText", R.string.CallText, minutes, seconds)); + } else { + timeText.setText(LocaleController.getString("Calling", R.string.Calling)); + destroyTimer(); + createCodeTimer(); + TLRPC.TL_auth_sendCall req = new TLRPC.TL_auth_sendCall(); + req.phone_number = requestPhone; + req.phone_code_hash = phoneHash; + ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, final TLRPC.TL_error error) { + if (error != null && error.text != null) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + lastError = error.text; + } + }); + } + } + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors | RPCRequest.RPCRequestClassWithoutLogin); + } + } + }); + } + }, 0, 1000); + } + + private void destroyTimer() { + try { + synchronized(timerSync) { + if (timeTimer != null) { + timeTimer.cancel(); + timeTimer = null; + } + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + + @Override + public void onNextPressed() { + if (nextPressed) { + return; + } + nextPressed = true; + waitingForSms = false; + AndroidUtilities.setWaitingForSms(false); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.didReceiveSmsCode); + final TLRPC.TL_account_changePhone req = new TLRPC.TL_account_changePhone(); + req.phone_number = requestPhone; + req.phone_code = codeField.getText().toString(); + req.phone_code_hash = phoneHash; + destroyTimer(); + needShowProgress(); + ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(final TLObject response, final TLRPC.TL_error error) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + needHideProgress(); + nextPressed = false; + if (error == null) { + TLRPC.User user = (TLRPC.User) response; + destroyTimer(); + destroyCodeTimer(); + UserConfig.setCurrentUser(user); + UserConfig.saveConfig(true); + ArrayList users = new ArrayList(); + users.add(user); + MessagesStorage.getInstance().putUsersAndChats(users, null, true, true); + MessagesController.getInstance().putUser(user, false); + finishFragment(); + } else { + lastError = error.text; + createTimer(); + if (error.text.contains("PHONE_NUMBER_INVALID")) { + needShowAlert(LocaleController.getString("InvalidPhoneNumber", R.string.InvalidPhoneNumber)); + } else if (error.text.contains("PHONE_CODE_EMPTY") || error.text.contains("PHONE_CODE_INVALID")) { + needShowAlert(LocaleController.getString("InvalidCode", R.string.InvalidCode)); + } else if (error.text.contains("PHONE_CODE_EXPIRED")) { + needShowAlert(LocaleController.getString("CodeExpired", R.string.CodeExpired)); + } else if (error.text.startsWith("FLOOD_WAIT")) { + needShowAlert(LocaleController.getString("FloodWait", R.string.FloodWait)); + } else { + needShowAlert(error.text); + } + } + } + }); + } + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors | RPCRequest.RPCRequestClassWithoutLogin); + } + + @Override + public void onBackPressed() { + destroyTimer(); + destroyCodeTimer(); + currentParams = null; + AndroidUtilities.setWaitingForSms(false); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.didReceiveSmsCode); + waitingForSms = false; + } + + @Override + public void onDestroyActivity() { + super.onDestroyActivity(); + AndroidUtilities.setWaitingForSms(false); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.didReceiveSmsCode); + destroyTimer(); + destroyCodeTimer(); + waitingForSms = false; + } + + @Override + public void onShow() { + super.onShow(); + if (codeField != null) { + codeField.requestFocus(); + codeField.setSelection(codeField.length()); + } + } + + @Override + public void didReceivedNotification(int id, final Object... args) { + if (id == NotificationCenter.didReceiveSmsCode) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (!waitingForSms) { + return; + } + if (codeField != null) { + codeField.setText("" + args[0]); + onNextPressed(); + } + } + }); + } + } + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneHelpActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneHelpActivity.java new file mode 100644 index 000000000..e2c2b2cb5 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneHelpActivity.java @@ -0,0 +1,163 @@ +/* + * This is the source code of Telegram for Android v. 1.7.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2014. + */ + +package org.telegram.ui; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.ScrollView; +import android.widget.TextView; + +import org.telegram.PhoneFormat.PhoneFormat; +import org.telegram.android.AndroidUtilities; +import org.telegram.android.LocaleController; +import org.telegram.messenger.FileLog; +import org.telegram.messenger.R; +import org.telegram.messenger.TLRPC; +import org.telegram.messenger.UserConfig; +import org.telegram.ui.ActionBar.ActionBar; +import org.telegram.ui.ActionBar.BaseFragment; + +public class ChangePhoneHelpActivity extends BaseFragment { + + @Override + public View createView(LayoutInflater inflater, ViewGroup container) { + if (fragmentView == null) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + + TLRPC.User user = UserConfig.getCurrentUser(); + String value; + if (user != null && user.phone != null && user.phone.length() != 0) { + value = PhoneFormat.getInstance().format("+" + user.phone); + } else { + value = LocaleController.getString("NumberUnknown", R.string.NumberUnknown); + } + + actionBar.setTitle(value); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } + } + }); + + fragmentView = new RelativeLayout(getParentActivity()); + fragmentView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + RelativeLayout relativeLayout = (RelativeLayout) fragmentView; + + ScrollView scrollView = new ScrollView(getParentActivity()); + relativeLayout.addView(scrollView); + RelativeLayout.LayoutParams layoutParams3 = (RelativeLayout.LayoutParams) scrollView.getLayoutParams(); + layoutParams3.width = RelativeLayout.LayoutParams.MATCH_PARENT; + layoutParams3.height = RelativeLayout.LayoutParams.WRAP_CONTENT; + layoutParams3.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE); + scrollView.setLayoutParams(layoutParams3); + + LinearLayout linearLayout = new LinearLayout(getParentActivity()); + linearLayout.setOrientation(LinearLayout.VERTICAL); + linearLayout.setPadding(0, AndroidUtilities.dp(20), 0, AndroidUtilities.dp(20)); + scrollView.addView(linearLayout); + ScrollView.LayoutParams layoutParams = (ScrollView.LayoutParams) linearLayout.getLayoutParams(); + layoutParams.width = ScrollView.LayoutParams.MATCH_PARENT; + layoutParams.height = ScrollView.LayoutParams.WRAP_CONTENT; + linearLayout.setLayoutParams(layoutParams); + + ImageView imageView = new ImageView(getParentActivity()); + imageView.setImageResource(R.drawable.phone_change); + linearLayout.addView(imageView); + LinearLayout.LayoutParams layoutParams2 = (LinearLayout.LayoutParams)imageView.getLayoutParams(); + layoutParams2.width = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.height = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.gravity = Gravity.CENTER_HORIZONTAL; + imageView.setLayoutParams(layoutParams2); + + TextView textView = new TextView(getParentActivity()); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + textView.setGravity(Gravity.CENTER_HORIZONTAL); + textView.setTextColor(0xff212121); + + try { + textView.setText(AndroidUtilities.replaceBold(LocaleController.getString("PhoneNumberHelp", R.string.PhoneNumberHelp))); + } catch (Exception e) { + FileLog.e("tmessages", e); + textView.setText(LocaleController.getString("PhoneNumberHelp", R.string.PhoneNumberHelp)); + } + linearLayout.addView(textView); + layoutParams2 = (LinearLayout.LayoutParams)textView.getLayoutParams(); + layoutParams2.width = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.height = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.gravity = Gravity.CENTER_HORIZONTAL; + layoutParams2.leftMargin = AndroidUtilities.dp(20); + layoutParams2.rightMargin = AndroidUtilities.dp(20); + layoutParams2.topMargin = AndroidUtilities.dp(56); + textView.setLayoutParams(layoutParams2); + + textView = new TextView(getParentActivity()); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + textView.setGravity(Gravity.CENTER_HORIZONTAL); + textView.setTextColor(0xff4d83b3); + textView.setText(LocaleController.getString("PhoneNumberChange", R.string.PhoneNumberChange)); + textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + textView.setPadding(0, AndroidUtilities.dp(10), 0, AndroidUtilities.dp(10)); + linearLayout.addView(textView); + layoutParams2 = (LinearLayout.LayoutParams)textView.getLayoutParams(); + layoutParams2.width = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.height = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.gravity = Gravity.CENTER_HORIZONTAL; + layoutParams2.leftMargin = AndroidUtilities.dp(20); + layoutParams2.rightMargin = AndroidUtilities.dp(20); + layoutParams2.topMargin = AndroidUtilities.dp(46); + textView.setLayoutParams(layoutParams2); + + textView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (getParentActivity() == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setMessage(LocaleController.getString("PhoneNumberAlert", R.string.PhoneNumberAlert)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + presentFragment(new ChangePhoneActivity(), true); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } + }); + + } else { + ViewGroup parent = (ViewGroup)fragmentView.getParent(); + if (parent != null) { + parent.removeView(fragmentView); + } + } + return fragmentView; + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChangeUsernameActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangeUsernameActivity.java index 6ebeae2dd..681228d85 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChangeUsernameActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangeUsernameActivity.java @@ -34,6 +34,7 @@ import org.telegram.android.LocaleController; import org.telegram.android.MessagesController; import org.telegram.android.MessagesStorage; import org.telegram.android.NotificationCenter; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; @@ -84,7 +85,7 @@ public class ChangeUsernameActivity extends BaseFragment { user = UserConfig.getCurrentUser(); } - fragmentView = new LinearLayout(inflater.getContext()); + fragmentView = new LinearLayout(getParentActivity()); fragmentView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); ((LinearLayout) fragmentView).setOrientation(LinearLayout.VERTICAL); fragmentView.setOnTouchListener(new View.OnTouchListener() { @@ -94,7 +95,7 @@ public class ChangeUsernameActivity extends BaseFragment { } }); - firstNameField = new EditText(inflater.getContext()); + firstNameField = new EditText(getParentActivity()); firstNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); firstNameField.setHintTextColor(0xff979797); firstNameField.setTextColor(0xff212121); @@ -132,7 +133,7 @@ public class ChangeUsernameActivity extends BaseFragment { firstNameField.setSelection(firstNameField.length()); } - checkTextView = new TextView(inflater.getContext()); + checkTextView = new TextView(getParentActivity()); checkTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); checkTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); ((LinearLayout) fragmentView).addView(checkTextView); @@ -145,7 +146,7 @@ public class ChangeUsernameActivity extends BaseFragment { layoutParams.rightMargin = AndroidUtilities.dp(24); checkTextView.setLayoutParams(layoutParams); - TextView helpTextView = new TextView(inflater.getContext()); + TextView helpTextView = new TextView(getParentActivity()); helpTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); helpTextView.setTextColor(0xff6d6d72); helpTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index a8880bab4..508f34baf 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -49,7 +49,9 @@ import org.telegram.android.LocaleController; import org.telegram.android.MediaController; import org.telegram.android.MessagesStorage; import org.telegram.android.NotificationsController; +import org.telegram.android.SecretChatHelper; import org.telegram.android.SendMessagesHelper; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLoader; import org.telegram.messenger.TLRPC; import org.telegram.android.ContactsController; @@ -75,16 +77,16 @@ import org.telegram.ui.Cells.ChatMessageCell; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; -import org.telegram.ui.Views.AvatarDrawable; -import org.telegram.ui.Views.BackupImageView; +import org.telegram.ui.Components.AvatarDrawable; +import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.Views.ChatActivityEnterView; +import org.telegram.ui.Components.ChatActivityEnterView; import org.telegram.android.ImageReceiver; -import org.telegram.ui.Views.FrameLayoutFixed; -import org.telegram.ui.Views.LayoutListView; -import org.telegram.ui.Views.SizeNotifierRelativeLayout; -import org.telegram.ui.Views.TimerDrawable; -import org.telegram.ui.Views.TypingDotsDrawable; +import org.telegram.ui.Components.FrameLayoutFixed; +import org.telegram.ui.Components.LayoutListView; +import org.telegram.ui.Components.SizeNotifierRelativeLayout; +import org.telegram.ui.Components.TimerDrawable; +import org.telegram.ui.Components.TypingDotsDrawable; import java.io.File; import java.util.ArrayList; @@ -429,8 +431,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not typingDotsDrawable = new TypingDotsDrawable(); typingDotsDrawable.setIsChat(currentChat != null); - if (currentEncryptedChat != null && AndroidUtilities.getMyLayerVersion(currentEncryptedChat.layer) != SendMessagesHelper.CURRENT_SECRET_CHAT_LAYER) { - SendMessagesHelper.getInstance().sendNotifyLayerMessage(currentEncryptedChat, null); + if (currentEncryptedChat != null && AndroidUtilities.getMyLayerVersion(currentEncryptedChat.layer) != SecretChatHelper.CURRENT_SECRET_CHAT_LAYER) { + SecretChatHelper.getInstance().sendNotifyLayerMessage(currentEncryptedChat, null); } return true; @@ -2431,7 +2433,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } else if (obj.isOut() && !obj.isUnread()) { break; } - if (obj.messageOwner.date <= date) { + if (obj.messageOwner.date - 1 <= date) { obj.setIsRead(); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/AvatarDrawable.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarDrawable.java similarity index 96% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/AvatarDrawable.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarDrawable.java index b38772f3c..7c7e230ce 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/AvatarDrawable.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarDrawable.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013-2014. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.graphics.Canvas; import android.graphics.ColorFilter; @@ -22,7 +22,7 @@ import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; -import org.telegram.ui.ApplicationLoader; +import org.telegram.messenger.ApplicationLoader; import java.util.Locale; @@ -34,9 +34,12 @@ public class AvatarDrawable extends Drawable { private static int[] arrColorsProfiles = {0xffd86f65, 0xfff69d61, 0xfffabb3c, 0xff67b35d, 0xff56a2bb, 0xff5c98cd, 0xff8c79d2, 0xfff37fa6}; private static int[] arrColorsProfilesBack = {0xffca6056, 0xfff18944, 0xfff2b02c, 0xff56a14c, 0xff4492ac, 0xff4c84b6, 0xff7d6ac4, 0xffe66b94}; private static int[] arrColorsProfilesText = {0xfff9cbc5, 0xfffdddc8, 0xfffce5bb, 0xffc0edba, 0xffb8e2f0, 0xffb3d7f7, 0xffcdc4ed, 0xfffed1e0}; + private static int[] arrColorsNames = {0xffca5650, 0xffd87b29, 0xffc7a21c, 0xff50b232, 0xff42b1a8, 0xff4e92cc, 0xff4e92cc, 0xffdb5b9d}; private static int[] arrColorsButtons = {R.drawable.bar_selector_red, R.drawable.bar_selector_orange, R.drawable.bar_selector_yellow, R.drawable.bar_selector_green, R.drawable.bar_selector_cyan, R.drawable.bar_selector_blue, R.drawable.bar_selector_violet, R.drawable.bar_selector_pink}; + + private static Drawable broadcastDrawable; private static Drawable photoDrawable; @@ -132,6 +135,10 @@ public class AvatarDrawable extends Drawable { return arrColorsProfilesBack[getColorIndex(id)]; } + public static int getNameColorForId(int id) { + return arrColorsNames[getColorIndex(id)]; + } + public void setInfo(TLRPC.User user) { if (user != null) { setInfo(user.id, user.first_name, user.last_name, false); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/AvatarUpdater.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarUpdater.java similarity index 99% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/AvatarUpdater.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarUpdater.java index c462cd51c..07edc7ad1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/AvatarUpdater.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarUpdater.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.app.Activity; import android.content.Intent; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/BackupImageView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/BackupImageView.java similarity index 98% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/BackupImageView.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/BackupImageView.java index f311f94b5..950a2cdab 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/BackupImageView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/BackupImageView.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.content.Context; import android.graphics.Bitmap; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/ChatActivityEnterView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java similarity index 89% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/ChatActivityEnterView.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java index 106435595..01cbcdc0c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/ChatActivityEnterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java @@ -6,12 +6,13 @@ * Copyright Nikolai Kudashov, 2013-2014. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.graphics.Rect; +import android.os.Build; import android.os.PowerManager; import android.text.Editable; import android.text.TextWatcher; @@ -29,7 +30,6 @@ import android.widget.EditText; import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.ImageView; -import android.widget.PopupWindow; import android.widget.TextView; import org.telegram.android.AndroidUtilities; @@ -43,11 +43,12 @@ import org.telegram.messenger.FileLog; import org.telegram.android.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; +import org.telegram.messenger.UserConfig; import org.telegram.ui.AnimationCompat.AnimatorListenerAdapterProxy; import org.telegram.ui.AnimationCompat.AnimatorSetProxy; import org.telegram.ui.AnimationCompat.ObjectAnimatorProxy; import org.telegram.ui.AnimationCompat.ViewProxy; -import org.telegram.ui.ApplicationLoader; +import org.telegram.messenger.ApplicationLoader; public class ChatActivityEnterView implements NotificationCenter.NotificationCenterDelegate, SizeNotifierRelativeLayout.SizeNotifierRelativeLayoutDelegate { @@ -60,7 +61,6 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen private EditText messsageEditText; private ImageButton sendButton; - private PopupWindow emojiPopup; private ImageView emojiButton; private EmojiView emojiView; private TextView recordTimeText; @@ -76,6 +76,9 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen private int runningAnimationType; private int audioInterfaceState; + private WindowManager.LayoutParams windowLayoutParams; + private boolean showingEmoji; + private int keyboardHeight; private int keyboardHeightLand; private boolean keyboardVisible; @@ -124,6 +127,7 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen if (sizeNotifierRelativeLayout != null) { sizeNotifierRelativeLayout.delegate = null; } + removeEmojiWindow(); } public void setContainerView(Activity activity, View containerView) { @@ -160,18 +164,14 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen emojiButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - if (emojiPopup == null) { - showEmojiPopup(true); - } else { - showEmojiPopup(!emojiPopup.isShowing()); - } + showEmojiPopup(!showingEmoji); } }); messsageEditText.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View view, int i, KeyEvent keyEvent) { - if (i == 4 && !keyboardVisible && emojiPopup != null && emojiPopup.isShowing()) { + if (i == 4 && !keyboardVisible && showingEmoji) { if (keyEvent.getAction() == 1) { showEmojiPopup(false); } @@ -187,7 +187,7 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen messsageEditText.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - if (emojiPopup != null && emojiPopup.isShowing()) { + if (showingEmoji) { showEmojiPopup(false); } } @@ -291,7 +291,7 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen if ((int) dialog_id > 0) { currentUser = MessagesController.getInstance().getUser((int) dialog_id); } - if (currentUser != null && currentUser.status != null && currentUser.status.expires < currentTime) { + if (currentUser != null && (currentUser.id == UserConfig.getClientUserId() || currentUser.status != null && currentUser.status.expires < currentTime)) { return; } lastTypingTimeSend = System.currentTimeMillis(); @@ -609,13 +609,47 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen } private void showEmojiPopup(boolean show) { + showingEmoji = show; if (show) { - if (emojiPopup == null) { - createEmojiPopup(); + if (emojiView == null) { + if (parentActivity == null) { + return; + } + emojiView = new EmojiView(parentActivity); + emojiView.setListener(new EmojiView.Listener() { + public void onBackspace() { + messsageEditText.dispatchKeyEvent(new KeyEvent(0, 67)); + } + + public void onEmojiSelected(String symbol) { + int i = messsageEditText.getSelectionEnd(); + if (i < 0) { + i = 0; + } + try { + CharSequence localCharSequence = Emoji.replaceEmoji(symbol, messsageEditText.getPaint().getFontMetricsInt(), AndroidUtilities.dp(20)); + messsageEditText.setText(messsageEditText.getText().insert(i, localCharSequence)); + int j = i + localCharSequence.length(); + messsageEditText.setSelection(j, j); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + + windowLayoutParams = new WindowManager.LayoutParams(); + windowLayoutParams.gravity = Gravity.BOTTOM | Gravity.LEFT; + if (Build.VERSION.SDK_INT >= 21) { + windowLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR; + } else { + windowLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; + windowLayoutParams.token = parentActivity.getWindow().getDecorView().getWindowToken(); + } + windowLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; } int currentHeight; - WindowManager manager = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); - int rotation = manager.getDefaultDisplay().getRotation(); + WindowManager wm = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); + int rotation = wm.getDefaultDisplay().getRotation(); if (keyboardHeight <= 0) { keyboardHeight = ApplicationLoader.applicationContext.getSharedPreferences("emoji", 0).getInt("kbd_height", AndroidUtilities.dp(200)); } @@ -627,16 +661,24 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen } else { currentHeight = keyboardHeight; } - emojiPopup.setHeight(View.MeasureSpec.makeMeasureSpec(currentHeight, View.MeasureSpec.EXACTLY)); - if (sizeNotifierRelativeLayout != null) { - emojiPopup.setWidth(View.MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.x, View.MeasureSpec.EXACTLY)); - } + windowLayoutParams.height = currentHeight; + windowLayoutParams.width = AndroidUtilities.displaySize.x; try { - emojiPopup.showAtLocation(parentActivity.getWindow().getDecorView(), Gravity.BOTTOM | Gravity.LEFT, 0, 0); + if (emojiView.getParent() != null) { + wm.removeViewImmediate(emojiView); + } } catch (Exception e) { FileLog.e("tmessages", e); } + + try { + wm.addView(emojiView, windowLayoutParams); + } catch (Exception e) { + FileLog.e("tmessages", e); + return; + } + if (!keyboardVisible) { if (sizeNotifierRelativeLayout != null) { sizeNotifierRelativeLayout.setPadding(0, 0, 0, currentHeight); @@ -650,9 +692,7 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen if (emojiButton != null) { emojiButton.setImageResource(R.drawable.ic_msg_panel_smiles); } - if (emojiPopup != null) { - emojiPopup.dismiss(); - } + removeEmojiWindow(); if (sizeNotifierRelativeLayout != null) { sizeNotifierRelativeLayout.post(new Runnable() { public void run() { @@ -664,38 +704,24 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen } } - public void hideEmojiPopup() { - if (emojiPopup != null && emojiPopup.isShowing()) { - showEmojiPopup(false); + private void removeEmojiWindow() { + if (emojiView == null) { + return; + } + try { + if (emojiView.getParent() != null) { + WindowManager wm = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE); + wm.removeViewImmediate(emojiView); + } + } catch (Exception e) { + FileLog.e("tmessages", e); } } - private void createEmojiPopup() { - if (parentActivity == null) { - return; + public void hideEmojiPopup() { + if (showingEmoji) { + showEmojiPopup(false); } - emojiView = new EmojiView(parentActivity); - emojiView.setListener(new EmojiView.Listener() { - public void onBackspace() { - messsageEditText.dispatchKeyEvent(new KeyEvent(0, 67)); - } - - public void onEmojiSelected(String symbol) { - int i = messsageEditText.getSelectionEnd(); - if (i < 0) { - i = 0; - } - try { - CharSequence localCharSequence = Emoji.replaceEmoji(symbol, messsageEditText.getPaint().getFontMetricsInt(), AndroidUtilities.dp(20)); - messsageEditText.setText(messsageEditText.getText().insert(i, localCharSequence)); - int j = i + localCharSequence.length(); - messsageEditText.setSelection(j, j); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } - }); - emojiPopup = new PopupWindow(emojiView); } public void setDelegate(ChatActivityEnterViewDelegate delegate) { @@ -754,7 +780,7 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen } public boolean isEmojiPopupShowing() { - return emojiPopup != null && emojiPopup.isShowing(); + return showingEmoji; } public void addToAttachLayout(View view) { @@ -778,11 +804,11 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen Rect localRect = new Rect(); parentActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(localRect); - WindowManager manager = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); - if (manager == null || manager.getDefaultDisplay() == null) { + WindowManager wm = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); + if (wm == null || wm.getDefaultDisplay() == null) { return; } - int rotation = manager.getDefaultDisplay().getRotation(); + int rotation = wm.getDefaultDisplay().getRotation(); if (height > AndroidUtilities.dp(50) && keyboardVisible) { if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { @@ -794,25 +820,23 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen } } - if (emojiPopup != null && emojiPopup.isShowing()) { + if (showingEmoji) { int newHeight = 0; if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { newHeight = keyboardHeightLand; } else { newHeight = keyboardHeight; } - final WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) emojiPopup.getContentView().getLayoutParams(); - if (layoutParams.width != AndroidUtilities.displaySize.x || layoutParams.height != newHeight) { - WindowManager wm = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE); - layoutParams.width = AndroidUtilities.displaySize.x; - layoutParams.height = newHeight; - wm.updateViewLayout(emojiPopup.getContentView(), layoutParams); + if (windowLayoutParams.width != AndroidUtilities.displaySize.x || windowLayoutParams.height != newHeight) { + windowLayoutParams.width = AndroidUtilities.displaySize.x; + windowLayoutParams.height = newHeight; + wm.updateViewLayout(emojiView, windowLayoutParams); if (!keyboardVisible) { sizeNotifierRelativeLayout.post(new Runnable() { @Override public void run() { if (sizeNotifierRelativeLayout != null) { - sizeNotifierRelativeLayout.setPadding(0, 0, 0, layoutParams.height); + sizeNotifierRelativeLayout.setPadding(0, 0, 0, windowLayoutParams.height); sizeNotifierRelativeLayout.requestLayout(); } } @@ -825,7 +849,7 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen keyboardVisible = height > 0; if (keyboardVisible && sizeNotifierRelativeLayout.getPaddingBottom() > 0) { showEmojiPopup(false); - } else if (!keyboardVisible && keyboardVisible != oldValue && emojiPopup != null && emojiPopup.isShowing()) { + } else if (!keyboardVisible && keyboardVisible != oldValue && showingEmoji) { showEmojiPopup(false); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/CheckBox.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/CheckBox.java similarity index 99% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/CheckBox.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/CheckBox.java index 6f5275b26..7bedce803 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/CheckBox.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/CheckBox.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013-2014. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.content.Context; import android.graphics.Bitmap; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/ClippingImageView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ClippingImageView.java similarity index 99% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/ClippingImageView.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/ClippingImageView.java index e3243f9e5..a288647f5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/ClippingImageView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ClippingImageView.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013-2014. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.content.Context; import android.graphics.Bitmap; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/ColorPickerView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ColorPickerView.java similarity index 99% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/ColorPickerView.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/ColorPickerView.java index 7135cbfbc..ef7319a03 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/ColorPickerView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ColorPickerView.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.content.Context; import android.graphics.Canvas; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/EmojiView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiView.java similarity index 99% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/EmojiView.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiView.java index eb0184217..708e00f0b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/EmojiView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiView.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.content.Context; import android.database.DataSetObserver; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/FrameLayoutFixed.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/FrameLayoutFixed.java similarity index 99% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/FrameLayoutFixed.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/FrameLayoutFixed.java index 73bcd9dcd..1d30c5682 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/FrameLayoutFixed.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/FrameLayoutFixed.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.content.Context; import android.graphics.drawable.Drawable; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/GifDrawable.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/GifDrawable.java similarity index 99% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/GifDrawable.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/GifDrawable.java index 5af31e03e..2462db98f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/GifDrawable.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/GifDrawable.java @@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.graphics.Bitmap; import android.graphics.Canvas; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/HorizontalListView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/HorizontalListView.java similarity index 99% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/HorizontalListView.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/HorizontalListView.java index 0bef5eb8e..4cc5b0915 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/HorizontalListView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/HorizontalListView.java @@ -5,7 +5,7 @@ * * Copyright Nikolai Kudashov, 2013. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import java.util.HashMap; import java.util.LinkedList; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/IdenticonDrawable.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/IdenticonDrawable.java similarity index 74% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/IdenticonDrawable.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/IdenticonDrawable.java index 6ceba01c7..b1a04b8e4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/IdenticonDrawable.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/IdenticonDrawable.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013-2014. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.graphics.Canvas; import android.graphics.ColorFilter; @@ -14,9 +14,11 @@ import android.graphics.Paint; import android.graphics.drawable.Drawable; import org.telegram.android.AndroidUtilities; +import org.telegram.messenger.TLRPC; import org.telegram.messenger.Utilities; public class IdenticonDrawable extends Drawable { + private byte[] data; private Paint paint = new Paint(); private int colors[] = { @@ -26,23 +28,16 @@ public class IdenticonDrawable extends Drawable { 0xff2f99c9 }; - int get_bits(int bitOffset, int numBits) { - numBits = (int)Math.pow(2, numBits) - 1; - int offset = bitOffset / 8; - bitOffset %= 8; - int val = data[offset + 3] << 24 | data[offset + 2] << 16 | data[offset + 1] << 8 | data[offset]; - return (val >> bitOffset) & numBits; + private int getBits(int bitOffset) { + return (data[bitOffset / 8] >> (bitOffset % 8)) & 0x3; } - public void setBytes(byte[] bytes) { - if (bytes == null) { - return; - } - data = Utilities.computeSHA1(bytes); - if (data.length < 128) { - byte[] temp = new byte[128]; - System.arraycopy(data, 0, temp, 0, data.length); - data = temp; + public void setEncryptedChat(TLRPC.EncryptedChat encryptedChat) { + data = encryptedChat.key_hash; + if (data == null) { + byte[] sha1 = Utilities.computeSHA1(encryptedChat.auth_key); + encryptedChat.key_hash = data = new byte[16]; + System.arraycopy(sha1, 0, data, 0, data.length); } invalidateSelf(); } @@ -59,7 +54,7 @@ public class IdenticonDrawable extends Drawable { float yOffset = Math.max(0, (getBounds().height() - rectSize * 8) / 2); for (int iy = 0; iy < 8; iy++) { for (int ix = 0; ix < 8; ix++) { - int byteValue = get_bits(bitPointer, 2); + int byteValue = getBits(bitPointer); bitPointer += 2; int colorIndex = Math.abs(byteValue) % 4; paint.setColor(colors[colorIndex]); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/LayoutListView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/LayoutListView.java similarity index 98% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/LayoutListView.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/LayoutListView.java index 4d5617a80..6712cf6fb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/LayoutListView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/LayoutListView.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.content.Context; import android.util.AttributeSet; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/NumberPicker.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/NumberPicker.java similarity index 99% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/NumberPicker.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/NumberPicker.java index bd5e23b29..a0c15f5f2 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/NumberPicker.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/NumberPicker.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.content.Context; import android.content.res.ColorStateList; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/PagerSlidingTabStrip.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PagerSlidingTabStrip.java similarity index 99% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/PagerSlidingTabStrip.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/PagerSlidingTabStrip.java index e3ab3e1c9..c568f4a78 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/PagerSlidingTabStrip.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PagerSlidingTabStrip.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import java.util.Locale; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/PopupAudioView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PopupAudioView.java similarity index 99% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/PopupAudioView.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/PopupAudioView.java index 2af5b6c6b..e7a78a4a9 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/PopupAudioView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PopupAudioView.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013-2014. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.content.Context; import android.graphics.Canvas; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/ProgressView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ProgressView.java similarity index 97% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/ProgressView.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/ProgressView.java index 6dc14ac36..adaa786e2 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/ProgressView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ProgressView.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013-2014. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.graphics.Canvas; import android.graphics.Paint; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/RadialProgress.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/RadialProgress.java new file mode 100644 index 000000000..02438ea9c --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/RadialProgress.java @@ -0,0 +1,163 @@ +/* + * This is the source code of Telegram for Android v. 2.0.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2014. + */ + +package org.telegram.ui.Components; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; +import android.graphics.drawable.Drawable; +import android.view.View; +import android.view.animation.DecelerateInterpolator; + +import org.telegram.android.AndroidUtilities; + +public class RadialProgress { + + private long lastUpdateTime = 0; + private float radOffset = 0; + private float currentProgress = 0; + private float animationProgressStart = 0; + private long currentProgressTime = 0; + private float animatedProgressValue = 0; + private RectF progressRect = new RectF(); + private RectF cicleRect = new RectF(); + private View parent = null; + private float animatedAlphaValue = 1.0f; + + private boolean currentWithRound; + private boolean previousWithRound; + private Drawable currentDrawable; + private Drawable previousDrawable; + private boolean hideCurrentDrawable; + + private static DecelerateInterpolator decelerateInterpolator = null; + private static Paint progressPaint = null; + + public RadialProgress(View parentView) { + if (decelerateInterpolator == null) { + decelerateInterpolator = new DecelerateInterpolator(); + progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + progressPaint.setStyle(Paint.Style.STROKE); + progressPaint.setStrokeCap(Paint.Cap.ROUND); + progressPaint.setStrokeWidth(AndroidUtilities.dp(2)); + progressPaint.setColor(0xffffffff); + } + parent = parentView; + } + + public void setProgressRect(int left, int top, int right, int bottom) { + progressRect.set(left, top, right, bottom); + } + + private void updateAnimation() { + long newTime = System.currentTimeMillis(); + long dt = newTime - lastUpdateTime; + lastUpdateTime = newTime; + + if (animatedProgressValue != 1) { + radOffset += 360 * dt / 3000.0f; + float progressDiff = currentProgress - animationProgressStart; + if (progressDiff > 0) { + currentProgressTime += dt; + if (currentProgressTime >= 300) { + animatedProgressValue = currentProgress; + animationProgressStart = currentProgress; + currentProgressTime = 0; + } else { + animatedProgressValue = animationProgressStart + progressDiff * decelerateInterpolator.getInterpolation(currentProgressTime / 300.0f); + } + } + invalidateParent(); + } + if (animatedProgressValue >= 1 && previousDrawable != null) { + animatedAlphaValue -= dt / 200.0f; + if (animatedAlphaValue <= 0) { + animatedAlphaValue = 0.0f; + previousDrawable = null; + } + invalidateParent(); + } + } + + public void setProgressColor(int color) { + progressPaint.setColor(color); + } + + public void setHideCurrentDrawable(boolean value) { + hideCurrentDrawable = value; + } + + public void setProgress(float value, boolean animated) { + if (!animated) { + animatedProgressValue = value; + animationProgressStart = value; + } else { + animationProgressStart = animatedProgressValue; + } + currentProgress = value; + currentProgressTime = 0; + + invalidateParent(); + } + + private void invalidateParent() { + int offset = AndroidUtilities.dp(2); + parent.invalidate((int)progressRect.left - offset, (int)progressRect.top - offset, (int)progressRect.right + offset * 2, (int)progressRect.bottom + offset * 2); + } + + public void setBackground(Drawable drawable, boolean withRound, boolean animated) { + lastUpdateTime = System.currentTimeMillis(); + if (animated && currentDrawable != drawable) { + setProgress(1, animated); + previousDrawable = currentDrawable; + previousWithRound = currentWithRound; + animatedAlphaValue = 1.0f; + } else { + previousDrawable = null; + previousWithRound = false; + } + currentWithRound = withRound; + currentDrawable = drawable; + invalidateParent(); + } + + public void swapBackground(Drawable drawable) { + currentDrawable = drawable; + } + + public void onDraw(Canvas canvas) { + if (previousDrawable != null) { + previousDrawable.setAlpha((int)(255 * animatedAlphaValue)); + previousDrawable.setBounds((int)progressRect.left, (int)progressRect.top, (int)progressRect.right, (int)progressRect.bottom); + previousDrawable.draw(canvas); + } + + if (!hideCurrentDrawable && currentDrawable != null) { + if (previousDrawable != null) { + currentDrawable.setAlpha((int)(255 * (1.0f - animatedAlphaValue))); + } else { + currentDrawable.setAlpha(255); + } + currentDrawable.setBounds((int)progressRect.left, (int)progressRect.top, (int)progressRect.right, (int)progressRect.bottom); + currentDrawable.draw(canvas); + } + + if (currentWithRound || previousWithRound) { + int diff = AndroidUtilities.dp(1); + if (previousWithRound) { + progressPaint.setAlpha((int)(255 * animatedAlphaValue)); + } else { + progressPaint.setAlpha(255); + } + cicleRect.set(progressRect.left + diff, progressRect.top + diff, progressRect.right - diff, progressRect.bottom - diff); + canvas.drawArc(cicleRect, -90 + radOffset, Math.max(4, 360 * animatedProgressValue), false, progressPaint); + updateAnimation(); + } + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/Scroller.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Scroller.java similarity index 99% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/Scroller.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/Scroller.java index b87b9b7cb..56890bfb2 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/Scroller.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Scroller.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.content.Context; import android.hardware.SensorManager; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/SectionsListView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SectionsListView.java similarity index 99% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/SectionsListView.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/SectionsListView.java index 90898f5b2..0d833ee41 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/SectionsListView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SectionsListView.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013-2014. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.content.Context; import android.graphics.Canvas; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/SeekBar.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SeekBar.java similarity index 99% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/SeekBar.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/SeekBar.java index 37543fc27..8efc59c26 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/SeekBar.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SeekBar.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.content.Context; import android.graphics.Canvas; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/SizeNotifierRelativeLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayout.java similarity index 98% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/SizeNotifierRelativeLayout.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayout.java index f74e2a4cd..214f320f8 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/SizeNotifierRelativeLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayout.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.content.Context; import android.graphics.Canvas; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/SlideView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SlideView.java new file mode 100644 index 000000000..6464ce5f9 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SlideView.java @@ -0,0 +1,52 @@ +/* + * This is the source code of Telegram for Android v. 2.0.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2014. + */ + +package org.telegram.ui.Components; + +import android.content.Context; +import android.os.Bundle; +import android.widget.LinearLayout; + +public class SlideView extends LinearLayout { + + public SlideView(Context context) { + super(context); + } + + public String getHeaderName() { + return ""; + } + + public void setParams(Bundle params) { + + } + + public void onBackPressed() { + + } + + public void onShow() { + + } + + public void onDestroyActivity() { + + } + + public void onNextPressed() { + + } + + public void saveStateParams(Bundle bundle) { + + } + + public void restoreStateParams(Bundle bundle) { + + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/Switch.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Switch.java similarity index 99% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/Switch.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/Switch.java index 02e2a5379..f1a940f40 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/Switch.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Switch.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.content.Context; import android.graphics.Canvas; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/TimerDrawable.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/TimerDrawable.java similarity index 99% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/TimerDrawable.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/TimerDrawable.java index 6252ac35d..7bfd47999 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/TimerDrawable.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/TimerDrawable.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013-2014. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.content.Context; import android.graphics.Canvas; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/TypefaceSpan.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/TypefaceSpan.java new file mode 100644 index 000000000..9f86fe3b7 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/TypefaceSpan.java @@ -0,0 +1,35 @@ +/* + * This is the source code of Telegram for Android v. 1.7.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2014. + */ + +package org.telegram.ui.Components; + +import android.graphics.Paint; +import android.graphics.Typeface; +import android.text.TextPaint; +import android.text.style.MetricAffectingSpan; + +public class TypefaceSpan extends MetricAffectingSpan { + + private Typeface mTypeface; + + public TypefaceSpan(Typeface typeface) { + mTypeface = typeface; + } + + @Override + public void updateMeasureState(TextPaint p) { + p.setTypeface(mTypeface); + p.setFlags(p.getFlags() | Paint.SUBPIXEL_TEXT_FLAG); + } + + @Override + public void updateDrawState(TextPaint tp) { + tp.setTypeface(mTypeface); + tp.setFlags(tp.getFlags() | Paint.SUBPIXEL_TEXT_FLAG); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/TypingDotsDrawable.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/TypingDotsDrawable.java similarity index 99% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/TypingDotsDrawable.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/TypingDotsDrawable.java index ff9d59c4d..393482f89 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/TypingDotsDrawable.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/TypingDotsDrawable.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013-2014. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.graphics.Canvas; import android.graphics.ColorFilter; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/URLSpanNoUnderline.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/URLSpanNoUnderline.java similarity index 94% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/URLSpanNoUnderline.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/URLSpanNoUnderline.java index c2d7b1e0f..8debb5211 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/URLSpanNoUnderline.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/URLSpanNoUnderline.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013-2014. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.text.TextPaint; import android.text.style.URLSpan; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/VideoSeekBarView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/VideoSeekBarView.java similarity index 99% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/VideoSeekBarView.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/VideoSeekBarView.java index f414b650c..c62ed5062 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/VideoSeekBarView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/VideoSeekBarView.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013-2014. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.content.Context; import android.graphics.Canvas; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/VideoTimelineView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/VideoTimelineView.java similarity index 99% rename from TMessagesProj/src/main/java/org/telegram/ui/Views/VideoTimelineView.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/VideoTimelineView.java index 451a7e14d..33740781a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/VideoTimelineView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/VideoTimelineView.java @@ -6,7 +6,7 @@ * Copyright Nikolai Kudashov, 2013-2014. */ -package org.telegram.ui.Views; +package org.telegram.ui.Components; import android.annotation.TargetApi; import android.content.Context; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java index 8afcbcb51..19e7c29d6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java @@ -31,14 +31,15 @@ import org.telegram.android.AndroidUtilities; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.ContactsController; import org.telegram.android.LocaleController; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.TLRPC; import org.telegram.android.MessagesController; import org.telegram.android.NotificationCenter; import org.telegram.messenger.R; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; -import org.telegram.ui.Views.AvatarDrawable; -import org.telegram.ui.Views.BackupImageView; +import org.telegram.ui.Components.AvatarDrawable; +import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.ActionBar.BaseFragment; public class ContactAddActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate { @@ -107,53 +108,6 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent ActionBarMenu menu = actionBar.createMenu(); doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); - /* - - - - - - - - - - - - - - - -*/ - fragmentView = new ScrollView(getParentActivity()); LinearLayout linearLayout = new LinearLayout(getParentActivity()); @@ -227,7 +181,7 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent layoutParams3.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP; onlineTextView.setLayoutParams(layoutParams3); - firstNameField = new EditText(inflater.getContext()); + firstNameField = new EditText(getParentActivity()); firstNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); firstNameField.setHintTextColor(0xff979797); firstNameField.setTextColor(0xff212121); @@ -259,7 +213,7 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent } }); - lastNameField = new EditText(inflater.getContext()); + lastNameField = new EditText(getParentActivity()); lastNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); lastNameField.setHintTextColor(0xff979797); lastNameField.setTextColor(0xff212121); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java index a2b44f87c..accab2862 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java @@ -32,6 +32,7 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; import org.telegram.android.MessagesStorage; +import org.telegram.android.SecretChatHelper; import org.telegram.messenger.TLRPC; import org.telegram.android.ContactsController; import org.telegram.messenger.FileLog; @@ -47,7 +48,7 @@ import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.Views.SectionsListView; +import org.telegram.ui.Components.SectionsListView; import java.util.ArrayList; import java.util.HashMap; @@ -268,7 +269,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter } else { if (createSecretChat) { creatingChat = true; - MessagesController.getInstance().startSecretChat(getParentActivity(), user); + SecretChatHelper.getInstance().startSecretChat(getParentActivity(), user); } else { Bundle args = new Bundle(); args.putInt("user_id", user.id); @@ -324,7 +325,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter } else { if (createSecretChat) { creatingChat = true; - MessagesController.getInstance().startSecretChat(getParentActivity(), user); + SecretChatHelper.getInstance().startSecretChat(getParentActivity(), user); } else { Bundle args = new Bundle(); args.putInt("user_id", user.id); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java index 66b77fa57..3192b2fac 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java @@ -32,7 +32,7 @@ import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.Views.SectionsListView; +import org.telegram.ui.Components.SectionsListView; public class CountrySelectActivity extends BaseFragment { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java index 18ec6a7e5..d87222892 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java @@ -41,6 +41,7 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.LocaleController; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.TLRPC; import org.telegram.android.ContactsController; import org.telegram.messenger.FileLog; @@ -53,7 +54,7 @@ import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.Cells.UserCell; -import org.telegram.ui.Views.SectionsListView; +import org.telegram.ui.Components.SectionsListView; import java.util.ArrayList; import java.util.HashMap; @@ -514,7 +515,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen } private XImageSpan createAndPutChipForUser(TLRPC.User user) { - LayoutInflater lf = (LayoutInflater)ApplicationLoader.applicationContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); + LayoutInflater lf = (LayoutInflater) ApplicationLoader.applicationContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); View textView = lf.inflate(R.layout.group_create_bubble, null); TextView text = (TextView)textView.findViewById(R.id.bubble_text_view); String name = ContactsController.formatName(user.first_name, user.last_name); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java index b558745ea..ab3fd663f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java @@ -42,11 +42,11 @@ import org.telegram.ui.Cells.GreySectionCell; import org.telegram.ui.Cells.UserCell; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; -import org.telegram.ui.Views.AvatarDrawable; -import org.telegram.ui.Views.AvatarUpdater; -import org.telegram.ui.Views.BackupImageView; +import org.telegram.ui.Components.AvatarDrawable; +import org.telegram.ui.Components.AvatarUpdater; +import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.Views.FrameLayoutFixed; +import org.telegram.ui.Components.FrameLayoutFixed; import java.util.ArrayList; import java.util.concurrent.Semaphore; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/IdenticonActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/IdenticonActivity.java index f33daa478..a4a591998 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/IdenticonActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/IdenticonActivity.java @@ -23,12 +23,13 @@ import android.widget.LinearLayout; import android.widget.TextView; import org.telegram.android.LocaleController; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.TLRPC; import org.telegram.android.MessagesController; import org.telegram.messenger.R; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.Views.IdenticonDrawable; +import org.telegram.ui.Components.IdenticonDrawable; public class IdenticonActivity extends BaseFragment { private int chat_id; @@ -66,7 +67,7 @@ public class IdenticonActivity extends BaseFragment { if (encryptedChat != null) { IdenticonDrawable drawable = new IdenticonDrawable(); identiconView.setImageDrawable(drawable); - drawable.setBytes(encryptedChat.auth_key); + drawable.setEncryptedChat(encryptedChat); TLRPC.User user = MessagesController.getInstance().getUser(encryptedChat.user_id); textView.setText(Html.fromHtml(LocaleController.formatString("EncryptionKeyDescription", R.string.EncryptionKeyDescription, user.first_name, user.first_name))); } @@ -110,7 +111,7 @@ public class IdenticonActivity extends BaseFragment { return true; } LinearLayout layout = (LinearLayout)fragmentView; - WindowManager manager = (WindowManager)ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE); + WindowManager manager = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE); int rotation = manager.getDefaultDisplay().getRotation(); if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LastSeenActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LastSeenActivity.java index 653e39fde..7ed9dd150 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LastSeenActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LastSeenActivity.java @@ -32,6 +32,7 @@ import org.telegram.android.ContactsController; import org.telegram.android.LocaleController; import org.telegram.android.MessagesController; import org.telegram.android.NotificationCenter; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java index 604f0de21..4b59bcec8 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java @@ -9,7 +9,9 @@ package org.telegram.ui; import android.app.Activity; +import android.app.ProgressDialog; import android.content.ContentResolver; +import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; @@ -39,12 +41,17 @@ import android.widget.Toast; import org.telegram.android.AndroidUtilities; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.ContactsController; +import org.telegram.android.MessagesController; +import org.telegram.android.MessagesStorage; import org.telegram.android.SendMessagesHelper; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; import org.telegram.android.LocaleController; import org.telegram.android.NotificationCenter; import org.telegram.messenger.R; +import org.telegram.messenger.RPCRequest; +import org.telegram.messenger.TLObject; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; @@ -352,11 +359,16 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa FileLog.e("tmessages", e); } } else { + boolean allowOpen = false; if (AndroidUtilities.isTablet()) { - drawerLayoutContainer.setAllowOpenDrawer(actionBarLayout.fragmentsStack.size() <= 1 && layersActionBarLayout.fragmentsStack.isEmpty()); + allowOpen = actionBarLayout.fragmentsStack.size() <= 1 && layersActionBarLayout.fragmentsStack.isEmpty(); } else { - drawerLayoutContainer.setAllowOpenDrawer(actionBarLayout.fragmentsStack.size() <= 1); + allowOpen = actionBarLayout.fragmentsStack.size() <= 1; } + if (actionBarLayout.fragmentsStack.size() == 1 && actionBarLayout.fragmentsStack.get(0) instanceof LoginActivity) { + allowOpen = false; + } + drawerLayoutContainer.setAllowOpenDrawer(allowOpen); } handleIntent(getIntent(), false, savedInstanceState != null); @@ -381,7 +393,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa documentsUrisArray = null; contactsToSend = null; - if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) { + if (UserConfig.isClientActivated() && (intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) { if (intent != null && intent.getAction() != null && !restore) { if (Intent.ACTION_SEND.equals(intent.getAction())) { boolean error = false; @@ -567,39 +579,112 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa Toast.makeText(this, "Unsupported content", Toast.LENGTH_SHORT).show(); } } else if (Intent.ACTION_VIEW.equals(intent.getAction())) { - try { - Cursor cursor = getContentResolver().query(intent.getData(), null, null, null, null); - if (cursor != null) { - if (cursor.moveToFirst()) { - int userId = cursor.getInt(cursor.getColumnIndex("DATA4")); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); - push_user_id = userId; + Uri data = intent.getData(); + if (data != null) { + String username = null; + String scheme = data.getScheme(); + if (scheme != null) { + if ((scheme.equals("http") || scheme.equals("https"))) { + String host = data.getHost(); + if (host.equals("telegram.me")) { + String path = data.getPath(); + if (path != null && path.length() >= 6) { + username = path.substring(1); + } + } + } else if (scheme.equals("tg")) { + String url = data.toString(); + if (url.startsWith("tg:resolve") || url.startsWith("tg://resolve")) { + url = url.replace("tg:resolve", "tg://telegram.org").replace("tg://resolve", "tg://telegram.org"); + data = Uri.parse(url); + username = data.getQueryParameter("domain"); + } + } + } + if (username != null) { + final ProgressDialog progressDialog = new ProgressDialog(this); + progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.setCancelable(false); + + TLRPC.TL_contacts_resolveUsername req = new TLRPC.TL_contacts_resolveUsername(); + req.username = username; + final long reqId = ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(final TLObject response, final TLRPC.TL_error error) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (!LaunchActivity.this.isFinishing()) { + try { + progressDialog.dismiss(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + if (error == null && actionBarLayout != null) { + TLRPC.User user = (TLRPC.User) response; + MessagesController.getInstance().putUser(user, false); + ArrayList users = new ArrayList(); + users.add(user); + MessagesStorage.getInstance().putUsersAndChats(users, null, false, true); + Bundle args = new Bundle(); + args.putInt("user_id", user.id); + ChatActivity fragment = new ChatActivity(args); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); + actionBarLayout.presentFragment(fragment, false, true, true); + } + } + } + }); + } + }); + + progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, LocaleController.getString("Cancel", R.string.Cancel), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + ConnectionsManager.getInstance().cancelRpc(reqId, true); + try { + dialog.dismiss(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + progressDialog.show(); + } else { + try { + Cursor cursor = getContentResolver().query(intent.getData(), null, null, null, null); + if (cursor != null) { + if (cursor.moveToFirst()) { + int userId = cursor.getInt(cursor.getColumnIndex("DATA4")); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); + push_user_id = userId; + } + cursor.close(); + } + } catch (Exception e) { + FileLog.e("tmessages", e); } - cursor.close(); } - } catch (Exception e) { - FileLog.e("tmessages", e); } } else if (intent.getAction().equals("org.telegram.messenger.OPEN_ACCOUNT")) { open_settings = 1; - } - } - - if (intent.getAction() != null && intent.getAction().startsWith("com.tmessages.openchat") && !restore) { - int chatId = intent.getIntExtra("chatId", 0); - int userId = intent.getIntExtra("userId", 0); - int encId = intent.getIntExtra("encId", 0); - if (chatId != 0) { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); - push_chat_id = chatId; - } else if (userId != 0) { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); - push_user_id = userId; - } else if (encId != 0) { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); - push_enc_id = encId; - } else { - showDialogsList = true; + } else if (intent.getAction().startsWith("com.tmessages.openchat")) { + int chatId = intent.getIntExtra("chatId", 0); + int userId = intent.getIntExtra("userId", 0); + int encId = intent.getIntExtra("encId", 0); + if (chatId != 0) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); + push_chat_id = chatId; + } else if (userId != 0) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); + push_user_id = userId; + } else if (encId != 0) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); + push_enc_id = encId; + } else { + showDialogsList = true; + } } } } @@ -635,8 +720,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } pushOpened = false; isNew = false; - } - if (videoPath != null || photoPathsArray != null || sendingText != null || documentsPathsArray != null || contactsToSend != null || documentsUrisArray != null) { + } else if (videoPath != null || photoPathsArray != null || sendingText != null || documentsPathsArray != null || contactsToSend != null || documentsUrisArray != null) { if (!AndroidUtilities.isTablet()) { NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); } @@ -657,8 +741,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa rightActionBarLayout.showLastFragment(); } drawerLayoutContainer.setAllowOpenDrawer(false); - } - if (open_settings != 0) { + } else if (open_settings != 0) { actionBarLayout.presentFragment(new SettingsActivity(), false, true, true); drawerLayoutContainer.setAllowOpenDrawer(false); if (AndroidUtilities.isTablet()) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java index be7760ae3..195ebf11e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java @@ -29,6 +29,7 @@ import com.google.android.gms.maps.model.MarkerOptions; import org.telegram.android.AndroidUtilities; import org.telegram.android.ContactsController; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLog; import org.telegram.android.LocaleController; import org.telegram.messenger.TLRPC; @@ -39,8 +40,8 @@ import org.telegram.messenger.R; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; -import org.telegram.ui.Views.AvatarDrawable; -import org.telegram.ui.Views.BackupImageView; +import org.telegram.ui.Components.AvatarDrawable; +import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.ActionBar.BaseFragment; import java.util.List; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java index a906231cc..2e0a51865 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java @@ -16,8 +16,6 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageInfo; -import android.graphics.Paint; -import android.graphics.Typeface; import android.os.Build; import android.os.Bundle; import android.telephony.TelephonyManager; @@ -26,10 +24,8 @@ import android.text.InputFilter; import android.text.InputType; import android.text.SpannableStringBuilder; import android.text.Spanned; -import android.text.TextPaint; import android.text.TextUtils; import android.text.TextWatcher; -import android.text.style.MetricAffectingSpan; import android.util.TypedValue; import android.view.Gravity; import android.view.KeyEvent; @@ -52,6 +48,7 @@ import org.telegram.android.ContactsController; import org.telegram.android.MessagesController; import org.telegram.android.MessagesStorage; import org.telegram.android.NotificationCenter; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.BuildVars; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; @@ -64,6 +61,8 @@ import org.telegram.messenger.UserConfig; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.BaseFragment; +import org.telegram.ui.Components.SlideView; +import org.telegram.ui.Components.TypefaceSpan; import java.io.BufferedReader; import java.io.InputStreamReader; @@ -78,6 +77,7 @@ import java.util.Timer; import java.util.TimerTask; public class LoginActivity extends BaseFragment { + private int currentViewNum = 0; private SlideView[] views = new SlideView[3]; private ProgressDialog progressDialog; @@ -418,45 +418,6 @@ public class LoginActivity extends BaseFragment { NotificationCenter.getInstance().postNotificationName(NotificationCenter.mainUserInfoChanged); } - public class SlideView extends LinearLayout { - - public SlideView(Context context) { - super(context); - } - - public String getHeaderName() { - return ""; - } - - public void setParams(Bundle params) { - - } - - public void onBackPressed() { - - } - - public void onShow() { - - } - - public void onDestroyActivity() { - - } - - public void onNextPressed() { - - } - - public void saveStateParams(Bundle bundle) { - - } - - public void restoreStateParams(Bundle bundle) { - - } - } - public class PhoneView extends SlideView implements AdapterView.OnItemSelectedListener { private EditText codeField; @@ -480,7 +441,7 @@ public class LoginActivity extends BaseFragment { setOrientation(VERTICAL); countryButton = new TextView(context); - countryButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + countryButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); countryButton.setPadding(AndroidUtilities.dp(12), AndroidUtilities.dp(10), AndroidUtilities.dp(12), 0); countryButton.setTextColor(0xff212121); countryButton.setMaxLines(1); @@ -535,7 +496,7 @@ public class LoginActivity extends BaseFragment { TextView textView = new TextView(context); textView.setText("+"); textView.setTextColor(0xff212121); - textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); linearLayout.addView(textView); layoutParams = (LayoutParams) textView.getLayoutParams(); layoutParams.width = LayoutParams.WRAP_CONTENT; @@ -548,7 +509,7 @@ public class LoginActivity extends BaseFragment { codeField.setTextColor(0xff212121); AndroidUtilities.clearCursorDrawable(codeField); codeField.setPadding(AndroidUtilities.dp(10), 0, 0, 0); - codeField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + codeField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); codeField.setMaxLines(1); codeField.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL); codeField.setImeOptions(EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NO_EXTRACT_UI); @@ -624,7 +585,7 @@ public class LoginActivity extends BaseFragment { phoneField.setHintTextColor(0xff979797); phoneField.setPadding(0, 0, 0, 0); AndroidUtilities.clearCursorDrawable(phoneField); - phoneField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + phoneField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); phoneField.setMaxLines(1); phoneField.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL); phoneField.setImeOptions(EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NO_EXTRACT_UI); @@ -693,7 +654,7 @@ public class LoginActivity extends BaseFragment { }); textView = new TextView(context); - textView.setText(LocaleController.getString("StartText", R.string.StartText)); + textView.setText(LocaleController.getString("ChangePhoneHelp", R.string.ChangePhoneHelp)); textView.setTextColor(0xff757575); textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); textView.setGravity(Gravity.LEFT); @@ -828,7 +789,7 @@ public class LoginActivity extends BaseFragment { if (countryState == 1) { needShowAlert(LocaleController.getString("ChooseCountry", R.string.ChooseCountry)); return; - } else if (countryState == 2) { + } else if (countryState == 2 && !BuildVars.DEBUG_VERSION) { needShowAlert(LocaleController.getString("WrongCountry", R.string.WrongCountry)); return; } @@ -951,27 +912,6 @@ public class LoginActivity extends BaseFragment { private boolean nextPressed = false; private String lastError = ""; - public class TypefaceSpan extends MetricAffectingSpan { - - private Typeface mTypeface; - - public TypefaceSpan(Typeface typeface) { - mTypeface = typeface; - } - - @Override - public void updateMeasureState(TextPaint p) { - p.setTypeface(mTypeface); - p.setFlags(p.getFlags() | Paint.SUBPIXEL_TEXT_FLAG); - } - - @Override - public void updateDrawState(TextPaint tp) { - tp.setTypeface(mTypeface); - tp.setFlags(tp.getFlags() | Paint.SUBPIXEL_TEXT_FLAG); - } - } - public LoginActivitySmsView(Context context) { super(context); @@ -997,7 +937,7 @@ public class LoginActivity extends BaseFragment { AndroidUtilities.clearCursorDrawable(codeField); codeField.setHintTextColor(0xff979797); codeField.setImeOptions(EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NO_EXTRACT_UI); - codeField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + codeField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); codeField.setInputType(InputType.TYPE_CLASS_PHONE); codeField.setMaxLines(1); codeField.setPadding(0, 0, 0, 0); @@ -1440,7 +1380,7 @@ public class LoginActivity extends BaseFragment { AndroidUtilities.clearCursorDrawable(firstNameField); firstNameField.setHint(LocaleController.getString("FirstName", R.string.FirstName)); firstNameField.setImeOptions(EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NO_EXTRACT_UI); - firstNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + firstNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); firstNameField.setMaxLines(1); firstNameField.setInputType(InputType.TYPE_TEXT_FLAG_CAP_WORDS); addView(firstNameField); @@ -1468,7 +1408,7 @@ public class LoginActivity extends BaseFragment { lastNameField.setTextColor(0xff212121); AndroidUtilities.clearCursorDrawable(lastNameField); lastNameField.setImeOptions(EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NO_EXTRACT_UI); - lastNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + lastNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); lastNameField.setMaxLines(1); lastNameField.setInputType(InputType.TYPE_TEXT_FLAG_CAP_WORDS); addView(lastNameField); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java index 844a63fe4..7443e4c3e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java @@ -26,6 +26,7 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLoader; import org.telegram.messenger.TLRPC; import org.telegram.android.MessageObject; @@ -34,7 +35,7 @@ import org.telegram.android.NotificationCenter; import org.telegram.messenger.R; import org.telegram.ui.Adapters.BaseFragmentAdapter; import org.telegram.ui.ActionBar.ActionBar; -import org.telegram.ui.Views.BackupImageView; +import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.ActionBar.BaseFragment; import java.util.ArrayList; @@ -122,6 +123,9 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView adapterView, View view, int i, long l) { + if (i < 0 || i >= messages.size()) { + return; + } PhotoViewer.getInstance().setParentActivity(getParentActivity()); PhotoViewer.getInstance().openPhoto(messages, i, MediaActivity.this); } @@ -331,7 +335,7 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { - WindowManager manager = (WindowManager)ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); + WindowManager manager = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); int rotation = manager.getDefaultDisplay().getRotation(); if (AndroidUtilities.isTablet()) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/NotificationsSettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/NotificationsSettingsActivity.java index cfdeee9b8..ace44bad7 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/NotificationsSettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/NotificationsSettingsActivity.java @@ -31,6 +31,7 @@ import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; import org.telegram.android.NotificationsController; import org.telegram.android.NotificationCenter; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.TLObject; import org.telegram.messenger.TLRPC; import org.telegram.messenger.ConnectionsManager; @@ -46,7 +47,7 @@ import org.telegram.ui.Cells.TextColorCell; import org.telegram.ui.Cells.TextDetailSettingsCell; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.Views.ColorPickerView; +import org.telegram.ui.Components.ColorPickerView; public class NotificationsSettingsActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate { private ListView listView; @@ -660,7 +661,7 @@ public class NotificationsSettingsActivity extends BaseFragment implements Notif } else if (i == eventsSectionRow) { ((HeaderCell) view).setText(LocaleController.getString("Events", R.string.Events)); } else if (i == otherSectionRow) { - ((HeaderCell) view).setText(LocaleController.getString("PhoneOther", R.string.PhoneOther)); + ((HeaderCell) view).setText(LocaleController.getString("NotificationsOther", R.string.NotificationsOther)); } else if (i == resetSectionRow) { ((HeaderCell) view).setText(LocaleController.getString("Reset", R.string.Reset)); } @@ -761,7 +762,7 @@ public class NotificationsSettingsActivity extends BaseFragment implements Notif int minutes = preferences.getInt("repeat_messages", 60); String value; if (minutes == 0) { - value = LocaleController.getString("ShortMessageLifetimeForever", R.string.ShortMessageLifetimeForever); + value = LocaleController.getString("RepeatNotificationsNever", R.string.RepeatNotificationsNever); } else if (minutes < 60) { value = LocaleController.formatPluralString("Minutes", minutes); } else { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java index 3e2ea05b7..5d0681e7c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java @@ -28,6 +28,7 @@ import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; import org.telegram.android.MediaController; import org.telegram.android.NotificationCenter; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.android.MessageObject; @@ -35,7 +36,7 @@ import org.telegram.ui.Adapters.BaseFragmentAdapter; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.Views.BackupImageView; +import org.telegram.ui.Components.BackupImageView; import java.util.ArrayList; import java.util.HashMap; @@ -401,7 +402,7 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen return; } int position = listView.getFirstVisiblePosition(); - WindowManager manager = (WindowManager)ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); + WindowManager manager = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); int rotation = manager.getDefaultDisplay().getRotation(); int columnsCount = 2; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java index e6c749153..4d32b700d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java @@ -48,6 +48,7 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.android.ContactsController; import org.telegram.android.MessagesStorage; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; @@ -67,7 +68,7 @@ import org.telegram.ui.AnimationCompat.ViewProxy; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; -import org.telegram.ui.Views.ClippingImageView; +import org.telegram.ui.Components.ClippingImageView; import org.telegram.android.ImageReceiver; import java.io.File; @@ -692,6 +693,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat ActionBarMenu menu = actionBar.createMenu(); menuItem = menu.addItem(0, R.drawable.ic_ab_other); + menuItem.setNeedOffset(false); menuItem.addSubItem(gallery_menu_save, LocaleController.getString("SaveToGallery", R.string.SaveToGallery), 0); menuItem.addSubItem(gallery_menu_showall, LocaleController.getString("ShowAllMedia", R.string.ShowAllMedia), 0); @@ -927,7 +929,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat layoutParams.height = AndroidUtilities.dp(46); layoutParams.gravity = Gravity.RIGHT; layoutParams.rightMargin = AndroidUtilities.dp(10); - WindowManager manager = (WindowManager)ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); + WindowManager manager = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); int rotation = manager.getDefaultDisplay().getRotation(); if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { layoutParams.topMargin = AndroidUtilities.dp(48); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java index f1acb8a59..5c7b22269 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java @@ -37,6 +37,7 @@ import org.telegram.android.MediaController; import org.telegram.android.MessagesController; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.NotificationsController; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; @@ -47,15 +48,16 @@ import org.telegram.android.MessageObject; import org.telegram.android.PhotoObject; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; -import org.telegram.ui.Views.AvatarDrawable; -import org.telegram.ui.Views.BackupImageView; -import org.telegram.ui.Views.ChatActivityEnterView; -import org.telegram.ui.Views.FrameLayoutFixed; -import org.telegram.ui.Views.PopupAudioView; -import org.telegram.ui.Views.TypingDotsDrawable; +import org.telegram.ui.Components.AvatarDrawable; +import org.telegram.ui.Components.BackupImageView; +import org.telegram.ui.Components.ChatActivityEnterView; +import org.telegram.ui.Components.FrameLayoutFixed; +import org.telegram.ui.Components.PopupAudioView; +import org.telegram.ui.Components.TypingDotsDrawable; import java.io.File; import java.util.ArrayList; +import java.util.Locale; public class PopupNotificationActivity extends Activity implements NotificationCenter.NotificationCenterDelegate { @@ -282,7 +284,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC chatActivityEnterView.setContainerView(this, findViewById(R.id.chat_layout)); - PowerManager pm = (PowerManager)ApplicationLoader.applicationContext.getSystemService(Context.POWER_SERVICE); + PowerManager pm = (PowerManager) ApplicationLoader.applicationContext.getSystemService(Context.POWER_SERVICE); wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "screen"); wakeLock.setReferenceCounted(false); @@ -490,7 +492,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC } ViewGroup view = null; MessageObject messageObject = NotificationsController.getInstance().popupMessages.get(num); - if (messageObject.type == 1) { + if (messageObject.type == 1 || messageObject.type == 4) { if (imageViews.size() > 0) { view = imageViews.get(0); imageViews.remove(0); @@ -510,34 +512,45 @@ public class PopupNotificationActivity extends Activity implements NotificationC TextView messageText = (TextView)view.findViewById(R.id.message_text); BackupImageView imageView = (BackupImageView) view.findViewById(R.id.message_image); imageView.imageReceiver.setAspectFit(true); - PhotoObject currentPhotoObject = PhotoObject.getClosestImageWithSize(messageObject.photoThumbs, AndroidUtilities.getPhotoSize()); - boolean photoSet = false; - if (currentPhotoObject != null) { - boolean photoExist = true; - if (messageObject.type == 1) { - File cacheFile = FileLoader.getPathToMessage(messageObject.messageOwner); - if (!cacheFile.exists()) { - photoExist = false; + + if (messageObject.type == 1) { + PhotoObject currentPhotoObject = PhotoObject.getClosestImageWithSize(messageObject.photoThumbs, AndroidUtilities.getPhotoSize()); + boolean photoSet = false; + if (currentPhotoObject != null) { + boolean photoExist = true; + if (messageObject.type == 1) { + File cacheFile = FileLoader.getPathToMessage(messageObject.messageOwner); + if (!cacheFile.exists()) { + photoExist = false; + } } - } - if (photoExist || MediaController.getInstance().canDownloadMedia(MediaController.AUTODOWNLOAD_MASK_PHOTO)) { - imageView.setImage(currentPhotoObject.photoOwner.location, "100_100", messageObject.imagePreview, currentPhotoObject.photoOwner.size); - photoSet = true; - } else { - if (messageObject.imagePreview != null) { - imageView.setImageBitmap(messageObject.imagePreview); + if (photoExist || MediaController.getInstance().canDownloadMedia(MediaController.AUTODOWNLOAD_MASK_PHOTO)) { + imageView.setImage(currentPhotoObject.photoOwner.location, "100_100", messageObject.imagePreview, currentPhotoObject.photoOwner.size); photoSet = true; + } else { + if (messageObject.imagePreview != null) { + imageView.setImageBitmap(messageObject.imagePreview); + photoSet = true; + } } } - } - if (!photoSet) { - imageView.setVisibility(View.GONE); - messageText.setVisibility(View.VISIBLE); - messageText.setTextSize(TypedValue.COMPLEX_UNIT_SP, MessagesController.getInstance().fontSize); - messageText.setText(messageObject.messageText); - } else { - imageView.setVisibility(View.VISIBLE); + if (!photoSet) { + imageView.setVisibility(View.GONE); + messageText.setVisibility(View.VISIBLE); + messageText.setTextSize(TypedValue.COMPLEX_UNIT_SP, MessagesController.getInstance().fontSize); + messageText.setText(messageObject.messageText); + } else { + imageView.setVisibility(View.VISIBLE); + messageText.setVisibility(View.GONE); + } + } else if (messageObject.type == 4) { messageText.setVisibility(View.GONE); + messageText.setText(messageObject.messageText); + imageView.setVisibility(View.VISIBLE); + double lat = messageObject.messageOwner.media.geo.lat; + double lon = messageObject.messageOwner.media.geo._long; + String currentUrl = String.format(Locale.US, "https://maps.googleapis.com/maps/api/staticmap?center=%f,%f&zoom=13&size=100x100&maptype=roadmap&scale=%d&markers=color:red|size:big|%f,%f&sensor=false", lat, lon, Math.min(2, (int)Math.ceil(AndroidUtilities.density)), lat, lon); + imageView.setImage(currentUrl, null, null); } } else if (messageObject.type == 2) { PopupAudioView cell = null; @@ -585,6 +598,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC }); } TextView messageText = (TextView)view.findViewById(R.id.message_text); + messageText.setTag(301); messageText.setTextSize(TypedValue.COMPLEX_UNIT_SP, MessagesController.getInstance().fontSize); messageText.setText(messageObject.messageText); } @@ -1006,7 +1020,12 @@ public class PopupNotificationActivity extends Activity implements NotificationC int count = messageContainer.getChildCount(); for (int a = 0; a < count; a++) { View view = messageContainer.getChildAt(a); - view.invalidate(); + if ((Integer)view.getTag() == 1) { + TextView textView = (TextView)view.findViewWithTag(301); + if (textView != null) { + textView.invalidate(); + } + } } } } else if (id == NotificationCenter.contactsDidLoaded) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java index 14ad761c0..71921438d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java @@ -35,7 +35,9 @@ import org.telegram.android.AndroidUtilities; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.LocaleController; import org.telegram.android.MessagesStorage; +import org.telegram.android.SecretChatHelper; import org.telegram.android.SendMessagesHelper; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.TLRPC; import org.telegram.android.ContactsController; @@ -57,11 +59,11 @@ import org.telegram.ui.Cells.UserCell; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; -import org.telegram.ui.Views.AvatarDrawable; -import org.telegram.ui.Views.AvatarUpdater; -import org.telegram.ui.Views.BackupImageView; +import org.telegram.ui.Components.AvatarDrawable; +import org.telegram.ui.Components.AvatarUpdater; +import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.Views.IdenticonDrawable; +import org.telegram.ui.Components.IdenticonDrawable; import java.util.ArrayList; import java.util.Collections; @@ -459,7 +461,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. @Override public void onClick(DialogInterface dialogInterface, int i) { creatingChat = true; - MessagesController.getInstance().startSecretChat(getParentActivity(), MessagesController.getInstance().getUser(user_id)); + SecretChatHelper.getInstance().startSecretChat(getParentActivity(), MessagesController.getInstance().getUser(user_id)); } }); builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); @@ -484,7 +486,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } } else if (i == 1) { if(Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB) { - android.text.ClipboardManager clipboard = (android.text.ClipboardManager)ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); + android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); clipboard.setText("+" + user.phone); } else { android.content.ClipboardManager clipboard = (android.content.ClipboardManager)ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); @@ -766,6 +768,11 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. if ((mask & MessagesController.UPDATE_MASK_AVATAR) != 0 || (mask & MessagesController.UPDATE_MASK_NAME) != 0 || (mask & MessagesController.UPDATE_MASK_STATUS) != 0) { updateProfileData(); } + if ((mask & MessagesController.UPDATE_MASK_PHONE) != 0) { + if (listView != null) { + listView.invalidateViews(); + } + } } else if (chat_id != 0) { if ((mask & MessagesController.UPDATE_MASK_CHAT_AVATAR) != 0 || (mask & MessagesController.UPDATE_MASK_CHAT_NAME) != 0 || (mask & MessagesController.UPDATE_MASK_CHAT_MEMBERS) != 0 || (mask & MessagesController.UPDATE_MASK_STATUS) != 0) { updateOnlineCount(); @@ -1283,7 +1290,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } else if (i == settingsKeyRow) { IdenticonDrawable identiconDrawable = new IdenticonDrawable(); TLRPC.EncryptedChat encryptedChat = MessagesController.getInstance().getEncryptedChat((int)(dialog_id >> 32)); - identiconDrawable.setBytes(encryptedChat.auth_key); + identiconDrawable.setEncryptedChat(encryptedChat); textCell.setTextAndValueDrawable(LocaleController.getString("EncryptionKey", R.string.EncryptionKey), identiconDrawable); } } else if (type == 4) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileNotificationsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileNotificationsActivity.java index a56eab28c..e569eedcb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileNotificationsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileNotificationsActivity.java @@ -30,6 +30,7 @@ import android.widget.ListView; import org.telegram.android.AndroidUtilities; import org.telegram.android.MessagesController; import org.telegram.android.MessagesStorage; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; import org.telegram.android.LocaleController; @@ -43,8 +44,8 @@ import org.telegram.ui.Cells.TextColorCell; import org.telegram.ui.Cells.TextDetailSettingsCell; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.Views.AvatarDrawable; -import org.telegram.ui.Views.ColorPickerView; +import org.telegram.ui.Components.AvatarDrawable; +import org.telegram.ui.Components.ColorPickerView; public class ProfileNotificationsActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java index b7e1bfc64..b67b3c5f5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java @@ -42,6 +42,7 @@ import org.telegram.android.AndroidUtilities; import org.telegram.android.ContactsController; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.MediaController; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.BuildVars; import org.telegram.android.LocaleController; import org.telegram.messenger.FileLoader; @@ -70,11 +71,11 @@ import org.telegram.ui.Cells.TextSettingsCell; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; -import org.telegram.ui.Views.AvatarDrawable; -import org.telegram.ui.Views.AvatarUpdater; -import org.telegram.ui.Views.BackupImageView; +import org.telegram.ui.Components.AvatarDrawable; +import org.telegram.ui.Components.AvatarUpdater; +import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.Views.NumberPicker; +import org.telegram.ui.Components.NumberPicker; import java.io.File; import java.util.ArrayList; @@ -585,6 +586,8 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter showAlertDialog(builder); } else if (i == usernameRow) { presentFragment(new ChangeUsernameActivity()); + } else if (i == numberRow) { + presentFragment(new ChangePhoneHelpActivity()); } } }); @@ -986,7 +989,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter @Override public boolean isEnabled(int i) { - return i == textSizeRow || i == enableAnimationsRow || i == notificationRow || i == backgroundRow || + return i == textSizeRow || i == enableAnimationsRow || i == notificationRow || i == backgroundRow || i == numberRow || i == askQuestionRow || i == sendLogsRow || i == sendByEnterRow || i == privacyRow || i == wifiDownloadRow || i == mobileDownloadRow || i == clearLogsRow || i == roamingDownloadRow || i == languageRow || i == usernameRow || i == switchBackendButtonRow || i == telegramFaqRow || i == contactsSortRow || i == contactsReimportRow || i == saveToGalleryRow; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java index 4c9aca489..63d0da9c5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java @@ -43,14 +43,15 @@ import com.googlecode.mp4parser.util.Path; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; import org.telegram.android.MediaController; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.Utilities; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.Views.VideoSeekBarView; -import org.telegram.ui.Views.VideoTimelineView; +import org.telegram.ui.Components.VideoSeekBarView; +import org.telegram.ui.Components.VideoTimelineView; import java.io.File; import java.util.List; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/WallpapersActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/WallpapersActivity.java index 50b3b8fc8..5f0c6a45b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/WallpapersActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/WallpapersActivity.java @@ -32,6 +32,7 @@ import android.widget.ProgressBar; import org.telegram.android.AndroidUtilities; import org.telegram.android.ImageLoader; import org.telegram.android.LocaleController; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.TLObject; import org.telegram.messenger.TLRPC; import org.telegram.messenger.ConnectionsManager; @@ -45,9 +46,9 @@ import org.telegram.messenger.Utilities; import org.telegram.ui.Adapters.BaseFragmentAdapter; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; -import org.telegram.ui.Views.BackupImageView; +import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.Views.HorizontalListView; +import org.telegram.ui.Components.HorizontalListView; import java.io.File; import java.io.FileOutputStream; diff --git a/TMessagesProj/src/main/res/drawable-hdpi/phone_change.png b/TMessagesProj/src/main/res/drawable-hdpi/phone_change.png new file mode 100644 index 000000000..dfd3a8e4b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/phone_change.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/phone_change.png b/TMessagesProj/src/main/res/drawable-mdpi/phone_change.png new file mode 100644 index 000000000..99e036d89 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/phone_change.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/phone_change.png b/TMessagesProj/src/main/res/drawable-xhdpi/phone_change.png new file mode 100644 index 000000000..770c9bd67 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/phone_change.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/phone_change.png b/TMessagesProj/src/main/res/drawable-xxhdpi/phone_change.png new file mode 100644 index 000000000..169a52164 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/phone_change.png differ diff --git a/TMessagesProj/src/main/res/layout-ar/location_view_layout.xml b/TMessagesProj/src/main/res/layout-ar/location_view_layout.xml index b82488ea2..a39c6a5e5 100644 --- a/TMessagesProj/src/main/res/layout-ar/location_view_layout.xml +++ b/TMessagesProj/src/main/res/layout-ar/location_view_layout.xml @@ -19,7 +19,7 @@ android:background="@drawable/location_panel" android:id="@+id/location_bottom_view"> - - - + - - @@ -131,7 +131,7 @@ android:enabled="false" android:layout_gravity="bottom|right"/> - - + - + - \ No newline at end of file + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/location_view_layout.xml b/TMessagesProj/src/main/res/layout/location_view_layout.xml index 9c34b9fe8..d89e26ebd 100644 --- a/TMessagesProj/src/main/res/layout/location_view_layout.xml +++ b/TMessagesProj/src/main/res/layout/location_view_layout.xml @@ -19,7 +19,7 @@ android:background="@drawable/location_panel" android:id="@+id/location_bottom_view"> - - diff --git a/TMessagesProj/src/main/res/layout/media_video_layout.xml b/TMessagesProj/src/main/res/layout/media_video_layout.xml index 810f77f3b..17de40a58 100644 --- a/TMessagesProj/src/main/res/layout/media_video_layout.xml +++ b/TMessagesProj/src/main/res/layout/media_video_layout.xml @@ -3,7 +3,7 @@ android:layout_width="100dp" android:layout_height="100dp"> - diff --git a/TMessagesProj/src/main/res/layout/photo_picker_album_layout.xml b/TMessagesProj/src/main/res/layout/photo_picker_album_layout.xml index 1773bc96d..1f966a1f8 100644 --- a/TMessagesProj/src/main/res/layout/photo_picker_album_layout.xml +++ b/TMessagesProj/src/main/res/layout/photo_picker_album_layout.xml @@ -4,7 +4,7 @@ android:layout_height="100dp" android:layout_gravity="top"> - diff --git a/TMessagesProj/src/main/res/layout/photo_picker_photo_layout.xml b/TMessagesProj/src/main/res/layout/photo_picker_photo_layout.xml index a0a6f9142..8c1440e16 100644 --- a/TMessagesProj/src/main/res/layout/photo_picker_photo_layout.xml +++ b/TMessagesProj/src/main/res/layout/photo_picker_photo_layout.xml @@ -4,7 +4,7 @@ android:layout_height="100dp" android:layout_gravity="top"> - diff --git a/TMessagesProj/src/main/res/layout/popup_image_layout.xml b/TMessagesProj/src/main/res/layout/popup_image_layout.xml index f9e1beb95..e1fbaccd1 100644 --- a/TMessagesProj/src/main/res/layout/popup_image_layout.xml +++ b/TMessagesProj/src/main/res/layout/popup_image_layout.xml @@ -7,7 +7,7 @@ android:padding="10dp" android:background="@drawable/list_selector"> - - @@ -65,7 +65,7 @@ android:textCursorDrawable="@null" android:textColor="#000000"/> - - + - + - \ No newline at end of file + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/settings_color_dialog_layout.xml b/TMessagesProj/src/main/res/layout/settings_color_dialog_layout.xml index 075480742..981b72c3a 100644 --- a/TMessagesProj/src/main/res/layout/settings_color_dialog_layout.xml +++ b/TMessagesProj/src/main/res/layout/settings_color_dialog_layout.xml @@ -5,7 +5,7 @@ android:layout_height="match_parent" android:layout_gravity="center"> - - - - - لا يوجد وسائط حفظ في الجهاز تعديل الاسم - Priority - Default - Low - High - Max - Repeat Notifications + الأولوية + افتراضي + منخفض + مرتفع + القصوى + للأبد + إعادة الإشعارات + يمكنك تغيير رقم تيليجرام الخاص بك هنا. حسابك وجميع بياناتك التي في السحاب بما فيها رسائلك، الوسائط، جهات الاتصال وغيرها سيتم نقلها للرقم الجديد.هام:]]> جميع جهات الاتصال الخاصة بك في تيليجرام سيضاف لها رقمك الجديد]]>، في حال تواجد بها رقمك القديم ولم تقم بحظره في تيليجرام. + جميع جهات الاتصال الخاصة بك في تيليجرام سيضاف لها رقمك الجديد، في حال تواجد بها رقمك القديم ولم تقم بحظره في تيليجرام. + تغيير الرقم + الرقم الجديد + سيتم إرسال رسالة قصيرة تحتوي على رمز التفعيل الخاص إلى رقمك الجديد. + الرقم %1$s لديه حساب تيليجرام مسبقًا. يرجى حذف هذا الحساب قبل محاولة تغيير رقمك. + آخر لا توجد وسائط بعد diff --git a/TMessagesProj/src/main/res/values-de/strings.xml b/TMessagesProj/src/main/res/values-de/strings.xml index 04aa57a83..3f29a8f98 100644 --- a/TMessagesProj/src/main/res/values-de/strings.xml +++ b/TMessagesProj/src/main/res/values-de/strings.xml @@ -137,7 +137,7 @@ %1$s hat dich aus der Gruppe %2$s entfernt %1$s hat die Gruppe %2$s verlassen %1$s benutzt jetzt Telegram! - %1$s,\nWir haben eine Anmeldung von einem neuen Gerät am %2$s festgestellt.\n\nGerät: %3$s\nStandort: %4$s\n\nWenn du das nicht selbst gewesen bist, melde alle anderen Sitzungen in den Telegram Einstellungen unverzüglich ab.\n\nMit freundlichen Grüßen,\nDas Telegram Team + %1$s,\nWir haben eine Anmeldung von einem neuen Gerät am %2$s festgestellt.\n\nGerät: %3$s\nStandort: %4$s\n\nWenn du das nicht selbst gewesen bist, melde alle anderen Sitzungen in den Telegram Einstellungen unverzüglich ab.\n\nMit freundlichen Grüßen,\nDein Telegram Team %1$s hat das Profilbild geändert Beantworten %1$s antworten @@ -276,8 +276,16 @@ Standard Niedrig Hoch - Max - Wiederholen Benachrichtigungen + Max. + Niemals + Erneut benachrichtigen + Du kannst deine Telefonnummer hier ändern. Dein Konto und alle Daten in der Telegram-Cloud, also Nachrichten, Medien, Kontakte, etc. werden auf das neue Konto übertragen.\n\nWichtig:]]> Alle deine Kontakte erhalten deine neue Nummer]]> ihrem Telefonbuch hinzugefügt, sofern sie deine alte Nummer gespeichert hatten und du sie nicht blockiert hattest. + Deinen Kontakten wird deine neue Nummer ihrem Telefonbuch hinzugefügt, sofern sie deine alte Nummer gespeichert hatten und du sie nicht blockiert hattest. + NUMMER ÄNDERN + Neue Nummer + Der Bestätigungscode kommt per SMS an deine neue Nummer. + Die Telefonnummer %1$s ist bereits ein Telegram Konto. Bitte lösche es, bevor du mit der Übertragung auf das neue Konto startest. + Sonstige Noch keine geteilten Medien vorhanden diff --git a/TMessagesProj/src/main/res/values-es/strings.xml b/TMessagesProj/src/main/res/values-es/strings.xml index 2f4b1ca5f..cbd2463b3 100644 --- a/TMessagesProj/src/main/res/values-es/strings.xml +++ b/TMessagesProj/src/main/res/values-es/strings.xml @@ -137,7 +137,7 @@ %1$s te expulsó del grupo %2$s %1$s dejó el grupo %2$s ¡%1$s se unió a Telegram! - %1$s,\nDetectamos un inicio de sesión en tu cuenta desde un nuevo dispositivo, el %2$s\n\nDispositivo: %3$s\nUbicación: %4$s\n\nSi no eras tú, puedes ir a Ajustes - Cerrar todas las otras sesiones.\n\nAtentamente,\nEl equipo de Telegram + %1$s,\nDetectamos un inicio de sesión en tu cuenta desde un nuevo dispositivo, el %2$s\n\nDispositivo: %3$s\nUbicación: %4$s\n\nSi no eras tú, puedes ir a Ajustes - Privacidad y seguirdad - Cerrar todas las otras sesiones.\n\nAtentamente,\nEl equipo de Telegram %1$s actualizó su foto de perfil Responder Responder a %1$s @@ -277,7 +277,15 @@ Baja Alta Máxima + Nunca Repetir notificaciones + Puedes cambiar tu número de Telegram aquí. Tu cuenta y todos tus datos de la nube — mensajes, archivos, grupos, contactos, etc., se moverán al nuevo número.\n\nImportante:]]> Todos tus contactos de Telegram tendrán tu nuevo número]]> añadido a sus agendas de contactos, siempre que hayan tenido tu número viejo y no los hayas bloqueado en Telegram. + Todos tus contactos de Telegram tendrán tu número nuevo añadido a sus agendas de contactos, siempre que hayan tenido tu número viejo y no los hayas bloqueado en Telegram. + CAMBIAR NÚMERO + Nuevo número + Enviaremos un SMS con el código de confirmación a tu nuevo número. + El número %1$s ya está vinculado a una cuenta de Telegram. Por favor, elimina esa cuenta antes de migrar al nuevo número. + Otras Aún no hay fotos ni vídeos diff --git a/TMessagesProj/src/main/res/values-it/strings.xml b/TMessagesProj/src/main/res/values-it/strings.xml index 421a1c6ff..8587d8f4a 100644 --- a/TMessagesProj/src/main/res/values-it/strings.xml +++ b/TMessagesProj/src/main/res/values-it/strings.xml @@ -133,11 +133,11 @@ %1$s ha modificato il nome del gruppo %2$s %1$s ha modificato la foto del gruppo %2$s %1$s ha invitato %3$s nel gruppo %2$s - %1$s ha rimosso %3$s dal gruppo %2$s - %1$s ti ha rimosso dal gruppo %2$s + %1$s ha espulso %3$s dal gruppo %2$s + %1$s ti ha espulso dal gruppo %2$s %1$s ha lasciato il gruppo %2$s %1$s ha iniziato a usare Telegram! - %1$s,\nAbbiamo rilevato un accesso al tuo account da un nuovo dispositivo %2$s\n\nDispositivo: %3$s\nPosizione: %4$s\n\nSe non sei stato tu, puoi andare su Impostazioni - Termina tutte le sessioni.\n\nGrazie,\nil team di Telegram + %1$s,\nAbbiamo rilevato un accesso al tuo account da un nuovo dispositivo %2$s\n\nDispositivo: %3$s\nPosizione: %4$s\n\nSe non sei stato tu, puoi andare su Impostazioni - Privacy e Sicurezza - Termina tutte le sessioni.\n\nGrazie,\nil team di Telegram %1$s ha aggiornato la foto del profilo Rispondi Rispondi a %1$s @@ -277,7 +277,15 @@ Bassa Alta Massima + Mai Ripeti Notifiche + Puoi cambiare il tuo numero di telefono qui. Il tuo account e tutti i tuoi dati cloud — messaggi, file, contatti, etc. saranno spostati sul nuovo numero.\n\nImportante:]]> a tutti i tuoi contatti di Telegram verrà aggiunto il tuo nuovo numero]]> ai contatti, purché abbiano il tuo vecchio numero e tu non li abbia bloccati su Telegram. + Tutti i tuoi contatti Telegram avranno il tuo nuovo numero tra i loro contatti, purché abbiano il tuo vecchio numero e tu non li abbia bloccati su Telegram. + CAMBIA NUMERO + Nuovo numero + Invieremo un SMS con un codice di conferma al tuo nuovo numero. + Il numero %1$s è già connesso a un account Telegram. Per favore elimina quell\'account prima di migrare ad un nuovo numero. + Altro Nessun media condiviso @@ -354,21 +362,21 @@ Imposta OK - un1 ha rimosso un2 + un1 ha espulso un2 un1 ha lasciato il gruppo un1 ha aggiunto un2 un1 ha rimosso la foto del gruppo un1 ha cambiato la foto del gruppo un1 ha cambiato il nome del gruppo in un2 un1 ha creato il gruppo - Hai rimosso un2 + Hai espulso un2 Hai lasciato il gruppo Hai aggiunto un2 Hai rimosso la foto del gruppo Hai cambiato la foto del gruppo Hai cambiato il nome del gruppo in un2 Hai creato il gruppo - un1 ti ha rimosso + un1 ti ha espulso un1 ti ha aggiunto Questo messaggio non è supportato sulla tua versione di Telegram. Aggiorna l\'applicazione per visualizzarlo: http://telegram.org/update Foto @@ -378,8 +386,8 @@ File Audio Tu - Hai catturato la schermata! - un1 ha catturato la schermata! + Hai fatto uno screenshot! + un1 ha fatto uno screenshot! Numero di telefono non valido Codice scaduto, effettua di nuovo l\'accesso diff --git a/TMessagesProj/src/main/res/values-ko/strings.xml b/TMessagesProj/src/main/res/values-ko/strings.xml index f5dc781db..bd528a8a1 100644 --- a/TMessagesProj/src/main/res/values-ko/strings.xml +++ b/TMessagesProj/src/main/res/values-ko/strings.xml @@ -277,7 +277,15 @@ 낮음 높음 최우선 - Repeat Notifications + 사용 안 함 + 알림 반복 + 텔레그램 가입 번호를 여기서 변경할 수 있습니다. 계정 및 클라우드에 저장된 메시지나 사진/동영상, 대화상대 등이 새 번호로 이동됩니다.\n\n주의:]]> 회원님의 옛 전화번호를 알고 있으며 회원님이 차단한 대화상대가 아니라면, 텔레그램 대화상대 모두의 연락처에 회원님의 새 전화번호]]>가 추가됩니다. + 회원님의 옛 전화번호를 알고 있으며 회원님이 차단한 대화상대가 아니라면, 텔레그램 대화상대 모두의 연락처에 회원님의 새 전화번호가 추가됩니다. + 번호 변경 + 새 번호 + 인증코드 메시지를 새 번호로 전송하겠습니다. + The number %1$s is already connected to a Telegram account. Please delete that account before migrating to the new number. + 기타 공유한 미디어가 없습니다 diff --git a/TMessagesProj/src/main/res/values-nl/strings.xml b/TMessagesProj/src/main/res/values-nl/strings.xml index 37a238a2a..b123ab9c9 100644 --- a/TMessagesProj/src/main/res/values-nl/strings.xml +++ b/TMessagesProj/src/main/res/values-nl/strings.xml @@ -14,9 +14,9 @@ Onjuist landnummer Je code - We hebben een sms met een activatiecode verzonden naar je telefoon + We hebben een sms-bericht met een activatiecode verzonden naar je telefoon We bellen je over %1$d:%2$02d - We bellen je… + We bellen je Code Verkeerd nummer? Geen code ontvangen? @@ -33,24 +33,24 @@ Nieuwe groep gisteren Geen resultaten - Nog geen gesprekken… + Nog geen chats Begin een gesprek door op de\nopstellen-knop rechtsboven te drukken\nof druk op de menu knop voor meer opties. - Wachten op netwerk… - Verbinden… - Bijwerken… + Wachten op netwerk + Verbinden + Bijwerken Nieuwe geheime chat - Wachten tot %s online komt… + Wachten tot %s online komt Geheime chat geannuleerd - Encryptiesleutels uitwisselen… - Geheime chat gestart met %s + Encryptiesleutels uitwisselen + %s neemt deel aan je geheime chat. Toegevoegd aan de geheime chat. Geschiedenis wissen - Verwijderen en verlaten - Gesprek verwijderen + Verwijder en verlaat + Chat verwijderen Verwijderd account - Kies een gesprek + Kies een chat Druk en houd ingedrukt - %1$s gebruikt een oudere versie van Telegram, dus worden geheime foto\'s weergegeven in de compatibiliteitsmodus.\n\nZodra %2$s Telegram updatet werken foto\'s met timers voor 1 minuut of minder in de \'Druk en houd ingedrukt\'-modus en krijg je een bericht wanneer de andere partij een schermafbeelding maakt. + %1$s gebruikt een oudere versie van Telegram, dus worden geheime foto\'s weergegeven in de compatibiliteitsmodus.\n\nZodra %2$s Telegram updatet werken foto\'s met timers voor 1 minuut of minder in de \'Druk en houd ingedrukt\'-modus en krijg je een bericht wanneer de andere partij een schermafdruk maakt. BERICHTEN Nieuwe verzendlijst @@ -63,27 +63,27 @@ Vrij: %1$s van %2$s Onbekende fout Toegangsfout - Nog geen bestanden… + Nog geen bestanden Bestanden mogen maximaal %1$s zijn Geen opslagmedium gevonden USB-overdracht actief Interne opslag Externe opslag - Systeem map + Systeemmap SD-kaart Map onzichtbaar - aan het typen… - is aan het typen… - zijn aan het typen… + aan het typen + is aan het typen + zijn aan het typen Heb je een vraag\nover Telegram? Foto maken Galerij Locatie Video - Document - Nog geen berichten hier… + Bestand + Nog geen berichten Doorgestuurd bericht Van Niets recents @@ -94,14 +94,14 @@ %s heeft je uitgenodigd voor een geheime chat. Je hebt %s uitgenodigd voor een geheime chat. Geheime chat functies: - End-to-end encryptie + End-to-end-encryptie Geen serveropslag Zelfvernietigingstimers Doorstuurbescherming Je bent verwijderd uit deze groep Je hebt deze groep verlaten Deze groep verwijderen - Verwijder dit gesprek + Chat verwijderen SLEEP OM TE ANNULEREN Opslaan in Downloads Vertaling toepassen @@ -119,7 +119,7 @@ %1$s heeft je een video gestuurd %1$s heeft een contact met je gedeeld %1$s heeft je een locatie gestuurd - %1$s heeft je een document gestuurd + %1$s heeft je een bestand gestuurd %1$s heeft je een geluidsbestand gestuurd %1$s @ %2$s: %3$s %1$s heeft een bericht gestuurd naar de groep %2$s @@ -127,7 +127,7 @@ %1$s heeft een video gestuurd naar de groep %2$s %1$s heeft een contact gedeeld met de groep %2$s %1$s heeft een locatie gestuurd naar de groep %2$s - %1$s heeft een document gestuurd naar de groep %2$s + %1$s heeft een bestand gestuurd naar de groep %2$s %1$s heeft een geluidsbestand gestuurd naar de groep %2$s %1$s heeft je uitgenodigd voor de groep %2$s %1$s heeft de naam van de groep %2$s gewijzigd @@ -137,14 +137,14 @@ %1$s heeft je verwijderd uit de groep %2$s %1$s heeft de groep %2$s verlaten %1$s heeft nu Telegram! - %1$s,\nEr is op je account ingelogd vanaf een nieuw apparaat op %2$s\n\nApparaat: %3$s\nLocatie: %4$s\n\nAls jij dit niet was, kun je alle sessies beëindigen via Instellingen – Beëindig alle andere sessies.\n\nBedankt,\nHet Telegram-team + %1$s,\nEr is op je account ingelogd vanaf een nieuw apparaat op %2$s\n\nApparaat: %3$s\nLocatie: %4$s\n\nAls jij dit niet was, kun je alle sessies beëindigen via Instellingen - Privacy en veiligheid - Beëindig alle andere sessies.\n\nBedankt,\nHet Telegram-team %1$s heeft zijn/haar profielfoto gewijzigd Antwoord Antwoord op %1$s Antwoord op %1$s %1$s %2$s - Kies een contact + Contact kiezen Nog geen contacten Hey! Zullen we overstappen op Telegram? http://telegram.org/dl2 vandaag om @@ -160,8 +160,8 @@ lang geleden gezien Nieuw bericht - Bericht verzenden naar… - Groepsnaam... + Bericht versturen naar + Groepsnaam Groepsnaam %1$d/%2$d deelnemers @@ -175,9 +175,9 @@ Delen Toevoegen Contact toevoegen - Blokkeren - Bewerken - Verwijderen + Blokkeer + Wijzig + Verwijder Thuis Mobiel Werk @@ -188,7 +188,7 @@ Encryptiesleutel Zelfvernietigingstimer Uit - Dit is een weergave van de encryptiesleutel voor deze geheime chat met ]]>%1$s]]>.
]]>Als deze afbeelding er bij ]]>%2$s]]> hetzelfde uitziet, is jullie gesprek 200%% beveiligd.
]]>Lees meer op telegram.org.
+ Dit is een weergave van de encryptiesleutel voor deze geheime chat met ]]>%1$s]]>.
]]>Als deze afbeelding er bij ]]>%2$s]]> hetzelfde uitziet, is jullie chat 200%% beveiligd.
]]>Lees meer op telegram.org.
Onbekend Info Telefoon @@ -200,17 +200,17 @@ Je naam moet minimaal 5 tekens hebben. Je naam mag niet langer zijn dan 32 tekens. Sorry, begincijfers zijn niet toegestaan. - Je kan een gebruikersnaam kiezen voor ]]>Telegram]]>. Hiermee kunnen anderen je vinden en contact met je opnemen zonder je telefoonnummer te weten.
]]>Je mag ]]>a–z]]>, ]]>0–9]]> en liggend streepje gebruiken. De minimale lengte is ]]>5]]> tekens.
+ Je kan een gebruikersnaam kiezen voor ]]>Telegram]]>. Hiermee kunnen anderen je vinden en contact met je opnemen zonder je telefoonnummer te weten.
]]>Je mag ]]>a–z]]>, ]]>0–9]]> en liggend streepje gebruiken. De minimale lengte is ]]>5]]> tekens.
Gebruikersnaam controleren. %1$s is beschikbaar. Geen Er is een fout opgetreden. - Alle meldingsinstellingen herstellen + Meldingen gereset Tekstgrootte berichten Een vraag stellen Animaties - Deblokkeren + Deblokkeer Houd een gebruiker ingedrukt om hem/haar te deblokkeren. Geen geblokkeerde gebruikers Berichtmeldingen @@ -224,7 +224,7 @@ Trillen Voorvertoningen Resetten - Alle meldingen resetten + Meldingen resetten Aangepaste meldingsinstellingen wissen voor contacten en groepen. Meldingen en geluiden Geblokkeerde gebruikers @@ -234,7 +234,7 @@ Ondersteuning Achtergrond kiezen Berichten - Verzenden met Enter + Versturen met Enter Beëindig alle andere sessies Gebeurtenissen Contact lid van Telegram @@ -244,17 +244,17 @@ Vraag een vrijwilliger Veelgestelde vragen https://telegram.org/faq - Verwijder vertaling? + Vertaling verwijderen? Ongeldig vertalingsbestand Inschakelen - Uitschakelen + Uitgeschakeld Meldingenservice - Als Google Play Services genoeg voor je is om meldingen te ontvangen kun je de Meldingenservice uitschakelen. We raden echter aan dit ingeschakeld te laten om de app in de achtergrond te laten draaien en directe meldingen te ontvangen. + Als Google Play Services genoeg voor je is om meldingen te ontvangen kun je de meldingenservice uitschakelen. We raden echter aan dit ingeschakeld te laten om de app in de achtergrond te laten draaien en directe meldingen te ontvangen. Sorteren op Importeer contacten Voornaam Achternaam - LED kleur + LED-kleur Pop-up meldingen Geen pop-up Alleen bij scherm aan @@ -263,7 +263,7 @@ Badgenummer Kort Lang - Systeem standaard + Standaardinstelling Standaardinstelling Automatisch media downloaden Bij mobiele verbinding @@ -271,13 +271,21 @@ Bij roaming Geen media Opslaan in galerij - Naam bewerken + Naam wijzigen Prioriteit Standaard Laag Hoog Max + Nooit Meldingen herhalen + Je kan je telefoonnummer hier wijzigen. Al je clouddata — berichten, bestanden, groepen, contacten, etc. zullen worden gekopieërd naar je nieuwe nummer.\n\nLet op:]]> al je Telegram-contacten krijgen je nieuwe nummer]]> in hun adresboek, ervan uitgaande dat ze je oude nummer hadden en je hen niet had geblokkeerd in Telegram. + Al je Telegram-contacten krijgen je nieuwe nummer in hun adresboek, ervan uitgaande dat ze je oude nummer hadden en je hen niet had geblokkeerd in Telegram. + NUMMER WIJZIGEN + Nieuw nummer + We sturen een sms-bericht met verificatiecode naar je nieuwe nummer. + Aan telefoonnummer %1$s is al een Telegram-account gekoppeld. Verwijder het account om te kunnen migreren naar het nieuwe nummer. + Overig Nog geen media gedeeld @@ -286,7 +294,7 @@ Hybride m hiervandaan km hiervandaan - Locatie verzenden + Locatie versturen Locatie delen Alle media weergeven @@ -332,7 +340,7 @@ Video bewerken Originele video Bewerkte video - Video versturen... + Video versturen Video comprimeren Volgende @@ -341,17 +349,17 @@ Openen Annuleren Toevoegen - Bewerken - Verzenden + Wijzig + Stuur Bellen - Kopiëren - Verwijderen + Kopieer + Verwijder Doorsturen Opnieuw proberen Van camera Uit galerij Foto verwijderen - Instellen + Stel in OK un1 heeft un2 verwijderd @@ -375,11 +383,11 @@ Video Locatie Contact - Document + Bestand Geluidsbestand Jij - Je hebt een schermafbeelding gemaakt! - un1 maakte een schermafbeelding! + Schermafdruk gemaakt! + un1 heeft een schermafdruk gemaakt! Ongeldig telefoonnummer Code verlopen. Log opnieuw in. @@ -387,7 +395,7 @@ Ongeldige code Ongeldige voornaam Ongeldige achternaam - Bezig met laden… + Bezig met laden Je hebt geen mediaspeler. Installeer een mediaspeler om door te gaan. Mail ons op sms@telegram.org en vertel ons over je probleem. Je hebt geen apps die bestandstype \'%1$s\' kunnen verwerken, gelieve een compatibele app te installeren @@ -395,21 +403,21 @@ Weet je het zeker? %1$s toevoegen aan de groep?\n\nAantal recente berichten om door te sturen: Berichten doorsturen naar %1$s? - Berichten naar %1$s verzenden? + Berichten naar %1$s versturen? Weet je zeker dat je wilt uitloggen?\n\nTelegram kun je naadloos op al je apparaten tegelijkertijd gebruiken.\n\nLet op! Als je uitlogt worden al je geheime chats verwijderd. Alle apparaten behalve het huidige apparaat uitloggen? Echt alles verwijderen en de groep verlaten? - Gesprek echt verwijderen? + Chat echt verwijderen? Weet je zeker dat je je contactinformatie wilt delen? Weet je zeker dat je deze persoon wilt blokkeren? Weet je zeker dat je deze persoon wilt deblokkeren? - Contactpersoon echt verwijderen? + Contact echt verwijderen? Weet je zeker dat je een geheime chat wilt starten? Weet je zeker dat je de registratie wilt annuleren? Geschiedenis echt wissen? %1$s echt verwijderen? - Berichten naar %1$s verzenden? - Berichten naar %1$s doorsturen? + Berichten naar %1$s versturen? + Berichten doorsturen naar %1$s? Sorry, deze functie is momenteel niet beschikbaar in jouw land. Telegram @@ -423,7 +431,7 @@ Telegram]]> bezorgt berichten sneller dan]]>elke andere applicatie. Telegram]]> is altijd gratis. Geen advertenties.]]>Geen abonnementskosten. Telegram]]> beveiligd je berichten]]>tegen aanvallen van hackers. - Telegram]]> beperkt je niet in de grootte van]]>je media of gesprekken. + Telegram]]> beperkt je niet in de grootte van]]>je media of chats. Telegram]]> biedt toegang tot je berichten]]>vanaf meerdere apparaten. Telegram]]> berichten zijn sterk versleuteld]]>en kunnen zichzelf vernietigen. Begin met chatten @@ -458,12 +466,12 @@ %1$d berichten %1$d berichten %1$d berichten - van geen enkel contactpersoon - van %1$d contactpersoon - van %1$d contactpersonen - van %1$d contactpersonen - van %1$d contactpersonen - van %1$d contactpersonen + van geen enkel contact + van %1$d contacten + van %1$d contacten + van %1$d contacten + van %1$d contacten + van %1$d contacten %1$d seconden %1$d seconde %1$d seconden @@ -476,12 +484,12 @@ %1$d minuten %1$d minuten %1$d minuten - %1$d uren + %1$d uur %1$d uur - %1$d uren - %1$d uren - %1$d uren - %1$d uren + %1$d uur + %1$d uur + %1$d uur + %1$d uur %1$d dagen %1$d dag %1$d dagen @@ -500,12 +508,12 @@ %1$d maanden %1$d maanden %1$d maanden - %1$d jaren + %1$d jaar %1$d jaar - %1$d jaren - %1$d jaren - %1$d jaren - %1$d jaren + %1$d jaar + %1$d jaar + %1$d jaar + %1$d jaar %1$d gebruikers %1$d gebruiker %1$d gebruikers diff --git a/TMessagesProj/src/main/res/values-pt-rBR/strings.xml b/TMessagesProj/src/main/res/values-pt-rBR/strings.xml index 3804be3b3..4c80221cf 100644 --- a/TMessagesProj/src/main/res/values-pt-rBR/strings.xml +++ b/TMessagesProj/src/main/res/values-pt-rBR/strings.xml @@ -106,7 +106,7 @@ Salvar em downloads Aplicar arquivo de localização Anexo não suportado - Tempo de autodestruição + Definir timer de autodestruição %1$s estabeleceu o tempo de autodestruição para %2$s Você estabeleceu o tempo de autodestruição para %1$s @@ -137,7 +137,7 @@ %1$s removeu você do grupo %2$s %1$s saiu do grupo %2$s %1$s entrou para o Telegram! - %1$s,\nNós detectamos um login na sua conta de um novo dispositivo %2$s\n\nDispositivo: %3$s\nLocalização: %4$s\nSe não foi você, você pode ir em Configurações - Terminar todas as sessões.\n\nAtenciosamente,\nTime do Telegram + %1$s,\nDetectamos um acesso à sua conta de um novo dispositivo em %2$s\n\nDispositivo: %3$s\nLocalização: %4$s\n\nCaso não tenha sido você, vá em Configurações – Privacidade e Segurança – Terminar todas as outras sessões.\n\nObrigado,\nEquipe Telegram %1$s atualizou a foto do perfil Responder Responder para %1$s @@ -157,7 +157,7 @@ visto recentemente visto na última semana visto no último mês - visto há muito tempo atrás + visto há muito tempo Nova Mensagem Enviar mensagem para... @@ -272,12 +272,20 @@ Sem mídia Salvar na galeria Editar nome - Priority - Default - Low - High - Max - Repeat Notifications + Prioridade + Padrão + Baixa + Alta + Máxima + Nunca + Repetir Notificações + Você pode trocar seu número do Telegram aqui. Sua conta e todos os seus dados — mensagens, mídia, contatos, etc. serão movidos para o novo número.\n\nImportante:]]> todos os contatos do Telegram terão seu novo número]]> adicionado às suas lista de contatos, desde que eles tenham seu antigo número e você não os tenha bloqueado no Telegram. + Todos os contatos do Telegram terão seu novo número adicionado às suas listas de contatos, desde que eles tenham seu antigo número e você não os tenha bloqueado no Telegram. + TROCAR NÚMERO + Novo número + Vamos enviar uma SMS com um código de confirmação para o seu novo número. + O número %1$s já possui uma conta do Telegram. Por favor, delete esta conta antes de migrar para o novo número. + Outro Ainda não há mídia compartilhada @@ -316,7 +324,7 @@ Alterar quem pode ver o seu Último Acesso. Quem pode ver o seu Último Acesso? Adicionar exceções - Importante: você não será capaz de ver quando foi o Último Acesso para as pessoas com quem você não compartilha quando foi seu Último Acesso. Você visualizará a última vez visto aproximada. (recentemente, dentro de uma semana, dentro de um mês). + Importante: você não será capaz de ver quando foi o Último Acesso das pessoas com quem você não compartilha quando foi seu Último Acesso. Você visualizará o Último acesso aproximado (recentemente, dentro de uma semana, dentro de um mês). Sempre Mostrar Para Nunca Mostrar Para Estas configurações irão substituir os valores anteriores. diff --git a/TMessagesProj/src/main/res/values-pt-rPT/strings.xml b/TMessagesProj/src/main/res/values-pt-rPT/strings.xml index 3aa9c8253..33d3bb7f4 100644 --- a/TMessagesProj/src/main/res/values-pt-rPT/strings.xml +++ b/TMessagesProj/src/main/res/values-pt-rPT/strings.xml @@ -106,7 +106,7 @@ Salvar em downloads Aplicar arquivo de localização Anexo não suportado - Tempo de autodestruição + Definir timer de autodestruição %1$s estabeleceu o tempo de autodestruição para %2$s Você estabeleceu o tempo de autodestruição para %1$s @@ -137,7 +137,7 @@ %1$s removeu você do grupo %2$s %1$s saiu do grupo %2$s %1$s entrou para o Telegram! - %1$s,\nNós detectamos um login na sua conta de um novo dispositivo %2$s\n\nDispositivo: %3$s\nLocalização: %4$s\nSe não foi você, você pode ir em Configurações - Terminar todas as sessões.\n\nAtenciosamente,\nTime do Telegram + %1$s,\nDetectamos um acesso à sua conta de um novo dispositivo em %2$s\n\nDispositivo: %3$s\nLocalização: %4$s\n\nCaso não tenha sido você, vá em Configurações – Privacidade e Segurança – Terminar todas as outras sessões.\n\nObrigado,\nEquipe Telegram %1$s atualizou a foto do perfil Responder Responder para %1$s @@ -157,7 +157,7 @@ visto recentemente visto na última semana visto no último mês - visto há muito tempo atrás + visto há muito tempo Nova Mensagem Enviar mensagem para... @@ -272,12 +272,20 @@ Sem mídia Salvar na galeria Editar nome - Priority - Default - Low - High - Max - Repeat Notifications + Prioridade + Padrão + Baixa + Alta + Máxima + Nunca + Repetir Notificações + Você pode trocar seu número do Telegram aqui. Sua conta e todos os seus dados — mensagens, mídia, contatos, etc. serão movidos para o novo número.\n\nImportante:]]> todos os contatos do Telegram terão seu novo número]]> adicionado às suas lista de contatos, desde que eles tenham seu antigo número e você não os tenha bloqueado no Telegram. + Todos os contatos do Telegram terão seu novo número adicionado às suas listas de contatos, desde que eles tenham seu antigo número e você não os tenha bloqueado no Telegram. + TROCAR NÚMERO + Novo número + Vamos enviar uma SMS com um código de confirmação para o seu novo número. + O número %1$s já possui uma conta do Telegram. Por favor, delete esta conta antes de migrar para o novo número. + Outro Ainda não há mídia compartilhada @@ -316,7 +324,7 @@ Alterar quem pode ver o seu Último Acesso. Quem pode ver o seu Último Acesso? Adicionar exceções - Importante: você não será capaz de ver quando foi o Último Acesso para as pessoas com quem você não compartilha quando foi seu Último Acesso. Você visualizará a última vez visto aproximada. (recentemente, dentro de uma semana, dentro de um mês). + Importante: você não será capaz de ver quando foi o Último Acesso das pessoas com quem você não compartilha quando foi seu Último Acesso. Você visualizará o Último acesso aproximado (recentemente, dentro de uma semana, dentro de um mês). Sempre Mostrar Para Nunca Mostrar Para Estas configurações irão substituir os valores anteriores. diff --git a/TMessagesProj/src/main/res/values-v21/styles.xml b/TMessagesProj/src/main/res/values-v21/styles.xml index 87fc512cb..97ee0af7d 100644 --- a/TMessagesProj/src/main/res/values-v21/styles.xml +++ b/TMessagesProj/src/main/res/values-v21/styles.xml @@ -44,6 +44,7 @@ @null false true + #99000000