diff --git a/TMessagesProj/build.gradle b/TMessagesProj/build.gradle index 5fbedf976..7aa13b57d 100644 --- a/TMessagesProj/build.gradle +++ b/TMessagesProj/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:1.0.0' + classpath 'com.android.tools.build:gradle:1.1.3' } } apply plugin: 'com.android.application' @@ -13,7 +13,7 @@ repositories { } dependencies { - compile 'com.android.support:support-v4:21.0.+' + compile 'com.android.support:support-v4:22.0.+' compile 'com.google.android.gms:play-services:3.2.+' compile 'net.hockeyapp.android:HockeySDK:3.5.+' compile 'com.googlecode.mp4parser:isoparser:1.0.+' @@ -21,8 +21,8 @@ dependencies { } android { - compileSdkVersion 21 - buildToolsVersion '21.1.2' + compileSdkVersion 22 + buildToolsVersion '22.0.1' compileOptions { sourceCompatibility JavaVersion.VERSION_1_7 @@ -81,8 +81,8 @@ android { defaultConfig { minSdkVersion 8 - targetSdkVersion 21 - versionCode 423 - versionName "2.4.0" + targetSdkVersion 22 + versionCode 492 + versionName "2.7.0" } } diff --git a/TMessagesProj/config/debug/AndroidManifest.xml b/TMessagesProj/config/debug/AndroidManifest.xml index 7836674f2..a9ed995de 100644 --- a/TMessagesProj/config/debug/AndroidManifest.xml +++ b/TMessagesProj/config/debug/AndroidManifest.xml @@ -24,7 +24,7 @@ android:label="@string/AppName" android:theme="@style/Theme.TMessages.Start" android:name=".ApplicationLoader" - android:hardwareAccelerated="true" + android:hardwareAccelerated="@bool/useHardwareAcceleration" android:largeHeap="true"> diff --git a/TMessagesProj/config/foss/AndroidManifest.xml b/TMessagesProj/config/foss/AndroidManifest.xml index df2d1e24b..59b2f53b4 100644 --- a/TMessagesProj/config/foss/AndroidManifest.xml +++ b/TMessagesProj/config/foss/AndroidManifest.xml @@ -9,7 +9,7 @@ android:label="@string/AppName" android:theme="@style/Theme.TMessages.Start" android:name=".ApplicationLoader" - android:hardwareAccelerated="true" + android:hardwareAccelerated="@bool/useHardwareAcceleration" android:largeHeap="true"> diff --git a/TMessagesProj/config/release/AndroidManifest.xml b/TMessagesProj/config/release/AndroidManifest.xml index 17c2c2458..f2b0b5627 100644 --- a/TMessagesProj/config/release/AndroidManifest.xml +++ b/TMessagesProj/config/release/AndroidManifest.xml @@ -24,7 +24,7 @@ android:label="@string/AppName" android:theme="@style/Theme.TMessages.Start" android:name=".ApplicationLoader" - android:hardwareAccelerated="true" + android:hardwareAccelerated="@bool/useHardwareAcceleration" android:largeHeap="true"> diff --git a/TMessagesProj/jni/Android.mk b/TMessagesProj/jni/Android.mk index 88b4e6394..f9b84ba96 100755 --- a/TMessagesProj/jni/Android.mk +++ b/TMessagesProj/jni/Android.mk @@ -104,7 +104,7 @@ include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_PRELINK_MODULE := false LOCAL_STATIC_LIBRARIES := webp sqlite -LOCAL_MODULE := tmessages.5 +LOCAL_MODULE := tmessages.7 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 -ffast-math diff --git a/TMessagesProj/jni/image.c b/TMessagesProj/jni/image.c index 1532095b2..85a859007 100644 --- a/TMessagesProj/jni/image.c +++ b/TMessagesProj/jni/image.c @@ -21,6 +21,9 @@ jmethodID jclass_Bitmap_createBitmap; jclass jclass_Config; jfieldID jclass_Config_ARGB_8888; +const uint32_t PGPhotoEnhanceHistogramBins = 256; +const uint32_t PGPhotoEnhanceSegments = 4; + jclass createGlobarRef(JNIEnv *env, jclass class) { if (class) { return (*env)->NewGlobalRef(env, class); @@ -312,6 +315,115 @@ JNIEXPORT void Java_org_telegram_messenger_Utilities_blurBitmap(JNIEnv *env, jcl AndroidBitmap_unlockPixels(env, bitmap); } +JNIEXPORT void Java_org_telegram_messenger_Utilities_calcCDT(JNIEnv *env, jclass class, jobject hsvBuffer, int width, int height, jobject buffer) { + float imageWidth = width; + float imageHeight = height; + float _clipLimit = 1.25f; + + uint32_t totalSegments = PGPhotoEnhanceSegments * PGPhotoEnhanceSegments; + uint32_t tileArea = (uint32_t)(floorf(imageWidth / PGPhotoEnhanceSegments) * floorf(imageHeight / PGPhotoEnhanceSegments)); + uint32_t clipLimit = (uint32_t)max(1, _clipLimit * tileArea / (float) PGPhotoEnhanceHistogramBins); + float scale = 255.0f / (float) tileArea; + + + unsigned char *bytes = (*env)->GetDirectBufferAddress(env, hsvBuffer); + + uint32_t **hist = calloc(totalSegments, sizeof(uint32_t *)); + uint32_t **cdfs = calloc(totalSegments, sizeof(uint32_t *)); + uint32_t *cdfsMin = calloc(totalSegments, sizeof(uint32_t)); + uint32_t *cdfsMax = calloc(totalSegments, sizeof(uint32_t)); + + for (uint32_t a = 0; a < totalSegments; a++) { + hist[a] = calloc(PGPhotoEnhanceHistogramBins, sizeof(uint32_t)); + cdfs[a] = calloc(PGPhotoEnhanceHistogramBins, sizeof(uint32_t)); + } + + float xMul = PGPhotoEnhanceSegments / imageWidth; + float yMul = PGPhotoEnhanceSegments / imageHeight; + + for (uint32_t y = 0; y < imageHeight; y++) { + uint32_t yOffset = y * width * 4; + for (uint32_t x = 0; x < imageWidth; x++) { + uint32_t index = x * 4 + yOffset; + + uint32_t tx = (uint32_t)(x * xMul); + uint32_t ty = (uint32_t)(y * yMul); + uint32_t t = ty * PGPhotoEnhanceSegments + tx; + + hist[t][bytes[index + 2]]++; + } + } + + for (uint32_t i = 0; i < totalSegments; i++) { + if (clipLimit > 0) { + uint32_t clipped = 0; + for (uint32_t j = 0; j < PGPhotoEnhanceHistogramBins; ++j) { + if (hist[i][j] > clipLimit) { + clipped += hist[i][j] - clipLimit; + hist[i][j] = clipLimit; + } + } + + uint32_t redistBatch = clipped / PGPhotoEnhanceHistogramBins; + uint32_t residual = clipped - redistBatch * PGPhotoEnhanceHistogramBins; + + for (uint32_t j = 0; j < PGPhotoEnhanceHistogramBins; ++j) { + hist[i][j] += redistBatch; + } + + for (uint32_t j = 0; j < residual; ++j) { + hist[i][j]++; + } + } + memcpy(cdfs[i], hist[i], PGPhotoEnhanceHistogramBins * sizeof(uint32_t)); + + uint32_t hMin = PGPhotoEnhanceHistogramBins - 1; + for (uint32_t j = 0; j < hMin; ++j) { + if (cdfs[j] != 0) { + hMin = j; + } + } + + uint32_t cdf = 0; + for (uint32_t j = hMin; j < PGPhotoEnhanceHistogramBins; ++j) { + cdf += cdfs[i][j]; + cdfs[i][j] = (uint8_t) min(255, cdf * scale); + } + + cdfsMin[i] = cdfs[i][hMin]; + cdfsMax[i] = cdfs[i][PGPhotoEnhanceHistogramBins - 1]; + } + + uint32_t resultSize = 4 * PGPhotoEnhanceHistogramBins * totalSegments; + uint32_t resultBytesPerRow = 4 * PGPhotoEnhanceHistogramBins; + + unsigned char *result = (*env)->GetDirectBufferAddress(env, buffer); + for (uint32_t tile = 0; tile < totalSegments; tile++) { + uint32_t yOffset = tile * resultBytesPerRow; + for (uint32_t i = 0; i < PGPhotoEnhanceHistogramBins; i++) { + uint32_t index = i * 4 + yOffset; + result[index] = (uint8_t)cdfs[tile][i]; + result[index + 1] = (uint8_t)cdfsMin[tile]; + result[index + 2] = (uint8_t)cdfsMax[tile]; + result[index + 3] = 255; + } + } + + for (uint32_t a = 0; a < totalSegments; a++) { + free(hist[a]); + free(cdfs[a]); + } + free(hist); + free(cdfs); + free(cdfsMax); + free(cdfsMin); +} + +JNIEXPORT int Java_org_telegram_messenger_Utilities_pinBitmap(JNIEnv *env, jclass class, jobject bitmap) { + unsigned char *pixels; + return AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0 ? 1 : 0; +} + JNIEXPORT void Java_org_telegram_messenger_Utilities_loadBitmap(JNIEnv *env, jclass class, jstring path, jobject bitmap, int scale, int width, int height, int stride) { AndroidBitmapInfo info; diff --git a/TMessagesProj/libs/armeabi-v7a/libtmessages.5.so b/TMessagesProj/libs/armeabi-v7a/libtmessages.7.so similarity index 85% rename from TMessagesProj/libs/armeabi-v7a/libtmessages.5.so rename to TMessagesProj/libs/armeabi-v7a/libtmessages.7.so index 132154abf..c086f4a98 100755 Binary files a/TMessagesProj/libs/armeabi-v7a/libtmessages.5.so and b/TMessagesProj/libs/armeabi-v7a/libtmessages.7.so differ diff --git a/TMessagesProj/libs/armeabi/libtmessages.5.so b/TMessagesProj/libs/armeabi/libtmessages.7.so similarity index 77% rename from TMessagesProj/libs/armeabi/libtmessages.5.so rename to TMessagesProj/libs/armeabi/libtmessages.7.so index 3e08cd8f7..42ad265ae 100755 Binary files a/TMessagesProj/libs/armeabi/libtmessages.5.so and b/TMessagesProj/libs/armeabi/libtmessages.7.so differ diff --git a/TMessagesProj/libs/x86/libtmessages.5.so b/TMessagesProj/libs/x86/libtmessages.7.so similarity index 72% rename from TMessagesProj/libs/x86/libtmessages.5.so rename to TMessagesProj/libs/x86/libtmessages.7.so index 326a064f8..aaa768eac 100755 Binary files a/TMessagesProj/libs/x86/libtmessages.5.so and b/TMessagesProj/libs/x86/libtmessages.7.so differ diff --git a/TMessagesProj/src/main/AndroidManifest.xml b/TMessagesProj/src/main/AndroidManifest.xml index 5ca90c91e..dd3c5fc25 100644 --- a/TMessagesProj/src/main/AndroidManifest.xml +++ b/TMessagesProj/src/main/AndroidManifest.xml @@ -43,7 +43,7 @@ diff --git a/TMessagesProj/src/main/java/jawnae/pyronet/ByteStream.java b/TMessagesProj/src/main/java/jawnae/pyronet/ByteStream.java index 39966ac18..878a92acd 100755 --- a/TMessagesProj/src/main/java/jawnae/pyronet/ByteStream.java +++ b/TMessagesProj/src/main/java/jawnae/pyronet/ByteStream.java @@ -28,7 +28,7 @@ public class ByteStream { private final ArrayList queue; public ByteStream() { - this.queue = new ArrayList(); + this.queue = new ArrayList<>(); } public void append(ByteBufferDesc buf) { diff --git a/TMessagesProj/src/main/java/jawnae/pyronet/PyroClientListener.java b/TMessagesProj/src/main/java/jawnae/pyronet/PyroClientListener.java index 117cb1b83..a24913a13 100755 --- a/TMessagesProj/src/main/java/jawnae/pyronet/PyroClientListener.java +++ b/TMessagesProj/src/main/java/jawnae/pyronet/PyroClientListener.java @@ -22,17 +22,17 @@ import java.io.IOException; import java.nio.ByteBuffer; public interface PyroClientListener { - public void connectedClient(PyroClient client); + void connectedClient(PyroClient client); - public void unconnectableClient(PyroClient client, Exception cause); + void unconnectableClient(PyroClient client, Exception cause); - public void droppedClient(PyroClient client, IOException cause); + void droppedClient(PyroClient client, IOException cause); - public void disconnectedClient(PyroClient client); + void disconnectedClient(PyroClient client); // - public void receivedData(PyroClient client, ByteBuffer data); + void receivedData(PyroClient client, ByteBuffer data); - public void sentData(PyroClient client, int bytes); + void sentData(PyroClient client, int bytes); } diff --git a/TMessagesProj/src/main/java/org/telegram/PhoneFormat/PhoneFormat.java b/TMessagesProj/src/main/java/org/telegram/PhoneFormat/PhoneFormat.java index a6dbff0ac..63081ef8b 100644 --- a/TMessagesProj/src/main/java/org/telegram/PhoneFormat/PhoneFormat.java +++ b/TMessagesProj/src/main/java/org/telegram/PhoneFormat/PhoneFormat.java @@ -25,6 +25,7 @@ package org.telegram.PhoneFormat; import org.telegram.messenger.ApplicationLoader; +import org.telegram.messenger.FileLog; import java.io.ByteArrayOutputStream; import java.io.InputStream; @@ -97,9 +98,11 @@ public class PhoneFormat { } public void init(String countryCode) { + InputStream stream = null; + ByteArrayOutputStream bos = null; try { - InputStream stream = ApplicationLoader.applicationContext.getAssets().open("PhoneFormats.dat"); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); + stream = ApplicationLoader.applicationContext.getAssets().open("PhoneFormats.dat"); + bos = new ByteArrayOutputStream(); byte[] buf = new byte[1024]; int len; while ((len = stream.read(buf, 0, 1024)) != -1) { @@ -111,6 +114,21 @@ public class PhoneFormat { } catch (Exception e) { e.printStackTrace(); return; + } finally { + try { + if (bos != null) { + bos.close(); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + try { + if (stream != null) { + stream.close(); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } } if (countryCode != null && countryCode.length() != 0) { @@ -119,10 +137,10 @@ public class PhoneFormat { Locale loc = Locale.getDefault(); defaultCountry = loc.getCountry().toLowerCase(); } - callingCodeOffsets = new HashMap(255); - callingCodeCountries = new HashMap>(255); - callingCodeData = new HashMap(10); - countryCallingCode = new HashMap(255); + callingCodeOffsets = new HashMap<>(255); + callingCodeCountries = new HashMap<>(255); + callingCodeData = new HashMap<>(10); + countryCallingCode = new HashMap<>(255); parseDataHeader(); initialzed = true; @@ -293,7 +311,7 @@ public class PhoneFormat { offset += 2; - ArrayList strs = new ArrayList(5); + ArrayList strs = new ArrayList<>(5); String str; while ((str = valueString(offset)).length() != 0) { strs.add(str); @@ -302,14 +320,14 @@ public class PhoneFormat { res.trunkPrefixes = strs; offset++; - strs = new ArrayList(5); + strs = new ArrayList<>(5); while ((str = valueString(offset)).length() != 0) { strs.add(str); offset += str.length() + 1; } res.intlPrefixes = strs; - ArrayList ruleSets = new ArrayList(setCnt); + ArrayList ruleSets = new ArrayList<>(setCnt); offset = start + block1Len; for (int s = 0; s < setCnt; s++) { RuleSet ruleSet = new RuleSet(); @@ -317,7 +335,7 @@ public class PhoneFormat { offset += 2; int ruleCnt = value16(offset); offset += 2; - ArrayList rules = new ArrayList(ruleCnt); + ArrayList rules = new ArrayList<>(ruleCnt); for (int r = 0; r < ruleCnt; r++) { PhoneRule rule = new PhoneRule(); rule.minVal = value32(offset); @@ -380,7 +398,7 @@ public class PhoneFormat { callingCodeOffsets.put(callingCode, offset); ArrayList countries = callingCodeCountries.get(callingCode); if (countries == null) { - countries = new ArrayList(); + countries = new ArrayList<>(); callingCodeCountries.put(callingCode, countries); } countries.add(country); diff --git a/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java b/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java index 4455445f2..b14c401b2 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java +++ b/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java @@ -14,6 +14,7 @@ import android.content.Context; import android.content.DialogInterface; import android.content.pm.ActivityInfo; import android.content.res.Configuration; +import android.graphics.Color; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Typeface; @@ -23,6 +24,8 @@ import android.os.Environment; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.Spanned; +import android.text.style.ForegroundColorSpan; +import android.util.DisplayMetrics; import android.util.StateSet; import android.view.Display; import android.view.Surface; @@ -33,12 +36,20 @@ import android.widget.AbsListView; import android.widget.EdgeEffect; import android.widget.EditText; import android.widget.ListView; +import android.widget.ProgressBar; import android.widget.TextView; +import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.messenger.ApplicationLoader; +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.Components.ForegroundDetector; import org.telegram.ui.Components.NumberPicker; import org.telegram.ui.Components.TypefaceSpan; @@ -59,15 +70,18 @@ public class AndroidUtilities { public static float density = 1; public static Point displaySize = new Point(); public static Integer photoSize = null; + public static DisplayMetrics displayMetrics = new DisplayMetrics(); + public static int leftBaseline; private static Boolean isTablet = null; static { density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density; + leftBaseline = isTablet() ? 80 : 72; checkDisplaySize(); } public static void lockOrientation(Activity activity) { - if (activity == null || prevOrientation != -10) { + if (activity == null || prevOrientation != -10 || Build.VERSION.SDK_INT < 9) { return; } try { @@ -115,7 +129,7 @@ public class AndroidUtilities { } public static void unlockOrientation(Activity activity) { - if (activity == null) { + if (activity == null || Build.VERSION.SDK_INT < 9) { return; } try { @@ -163,8 +177,6 @@ public class AndroidUtilities { } InputMethodManager inputManager = (InputMethodManager)view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); inputManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT); - - ((InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(view, 0); } public static boolean isKeyboardShowed(View view) { @@ -228,12 +240,13 @@ public class AndroidUtilities { if (manager != null) { Display display = manager.getDefaultDisplay(); if (display != null) { + display.getMetrics(displayMetrics); if(android.os.Build.VERSION.SDK_INT < 13) { displaySize.set(display.getWidth(), display.getHeight()); } else { display.getSize(displaySize); } - FileLog.e("tmessages", "display size = " + displaySize.x + " " + displaySize.y); + FileLog.e("tmessages", "display size = " + displaySize.x + " " + displaySize.y + " " + displayMetrics.xdpi + "x" + displayMetrics.ydpi); } } } catch (Exception e) { @@ -241,6 +254,10 @@ public class AndroidUtilities { } } + public static float getPixelsInCM(float cm, boolean isX) { + return (cm / 2.54f) * (isX ? displayMetrics.xdpi : displayMetrics.ydpi); + } + public static long makeBroadcastId(int id) { return 0x0000000100000000L | ((long)id & 0x00000000FFFFFFFFL); } @@ -421,6 +438,19 @@ public class AndroidUtilities { } } + public static void setProgressBarAnimationDuration(ProgressBar progressBar, int duration) { + if (progressBar == null) { + return; + } + try { + Field mCursorDrawableRes = ProgressBar.class.getDeclaredField("mDuration"); + mCursorDrawableRes.setAccessible(true); + mCursorDrawableRes.setInt(progressBar, duration); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + public static int getViewInset(View view) { if (view == null || Build.VERSION.SDK_INT < 21) { return 0; @@ -514,20 +544,133 @@ 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); + public static Spannable replaceTags(String str) { + try { + int start = -1; + int startColor = -1; + int end = -1; + StringBuilder stringBuilder = new StringBuilder(str); + while ((start = stringBuilder.indexOf("
")) != -1) { + stringBuilder.replace(start, start + 4, "\n"); + } + while ((start = stringBuilder.indexOf("
")) != -1) { + stringBuilder.replace(start, start + 5, "\n"); + } + ArrayList bolds = new ArrayList<>(); + ArrayList colors = new ArrayList<>(); + while ((start = stringBuilder.indexOf("")) != -1 || (startColor = stringBuilder.indexOf(""); + stringBuilder.replace(end, end + 4, ""); + bolds.add(start); + bolds.add(end); + } else if (startColor != -1) { + stringBuilder.replace(startColor, startColor + 2, ""); + end = stringBuilder.indexOf(">", startColor); + int color = Color.parseColor(stringBuilder.substring(startColor, end)); + stringBuilder.replace(startColor, end + 1, ""); + end = stringBuilder.indexOf(""); + stringBuilder.replace(end, end + 4, ""); + colors.add(startColor); + colors.add(end); + colors.add(color); + } + } + SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(stringBuilder); + for (int a = 0; a < bolds.size() / 2; a++) { + spannableStringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), bolds.get(a * 2), bolds.get(a * 2 + 1), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } + for (int a = 0; a < colors.size() / 3; a++) { + spannableStringBuilder.setSpan(new ForegroundColorSpan(colors.get(a * 3 + 2)), colors.get(a * 3), colors.get(a * 3 + 1), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } + return spannableStringBuilder; + } catch (Exception e) { + FileLog.e("tmessages", e); } - 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; + return new SpannableStringBuilder(str); } + + public static boolean needShowPasscode(boolean reset) { + boolean wasInBackground; + if (Build.VERSION.SDK_INT >= 14) { + wasInBackground = ForegroundDetector.getInstance().isWasInBackground(reset); + if (reset) { + ForegroundDetector.getInstance().resetBackgroundVar(); + } + } else { + wasInBackground = UserConfig.lastPauseTime != 0; + } + return UserConfig.passcodeHash.length() > 0 && wasInBackground && + (UserConfig.appLocked || UserConfig.autoLockIn != 0 && UserConfig.lastPauseTime != 0 && !UserConfig.appLocked && (UserConfig.lastPauseTime + UserConfig.autoLockIn) <= ConnectionsManager.getInstance().getCurrentTime()); + } + + public static void shakeTextView(final TextView textView, final float x, final int num) { + if (num == 6) { + ViewProxy.setTranslationX(textView, 0); + textView.clearAnimation(); + return; + } + AnimatorSetProxy animatorSetProxy = new AnimatorSetProxy(); + animatorSetProxy.playTogether(ObjectAnimatorProxy.ofFloat(textView, "translationX", AndroidUtilities.dp(x))); + animatorSetProxy.setDuration(50); + animatorSetProxy.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + shakeTextView(textView, num == 5 ? 0 : -x, num + 1); + } + }); + animatorSetProxy.start(); + } + + + + /*public static String ellipsize(String text, int maxLines, int maxWidth, TextPaint paint) { + if (text == null || paint == null) { + return null; + } + int count; + int offset = 0; + StringBuilder result = null; + TextView + for (int a = 0; a < maxLines; a++) { + count = paint.breakText(text, true, maxWidth, null); + if (a != maxLines - 1) { + if (result == null) { + result = new StringBuilder(count * maxLines + 1); + } + boolean foundSpace = false; + for (int c = count - 1; c >= offset; c--) { + if (text.charAt(c) == ' ') { + foundSpace = true; + result.append(text.substring(offset, c - 1)); + offset = c - 1; + } + } + if (!foundSpace) { + offset = count; + } + text = text.substring(0, offset); + } else if (maxLines == 1) { + return text.substring(0, count); + } else { + result.append(text.substring(0, count)); + } + } + return result.toString(); + }*/ + + /*public static void turnOffHardwareAcceleration(Window window) { + if (window == null || Build.MODEL == null || Build.VERSION.SDK_INT < 11) { + return; + } + if (Build.MODEL.contains("GT-S5301") || + Build.MODEL.contains("GT-S5303") || + Build.MODEL.contains("GT-B5330") || + Build.MODEL.contains("GT-S5302") || + Build.MODEL.contains("GT-S6012B") || + Build.MODEL.contains("MegaFon_SP-AI")) { + window.clearFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); + } + }*/ } diff --git a/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java b/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java index 75cb7bcbc..84ac04327 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java @@ -54,6 +54,7 @@ public class ContactsController { private ArrayList delayedContactsUpdate = new ArrayList<>(); private String inviteText; private boolean updatingInviteText = false; + private HashMap sectionsToReplace = new HashMap<>(); private int loadingDeleteInfo = 0; private int deleteAccountTTL; @@ -114,6 +115,28 @@ public class ContactsController { if (preferences.getBoolean("needGetStatuses", false)) { reloadContactsStatuses(); } + + sectionsToReplace.put("À", "A"); + sectionsToReplace.put("Á", "A"); + sectionsToReplace.put("Ä", "A"); + sectionsToReplace.put("Ù", "U"); + sectionsToReplace.put("Ú", "U"); + sectionsToReplace.put("Ü", "U"); + sectionsToReplace.put("Ì", "I"); + sectionsToReplace.put("Í", "I"); + sectionsToReplace.put("Ï", "I"); + sectionsToReplace.put("È", "E"); + sectionsToReplace.put("É", "E"); + sectionsToReplace.put("Ê", "E"); + sectionsToReplace.put("Ë", "E"); + sectionsToReplace.put("Ò", "O"); + sectionsToReplace.put("Ó", "O"); + sectionsToReplace.put("Ö", "O"); + sectionsToReplace.put("Ç", "C"); + sectionsToReplace.put("Ñ", "N"); + sectionsToReplace.put("Ÿ", "Y"); + sectionsToReplace.put("Ý", "Y"); + sectionsToReplace.put("Ţ", "Y"); } public void cleanup() { @@ -514,10 +537,10 @@ public class ContactsController { checkContactsInternal(); } final HashMap contactsMap = readContactsFromPhoneBook(); - final HashMap contactsBookShort = new HashMap(); + final HashMap contactsBookShort = new HashMap<>(); int oldCount = contactHashMap.size(); - ArrayList toImport = new ArrayList(); + ArrayList toImport = new ArrayList<>(); if (!contactHashMap.isEmpty()) { for (HashMap.Entry pair : contactsMap.entrySet()) { Integer id = pair.getKey(); @@ -619,10 +642,10 @@ public class ContactsController { } } - final ArrayList toDelete = new ArrayList(); + final ArrayList toDelete = new ArrayList<>(); if (contactHashMap != null && !contactHashMap.isEmpty()) { try { - final HashMap contactsPhonesShort = new HashMap(); + final HashMap contactsPhonesShort = new HashMap<>(); for (TLRPC.TL_contact value : contacts) { TLRPC.User user = MessagesController.getInstance().getUser(value.user_id); @@ -692,7 +715,7 @@ public class ContactsController { } final int count = (int)Math.ceil(toImport.size() / 500.0f); for (int a = 0; a < count; a++) { - ArrayList finalToImport = new ArrayList(); + ArrayList finalToImport = new ArrayList<>(); finalToImport.addAll(toImport.subList(a * 500, Math.min((a + 1) * 500, toImport.size()))); TLRPC.TL_contacts_importContacts req = new TLRPC.TL_contacts_importContacts(); req.contacts = finalToImport; @@ -713,7 +736,7 @@ public class ContactsController { // } } MessagesStorage.getInstance().putUsersAndChats(res.users, null, true, true); - ArrayList cArr = new ArrayList(); + ArrayList cArr = new ArrayList<>(); for (TLRPC.TL_importedContact c : res.imported) { TLRPC.TL_contact contact = new TLRPC.TL_contact(); contact.user_id = c.user_id; @@ -848,7 +871,7 @@ public class ContactsController { public void run() { MessagesController.getInstance().putUsers(usersArr, from == 1); - final HashMap usersDict = new HashMap(); + final HashMap usersDict = new HashMap<>(); final boolean isEmpty = contactsArr.isEmpty(); @@ -933,9 +956,9 @@ public class ContactsController { } }); - final SparseArray contactsDictionary = new SparseArray(); - final HashMap> sectionsDict = new HashMap>(); - final ArrayList sortedSectionsArray = new ArrayList(); + final SparseArray contactsDictionary = new SparseArray<>(); + final HashMap> sectionsDict = new HashMap<>(); + final ArrayList sortedSectionsArray = new ArrayList<>(); HashMap contactsByPhonesDict = null; if (!contactsBookLoaded) { @@ -958,13 +981,17 @@ public class ContactsController { if (key == null || key.length() == 0) { key = user.last_name; } + if (key.length() > 1) { + key = key.substring(0, 1); + } if (key.length() == 0) { key = "#"; } else { key = key.toUpperCase(); } - if (key.length() > 1) { - key = key.substring(0, 1); + String replace = sectionsToReplace.get(key); + if (replace != null) { + key = replace; } ArrayList arr = sectionsDict.get(key); if (arr == null) { @@ -1067,7 +1094,7 @@ public class ContactsController { } private void updateUnregisteredContacts(final ArrayList contactsArr) { - final HashMap contactsPhonesShort = new HashMap(); + final HashMap contactsPhonesShort = new HashMap<>(); for (TLRPC.TL_contact value : contactsArr) { TLRPC.User user = MessagesController.getInstance().getUser(value.user_id); @@ -1077,7 +1104,7 @@ public class ContactsController { contactsPhonesShort.put(user.phone, value); } - final ArrayList sortedPhoneBookContacts = new ArrayList(); + final ArrayList sortedPhoneBookContacts = new ArrayList<>(); for (HashMap.Entry pair : contactsBook.entrySet()) { Contact value = pair.getValue(); int id = pair.getKey(); @@ -1135,8 +1162,8 @@ public class ContactsController { } StringBuilder ids = new StringBuilder(); - final HashMap> sectionsDict = new HashMap>(); - final ArrayList sortedSectionsArray = new ArrayList(); + final HashMap> sectionsDict = new HashMap<>(); + final ArrayList sortedSectionsArray = new ArrayList<>(); for (TLRPC.TL_contact value : contacts) { TLRPC.User user = MessagesController.getInstance().getUser(value.user_id); @@ -1148,17 +1175,21 @@ public class ContactsController { if (key == null || key.length() == 0) { key = user.last_name; } + if (key.length() > 1) { + key = key.substring(0, 1); + } if (key.length() == 0) { key = "#"; } else { key = key.toUpperCase(); } - if (key.length() > 1) { - key = key.substring(0, 1); + String replace = sectionsToReplace.get(key); + if (replace != null) { + key = replace; } ArrayList arr = sectionsDict.get(key); if (arr == null) { - arr = new ArrayList(); + arr = new ArrayList<>(); sectionsDict.put(key, arr); sortedSectionsArray.add(key); } @@ -1193,7 +1224,7 @@ public class ContactsController { try { Uri rawContactUri = ContactsContract.RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, currentAccount.name).appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, currentAccount.type).build(); Cursor c1 = ApplicationLoader.applicationContext.getContentResolver().query(rawContactUri, new String[]{BaseColumns._ID, ContactsContract.RawContacts.SYNC2}, null, null, null); - HashMap bookContacts = new HashMap(); + HashMap bookContacts = new HashMap<>(); if (c1 != null) { while (c1.moveToNext()) { bookContacts.put(c1.getInt(1), c1.getLong(0)); @@ -1213,7 +1244,7 @@ public class ContactsController { } private void performWriteContactsToPhoneBook() { - final ArrayList contactsArray = new ArrayList(); + final ArrayList contactsArray = new ArrayList<>(); contactsArray.addAll(contacts); Utilities.photoBookQueue.postRunnable(new Runnable() { @Override @@ -1225,8 +1256,8 @@ public class ContactsController { private void applyContactsUpdates(ArrayList ids, ConcurrentHashMap userDict, ArrayList newC, ArrayList contactsTD) { if (newC == null || contactsTD == null) { - newC = new ArrayList(); - contactsTD = new ArrayList(); + newC = new ArrayList<>(); + contactsTD = new ArrayList<>(); for (Integer uid : ids) { if (uid > 0) { TLRPC.TL_contact contact = new TLRPC.TL_contact(); @@ -1351,8 +1382,8 @@ public class ContactsController { } public void processContactsUpdates(ArrayList ids, ConcurrentHashMap userDict) { - final ArrayList newContacts = new ArrayList(); - final ArrayList contactsToDelete = new ArrayList(); + final ArrayList newContacts = new ArrayList<>(); + final ArrayList contactsToDelete = new ArrayList<>(); for (Integer uid : ids) { if (uid > 0) { TLRPC.TL_contact contact = new TLRPC.TL_contact(); @@ -1406,7 +1437,7 @@ public class ContactsController { } } - ArrayList query = new ArrayList(); + ArrayList query = new ArrayList<>(); ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI); builder.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, currentAccount.name); @@ -1471,7 +1502,7 @@ public class ContactsController { } TLRPC.TL_contacts_importContacts req = new TLRPC.TL_contacts_importContacts(); - ArrayList contactsParams = new ArrayList(); + ArrayList contactsParams = new ArrayList<>(); TLRPC.TL_inputPhoneContact c = new TLRPC.TL_inputPhoneContact(); c.phone = user.phone; if (!c.phone.startsWith("+")) { @@ -1510,7 +1541,7 @@ public class ContactsController { }); TLRPC.TL_contact newContact = new TLRPC.TL_contact(); newContact.user_id = u.id; - ArrayList arrayList = new ArrayList(); + ArrayList arrayList = new ArrayList<>(); arrayList.add(newContact); MessagesStorage.getInstance().putContacts(arrayList, false); @@ -1552,7 +1583,7 @@ public class ContactsController { return; } TLRPC.TL_contacts_deleteContacts req = new TLRPC.TL_contacts_deleteContacts(); - final ArrayList uids = new ArrayList(); + final ArrayList uids = new ArrayList<>(); for (TLRPC.User user : users) { TLRPC.InputUser inputUser = MessagesController.getInputUser(user); if (inputUser == null) { @@ -1631,7 +1662,7 @@ public class ContactsController { editor.remove("needGetStatuses").commit(); TLRPC.Vector vector = (TLRPC.Vector) response; if (!vector.objects.isEmpty()) { - ArrayList dbUsersStatus = new ArrayList(); + ArrayList dbUsersStatus = new ArrayList<>(); for (Object object : vector.objects) { TLRPC.User toDbUser = new TLRPC.User(); TLRPC.TL_contactStatus status = (TLRPC.TL_contactStatus) object; @@ -1741,7 +1772,7 @@ public class ContactsController { } public static String formatName(String firstName, String lastName) { - String result = null; + String result = ""; if (LocaleController.nameDisplayOrder == 1) { result = firstName; if (result == null || result.length() == 0) { diff --git a/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java b/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java index 1e9a454a7..fb6363697 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java @@ -344,7 +344,7 @@ public class ImageLoader { }); } }); - AndroidUtilities.runOnUIThread(new Runnable() { + imageLoadQueue.postRunnable(new Runnable() { @Override public void run() { runHttpTasks(true); @@ -354,7 +354,7 @@ public class ImageLoader { @Override protected void onCancelled() { - AndroidUtilities.runOnUIThread(new Runnable() { + imageLoadQueue.postRunnable(new Runnable() { @Override public void run() { runHttpTasks(true); @@ -449,6 +449,11 @@ public class ImageLoader { originalBitmap = scaledBitmap; FileOutputStream stream = new FileOutputStream(thumbFile); originalBitmap.compress(Bitmap.CompressFormat.JPEG, 60, stream); + try { + stream.close(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } final BitmapDrawable bitmapDrawable = new BitmapDrawable(originalBitmap); AndroidUtilities.runOnUIThread(new Runnable() { @Override @@ -615,7 +620,9 @@ public class ImageLoader { if (mediaId != null) { MediaStore.Images.Thumbnails.getThumbnail(ApplicationLoader.applicationContext.getContentResolver(), mediaId, MediaStore.Images.Thumbnails.MINI_KIND, opts); } else { - BitmapFactory.decodeFile(cacheImage.finalFilePath.getAbsolutePath(), opts); + FileInputStream is = new FileInputStream(cacheFileFinal); + image = BitmapFactory.decodeStream(is, null, opts); + is.close(); } float photoW = opts.outWidth; @@ -633,14 +640,18 @@ public class ImageLoader { } } - if (cacheImage.filter == null || blur) { + if (cacheImage.filter == null || blur || cacheImage.httpUrl != null) { opts.inPreferredConfig = Bitmap.Config.ARGB_8888; } else { opts.inPreferredConfig = Bitmap.Config.RGB_565; } + //if (Build.VERSION.SDK_INT < 21) { + // opts.inPurgeable = true; + //} + opts.inDither = false; if (mediaId != null) { - image = MediaStore.Images.Thumbnails.getThumbnail(ApplicationLoader.applicationContext.getContentResolver(), mediaId, MediaStore.Images.Thumbnails.MINI_KIND, null); + image = MediaStore.Images.Thumbnails.getThumbnail(ApplicationLoader.applicationContext.getContentResolver(), mediaId, MediaStore.Images.Thumbnails.MINI_KIND, opts); } if (image == null) { if (isWebp) { @@ -1057,6 +1068,12 @@ public class ImageLoader { FileLog.e("tmessages", e); } } + try { + new File(cachePath, ".nomedia").createNewFile(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + mediaDirs.put(FileLoader.MEDIA_DIR_CACHE, cachePath); FileLog.e("tmessages", "cache path = " + cachePath); @@ -1678,42 +1695,47 @@ public class ImageLoader { runHttpFileLoadTasks(null, 0); } - private void runHttpFileLoadTasks(HttpFileTask oldTask, int reason) { - if (oldTask != null) { - currentHttpFileLoadTasksCount--; - } - if (oldTask != null) { - if (reason == 1) { - if (oldTask.canRetry) { - final HttpFileTask newTask = new HttpFileTask(oldTask.url, oldTask.tempFile, oldTask.ext); - Runnable runnable = new Runnable() { - @Override - public void run() { - httpFileLoadTasks.add(newTask); - runHttpFileLoadTasks(null, 0); - } - }; - retryHttpsTasks.put(oldTask.url, runnable); - AndroidUtilities.runOnUIThread(runnable, 1000); - } else { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.httpFileDidFailedLoad, oldTask.url); + private void runHttpFileLoadTasks(final HttpFileTask oldTask, final int reason) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (oldTask != null) { + currentHttpFileLoadTasksCount--; + } + if (oldTask != null) { + if (reason == 1) { + if (oldTask.canRetry) { + final HttpFileTask newTask = new HttpFileTask(oldTask.url, oldTask.tempFile, oldTask.ext); + Runnable runnable = new Runnable() { + @Override + public void run() { + httpFileLoadTasks.add(newTask); + runHttpFileLoadTasks(null, 0); + } + }; + retryHttpsTasks.put(oldTask.url, runnable); + AndroidUtilities.runOnUIThread(runnable, 1000); + } else { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.httpFileDidFailedLoad, oldTask.url); + } + } else if (reason == 2) { + httpFileLoadTasksByKeys.remove(oldTask.url); + File file = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), Utilities.MD5(oldTask.url) + "." + oldTask.ext); + String result = oldTask.tempFile.renameTo(file) ? file.toString() : oldTask.tempFile.toString(); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.httpFileDidLoaded, oldTask.url, result); + } + } + while (currentHttpFileLoadTasksCount < 2 && !httpFileLoadTasks.isEmpty()) { + HttpFileTask task = httpFileLoadTasks.poll(); + if (android.os.Build.VERSION.SDK_INT >= 11) { + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null, null, null); + } else { + task.execute(null, null, null); + } + currentHttpFileLoadTasksCount++; } - } else if (reason == 2) { - httpFileLoadTasksByKeys.remove(oldTask.url); - File file = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), Utilities.MD5(oldTask.url) + "." + oldTask.ext); - String result = oldTask.tempFile.renameTo(file) ? file.toString() : oldTask.tempFile.toString(); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.httpFileDidLoaded, oldTask.url, result); } - } - while (currentHttpFileLoadTasksCount < 2 && !httpFileLoadTasks.isEmpty()) { - HttpFileTask task = httpFileLoadTasks.poll(); - if (android.os.Build.VERSION.SDK_INT >= 11) { - task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null, null, null); - } else { - task.execute(null, null, null); - } - currentHttpFileLoadTasksCount++; - } + }); } public static Bitmap loadBitmap(String path, Uri uri, float maxWidth, float maxHeight, boolean useMaxScale) { @@ -1963,6 +1985,15 @@ public class ImageLoader { } } } + } else if (message.media instanceof TLRPC.TL_messageMediaWebPage) { + if (message.media.webpage.photo != null) { + for (TLRPC.PhotoSize size : message.media.webpage.photo.sizes) { + if (size instanceof TLRPC.TL_photoCachedSize) { + photoSize = size; + break; + } + } + } } if (photoSize != null && photoSize.bytes != null && photoSize.bytes.length != 0) { if (photoSize.location instanceof TLRPC.TL_fileLocationUnavailable) { @@ -2000,6 +2031,13 @@ public class ImageLoader { message.media.video.thumb = newPhotoSize; } else if (message.media instanceof TLRPC.TL_messageMediaDocument) { message.media.document.thumb = newPhotoSize; + } else if (message.media instanceof TLRPC.TL_messageMediaWebPage) { + for (int a = 0; a < message.media.webpage.photo.sizes.size(); a++) { + if (message.media.webpage.photo.sizes.get(a) instanceof TLRPC.TL_photoCachedSize) { + message.media.webpage.photo.sizes.set(a, newPhotoSize); + break; + } + } } } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/ImageReceiver.java b/TMessagesProj/src/main/java/org/telegram/android/ImageReceiver.java index 9c467f72b..6f50bdc59 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/ImageReceiver.java +++ b/TMessagesProj/src/main/java/org/telegram/android/ImageReceiver.java @@ -29,8 +29,8 @@ import org.telegram.messenger.Utilities; public class ImageReceiver implements NotificationCenter.NotificationCenterDelegate { - public static interface ImageReceiverDelegate { - public void didSetImage(ImageReceiver imageReceiver, boolean set, boolean thumb); + public interface ImageReceiverDelegate { + void didSetImage(ImageReceiver imageReceiver, boolean set, boolean thumb); } private View parentView; @@ -68,7 +68,8 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg private Matrix shaderMatrix; private int alpha = 255; private boolean isPressed; - private boolean disableRecycle; + private int orientation; + private boolean centerRotation; private ImageReceiverDelegate delegate; public ImageReceiver() { @@ -209,12 +210,17 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg return isPressed; } - public void setImageBitmap(Bitmap bitmap) { - setImageBitmap(bitmap != null ? new BitmapDrawable(null, bitmap) : null); + public void setOrientation(int angle, boolean center) { + orientation = angle; + centerRotation = center; } - public void setDisableRecycle(boolean value) { - disableRecycle = value; + public int getOrientation() { + return orientation; + } + + public void setImageBitmap(Bitmap bitmap) { + setImageBitmap(bitmap != null ? new BitmapDrawable(null, bitmap) : null); } public void setImageBitmap(Drawable bitmap) { @@ -280,8 +286,17 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg canvas.drawRoundRect(roundRect, roundRadius, roundRadius, roundPaint); } } else { - int bitmapW = bitmapDrawable.getIntrinsicWidth(); - int bitmapH = bitmapDrawable.getIntrinsicHeight(); + int bitmapW; + int bitmapH; + int originalW = bitmapDrawable.getIntrinsicWidth(); + int originalH = bitmapDrawable.getIntrinsicHeight(); + if (orientation == 90 || orientation == 270) { + bitmapW = bitmapDrawable.getIntrinsicHeight(); + bitmapH = bitmapDrawable.getIntrinsicWidth(); + } else { + bitmapW = bitmapDrawable.getIntrinsicWidth(); + bitmapH = bitmapDrawable.getIntrinsicHeight(); + } float scaleW = bitmapW / (float) imageW; float scaleH = bitmapH / (float) imageH; @@ -312,14 +327,32 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg canvas.save(); canvas.clipRect(imageX, imageY, imageX + imageW, imageY + imageH); + if (orientation != 0) { + if (centerRotation) { + canvas.rotate(orientation, imageW / 2, imageH / 2); + } else { + canvas.rotate(orientation, 0, 0); + } + } + if (bitmapW / scaleH > imageW) { bitmapW /= scaleH; + originalW /= scaleH; drawRegion.set(imageX - (bitmapW - imageW) / 2, imageY, imageX + (bitmapW + imageW) / 2, imageY + imageH); } else { bitmapH /= scaleW; + originalH /= scaleW; drawRegion.set(imageX, imageY - (bitmapH - imageH) / 2, imageX + imageW, imageY + (bitmapH + imageH) / 2); } - bitmapDrawable.setBounds(drawRegion); + if (orientation == 90 || orientation == 270) { + int width = (drawRegion.right - drawRegion.left) / 2; + int height = (drawRegion.bottom - drawRegion.top) / 2; + int centerX = (drawRegion.right + drawRegion.left) / 2; + int centerY = (drawRegion.top + drawRegion.bottom) / 2; + bitmapDrawable.setBounds(centerX - height, centerY - width, centerX + height, centerY + width); + } else { + bitmapDrawable.setBounds(drawRegion); + } if (isVisible) { try { bitmapDrawable.setAlpha(alpha); @@ -339,8 +372,24 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg canvas.restore(); } else { + canvas.save(); + if (orientation != 0) { + if (centerRotation) { + canvas.rotate(orientation, imageW / 2, imageH / 2); + } else { + canvas.rotate(orientation, 0, 0); + } + } drawRegion.set(imageX, imageY, imageX + imageW, imageY + imageH); - bitmapDrawable.setBounds(drawRegion); + if (orientation == 90 || orientation == 270) { + int width = (drawRegion.right - drawRegion.left) / 2; + int height = (drawRegion.bottom - drawRegion.top) / 2; + int centerX = (drawRegion.right + drawRegion.left) / 2; + int centerY = (drawRegion.top + drawRegion.bottom) / 2; + bitmapDrawable.setBounds(centerX - height, centerY - width, centerX + height, centerY + width); + } else { + bitmapDrawable.setBounds(drawRegion); + } if (isVisible) { try { bitmapDrawable.setAlpha(alpha); @@ -357,6 +406,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg FileLog.e("tmessages", e); } } + canvas.restore(); } } } @@ -391,6 +441,16 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg return null; } + public int getBitmapWidth() { + Bitmap bitmap = getBitmap(); + return orientation == 0 || orientation == 180 ? bitmap.getWidth() : bitmap.getHeight(); + } + + public int getBitmapHeight() { + Bitmap bitmap = getBitmap(); + return orientation == 0 || orientation == 180 ? bitmap.getHeight() : bitmap.getWidth(); + } + public void setVisible(boolean value, boolean invalidate) { if (isVisible == value) { return; @@ -432,10 +492,18 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg return imageX; } + public int getImageX2() { + return imageX + imageW; + } + public int getImageY() { return imageY; } + public int getImageY2() { + return imageY + imageH; + } + public int getImageWidth() { return imageW; } @@ -617,7 +685,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg if (newKey != null) { newBitmap = ImageLoader.getInstance().getImageFromMemory(newKey); } - if (key == null || image == null || image == newBitmap || disableRecycle) { + if (key == null || image == null || image == newBitmap) { return; } Bitmap bitmap = image.getBitmap(); diff --git a/TMessagesProj/src/main/java/org/telegram/android/LocaleController.java b/TMessagesProj/src/main/java/org/telegram/android/LocaleController.java index db7b228b3..1d2094bc8 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/LocaleController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/LocaleController.java @@ -54,6 +54,7 @@ public class LocaleController { public static FastDateFormat formatterWeek; public static FastDateFormat formatterMonth; public static FastDateFormat formatterYear; + public static FastDateFormat formatterMonthYear; public static FastDateFormat formatterYearMax; public static FastDateFormat chatDate; public static FastDateFormat chatFullDate; @@ -135,7 +136,7 @@ public class LocaleController { addRules(new String[]{"bem", "brx", "da", "de", "el", "en", "eo", "es", "et", "fi", "fo", "gl", "he", "iw", "it", "nb", "nl", "nn", "no", "sv", "af", "bg", "bn", "ca", "eu", "fur", "fy", "gu", "ha", "is", "ku", "lb", "ml", "mr", "nah", "ne", "om", "or", "pa", "pap", "ps", "so", "sq", "sw", "ta", "te", - "tk", "ur", "zu", "mn", "gsw", "chr", "rm", "pt"}, new PluralRules_One()); + "tk", "ur", "zu", "mn", "gsw", "chr", "rm", "pt", "an", "ast"}, new PluralRules_One()); addRules(new String[]{"cs", "sk"}, new PluralRules_Czech()); addRules(new String[]{"ff", "fr", "kab"}, new PluralRules_French()); addRules(new String[]{"hr", "ru", "sr", "uk", "be", "bs", "sh"}, new PluralRules_Balkan()); @@ -443,10 +444,12 @@ public class LocaleController { } private HashMap getLocaleFileStrings(File file) { + FileInputStream stream = null; try { HashMap stringMap = new HashMap<>(); XmlPullParser parser = Xml.newPullParser(); - parser.setInput(new FileInputStream(file), "UTF-8"); + stream = new FileInputStream(file); + parser.setInput(stream, "UTF-8"); int eventType = parser.getEventType(); String name = null; String value = null; @@ -483,6 +486,15 @@ public class LocaleController { return stringMap; } catch (Exception e) { FileLog.e("tmessages", e); + } finally { + try { + if (stream != null) { + stream.close(); + stream = null; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } } return null; } @@ -544,6 +556,9 @@ public class LocaleController { currentLocale = newLocale; currentLocaleInfo = localeInfo; currentPluralRules = allRules.get(currentLocale.getLanguage()); + if (currentPluralRules == null) { + currentPluralRules = allRules.get("en"); + } changingConfiguration = true; Locale.setDefault(currentLocale); android.content.res.Configuration config = new android.content.res.Configuration(); @@ -571,6 +586,9 @@ public class LocaleController { if (value == null) { value = ApplicationLoader.applicationContext.getString(res); } + if (value == null) { + value = "LOC_ERR:" + key; + } return value; } @@ -638,6 +656,9 @@ public class LocaleController { } currentLocale = newLocale; currentPluralRules = allRules.get(currentLocale.getLanguage()); + if (currentPluralRules == null) { + currentPluralRules = allRules.get("en"); + } } } } @@ -695,6 +716,20 @@ public class LocaleController { } } + private FastDateFormat createFormatter(Locale locale, String format, String defaultFormat) { + if (format == null || format.length() == 0) { + format = defaultFormat; + } + FastDateFormat formatter = null; + try { + formatter = FastDateFormat.getInstance(format, locale); + } catch (Exception e) { + format = defaultFormat; + formatter = FastDateFormat.getInstance(format, locale); + } + return formatter; + } + public void recreateFormatters() { Locale locale = currentLocale; if (locale == null) { @@ -706,59 +741,15 @@ public class LocaleController { } isRTL = lang.toLowerCase().equals("ar"); nameDisplayOrder = lang.toLowerCase().equals("ko") ? 2 : 1; - String formatString = getStringInternal("formatterMonth", R.string.formatterMonth); - if (formatString == null || formatString.length() == 0) { - formatString = "dd MMM"; - } - formatterMonth = FastDateFormat.getInstance(formatString, locale); - formatString = getStringInternal("formatterYear", R.string.formatterYear); - if (formatString == null || formatString.length() == 0) { - formatString = "dd.MM.yy"; - } - formatterYear = FastDateFormat.getInstance(formatString, locale); - - formatString = getStringInternal("formatterYearMax", R.string.formatterYearMax); - if (formatString == null || formatString.length() == 0) { - formatString = "dd.MM.yyyy"; - } - formatterYearMax = FastDateFormat.getInstance(formatString, locale); - - formatString = getStringInternal("chatDate", R.string.chatDate); - if (formatString == null || formatString.length() == 0) { - formatString = "d MMMM"; - } - chatDate = FastDateFormat.getInstance(formatString, locale); - - formatString = getStringInternal("chatFullDate", R.string.chatFullDate); - if (formatString == null || formatString.length() == 0) { - formatString = "d MMMM yyyy"; - } - chatFullDate = FastDateFormat.getInstance(formatString, locale); - - formatString = getStringInternal("formatterWeek", R.string.formatterWeek); - if (formatString == null || formatString.length() == 0) { - formatString = "EEE"; - } - formatterWeek = FastDateFormat.getInstance(formatString, locale); - - if (is24HourFormat) { - formatString = getStringInternal("formatterDay24H", R.string.formatterDay24H); - } else { - formatString = getStringInternal("formatterDay12H", R.string.formatterDay12H); - } - if (formatString == null || formatString.length() == 0) { - if (is24HourFormat) { - formatString = "HH:mm"; - } else { - formatString = "h:mm a"; - } - } - if (lang.toLowerCase().equals("ar") || lang.toLowerCase().equals("ko")) { - formatterDay = FastDateFormat.getInstance(formatString, locale); - } else { - formatterDay = FastDateFormat.getInstance(formatString, Locale.US); - } + formatterMonth = createFormatter(locale, getStringInternal("formatterMonth", R.string.formatterMonth), "dd MMM"); + formatterYear = createFormatter(locale, getStringInternal("formatterYear", R.string.formatterYear), "dd.MM.yy"); + formatterYearMax = createFormatter(locale, getStringInternal("formatterYearMax", R.string.formatterYearMax), "dd.MM.yyyy"); + chatDate = createFormatter(locale, getStringInternal("chatDate", R.string.chatDate), "d MMMM"); + chatFullDate = createFormatter(locale, getStringInternal("chatFullDate", R.string.chatFullDate), "d MMMM yyyy"); + formatterWeek = createFormatter(locale, getStringInternal("formatterWeek", R.string.formatterWeek), "EEE"); + formatterMonthYear = createFormatter(locale, getStringInternal("formatterMonthYear", R.string.formatterMonthYear), "MMMM yyyy"); + formatterDay = createFormatter(lang.toLowerCase().equals("ar") || lang.toLowerCase().equals("ko") ? locale : Locale.US, is24HourFormat ? getStringInternal("formatterDay24H", R.string.formatterDay24H) : getStringInternal("formatterDay12H", R.string.formatterDay12H), is24HourFormat ? "HH:mm" : "h:mm a"); } public static String stringForMessageListDate(long date) { diff --git a/TMessagesProj/src/main/java/org/telegram/android/MediaController.java b/TMessagesProj/src/main/java/org/telegram/android/MediaController.java index efa53b092..629268341 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MediaController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MediaController.java @@ -87,12 +87,12 @@ public class MediaController implements NotificationCenter.NotificationCenterDel public static int[] readArgs = new int[3]; - public static interface FileDownloadProgressListener { - public void onFailedDownload(String fileName); - public void onSuccessDownload(String fileName); - public void onProgressDownload(String fileName, float progress); - public void onProgressUpload(String fileName, float progress, boolean isEncrypted); - public int getObserverTag(); + public interface FileDownloadProgressListener { + void onFailedDownload(String fileName); + void onSuccessDownload(String fileName); + void onProgressDownload(String fileName, float progress); + void onProgressUpload(String fileName, float progress, boolean isEncrypted); + int getObserverTag(); } private class AudioBuffer { @@ -165,6 +165,8 @@ public class MediaController implements NotificationCenter.NotificationCenterDel public int size; public int type; public int date; + public String thumbPath; + public String imagePath; } public final static String MIME_TYPE = "video/avc"; @@ -232,6 +234,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel private long recordStartTime; private long recordTimeCount; private long recordDialogId; + private MessageObject recordReplyingMessageObject; private DispatchQueue fileDecodingQueue; private DispatchQueue playerQueue; private ArrayList usedPlayerBuffers = new ArrayList<>(); @@ -507,7 +510,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel lastProgress = progress; playingMessageObject.audioProgress = value; playingMessageObject.audioProgressSec = lastProgress / 1000; - NotificationCenter.getInstance().postNotificationName(NotificationCenter.audioProgressDidChanged, playingMessageObject.messageOwner.id, value); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.audioProgressDidChanged, playingMessageObject.getId(), value); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -975,7 +978,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel } else if (id == NotificationCenter.messagesDeleted) { if (playingMessageObject != null) { ArrayList markAsDeletedMessages = (ArrayList)args[0]; - if (markAsDeletedMessages.contains(playingMessageObject.messageOwner.id)) { + if (markAsDeletedMessages.contains(playingMessageObject.getId())) { clenupPlayer(false); } } @@ -1102,8 +1105,16 @@ public class MediaController implements NotificationCenter.NotificationCenterDel if (proximitySensor != null && audioTrackPlayer == null && audioPlayer == null || isPaused || (useFrontSpeaker == (event.values[0] < proximitySensor.getMaximumRange() / 10))) { return; } + boolean newValue = event.values[0] < proximitySensor.getMaximumRange() / 10; + try { + if (newValue && NotificationsController.getInstance().audioManager.isWiredHeadsetOn()) { + return; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } ignoreProximity = true; - useFrontSpeaker = event.values[0] < proximitySensor.getMaximumRange() / 10; + useFrontSpeaker = newValue; NotificationCenter.getInstance().postNotificationName(NotificationCenter.audioRouteChanged, useFrontSpeaker); MessageObject currentMessageObject = playingMessageObject; float progress = playingMessageObject.audioProgress; @@ -1185,7 +1196,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel playingMessageObject.audioProgressSec = 0; playingMessageObject = null; if (notify) { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.audioDidReset, lastFile.messageOwner.id); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.audioDidReset, lastFile.getId()); } } } @@ -1225,7 +1236,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel } public boolean seekToProgress(MessageObject messageObject, float progress) { - if (audioTrackPlayer == null && audioPlayer == null || messageObject == null || playingMessageObject == null || playingMessageObject != null && playingMessageObject.messageOwner.id != messageObject.messageOwner.id) { + if (audioTrackPlayer == null && audioPlayer == null || messageObject == null || playingMessageObject == null || playingMessageObject != null && playingMessageObject.getId() != messageObject.getId()) { return false; } try { @@ -1247,7 +1258,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel if (messageObject == null) { return false; } - if ((audioTrackPlayer != null || audioPlayer != null) && playingMessageObject != null && messageObject.messageOwner.id == playingMessageObject.messageOwner.id) { + if ((audioTrackPlayer != null || audioPlayer != null) && playingMessageObject != null && messageObject.getId() == playingMessageObject.getId()) { if (isPaused) { resumeAudio(messageObject); } @@ -1410,7 +1421,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel public boolean pauseAudio(MessageObject messageObject) { stopProximitySensor(); - if (audioTrackPlayer == null && audioPlayer == null || messageObject == null || playingMessageObject == null || playingMessageObject != null && playingMessageObject.messageOwner.id != messageObject.messageOwner.id) { + if (audioTrackPlayer == null && audioPlayer == null || messageObject == null || playingMessageObject == null || playingMessageObject != null && playingMessageObject.getId() != messageObject.getId()) { return false; } try { @@ -1430,7 +1441,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel public boolean resumeAudio(MessageObject messageObject) { startProximitySensor(); - if (audioTrackPlayer == null && audioPlayer == null || messageObject == null || playingMessageObject == null || playingMessageObject != null && playingMessageObject.messageOwner.id != messageObject.messageOwner.id) { + if (audioTrackPlayer == null && audioPlayer == null || messageObject == null || playingMessageObject == null || playingMessageObject != null && playingMessageObject.getId() != messageObject.getId()) { return false; } try { @@ -1449,14 +1460,14 @@ public class MediaController implements NotificationCenter.NotificationCenterDel } public boolean isPlayingAudio(MessageObject messageObject) { - return !(audioTrackPlayer == null && audioPlayer == null || messageObject == null || playingMessageObject == null || playingMessageObject != null && playingMessageObject.messageOwner.id != messageObject.messageOwner.id); + return !(audioTrackPlayer == null && audioPlayer == null || messageObject == null || playingMessageObject == null || playingMessageObject != null && playingMessageObject.getId() != messageObject.getId()); } public boolean isAudioPaused() { return isPaused; } - public void startRecording(final long dialog_id) { + public void startRecording(final long dialog_id, final MessageObject reply_to_msg) { clenupPlayer(true); try { @@ -1503,6 +1514,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel recordStartTime = System.currentTimeMillis(); recordTimeCount = 0; recordDialogId = dialog_id; + recordReplyingMessageObject = reply_to_msg; fileBuffer.rewind(); audioRecorder.startRecording(); @@ -1555,11 +1567,11 @@ public class MediaController implements NotificationCenter.NotificationCenterDel long duration = recordTimeCount; audioToSend.duration = (int) (duration / 1000); if (duration > 700) { - SendMessagesHelper.getInstance().sendMessage(audioToSend, recordingAudioFileToSend.getAbsolutePath(), recordDialogId); + SendMessagesHelper.getInstance().sendMessage(audioToSend, recordingAudioFileToSend.getAbsolutePath(), recordDialogId, recordReplyingMessageObject); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.audioDidSent); } else { recordingAudioFileToSend.delete(); } - NotificationCenter.getInstance().postNotificationName(NotificationCenter.audioDidSent); } }); } @@ -1696,10 +1708,10 @@ public class MediaController implements NotificationCenter.NotificationCenterDel FileLog.e("tmessages", e); result = false; } finally { - if(source != null) { + if (source != null) { source.close(); } - if(destination != null) { + if (destination != null) { destination.close(); } } @@ -1737,7 +1749,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel return null; } - if (currentGifDrawable != null && currentGifMessageObject != null && messageObject.messageOwner.id == currentGifMessageObject.messageOwner.id) { + if (currentGifDrawable != null && currentGifMessageObject != null && messageObject.getId() == currentGifMessageObject.getId()) { currentMediaCell = cell; currentGifDrawable.parentView = new WeakReference(cell); return currentGifDrawable; @@ -1786,7 +1798,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel return; } - if (currentGifMessageObject != null && messageObject.messageOwner.id == currentGifMessageObject.messageOwner.id) { + if (currentGifMessageObject != null && messageObject.getId() == currentGifMessageObject.getId()) { if (currentGifDrawable != null) { currentGifDrawable.stop(); currentGifDrawable.recycle(); diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java b/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java index 1c6c0dd48..525c91eba 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java @@ -30,6 +30,8 @@ import java.util.AbstractMap; import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class MessageObject { @@ -39,9 +41,12 @@ public class MessageObject { public TLRPC.Message messageOwner; public CharSequence messageText; + public CharSequence linkDescription; + public MessageObject replyMessageObject; public int type; public int contentType; public String dateKey; + public String monthKey; public boolean deleted = false; public float audioProgress; public int audioProgressSec; @@ -75,6 +80,10 @@ public class MessageObject { messageOwner = message; + if (message.replyMessage != null) { + replyMessageObject = new MessageObject(message.replyMessage, users, false); + } + if (message instanceof TLRPC.TL_messageService) { if (message.action != null) { TLRPC.User fromUser = null; @@ -85,7 +94,7 @@ public class MessageObject { fromUser = MessagesController.getInstance().getUser(message.from_id); } if (message.action instanceof TLRPC.TL_messageActionChatCreate) { - if (isFromMe()) { + if (isOut()) { messageText = LocaleController.getString("ActionYouCreateGroup", R.string.ActionYouCreateGroup); } else { if (fromUser != null) { @@ -96,7 +105,7 @@ public class MessageObject { } } else if (message.action instanceof TLRPC.TL_messageActionChatDeleteUser) { if (message.action.user_id == message.from_id) { - if (isFromMe()) { + if (isOut()) { messageText = LocaleController.getString("ActionYouLeftUser", R.string.ActionYouLeftUser); } else { if (fromUser != null) { @@ -114,7 +123,7 @@ public class MessageObject { whoUser = MessagesController.getInstance().getUser(message.action.user_id); } if (whoUser != null && fromUser != null) { - if (isFromMe()) { + if (isOut()) { messageText = replaceWithLink(LocaleController.getString("ActionYouKickUser", R.string.ActionYouKickUser), "un2", whoUser); } else if (message.action.user_id == UserConfig.getClientUserId()) { messageText = replaceWithLink(LocaleController.getString("ActionKickUserYou", R.string.ActionKickUserYou), "un1", fromUser); @@ -135,7 +144,7 @@ public class MessageObject { whoUser = MessagesController.getInstance().getUser(message.action.user_id); } if (whoUser != null && fromUser != null) { - if (isFromMe()) { + if (isOut()) { messageText = replaceWithLink(LocaleController.getString("ActionYouAddUser", R.string.ActionYouAddUser), "un2", whoUser); } else if (message.action.user_id == UserConfig.getClientUserId()) { messageText = replaceWithLink(LocaleController.getString("ActionAddUserYou", R.string.ActionAddUserYou), "un1", fromUser); @@ -147,7 +156,7 @@ public class MessageObject { messageText = LocaleController.getString("ActionAddUser", R.string.ActionAddUser).replace("un2", "").replace("un1", ""); } } else if (message.action instanceof TLRPC.TL_messageActionChatEditPhoto) { - if (isFromMe()) { + if (isOut()) { messageText = LocaleController.getString("ActionYouChangedPhoto", R.string.ActionYouChangedPhoto); } else { if (fromUser != null) { @@ -157,7 +166,7 @@ public class MessageObject { } } } else if (message.action instanceof TLRPC.TL_messageActionChatEditTitle) { - if (isFromMe()) { + if (isOut()) { messageText = LocaleController.getString("ActionYouChangedTitle", R.string.ActionYouChangedTitle).replace("un2", message.action.title); } else { if (fromUser != null) { @@ -167,7 +176,7 @@ public class MessageObject { } } } else if (message.action instanceof TLRPC.TL_messageActionChatDeletePhoto) { - if (isFromMe()) { + if (isOut()) { messageText = LocaleController.getString("ActionYouRemovedPhoto", R.string.ActionYouRemovedPhoto); } else { if (fromUser != null) { @@ -178,7 +187,7 @@ public class MessageObject { } } else if (message.action instanceof TLRPC.TL_messageActionTTLChange) { if (message.action.ttl != 0) { - if (isFromMe()) { + if (isOut()) { messageText = LocaleController.formatString("MessageLifetimeChangedOutgoing", R.string.MessageLifetimeChangedOutgoing, AndroidUtilities.formatTTLString(message.action.ttl)); } else { if (fromUser != null) { @@ -188,7 +197,7 @@ public class MessageObject { } } } else { - if (isFromMe()) { + if (isOut()) { messageText = LocaleController.getString("MessageLifetimeYouRemoved", R.string.MessageLifetimeYouRemoved); } else { if (fromUser != null) { @@ -199,7 +208,7 @@ public class MessageObject { } } } else if (message.action instanceof TLRPC.TL_messageActionLoginUnknownLocation) { - String date = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, LocaleController.formatterYear.format(((long)message.date) * 1000), LocaleController.formatterDay.format(((long)message.date) * 1000)); + String date = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, LocaleController.formatterYear.format(((long) message.date) * 1000), LocaleController.formatterDay.format(((long) message.date) * 1000)); TLRPC.User to_user = UserConfig.getCurrentUser(); if (to_user == null) { if (users != null) { @@ -228,7 +237,7 @@ public class MessageObject { } } else if (message.action instanceof TLRPC.TL_messageEncryptedAction) { if (message.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages) { - if (isFromMe()) { + if (isOut()) { messageText = LocaleController.formatString("ActionTakeScreenshootYou", R.string.ActionTakeScreenshootYou); } else { if (fromUser != null) { @@ -240,7 +249,7 @@ public class MessageObject { } else if (message.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) { TLRPC.TL_decryptedMessageActionSetMessageTTL action = (TLRPC.TL_decryptedMessageActionSetMessageTTL) message.action.encryptedAction; if (action.ttl_seconds != 0) { - if (isFromMe()) { + if (isOut()) { messageText = LocaleController.formatString("MessageLifetimeChangedOutgoing", R.string.MessageLifetimeChangedOutgoing, AndroidUtilities.formatTTLString(action.ttl_seconds)); } else { if (fromUser != null) { @@ -250,7 +259,7 @@ public class MessageObject { } } } else { - if (isFromMe()) { + if (isOut()) { messageText = LocaleController.getString("MessageLifetimeYouRemoved", R.string.MessageLifetimeYouRemoved); } else { if (fromUser != null) { @@ -265,7 +274,7 @@ public class MessageObject { messageText = LocaleController.formatString("YouCreatedBroadcastList", R.string.YouCreatedBroadcastList); } } - } else if (message.media != null && !(message.media instanceof TLRPC.TL_messageMediaEmpty)) { + } else if (!isMediaEmpty()) { if (message.media instanceof TLRPC.TL_messageMediaPhoto) { messageText = LocaleController.getString("AttachPhoto", R.string.AttachPhoto); } else if (message.media instanceof TLRPC.TL_messageMediaVideo) { @@ -278,9 +287,19 @@ public class MessageObject { messageText = LocaleController.getString("UnsuppotedMedia", R.string.UnsuppotedMedia); } else if (message.media instanceof TLRPC.TL_messageMediaDocument) { if (isSticker()) { - messageText = LocaleController.getString("AttachSticker", R.string.AttachSticker); + String sch = getStrickerChar(); + if (sch != null && sch.length() > 0) { + messageText = String.format("%s %s", sch, LocaleController.getString("AttachSticker", R.string.AttachSticker)); + } else { + messageText = LocaleController.getString("AttachSticker", R.string.AttachSticker); + } } else { - messageText = LocaleController.getString("AttachDocument", R.string.AttachDocument); + String name = FileLoader.getDocumentFileName(message.media.document); + if (name != null && name.length() > 0) { + messageText = name; + } else { + messageText = LocaleController.getString("AttachDocument", R.string.AttachDocument); + } } } else if (message.media instanceof TLRPC.TL_messageMediaAudio) { messageText = LocaleController.getString("AttachAudio", R.string.AttachAudio); @@ -290,23 +309,23 @@ public class MessageObject { } messageText = Emoji.replaceEmoji(messageText, textPaint.getFontMetricsInt(), AndroidUtilities.dp(20)); - if (message instanceof TLRPC.TL_message || message instanceof TLRPC.TL_messageForwarded) { - if (message.media == null || message.media instanceof TLRPC.TL_messageMediaEmpty) { + if (message instanceof TLRPC.TL_message || message instanceof TLRPC.TL_messageForwarded_old2) { + if (isMediaEmpty()) { contentType = type = 0; - } else if (message.media != null && message.media instanceof TLRPC.TL_messageMediaPhoto) { + } else if (message.media instanceof TLRPC.TL_messageMediaPhoto) { contentType = type = 1; - } else if (message.media != null && message.media instanceof TLRPC.TL_messageMediaGeo) { + } else if (message.media instanceof TLRPC.TL_messageMediaGeo) { contentType = 1; type = 4; - } else if (message.media != null && message.media instanceof TLRPC.TL_messageMediaVideo) { + } else if (message.media instanceof TLRPC.TL_messageMediaVideo) { contentType = 1; type = 3; - } else if (message.media != null && message.media instanceof TLRPC.TL_messageMediaContact) { + } else if (message.media instanceof TLRPC.TL_messageMediaContact) { contentType = 3; type = 12; - } else if (message.media != null && message.media instanceof TLRPC.TL_messageMediaUnsupported) { + } else if (message.media instanceof TLRPC.TL_messageMediaUnsupported) { contentType = type = 0; - } else if (message.media != null && message.media instanceof TLRPC.TL_messageMediaDocument) { + } else if (message.media instanceof TLRPC.TL_messageMediaDocument) { contentType = 1; if (message.media.document.mime_type != null) { if (message.media.document.mime_type.equals("image/gif") && message.media.document.thumb != null && !(message.media.document.thumb instanceof TLRPC.TL_photoSizeEmpty)) { @@ -322,7 +341,7 @@ public class MessageObject { } else { type = 9; } - } else if (message.media != null && message.media instanceof TLRPC.TL_messageMediaAudio) { + } else if (message.media instanceof TLRPC.TL_messageMediaAudio) { contentType = type = 2; } } else if (message instanceof TLRPC.TL_messageService) { @@ -346,11 +365,14 @@ public class MessageObject { } Calendar rightNow = new GregorianCalendar(); - rightNow.setTimeInMillis((long)(messageOwner.date) * 1000); + rightNow.setTimeInMillis((long) (messageOwner.date) * 1000); int dateDay = rightNow.get(Calendar.DAY_OF_YEAR); int dateYear = rightNow.get(Calendar.YEAR); int dateMonth = rightNow.get(Calendar.MONTH); dateKey = String.format("%d_%02d_%02d", dateYear, dateMonth, dateDay); + if (contentType == 1 || contentType == 2) { + monthKey = String.format("%d_%02d", dateYear, dateMonth); + } if (generateLayout) { generateLayout(); @@ -412,6 +434,24 @@ public class MessageObject { photoObject.location = messageOwner.media.document.thumb.location; } } + } else if (messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) { + if (messageOwner.media.webpage.photo != null) { + if (!update || photoThumbs == null) { + photoThumbs = new ArrayList<>(messageOwner.media.webpage.photo.sizes); + } else if (photoThumbs != null && !photoThumbs.isEmpty()) { + for (TLRPC.PhotoSize photoObject : photoThumbs) { + for (TLRPC.PhotoSize size : messageOwner.media.webpage.photo.sizes) { + if (size instanceof TLRPC.TL_photoSizeEmpty) { + continue; + } + if (size.type.equals(photoObject.type)) { + photoObject.location = size.location; + break; + } + } + } + } + } } } } @@ -483,6 +523,9 @@ public class MessageObject { } else if (!(c != ' ' && digitsInRow > 0)) { digitsInRow = 0; } + if ((c == '@' || c == '#') && i == 0 || i != 0 && (message.charAt(i - 1) == ' ' || message.charAt(i - 1) == '\n')) { + return true; + } if (c == ':') { if (schemeSequence == 0) { schemeSequence = 1; @@ -514,11 +557,24 @@ public class MessageObject { return false; } + public void generateLinkDescription() { + if (linkDescription != null) { + return; + } + if (messageOwner.media instanceof TLRPC.TL_messageMediaWebPage && messageOwner.media.webpage instanceof TLRPC.TL_webPage && messageOwner.media.webpage.description != null) { + linkDescription = Spannable.Factory.getInstance().newSpannable(messageOwner.media.webpage.description); + if (containsUrls(linkDescription)) { + Linkify.addLinks((Spannable) linkDescription, Linkify.WEB_URLS); + } + } + } + private void generateLayout() { if (type != 0 || messageOwner.to_id == null || messageText == null || messageText.length() == 0) { return; } + generateLinkDescription(); textLayoutBlocks = new ArrayList<>(); if (messageText instanceof Spannable && containsUrls(messageText)) { @@ -527,17 +583,33 @@ public class MessageObject { } else { Linkify.addLinks((Spannable) messageText, Linkify.WEB_URLS); } + + try { + Pattern pattern = Pattern.compile("(^|\\s)@[a-zA-Z\\d_]{5,32}|(^|\\s)#[\\w\\.]+"); + Matcher matcher = pattern.matcher(messageText); + while (matcher.find()) { + int start = matcher.start(); + int end = matcher.end(); + if (messageText.charAt(start) != '@' && messageText.charAt(start) != '#') { + start++; + } + URLSpanNoUnderline url = new URLSpanNoUnderline(messageText.subSequence(start, end).toString()); + ((Spannable) messageText).setSpan(url, start, end, 0); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } } int maxWidth; if (AndroidUtilities.isTablet()) { - if (messageOwner.to_id.chat_id != 0) { + if (messageOwner.to_id.chat_id != 0 && !isOut()) { maxWidth = AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(122); } else { maxWidth = AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(80); } } else { - if (messageOwner.to_id.chat_id != 0) { + if (messageOwner.to_id.chat_id != 0 && !isOut()) { maxWidth = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) - AndroidUtilities.dp(122); } else { maxWidth = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) - AndroidUtilities.dp(80); @@ -556,7 +628,7 @@ public class MessageObject { textHeight = textLayout.getHeight(); int linesCount = textLayout.getLineCount(); - int blocksCount = (int)Math.ceil((float)linesCount / LINES_PER_BLOCK); + int blocksCount = (int) Math.ceil((float) linesCount / LINES_PER_BLOCK); int linesOffset = 0; float prevOffset = 0; @@ -581,7 +653,7 @@ public class MessageObject { block.textLayout = new StaticLayout(str, textPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); block.textYOffset = textLayout.getLineTop(linesOffset); if (a != 0) { - blockHeight = Math.min(blockHeight, (int)(block.textYOffset - prevOffset)); + blockHeight = Math.min(blockHeight, (int) (block.textYOffset - prevOffset)); } prevOffset = block.textYOffset; /*if (a != blocksCount - 1) { @@ -613,7 +685,7 @@ public class MessageObject { FileLog.e("tmessages", e); } - int linesMaxWidth = (int)Math.ceil(lastLine); + int linesMaxWidth = (int) Math.ceil(lastLine); int lastLineWidthWithLeft; int linesMaxWidthWithLeft; boolean hasNonRTL = false; @@ -622,7 +694,7 @@ public class MessageObject { lastLineWidth = linesMaxWidth; } - linesMaxWidthWithLeft = lastLineWidthWithLeft = (int)Math.ceil(lastLine + lastLeft); + linesMaxWidthWithLeft = lastLineWidthWithLeft = (int) Math.ceil(lastLine + lastLeft); if (lastLeft == 0) { hasNonRTL = true; } @@ -655,8 +727,8 @@ public class MessageObject { } textRealMaxWidth = Math.max(textRealMaxWidth, lineWidth); textRealMaxWidthWithLeft = Math.max(textRealMaxWidthWithLeft, lineWidth + lineLeft); - linesMaxWidth = Math.max(linesMaxWidth, (int)Math.ceil(lineWidth)); - linesMaxWidthWithLeft = Math.max(linesMaxWidthWithLeft, (int)Math.ceil(lineWidth + lineLeft)); + linesMaxWidth = Math.max(linesMaxWidth, (int) Math.ceil(lineWidth)); + linesMaxWidthWithLeft = Math.max(linesMaxWidthWithLeft, (int) Math.ceil(lineWidth + lineLeft)); } if (hasNonRTL) { textRealMaxWidth = textRealMaxWidthWithLeft; @@ -667,7 +739,7 @@ public class MessageObject { } else if (a == blocksCount - 1) { lastLineWidth = linesMaxWidth; } - textWidth = Math.max(textWidth, (int)Math.ceil(textRealMaxWidth)); + textWidth = Math.max(textWidth, (int) Math.ceil(textRealMaxWidth)); } else { textWidth = Math.max(textWidth, Math.min(maxWidth, linesMaxWidth)); } @@ -687,16 +759,16 @@ public class MessageObject { return (messageOwner.flags & TLRPC.MESSAGE_FLAG_OUT) != 0; } - public boolean isFromMe() { - return messageOwner.from_id == UserConfig.getClientUserId(); - } - public boolean isUnread() { return (messageOwner.flags & TLRPC.MESSAGE_FLAG_UNREAD) != 0; } public void setIsRead() { - messageOwner.flags &=~ TLRPC.MESSAGE_FLAG_UNREAD; + messageOwner.flags &= ~TLRPC.MESSAGE_FLAG_UNREAD; + } + + public int getId() { + return messageOwner.id; } public boolean isSecretPhoto() { @@ -706,15 +778,15 @@ public class MessageObject { public boolean isSecretMedia() { return messageOwner instanceof TLRPC.TL_message_secret && (messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && messageOwner.ttl != 0 && messageOwner.ttl <= 60 || - messageOwner.media instanceof TLRPC.TL_messageMediaAudio || - messageOwner.media instanceof TLRPC.TL_messageMediaVideo); + messageOwner.media instanceof TLRPC.TL_messageMediaAudio || + messageOwner.media instanceof TLRPC.TL_messageMediaVideo); } public static void setIsUnread(TLRPC.Message message, boolean unread) { if (unread) { message.flags |= TLRPC.MESSAGE_FLAG_UNREAD; } else { - message.flags &=~ TLRPC.MESSAGE_FLAG_UNREAD; + message.flags &= ~TLRPC.MESSAGE_FLAG_UNREAD; } } @@ -732,7 +804,7 @@ public class MessageObject { } else { if (messageOwner.to_id.chat_id != 0) { return -messageOwner.to_id.chat_id; - } else if (isFromMe()) { + } else if (isOut()) { return messageOwner.to_id.user_id; } else { return messageOwner.from_id; @@ -741,7 +813,7 @@ public class MessageObject { } public boolean isSending() { - return messageOwner.send_state == MESSAGE_SEND_STATE_SENDING; + return messageOwner.send_state == MESSAGE_SEND_STATE_SENDING && messageOwner.id < 0; } public boolean isSendError() { @@ -749,7 +821,7 @@ public class MessageObject { } public boolean isSent() { - return messageOwner.send_state == MESSAGE_SEND_STATE_SENT; + return messageOwner.send_state == MESSAGE_SEND_STATE_SENT || messageOwner.id > 0; } public String getSecretTimeString() { @@ -787,7 +859,129 @@ public class MessageObject { return false; } + public String getStrickerChar() { + if (messageOwner.media != null && messageOwner.media.document != null) { + for (TLRPC.DocumentAttribute attribute : messageOwner.media.document.attributes) { + if (attribute instanceof TLRPC.TL_documentAttributeSticker) { + return attribute.alt; + } + } + } + return null; + } + + public int getApproximateHeight() { + if (type == 0) { + return textHeight; + } else if (contentType == 2) { + return AndroidUtilities.dp(68); + } else if (contentType == 3) { + return AndroidUtilities.dp(71); + } else if (type == 9) { + return AndroidUtilities.dp(100); + } else if (type == 4) { + return AndroidUtilities.dp(114); + } else if (type == 13) { + float maxHeight = AndroidUtilities.displaySize.y * 0.4f; + float maxWidth; + if (AndroidUtilities.isTablet()) { + maxWidth = AndroidUtilities.getMinTabletSide() * 0.5f; + } else { + maxWidth = AndroidUtilities.displaySize.x * 0.5f; + } + int photoHeight = 0; + int photoWidth = 0; + for (TLRPC.DocumentAttribute attribute : messageOwner.media.document.attributes) { + if (attribute instanceof TLRPC.TL_documentAttributeImageSize) { + photoWidth = attribute.w; + photoHeight = attribute.h; + break; + } + } + if (photoWidth == 0) { + photoHeight = (int) maxHeight; + photoWidth = photoHeight + AndroidUtilities.dp(100); + } + if (photoHeight > maxHeight) { + photoWidth *= maxHeight / photoHeight; + photoHeight = (int)maxHeight; + } + if (photoWidth > maxWidth) { + photoHeight *= maxWidth / photoWidth; + } + return photoHeight + AndroidUtilities.dp(14); + } else { + int photoHeight = 0; + int photoWidth = 0; + + if (AndroidUtilities.isTablet()) { + photoWidth = (int) (AndroidUtilities.getMinTabletSide() * 0.7f); + } else { + photoWidth = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.7f); + } + photoHeight = photoWidth + AndroidUtilities.dp(100); + if (photoWidth > AndroidUtilities.getPhotoSize()) { + photoWidth = AndroidUtilities.getPhotoSize(); + } + if (photoHeight > AndroidUtilities.getPhotoSize()) { + photoHeight = AndroidUtilities.getPhotoSize(); + } + TLRPC.PhotoSize currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(photoThumbs, AndroidUtilities.getPhotoSize()); + + if (currentPhotoObject != null) { + float scale = (float) currentPhotoObject.w / (float) photoWidth; + int w = (int) (currentPhotoObject.w / scale); + int h = (int) (currentPhotoObject.h / scale); + if (w == 0) { + w = AndroidUtilities.dp(100); + } + if (h == 0) { + h = AndroidUtilities.dp(100); + } + if (h > photoHeight) { + float scale2 = h; + h = photoHeight; + scale2 /= h; + w = (int) (w / scale2); + } else if (h < AndroidUtilities.dp(120)) { + h = AndroidUtilities.dp(120); + float hScale = (float) currentPhotoObject.h / h; + if (currentPhotoObject.w / hScale < photoWidth) { + w = (int) (currentPhotoObject.w / hScale); + } + } + if (isSecretPhoto()) { + if (AndroidUtilities.isTablet()) { + w = h = (int) (AndroidUtilities.getMinTabletSide() * 0.5f); + } else { + w = h = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.5f); + } + } + + photoWidth = w; + photoHeight = h; + } + return photoHeight + AndroidUtilities.dp(14); + } + } + public boolean isSticker() { return isStickerMessage(messageOwner); } + + public boolean isForwarded() { + return (messageOwner.flags & TLRPC.MESSAGE_FLAG_FWD) != 0; + } + + public boolean isReply() { + return !(replyMessageObject != null && replyMessageObject.messageOwner instanceof TLRPC.TL_messageEmpty) && messageOwner.reply_to_msg_id != 0 && (messageOwner.flags & TLRPC.MESSAGE_FLAG_REPLY) != 0; + } + + public boolean isMediaEmpty() { + return isMediaEmpty(messageOwner); + } + + public static boolean isMediaEmpty(TLRPC.Message message) { + return message == null || message.media == null || message.media instanceof TLRPC.TL_messageMediaEmpty || message.media instanceof TLRPC.TL_messageMediaWebPage; + } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java index 71bd216e9..6d2b29972 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java @@ -9,10 +9,11 @@ package org.telegram.android; import android.app.Activity; +import android.app.AlertDialog; import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.os.Build; -import android.text.Html; +import android.util.Base64; import android.util.SparseArray; import org.telegram.messenger.ConnectionsManager; @@ -20,11 +21,14 @@ import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.RPCRequest; +import org.telegram.messenger.SerializedData; +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.messenger.ApplicationLoader; +import org.telegram.ui.ActionBar.BaseFragment; import java.util.ArrayList; import java.util.Collections; @@ -39,6 +43,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter 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); + private ConcurrentHashMap usersByUsernames = new ConcurrentHashMap<>(100, 1.0f, 2); public ArrayList dialogs = new ArrayList<>(); public ArrayList dialogsServerOnly = new ArrayList<>(); @@ -53,8 +58,12 @@ public class MessagesController implements NotificationCenter.NotificationCenter public boolean loadingBlockedUsers = false; public ArrayList blockedUsers = new ArrayList<>(); - private ArrayList updatesQueue = new ArrayList<>(); - private long updatesStartWaitTime = 0; + private ArrayList updatesQueueSeq = new ArrayList<>(); + private ArrayList updatesQueuePts = new ArrayList<>(); + private ArrayList updatesQueueQts = new ArrayList<>(); + private long updatesStartWaitTimeSeq = 0; + private long updatesStartWaitTimePts = 0; + private long updatesStartWaitTimeQts = 0; private ArrayList loadingFullUsers = new ArrayList<>(); private ArrayList loadedFullUsers = new ArrayList<>(); private ArrayList loadingFullChats = new ArrayList<>(); @@ -86,8 +95,14 @@ public class MessagesController implements NotificationCenter.NotificationCenter public int fontSize = AndroidUtilities.dp(16); public int maxGroupCount = 200; public int maxBroadcastCount = 100; + public int groupBigSize; + private ArrayList disabledFeatures = new ArrayList<>(); - private class UserActionUpdates extends TLRPC.Updates { + private class UserActionUpdatesSeq extends TLRPC.Updates { + + } + + private class UserActionUpdatesPts extends TLRPC.Updates { } @@ -102,6 +117,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter 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_PHONE = 1024; + public static final int UPDATE_MASK_NEW_MESSAGE = 2048; + public static final int UPDATE_MASK_SEND_STATE = 4096; 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 { @@ -138,24 +155,80 @@ public class MessagesController implements NotificationCenter.NotificationCenter preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); maxGroupCount = preferences.getInt("maxGroupCount", 200); maxBroadcastCount = preferences.getInt("maxBroadcastCount", 100); + groupBigSize = preferences.getInt("groupBigSize", 10); fontSize = preferences.getInt("fons_size", AndroidUtilities.isTablet() ? 18 : 16); + String disabledFeaturesString = preferences.getString("disabledFeatures", null); + if (disabledFeaturesString != null && disabledFeaturesString.length() != 0) { + try { + byte[] bytes = Base64.decode(disabledFeaturesString, Base64.DEFAULT); + if (bytes != null) { + SerializedData data = new SerializedData(bytes); + int count = data.readInt32(); + for (int a = 0; a < count; a++) { + TLRPC.TL_disabledFeature feature = (TLRPC.TL_disabledFeature) TLClassStore.Instance().TLdeserialize(data, data.readInt32()); + if (feature != null && feature.feature != null && feature.description != null) { + disabledFeatures.add(feature); + } + } + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } } public void updateConfig(final TLRPC.TL_config config) { - AndroidUtilities.runOnUIThread(new Runnable() { + AndroidUtilities.runOnUIThread(new Runnable() { //TODO use new config params @Override public void run() { maxBroadcastCount = config.broadcast_size_max; maxGroupCount = config.chat_size_max; + groupBigSize = config.chat_big_size; + disabledFeatures = config.disabled_features; + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); editor.putInt("maxGroupCount", maxGroupCount); editor.putInt("maxBroadcastCount", maxBroadcastCount); + editor.putInt("groupBigSize", groupBigSize); + try { + SerializedData data = new SerializedData(); + data.writeInt32(disabledFeatures.size()); + for (TLRPC.TL_disabledFeature disabledFeature : disabledFeatures) { + disabledFeature.serializeToStream(data); + } + String string = Base64.encodeToString(data.toByteArray(), Base64.DEFAULT); + if (string != null && string.length() != 0) { + editor.putString("disabledFeatures", string); + } + } catch (Exception e) { + editor.remove("disabledFeatures"); + FileLog.e("tmessages", e); + } editor.commit(); } }); } + public static boolean isFeatureEnabled(String feature, BaseFragment fragment) { + if (feature == null || feature.length() == 0 || getInstance().disabledFeatures.isEmpty() || fragment == null) { + return true; + } + for (TLRPC.TL_disabledFeature disabledFeature : getInstance().disabledFeatures) { + if (disabledFeature.feature.equals(feature)) { + if (fragment.getParentActivity() != null) { + AlertDialog.Builder builder = new AlertDialog.Builder(fragment.getParentActivity()); + builder.setTitle("Oops!"); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null); + builder.setMessage(disabledFeature.description); + fragment.showAlertDialog(builder); + } + return false; + } + } + return true; + } + public void addSupportUser() { TLRPC.TL_userForeign user = new TLRPC.TL_userForeign(); user.phone = "333"; @@ -302,6 +375,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter dialogs.clear(); dialogsServerOnly.clear(); users.clear(); + usersByUsernames.clear(); chats.clear(); dialogMessage.clear(); printingUsers.clear(); @@ -309,7 +383,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter onlinePrivacy.clear(); totalDialogsCount = 0; lastPrintingStringCount = 0; - updatesQueue.clear(); + updatesQueueSeq.clear(); + updatesQueuePts.clear(); + updatesQueueQts.clear(); blockedUsers.clear(); sendingTypings.clear(); loadingFullUsers.clear(); @@ -318,7 +394,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter loadingFullChats.clear(); loadedFullChats.clear(); - updatesStartWaitTime = 0; + updatesStartWaitTimeSeq = 0; + updatesStartWaitTimePts = 0; + updatesStartWaitTimeQts = 0; currentDeletingTaskTime = 0; currentDeletingTaskMids = null; gettingNewDeleteTask = false; @@ -348,6 +426,14 @@ public class MessagesController implements NotificationCenter.NotificationCenter return users.get(id); } + public TLRPC.User getUser(String username) { + return usersByUsernames.get(username); + } + + public ConcurrentHashMap getUsers() { + return users; + } + public TLRPC.Chat getChat(Integer id) { return chats.get(id); } @@ -383,6 +469,12 @@ public class MessagesController implements NotificationCenter.NotificationCenter } fromCache = fromCache && user.id / 1000 != 333 && user.id != 777000; TLRPC.User oldUser = users.get(user.id); + if (oldUser != null && oldUser.username != null && oldUser.username.length() > 0) { + usersByUsernames.remove(oldUser.username); + } + if (user.username != null && user.username.length() > 0) { + usersByUsernames.put(user.username, user); + } if (!fromCache) { users.put(user.id, user); if (user.id == UserConfig.getClientUserId()) { @@ -593,28 +685,48 @@ public class MessagesController implements NotificationCenter.NotificationCenter }); } - protected void processNewDifferenceParams(int seq, int pts, int date) { - if (MessagesStorage.lastSeqValue + 1 == seq) { - if (seq != -1) { - MessagesStorage.lastSeqValue = seq; - } - if (date != -1) { - MessagesStorage.lastDateValue = date; - } - if (pts != -1) { + protected void processNewDifferenceParams(int seq, int pts, int date, int pts_count) { + FileLog.e("tmessages", "processNewDifferenceParams seq = " + seq + " pts = " + pts + " date = " + date + " pts_count = " + pts_count); + if (pts != -1) { + if (MessagesStorage.lastPtsValue + pts_count == pts) { + FileLog.e("tmessages", "APPLY PTS"); MessagesStorage.lastPtsValue = pts; - } - MessagesStorage.getInstance().saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); - } else if (MessagesStorage.lastSeqValue != seq) { - if (gettingDifference || updatesStartWaitTime == 0 || updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 > System.currentTimeMillis()) { - if (updatesStartWaitTime == 0) { - updatesStartWaitTime = System.currentTimeMillis(); + MessagesStorage.getInstance().saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); + } else if (MessagesStorage.lastPtsValue != pts) { + if (gettingDifference || updatesStartWaitTimePts == 0 || updatesStartWaitTimePts != 0 && updatesStartWaitTimePts + 1500 > System.currentTimeMillis()) { + FileLog.e("tmessages", "ADD UPDATE TO QUEUE pts = " + pts + " pts_count = " + pts_count); + if (updatesStartWaitTimePts == 0) { + updatesStartWaitTimePts = System.currentTimeMillis(); + } + UserActionUpdatesPts updates = new UserActionUpdatesPts(); + updates.pts = pts; + updates.pts_count = pts_count; + updatesQueuePts.add(updates); + } else { + getDifference(); + } + } + } + if (seq != -1) { + if (MessagesStorage.lastSeqValue + 1 == seq) { + FileLog.e("tmessages", "APPLY SEQ"); + MessagesStorage.lastSeqValue = seq; + if (date != -1) { + MessagesStorage.lastDateValue = date; + } + MessagesStorage.getInstance().saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); + } else if (MessagesStorage.lastSeqValue != seq) { + if (gettingDifference || updatesStartWaitTimeSeq == 0 || updatesStartWaitTimeSeq != 0 && updatesStartWaitTimeSeq + 1500 > System.currentTimeMillis()) { + FileLog.e("tmessages", "ADD UPDATE TO QUEUE seq = " + seq); + if (updatesStartWaitTimeSeq == 0) { + updatesStartWaitTimeSeq = System.currentTimeMillis(); + } + UserActionUpdatesSeq updates = new UserActionUpdatesSeq(); + updates.seq = seq; + updatesQueueSeq.add(updates); + } else { + getDifference(); } - UserActionUpdates updates = new UserActionUpdates(); - updates.seq = seq; - updatesQueue.add(updates); - } else { - getDifference(); } } } @@ -760,7 +872,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (user == null) { return; } - blockedUsers.remove((Integer)user.id); + blockedUsers.remove((Integer) user.id); req.id = MessagesController.getInputUser(user); NotificationCenter.getInstance().postNotificationName(NotificationCenter.blockedUsersDidLoaded); ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { @@ -859,10 +971,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter ArrayList users = new ArrayList<>(); users.add(user); MessagesStorage.getInstance().putUsersAndChats(users, null, false, true); - user.photo = (TLRPC.UserProfilePhoto)response; + user.photo = (TLRPC.UserProfilePhoto) response; AndroidUtilities.runOnUIThread(new Runnable() { @Override public void run() { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.mainUserInfoChanged); NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, MessagesController.UPDATE_MASK_ALL); UserConfig.saveConfig(true); } @@ -938,16 +1051,15 @@ public class MessagesController implements NotificationCenter.NotificationCenter ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { @Override public void run(TLObject response, TLRPC.TL_error error) { - + if (error == null) { + TLRPC.TL_messages_affectedMessages res = (TLRPC.TL_messages_affectedMessages) response; + processNewDifferenceParams(-1, res.pts, -1, res.pts_count); + } } }); } public void deleteDialog(final long did, int offset, final boolean onlyHistory) { - if (offset == 0) { - MessagesStorage.getInstance().deleteDialog(did, onlyHistory); - } - int lower_part = (int)did; int high_id = (int)(did >> 32); @@ -963,7 +1075,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter dialog.unread_count = 0; } dialogMessage.remove(dialog.top_message); + dialog.top_message = 0; } + NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.removeAllMessagesFromDialog, did); MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { @@ -978,8 +1093,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter }); } }); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.removeAllMessagesFromDialog, did); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); + + MessagesStorage.getInstance().deleteDialog(did, onlyHistory); } if (high_id == 1) { @@ -1010,7 +1125,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (res.offset > 0) { deleteDialog(did, res.offset, onlyHistory); } - processNewDifferenceParams(res.seq, res.pts, -1); + processNewDifferenceParams(-1, res.pts, -1, res.pts_count); } } }); @@ -1096,9 +1211,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter }); } - if (updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 < currentTime) { - FileLog.e("tmessages", "UPDATES WAIT TIMEOUT - CHECK QUEUE"); - processUpdatesQueue(0); + for (int a = 0; a < 3; a++) { + if (getUpdatesStartTime(a) != 0 && getUpdatesStartTime(a) + 1500 < currentTime) { + FileLog.e("tmessages", a + " QUEUE UPDATES WAIT TIMEOUT - CHECK QUEUE"); + processUpdatesQueue(a, 0); + } } } if (!onlinePrivacy.isEmpty()) { @@ -1175,7 +1292,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (label.length() != 0) { label += ", "; } - label += ContactsController.formatName(user.first_name, user.last_name); + if (user.first_name != null && user.first_name.length() > 0) { + label += user.first_name; + } else if (user.last_name != null && user.last_name.length() > 0) { + label += user.last_name; + } count++; } if (count == 2) { @@ -1185,12 +1306,12 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (label.length() != 0) { if (count > 1) { if (arr.size() > 2) { - newPrintingStrings.put(key, Html.fromHtml(String.format("%s %s", label, LocaleController.formatPluralString("AndMoreTyping", arr.size() - 2)))); + newPrintingStrings.put(key, String.format("%s %s", label, LocaleController.formatPluralString("AndMoreTyping", arr.size() - 2))); } else { - newPrintingStrings.put(key, Html.fromHtml(String.format("%s %s", label, LocaleController.getString("AreTyping", R.string.AreTyping)))); + newPrintingStrings.put(key, String.format("%s %s", label, LocaleController.getString("AreTyping", R.string.AreTyping))); } } else { - newPrintingStrings.put(key, Html.fromHtml(String.format("%s %s", label, LocaleController.getString("IsTyping", R.string.IsTyping)))); + newPrintingStrings.put(key, String.format("%s %s", label, LocaleController.getString("IsTyping", R.string.IsTyping))); } } } @@ -1324,8 +1445,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter Utilities.stageQueue.postRunnable(new Runnable() { @Override public void run() { - int lower_id = (int)dialog_id; - int high_id = (int)(dialog_id >> 32); + int lower_id = (int) dialog_id; + int high_id = (int) (dialog_id >> 32); if (!isCache) { ImageLoader.saveMessagesThumbs(messagesRes.messages); } @@ -1350,12 +1471,21 @@ public class MessagesController implements NotificationCenter.NotificationCenter for (TLRPC.Message message : messagesRes.messages) { message.dialog_id = dialog_id; objects.add(new MessageObject(message, usersLocal, true)); - if (isCache && message.media instanceof TLRPC.TL_messageMediaUnsupported) { - if (message.media.bytes.length == 0 || message.media.bytes.length == 1 && message.media.bytes[0] < TLRPC.LAYER) { - if (messagesToReload == null) { - messagesToReload = new ArrayList<>(); + if (isCache) { + if (message.media instanceof TLRPC.TL_messageMediaUnsupported) { + if (message.media.bytes.length == 0 || message.media.bytes.length == 1 && message.media.bytes[0] < TLRPC.LAYER) { + if (messagesToReload == null) { + messagesToReload = new ArrayList<>(); + } + messagesToReload.add(message.id); + } + } else if (message.media instanceof TLRPC.TL_messageMediaWebPage) { + if (message.media.webpage instanceof TLRPC.TL_webPagePending && message.media.webpage.date <= ConnectionsManager.getInstance().getCurrentTime()) { + if (messagesToReload == null) { + messagesToReload = new ArrayList<>(); + } + messagesToReload.add(message.id); } - messagesToReload.add(message.id); } } } @@ -1437,8 +1567,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter currentDialog.unread_count = entry.getValue(); } } - NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate); NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); + NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate); } }); } @@ -1497,7 +1627,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (oldMsg != null && oldMsg.deleted || value.top_message > currentDialog.top_message) { dialogs_dict.put(key, value); if (oldMsg != null) { - dialogMessage.remove(oldMsg.messageOwner.id); + dialogMessage.remove(oldMsg.getId()); } dialogMessage.put(value.top_message, new_dialogMessage.get(value.top_message)); } @@ -1505,7 +1635,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter MessageObject newMsg = new_dialogMessage.get(value.top_message); if (oldMsg.deleted || newMsg == null || newMsg.messageOwner.date > oldMsg.messageOwner.date) { dialogs_dict.put(key, value); - dialogMessage.remove(oldMsg.messageOwner.id); + dialogMessage.remove(oldMsg.getId()); dialogMessage.put(value.top_message, new_dialogMessage.get(value.top_message)); } } @@ -1528,16 +1658,16 @@ public class MessagesController implements NotificationCenter.NotificationCenter } }); for (TLRPC.TL_dialog d : dialogs) { - int high_id = (int)(d.id >> 32); - if ((int)d.id != 0 && high_id != 1) { + int high_id = (int) (d.id >> 32); + if ((int) d.id != 0 && high_id != 1) { dialogsServerOnly.add(d); } } - NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate); NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); + NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate); } }); - } + } }); } @@ -1554,8 +1684,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (resetEnd) { dialogsEndReached = false; } - loadDialogs(offset, serverOffset, count, false); NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); + loadDialogs(offset, serverOffset, count, false); } }); return; @@ -1571,7 +1701,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } if (dialogsRes instanceof TLRPC.TL_messages_dialogsSlice) { - TLRPC.TL_messages_dialogsSlice slice = (TLRPC.TL_messages_dialogsSlice)dialogsRes; + TLRPC.TL_messages_dialogsSlice slice = (TLRPC.TL_messages_dialogsSlice) dialogsRes; new_totalDialogsCount = slice.count; } else { new_totalDialogsCount = dialogsRes.dialogs.size(); @@ -1633,7 +1763,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (oldMsg == null || currentDialog.top_message > 0) { if (oldMsg != null && oldMsg.deleted || value.top_message > currentDialog.top_message) { if (oldMsg != null) { - dialogMessage.remove(oldMsg.messageOwner.id); + dialogMessage.remove(oldMsg.getId()); } dialogs_dict.put(key, value); dialogMessage.put(value.top_message, new_dialogMessage.get(value.top_message)); @@ -1641,7 +1771,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } else { MessageObject newMsg = new_dialogMessage.get(value.top_message); if (oldMsg.deleted || newMsg == null || newMsg.messageOwner.date > oldMsg.messageOwner.date) { - dialogMessage.remove(oldMsg.messageOwner.id); + dialogMessage.remove(oldMsg.getId()); dialogs_dict.put(key, value); dialogMessage.put(value.top_message, new_dialogMessage.get(value.top_message)); } @@ -1665,8 +1795,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter } }); for (TLRPC.TL_dialog d : dialogs) { - int high_id = (int)(d.id >> 32); - if ((int)d.id != 0 && high_id != 1) { + int high_id = (int) (d.id >> 32); + if ((int) d.id != 0 && high_id != 1) { dialogsServerOnly.add(d); } } @@ -1713,6 +1843,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter req.peer.chat_id = -lower_part; } else { TLRPC.User user = getUser(lower_part); + if (user == null) { + return; + } if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { req.peer = new TLRPC.TL_inputPeerForeign(); req.peer.user_id = user.id; @@ -1724,7 +1857,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter } req.max_id = max_positive_id; req.offset = offset; - req.read_contents = true; if (offset == 0) { MessagesStorage.getInstance().processPendingRead(dialog_id, max_positive_id, max_date, false); MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @@ -1764,7 +1896,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (res.offset > 0) { markDialogAsRead(dialog_id, 0, max_positive_id, res.offset, max_date, was, popup); } - processNewDifferenceParams(res.seq, res.pts, -1); + processNewDifferenceParams(-1, res.pts, -1, res.pts_count); } } }); @@ -1817,7 +1949,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } - public long createChat(String title, ArrayList selectedContacts, final TLRPC.InputFile uploadedAvatar, boolean isBroadcast) { + public long createChat(String title, ArrayList selectedContacts, boolean isBroadcast) { if (isBroadcast) { TLRPC.TL_chat chat = new TLRPC.TL_chat(); chat.id = UserConfig.lastBroadcastId; @@ -1865,8 +1997,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter arr.add(newMsg); MessagesStorage.getInstance().putMessages(arr, false, true, false, 0); updateInterfaceWithMessages(newMsg.dialog_id, objArr); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatDidCreated, chat.id); NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatDidCreated, chat.id); return 0; } else { @@ -1891,30 +2023,21 @@ public class MessagesController implements NotificationCenter.NotificationCenter }); return; } - final TLRPC.messages_StatedMessage res = (TLRPC.messages_StatedMessage) response; - MessagesStorage.getInstance().putUsersAndChats(res.users, res.chats, true, true); - + final TLRPC.Updates updates = (TLRPC.Updates) response; + processUpdates(updates, false); AndroidUtilities.runOnUIThread(new Runnable() { @Override public void run() { - putUsers(res.users, false); - putChats(res.chats, false); - final ArrayList messagesObj = new ArrayList<>(); - messagesObj.add(new MessageObject(res.message, users, true)); - TLRPC.Chat chat = res.chats.get(0); - updateInterfaceWithMessages(-chat.id, messagesObj); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatDidCreated, chat.id); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); - if (uploadedAvatar != null) { - changeChatAvatar(chat.id, uploadedAvatar); + putUsers(updates.users, false); + putChats(updates.chats, false); + TLRPC.Chat chat = null; + if (updates.chats != null && !updates.chats.isEmpty()) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatDidCreated, updates.chats.get(0).id); + } else { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatDidFailCreate); } } }); - - final ArrayList messages = new ArrayList<>(); - messages.add(res.message); - MessagesStorage.getInstance().putMessages(messages, true, true, false, 0); - processNewDifferenceParams(res.seq, res.pts, -1); } }); } @@ -1937,43 +2060,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (error != null) { return; } - - final TLRPC.messages_StatedMessage res = (TLRPC.messages_StatedMessage) response; - MessagesStorage.getInstance().putUsersAndChats(res.users, res.chats, true, true); - - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - putUsers(res.users, false); - putChats(res.chats, false); - final ArrayList messagesObj = new ArrayList<>(); - messagesObj.add(new MessageObject(res.message, users, true)); - TLRPC.Chat chat = res.chats.get(0); - updateInterfaceWithMessages(-chat.id, messagesObj); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_CHAT_MEMBERS); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); - - if (info != null) { - for (TLRPC.TL_chatParticipant p : info.participants) { - if (p.user_id == user.id) { - return; - } - } - TLRPC.TL_chatParticipant newPart = new TLRPC.TL_chatParticipant(); - newPart.user_id = user.id; - newPart.inviter_id = UserConfig.getClientUserId(); - newPart.date = ConnectionsManager.getInstance().getCurrentTime(); - info.participants.add(0, newPart); - MessagesStorage.getInstance().updateChatInfo(info.chat_id, info, true); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatInfoDidLoaded, info.chat_id, info); - } - } - }); - - final ArrayList messages = new ArrayList<>(); - messages.add(res.message); - MessagesStorage.getInstance().putMessages(messages, true, true, false, 0); - processNewDifferenceParams(res.seq, res.pts, -1); + processUpdates((TLRPC.Updates) response, false); } }); } else { @@ -2016,53 +2103,16 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (error != null) { return; } - final TLRPC.messages_StatedMessage res = (TLRPC.messages_StatedMessage) response; + final TLRPC.Updates updates = (TLRPC.Updates) response; + processUpdates(updates, false); if (user.id == UserConfig.getClientUserId()) { - res.chats = null; - } - MessagesStorage.getInstance().putUsersAndChats(res.users, res.chats, true, true); - - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - putUsers(res.users, false); - putChats(res.chats, false); - if (user.id != UserConfig.getClientUserId()) { - final ArrayList messagesObj = new ArrayList<>(); - messagesObj.add(new MessageObject(res.message, users, true)); - TLRPC.Chat chat = res.chats.get(0); - updateInterfaceWithMessages(-chat.id, messagesObj); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_CHAT_MEMBERS); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + MessagesController.getInstance().deleteDialog(-chat_id, 0, false); } - boolean changed = false; - if (info != null) { - for (int a = 0; a < info.participants.size(); a++) { - TLRPC.TL_chatParticipant p = info.participants.get(a); - if (p.user_id == user.id) { - info.participants.remove(a); - changed = true; - break; - } - } - if (changed) { - MessagesStorage.getInstance().updateChatInfo(chat_id, info, true); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatInfoDidLoaded, info.chat_id, info); - } else { - MessagesStorage.getInstance().updateChatInfo(chat_id, user.id, true, 0, 0); - } - } else { - MessagesStorage.getInstance().updateChatInfo(chat_id, user.id, true, 0, 0); - } - } - }); - - if (user.id != UserConfig.getClientUserId()) { - final ArrayList messages = new ArrayList<>(); - messages.add(res.message); - MessagesStorage.getInstance().putMessages(messages, true, true, false, 0); + }); } - processNewDifferenceParams(res.seq, res.pts, -1); } }); } else { @@ -2104,27 +2154,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (error != null) { return; } - final TLRPC.messages_StatedMessage res = (TLRPC.messages_StatedMessage) response; - MessagesStorage.getInstance().putUsersAndChats(res.users, res.chats, true, true); - - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - putUsers(res.users, false); - putChats(res.chats, false); - final ArrayList messagesObj = new ArrayList<>(); - messagesObj.add(new MessageObject(res.message, users, true)); - TLRPC.Chat chat = res.chats.get(0); - updateInterfaceWithMessages(-chat.id, messagesObj); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_CHAT_NAME); - } - }); - - final ArrayList messages = new ArrayList<>(); - messages.add(res.message); - MessagesStorage.getInstance().putMessages(messages, true, true, false, 0); - processNewDifferenceParams(res.seq, res.pts, -1); + processUpdates((TLRPC.Updates) response, false); } }); } else { @@ -2154,29 +2184,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (error != null) { return; } - final TLRPC.messages_StatedMessage res = (TLRPC.messages_StatedMessage) response; - MessagesStorage.getInstance().putUsersAndChats(res.users, res.chats, true, true); - - final ArrayList messages = new ArrayList<>(); - messages.add(res.message); - ImageLoader.saveMessagesThumbs(messages); - - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - putUsers(res.users, false); - putChats(res.chats, false); - final ArrayList messagesObj = new ArrayList<>(); - messagesObj.add(new MessageObject(res.message, users, true)); - TLRPC.Chat chat = res.chats.get(0); - updateInterfaceWithMessages(-chat.id, messagesObj); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_CHAT_AVATAR); - } - }); - - MessagesStorage.getInstance().putMessages(messages, true, true, false, 0); - processNewDifferenceParams(res.seq, res.pts, -1); + processUpdates((TLRPC.Updates) response, false); } }); } @@ -2288,7 +2296,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter MessagesStorage.lastPtsValue = res.pts; MessagesStorage.lastSeqValue = res.seq; MessagesStorage.lastQtsValue = res.qts; - processUpdatesQueue(2); + for (int a = 0; a < 3; a++) { + processUpdatesQueue(a, 2); + } MessagesStorage.getInstance().saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); } else { if (error.code != 401) { @@ -2307,8 +2317,61 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } - private void processUpdatesQueue(int state) { - if (!updatesQueue.isEmpty()) { + private void setUpdatesStartTime(int type, long time) { + if (type == 0) { + updatesStartWaitTimeSeq = time; + } else if (type == 1) { + updatesStartWaitTimePts = time; + } else if (type == 2) { + updatesStartWaitTimeQts = time; + } + } + + public long getUpdatesStartTime(int type) { + if (type == 0) { + return updatesStartWaitTimeSeq; + } else if (type == 1) { + return updatesStartWaitTimePts; + } else if (type == 2) { + return updatesStartWaitTimeQts; + } + return 0; + } + + private int isValidUpdate(TLRPC.Updates updates, int type) { + if (type == 0) { + int seq = getUpdateSeq(updates); + if (MessagesStorage.lastSeqValue + 1 == seq || MessagesStorage.lastSeqValue == seq) { + return 0; + } else if (MessagesStorage.lastSeqValue < seq) { + return 1; + } else { + return 2; + } + } else if (type == 1) { + if (updates.pts <= MessagesStorage.lastPtsValue) { + return 2; + } else if (MessagesStorage.lastPtsValue + updates.pts_count == updates.pts) { + return 0; + } else { + return 1; + } + } else if (type == 2) { + if (updates.qts <= MessagesStorage.lastQtsValue) { + return 2; + } else if (MessagesStorage.lastQtsValue + 1 == updates.qts) { + return 0; + } else { + return 1; + } + } + return 0; + } + + private boolean processUpdatesQueue(int type, int state) { + ArrayList updatesQueue = null; + if (type == 0) { + updatesQueue = updatesQueueSeq; Collections.sort(updatesQueue, new Comparator() { @Override public int compare(TLRPC.Updates updates, TLRPC.Updates updates2) { @@ -2322,32 +2385,66 @@ public class MessagesController implements NotificationCenter.NotificationCenter return -1; } }); + } else if (type == 1) { + updatesQueue = updatesQueuePts; + Collections.sort(updatesQueue, new Comparator() { + @Override + public int compare(TLRPC.Updates updates, TLRPC.Updates updates2) { + if (updates.pts == updates2.pts) { + return 0; + } else if (updates.pts > updates2.pts) { + return 1; + } + return -1; + } + }); + } else if (type == 2) { + updatesQueue = updatesQueueQts; + Collections.sort(updatesQueue, new Comparator() { + @Override + public int compare(TLRPC.Updates updates, TLRPC.Updates updates2) { + if (updates.qts == updates2.qts) { + return 0; + } else if (updates.qts > updates2.qts) { + return 1; + } + return -1; + } + }); + } + if (!updatesQueue.isEmpty()) { boolean anyProceed = false; if (state == 2) { TLRPC.Updates updates = updatesQueue.get(0); - MessagesStorage.lastSeqValue = getUpdateSeq(updates); + if (type == 0) { + MessagesStorage.lastSeqValue = getUpdateSeq(updates); + } else if (type == 1) { + MessagesStorage.lastPtsValue = updates.pts; + } else if (type == 2) { + MessagesStorage.lastQtsValue = updates.qts; + } } for (int a = 0; a < updatesQueue.size(); a++) { TLRPC.Updates updates = updatesQueue.get(a); - int seq = getUpdateSeq(updates); - if (MessagesStorage.lastSeqValue + 1 == seq || MessagesStorage.lastSeqValue == seq) { + int updateState = isValidUpdate(updates, type); + if (updateState == 0) { processUpdates(updates, true); anyProceed = true; updatesQueue.remove(a); a--; - } else if (MessagesStorage.lastSeqValue < seq) { - if (updatesStartWaitTime != 0 && (anyProceed || updatesStartWaitTime + 1500 > System.currentTimeMillis())) { + } else if (updateState == 1) { + if (getUpdatesStartTime(type) != 0 && (anyProceed || getUpdatesStartTime(type) + 1500 > System.currentTimeMillis())) { FileLog.e("tmessages", "HOLE IN UPDATES QUEUE - will wait more time"); if (anyProceed) { - updatesStartWaitTime = System.currentTimeMillis(); + setUpdatesStartTime(type, System.currentTimeMillis()); } - return; + return false; } else { FileLog.e("tmessages", "HOLE IN UPDATES QUEUE - getDifference"); - updatesStartWaitTime = 0; + setUpdatesStartTime(type, 0); updatesQueue.clear(); getDifference(); - return; + return false; } } else { updatesQueue.remove(a); @@ -2356,34 +2453,14 @@ public class MessagesController implements NotificationCenter.NotificationCenter } updatesQueue.clear(); FileLog.e("tmessages", "UPDATES QUEUE PROCEED - OK"); - updatesStartWaitTime = 0; - if (state == 1) { - final int stateCopy = ConnectionsManager.getInstance().getConnectionState(); - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.didUpdatedConnectionState, stateCopy); - } - }); - } - } else { - if (state == 1) { - final int stateCopy = ConnectionsManager.getInstance().getConnectionState(); - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.didUpdatedConnectionState, stateCopy); - } - }); - } else { - updatesStartWaitTime = 0; - } } + setUpdatesStartTime(type, 0); + return true; } public void getDifference() { registerForPush(UserConfig.pushString); - if (MessagesStorage.lastDateValue == 0) { + if (MessagesStorage.lastPtsValue == 0) { loadCurrentState(); return; } @@ -2399,6 +2476,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter req.pts = MessagesStorage.lastPtsValue; req.date = MessagesStorage.lastDateValue; req.qts = MessagesStorage.lastQtsValue; + if (req.date == 0) { + req.date = ConnectionsManager.getInstance().getCurrentTime(); + } FileLog.e("tmessages", "start getDifference with date = " + MessagesStorage.lastDateValue + " pts = " + MessagesStorage.lastPtsValue + " seq = " + MessagesStorage.lastSeqValue); if (ConnectionsManager.getInstance().getConnectionState() == 0) { ConnectionsManager.getInstance().setConnectionState(3); @@ -2463,7 +2543,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter Integer oldId = entry.getKey(); SendMessagesHelper.getInstance().processSentMessage(oldId); Integer newId = entry.getValue(); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, oldId, newId, null); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, oldId, newId, null, false); } } }); @@ -2499,7 +2579,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } - if (!obj.isFromMe() && obj.isUnread()) { + if (!obj.isOut() && obj.isUnread()) { pushMessages.add(obj); } @@ -2567,7 +2647,21 @@ public class MessagesController implements NotificationCenter.NotificationCenter MessagesStorage.lastPtsValue = res.state.pts; MessagesStorage.lastQtsValue = res.state.qts; ConnectionsManager.getInstance().setConnectionState(0); - processUpdatesQueue(1); + boolean done = true; + for (int a = 0; a < 3; a++) { + if (!processUpdatesQueue(a, 1)) { + done = false; + } + } + if (done) { + final int stateCopy = ConnectionsManager.getInstance().getConnectionState(); + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.didUpdatedConnectionState, stateCopy); + } + }); + } } else if (res instanceof TLRPC.TL_updates_differenceSlice) { MessagesStorage.lastDateValue = res.intermediate_state.date; MessagesStorage.lastPtsValue = res.intermediate_state.pts; @@ -2578,7 +2672,21 @@ public class MessagesController implements NotificationCenter.NotificationCenter MessagesStorage.lastSeqValue = res.seq; MessagesStorage.lastDateValue = res.date; ConnectionsManager.getInstance().setConnectionState(0); - processUpdatesQueue(1); + boolean done = true; + for (int a = 0; a < 3; a++) { + if (!processUpdatesQueue(a, 1)) { + done = false; + } + } + if (done) { + final int stateCopy = ConnectionsManager.getInstance().getConnectionState(); + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.didUpdatedConnectionState, stateCopy); + } + }); + } } MessagesStorage.getInstance().saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); FileLog.e("tmessages", "received difference with date = " + MessagesStorage.lastDateValue + " pts = " + MessagesStorage.lastPtsValue + " seq = " + MessagesStorage.lastSeqValue); @@ -2605,131 +2713,120 @@ public class MessagesController implements NotificationCenter.NotificationCenter public void processUpdates(final TLRPC.Updates updates, boolean fromQueue) { boolean needGetDiff = false; boolean needReceivedQueue = false; - boolean addedToQueue = false; boolean updateStatus = false; if (updates instanceof TLRPC.TL_updateShort) { ArrayList arr = new ArrayList<>(); arr.add(updates.update); processUpdateArray(arr, null, null); - } else if (updates instanceof TLRPC.TL_updateShortChatMessage) { - TLRPC.User user = getUser(updates.from_id); - if (user != null && user.status != null && user.status.expires <= 0) { - onlinePrivacy.put(user.id, ConnectionsManager.getInstance().getCurrentTime()); - updateStatus = true; - } - boolean missingData = getChat(updates.chat_id) == null || user == null; - if (missingData) { - needGetDiff = true; - } else { - if (MessagesStorage.lastSeqValue + 1 == updates.seq) { - TLRPC.TL_message message = new TLRPC.TL_message(); - message.from_id = updates.from_id; - message.id = updates.id; - message.to_id = new TLRPC.TL_peerChat(); - message.to_id.chat_id = updates.chat_id; - message.message = updates.message; - message.date = updates.date; - message.flags = TLRPC.MESSAGE_FLAG_UNREAD; - message.media = new TLRPC.TL_messageMediaEmpty(); - MessagesStorage.lastSeqValue = updates.seq; - MessagesStorage.lastPtsValue = updates.pts; - final MessageObject obj = new MessageObject(message, null, true); - final ArrayList objArr = new ArrayList<>(); - objArr.add(obj); - ArrayList arr = new ArrayList<>(); - arr.add(message); - final boolean printUpdate = updatePrintingUsersWithNewMessages(-updates.chat_id, objArr); - if (printUpdate) { - updatePrintingStrings(); - } - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - if (printUpdate) { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_USER_PRINT); - } + } else if (updates instanceof TLRPC.TL_updateShortChatMessage || updates instanceof TLRPC.TL_updateShortMessage) { + TLRPC.User user = getUser(updates.user_id); + TLRPC.User user2 = null; - updateInterfaceWithMessages(-updates.chat_id, objArr); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); - } - }); - MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { - @Override - public void run() { - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - if (!obj.isFromMe() && obj.isUnread()) { - NotificationsController.getInstance().processNewMessages(objArr, true); - } - } - }); - } - }); - MessagesStorage.getInstance().putMessages(arr, false, true, false, 0); - } else if (MessagesStorage.lastSeqValue != updates.seq) { - FileLog.e("tmessages", "need get diff TL_updateShortChatMessage, seq: " + MessagesStorage.lastSeqValue + " " + updates.seq); - if (gettingDifference || updatesStartWaitTime == 0 || updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 > System.currentTimeMillis()) { - if (updatesStartWaitTime == 0) { - updatesStartWaitTime = System.currentTimeMillis(); - } - FileLog.e("tmessages", "add TL_updateShortChatMessage to queue"); - updatesQueue.add(updates); - addedToQueue = true; - } else { - needGetDiff = true; - } - } + if (user == null) { + user = MessagesStorage.getInstance().getUserSync(updates.user_id); + putUser(user, true); + } + + boolean needFwdUser = false; + if (updates.fwd_from_id != 0) { + user2 = getUser(updates.fwd_from_id); + if (user2 == null) { + user2 = MessagesStorage.getInstance().getUserSync(updates.fwd_from_id); + putUser(user2, true); + } + needFwdUser = true; + } + + boolean missingData = false; + if (updates instanceof TLRPC.TL_updateShortMessage) { + missingData = user == null || needFwdUser && user2 == null; + } else { + TLRPC.Chat chat = getChat(updates.chat_id); + if (chat == null) { + chat = MessagesStorage.getInstance().getChatSync(updates.chat_id); + putChat(chat, true); + } + missingData = chat == null || user == null || needFwdUser && user2 == null; } - } else if (updates instanceof TLRPC.TL_updateShortMessage) { - TLRPC.User user = getUser(updates.from_id); if (user != null && user.status != null && user.status.expires <= 0) { onlinePrivacy.put(user.id, ConnectionsManager.getInstance().getCurrentTime()); updateStatus = true; } - boolean missingData = user == null; + if (missingData) { needGetDiff = true; } else { - if (MessagesStorage.lastSeqValue + 1 == updates.seq) { + if (MessagesStorage.lastPtsValue + updates.pts_count == updates.pts) { TLRPC.TL_message message = new TLRPC.TL_message(); - message.from_id = updates.from_id; message.id = updates.id; - message.to_id = new TLRPC.TL_peerUser(); - message.to_id.user_id = updates.from_id; + if (updates instanceof TLRPC.TL_updateShortMessage) { + if ((updates.flags & TLRPC.MESSAGE_FLAG_OUT) != 0) { + message.from_id = UserConfig.getClientUserId(); + } else { + message.from_id = updates.user_id; + } + message.to_id = new TLRPC.TL_peerUser(); + message.to_id.user_id = updates.user_id; + message.dialog_id = updates.user_id; + } else { + message.from_id = updates.user_id; + message.to_id = new TLRPC.TL_peerChat(); + message.to_id.chat_id = updates.chat_id; + message.dialog_id = -updates.chat_id; + } message.message = updates.message; message.date = updates.date; - message.flags = TLRPC.MESSAGE_FLAG_UNREAD; + message.flags = updates.flags; + message.fwd_from_id = updates.fwd_from_id; + message.fwd_date = updates.fwd_date; + message.reply_to_msg_id = updates.reply_to_msg_id; message.media = new TLRPC.TL_messageMediaEmpty(); - MessagesStorage.lastSeqValue = updates.seq; MessagesStorage.lastPtsValue = updates.pts; - MessagesStorage.lastDateValue = updates.date; final MessageObject obj = new MessageObject(message, null, true); final ArrayList objArr = new ArrayList<>(); objArr.add(obj); ArrayList arr = new ArrayList<>(); arr.add(message); - final boolean printUpdate = updatePrintingUsersWithNewMessages(updates.from_id, objArr); - if (printUpdate) { - updatePrintingStrings(); - } - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - if (printUpdate) { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_USER_PRINT); - } - updateInterfaceWithMessages(updates.from_id, objArr); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); + if (updates instanceof TLRPC.TL_updateShortMessage) { + final boolean printUpdate = (updates.flags & TLRPC.MESSAGE_FLAG_OUT) == 0 && updatePrintingUsersWithNewMessages(updates.user_id, objArr); + if (printUpdate) { + updatePrintingStrings(); } - }); + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (printUpdate) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_USER_PRINT); + } + updateInterfaceWithMessages(updates.user_id, objArr); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); + } + }); + } else { + final boolean printUpdate = updatePrintingUsersWithNewMessages(-updates.chat_id, objArr); + if (printUpdate) { + updatePrintingStrings(); + } + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (printUpdate) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_USER_PRINT); + } + + updateInterfaceWithMessages(-updates.chat_id, objArr); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); + } + }); + } + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { AndroidUtilities.runOnUIThread(new Runnable() { @Override public void run() { - if (!obj.isFromMe() && obj.isUnread()) { + if (!obj.isOut()) { NotificationsController.getInstance().processNewMessages(objArr, true); } } @@ -2737,78 +2834,103 @@ public class MessagesController implements NotificationCenter.NotificationCenter } }); MessagesStorage.getInstance().putMessages(arr, false, true, false, 0); - } else if (MessagesStorage.lastSeqValue != updates.seq) { - FileLog.e("tmessages", "need get diff TL_updateShortMessage, seq: " + MessagesStorage.lastSeqValue + " " + updates.seq); - if (gettingDifference || updatesStartWaitTime == 0 || updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 > System.currentTimeMillis()) { - if (updatesStartWaitTime == 0) { - updatesStartWaitTime = System.currentTimeMillis(); + } else if (MessagesStorage.lastPtsValue != updates.pts) { + FileLog.e("tmessages", "need get diff short message, pts: " + MessagesStorage.lastPtsValue + " " + updates.pts + " count = " + updates.pts_count); + if (gettingDifference || updatesStartWaitTimePts == 0 || updatesStartWaitTimePts != 0 && updatesStartWaitTimePts + 1500 > System.currentTimeMillis()) { + if (updatesStartWaitTimePts == 0) { + updatesStartWaitTimePts = System.currentTimeMillis(); } - FileLog.e("tmessages", "add TL_updateShortMessage to queue"); - updatesQueue.add(updates); - addedToQueue = true; + FileLog.e("tmessages", "add short message to queue"); + updatesQueuePts.add(updates); } else { needGetDiff = true; } } } - } else if (updates instanceof TLRPC.TL_updatesCombined) { - if (MessagesStorage.lastSeqValue + 1 == updates.seq_start || MessagesStorage.lastSeqValue == updates.seq_start) { - MessagesStorage.getInstance().putUsersAndChats(updates.users, updates.chats, true, true); - int lastPtsValue = MessagesStorage.lastPtsValue; - int lastQtsValue = MessagesStorage.lastQtsValue; - if (!processUpdateArray(updates.updates, updates.users, updates.chats)) { - MessagesStorage.lastPtsValue = lastPtsValue; - MessagesStorage.lastQtsValue = lastQtsValue; - FileLog.e("tmessages", "need get diff inner TL_updatesCombined, seq: " + MessagesStorage.lastSeqValue + " " + updates.seq); - needGetDiff = true; - } else { - MessagesStorage.lastDateValue = updates.date; - MessagesStorage.lastSeqValue = updates.seq; - if (MessagesStorage.lastQtsValue != lastQtsValue) { + } else if (updates instanceof TLRPC.TL_updatesCombined || updates instanceof TLRPC.TL_updates) { + MessagesStorage.getInstance().putUsersAndChats(updates.users, updates.chats, true, true); + int lastQtsValue = MessagesStorage.lastQtsValue; + for (int a = 0; a < updates.updates.size(); a++) { + TLRPC.Update update = updates.updates.get(a); + if (update instanceof TLRPC.TL_updateNewMessage || update instanceof TLRPC.TL_updateReadMessages || update instanceof TLRPC.TL_updateReadHistoryInbox || + update instanceof TLRPC.TL_updateReadHistoryOutbox || update instanceof TLRPC.TL_updateDeleteMessages) { + TLRPC.TL_updates updatesNew = new TLRPC.TL_updates(); + updatesNew.updates.add(update); + updatesNew.pts = update.pts; + updatesNew.pts_count = update.pts_count; + if (MessagesStorage.lastPtsValue + update.pts_count == update.pts) { + if (!processUpdateArray(updatesNew.updates, updates.users, updates.chats)) { + FileLog.e("tmessages", "need get diff inner TL_updates, seq: " + MessagesStorage.lastSeqValue + " " + updates.seq); + needGetDiff = true; + } else { + MessagesStorage.lastPtsValue = update.pts; + } + } else if (MessagesStorage.lastPtsValue != update.pts) { + FileLog.e("tmessages", update + " need get diff, pts: " + MessagesStorage.lastPtsValue + " " + update.pts + " count = " + update.pts_count); + if (gettingDifference || updatesStartWaitTimePts == 0 || updatesStartWaitTimePts != 0 && updatesStartWaitTimePts + 1500 > System.currentTimeMillis()) { + if (updatesStartWaitTimePts == 0) { + updatesStartWaitTimePts = System.currentTimeMillis(); + } + FileLog.e("tmessages", "add short message to queue"); + updatesQueuePts.add(updatesNew); + } else { + needGetDiff = true; + } + } + } else if (update instanceof TLRPC.TL_updateNewEncryptedMessage) { + TLRPC.TL_updates updatesNew = new TLRPC.TL_updates(); + updatesNew.updates.add(update); + updatesNew.qts = update.qts; + if (MessagesStorage.lastQtsValue == 0 || MessagesStorage.lastQtsValue + 1 == update.qts) { + processUpdateArray(updatesNew.updates, updates.users, updates.chats); + MessagesStorage.lastQtsValue = update.qts; needReceivedQueue = true; + } else if (MessagesStorage.lastPtsValue != update.qts) { + FileLog.e("tmessages", update + " need get diff, qts: " + MessagesStorage.lastQtsValue + " " + update.qts); + if (gettingDifference || updatesStartWaitTimeQts == 0 || updatesStartWaitTimeQts != 0 && updatesStartWaitTimeQts + 1500 > System.currentTimeMillis()) { + if (updatesStartWaitTimeQts == 0) { + updatesStartWaitTimeQts = System.currentTimeMillis(); + } + FileLog.e("tmessages", "add short message to queue"); + updatesQueueQts.add(updatesNew); + } else { + needGetDiff = true; + } } - } - } else { - FileLog.e("tmessages", "need get diff TL_updatesCombined, seq: " + MessagesStorage.lastSeqValue + " " + updates.seq_start); - if (gettingDifference || updatesStartWaitTime == 0 || updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 > System.currentTimeMillis()) { - if (updatesStartWaitTime == 0) { - updatesStartWaitTime = System.currentTimeMillis(); - } - FileLog.e("tmessages", "add TL_updatesCombined to queue"); - updatesQueue.add(updates); - addedToQueue = true; } else { - needGetDiff = true; + continue; } + updates.updates.remove(a); + a--; } - } else if (updates instanceof TLRPC.TL_updates) { - if (MessagesStorage.lastSeqValue + 1 == updates.seq || updates.seq == 0 || updates.seq == MessagesStorage.lastSeqValue) { - MessagesStorage.getInstance().putUsersAndChats(updates.users, updates.chats, true, true); - int lastPtsValue = MessagesStorage.lastPtsValue; - int lastQtsValue = MessagesStorage.lastQtsValue; - if (!processUpdateArray(updates.updates, updates.users, updates.chats)) { - needGetDiff = true; - MessagesStorage.lastPtsValue = lastPtsValue; - MessagesStorage.lastQtsValue = lastQtsValue; - FileLog.e("tmessages", "need get diff inner TL_updates, seq: " + MessagesStorage.lastSeqValue + " " + updates.seq); - } else { + + boolean processUpdate = false; + if (updates instanceof TLRPC.TL_updatesCombined) { + processUpdate = MessagesStorage.lastSeqValue + 1 == updates.seq_start || MessagesStorage.lastSeqValue == updates.seq_start; + } else { + processUpdate = MessagesStorage.lastSeqValue + 1 == updates.seq || updates.seq == 0 || updates.seq == MessagesStorage.lastSeqValue; + } + if (processUpdate) { + processUpdateArray(updates.updates, updates.users, updates.chats); + if (updates.date != 0) { MessagesStorage.lastDateValue = updates.date; - if (updates.seq != 0) { - MessagesStorage.lastSeqValue = updates.seq; - } - if (MessagesStorage.lastQtsValue != lastQtsValue) { - needReceivedQueue = true; - } + } + if (updates.seq != 0) { + MessagesStorage.lastSeqValue = updates.seq; } } else { - FileLog.e("tmessages", "need get diff TL_updates, seq: " + MessagesStorage.lastSeqValue + " " + updates.seq); - if (gettingDifference || updatesStartWaitTime == 0 || updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 > System.currentTimeMillis()) { - if (updatesStartWaitTime == 0) { - updatesStartWaitTime = System.currentTimeMillis(); + if (updates instanceof TLRPC.TL_updatesCombined) { + FileLog.e("tmessages", "need get diff TL_updatesCombined, seq: " + MessagesStorage.lastSeqValue + " " + updates.seq_start); + } else { + FileLog.e("tmessages", "need get diff TL_updates, seq: " + MessagesStorage.lastSeqValue + " " + updates.seq); + } + + if (gettingDifference || updatesStartWaitTimeSeq == 0 || updatesStartWaitTimeSeq != 0 && updatesStartWaitTimeSeq + 1500 > System.currentTimeMillis()) { + if (updatesStartWaitTimeSeq == 0) { + updatesStartWaitTimeSeq = System.currentTimeMillis(); } - FileLog.e("tmessages", "add TL_updates to queue"); - updatesQueue.add(updates); - addedToQueue = true; + FileLog.e("tmessages", "add TL_updates/Combined to queue"); + updatesQueueSeq.add(updates); } else { needGetDiff = true; } @@ -2816,14 +2938,30 @@ public class MessagesController implements NotificationCenter.NotificationCenter } else if (updates instanceof TLRPC.TL_updatesTooLong) { FileLog.e("tmessages", "need get diff TL_updatesTooLong"); needGetDiff = true; - } else if (updates instanceof UserActionUpdates) { + } else if (updates instanceof UserActionUpdatesSeq) { MessagesStorage.lastSeqValue = updates.seq; + } else if (updates instanceof UserActionUpdatesPts) { + MessagesStorage.lastPtsValue = updates.pts; } SecretChatHelper.getInstance().processPendingEncMessages(); - if (needGetDiff && !fromQueue) { - getDifference(); - } else if (!fromQueue && !updatesQueue.isEmpty()) { - processUpdatesQueue(0); + if (!fromQueue) { + if (needGetDiff) { + getDifference(); + } else { + for (int a = 0; a < 3; a++) { + ArrayList updatesQueue = null; + if (a == 0) { + updatesQueue = updatesQueueSeq; + } else if (a == 1) { + updatesQueue = updatesQueuePts; + } else if (a == 2) { + updatesQueue = updatesQueueQts; + } + if (!updatesQueue.isEmpty()) { + processUpdatesQueue(a, 0); + } + } + } } if (needReceivedQueue) { TLRPC.TL_messages_receivedQueue req = new TLRPC.TL_messages_receivedQueue(); @@ -2846,29 +2984,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter MessagesStorage.getInstance().saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); } - private boolean isNotifySettingsMuted(TLRPC.PeerNotifySettings settings) { - return settings instanceof TLRPC.TL_peerNotifySettings && settings.mute_until > ConnectionsManager.getInstance().getCurrentTime(); - } - - public boolean isDialogMuted(long dialog_id) { - TLRPC.TL_dialog dialog = dialogs_dict.get(dialog_id); - if (dialog != null) { - return isNotifySettingsMuted(dialog.notify_settings); - } else { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - int mute_type = preferences.getInt("notify2_" + dialog_id, 0); - if (mute_type == 2) { - return true; - } else if (mute_type == 3) { - int mute_until = preferences.getInt("notifyuntil_" + dialog_id, 0); - if (mute_until >= ConnectionsManager.getInstance().getCurrentTime()) { - return true; - } - } - } - return false; - } - public boolean processUpdateArray(ArrayList updates, final ArrayList usersArr, final ArrayList chatsArr) { if (updates.isEmpty()) { return true; @@ -2876,9 +2991,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter long currentTime = System.currentTimeMillis(); final HashMap> messages = new HashMap<>(); + final HashMap webPages = new HashMap<>(); final ArrayList pushMessages = new ArrayList<>(); final ArrayList messagesArr = new ArrayList<>(); - final ArrayList markAsReadMessages = new ArrayList<>(); + final HashMap markAsReadMessagesInbox = new HashMap<>(); + final HashMap markAsReadMessagesOutbox = new HashMap<>(); final HashMap markAsReadEncrypted = new HashMap<>(); final ArrayList deletedMessages = new ArrayList<>(); boolean printChanged = false; @@ -2958,18 +3075,27 @@ public class MessagesController implements NotificationCenter.NotificationCenter messages.put(uid, arr); } arr.add(obj); - MessagesStorage.lastPtsValue = update.pts; - if (!obj.isFromMe() && obj.isUnread()) { + if (!obj.isOut() && obj.isUnread()) { pushMessages.add(obj); } } else if (update instanceof TLRPC.TL_updateReadMessages) { - markAsReadMessages.addAll(update.messages); - MessagesStorage.lastPtsValue = update.pts; + //markAsReadMessages.addAll(update.messages); disabled for now + } else if (update instanceof TLRPC.TL_updateReadHistoryInbox) { + TLRPC.Peer peer = ((TLRPC.TL_updateReadHistoryInbox) update).peer; + if (peer.chat_id != 0) { + markAsReadMessagesInbox.put(-peer.chat_id, update.max_id); + } else { + markAsReadMessagesInbox.put(peer.user_id, update.max_id); + } + } else if (update instanceof TLRPC.TL_updateReadHistoryOutbox) { + TLRPC.Peer peer = ((TLRPC.TL_updateReadHistoryOutbox) update).peer; + if (peer.chat_id != 0) { + markAsReadMessagesOutbox.put(-peer.chat_id, update.max_id); + } else { + markAsReadMessagesOutbox.put(peer.user_id, update.max_id); + } } else if (update instanceof TLRPC.TL_updateDeleteMessages) { deletedMessages.addAll(update.messages); - MessagesStorage.lastPtsValue = update.pts; - } else if (update instanceof TLRPC.TL_updateRestoreMessages) { - MessagesStorage.lastPtsValue = update.pts; } else if (update instanceof TLRPC.TL_updateUserTyping || update instanceof TLRPC.TL_updateChatUserTyping) { if (update.action instanceof TLRPC.TL_sendMessageTypingAction && update.user_id != UserConfig.getClientUserId()) { long uid = -update.chat_id; @@ -3038,7 +3164,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter pushMessages.add(obj); } } else if (update instanceof TLRPC.TL_updateContactLink) { - if (update.my_link instanceof TLRPC.TL_contacts_myLinkContact || update.my_link instanceof TLRPC.TL_contacts_myLinkRequested && update.my_link.contact) { + if (update.my_link instanceof TLRPC.TL_contactLinkContact) { int idx = contactsIds.indexOf(-update.user_id); if (idx != -1) { contactsIds.remove(idx); @@ -3058,6 +3184,12 @@ public class MessagesController implements NotificationCenter.NotificationCenter } else if (update instanceof TLRPC.TL_updateActivation) { //DEPRECATED } else if (update instanceof TLRPC.TL_updateNewAuthorization) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.newSessionReceived); + } + }); TLRPC.TL_messageService newMessage = new TLRPC.TL_messageService(); newMessage.action = new TLRPC.TL_messageActionLoginUnknownLocation(); newMessage.action.title = update.device; @@ -3083,8 +3215,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } else if (update instanceof TLRPC.TL_updateNewGeoChatMessage) { //DEPRECATED } else if (update instanceof TLRPC.TL_updateNewEncryptedMessage) { - MessagesStorage.lastQtsValue = update.qts; - ArrayList decryptedMessages = SecretChatHelper.getInstance().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; @@ -3130,7 +3261,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } else if (update instanceof TLRPC.TL_updateEncryptedMessagesRead) { markAsReadEncrypted.put(update.chat_id, Math.max(update.max_date, update.date)); - tasks.add((TLRPC.TL_updateEncryptedMessagesRead)update); + tasks.add((TLRPC.TL_updateEncryptedMessagesRead) update); } else if (update instanceof TLRPC.TL_updateChatParticipantAdd) { MessagesStorage.getInstance().updateChatInfo(update.chat_id, update.user_id, false, update.inviter_id, update.version); } else if (update instanceof TLRPC.TL_updateChatParticipantDelete) { @@ -3192,6 +3323,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter pushMessages.add(obj); } else if (update instanceof TLRPC.TL_updatePrivacy) { updatesOnMainThread.add(update); + } else if (update instanceof TLRPC.TL_updateWebPage) { + webPages.put(update.webpage.id, update.webpage); } } if (!messages.isEmpty()) { @@ -3270,6 +3403,12 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } else if (update instanceof TLRPC.TL_updateUserName) { if (currentUser != null) { + if (currentUser.username != null && currentUser.username.length() > 0) { + usersByUsernames.remove(currentUser.username); + } + if (update.username != null && update.username.length() > 0) { + usersByUsernames.put(update.username, currentUser); + } currentUser.first_name = update.first_name; currentUser.last_name = update.last_name; currentUser.username = update.username; @@ -3360,6 +3499,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter MessagesStorage.getInstance().updateUsers(dbUsers, false, true, true); } + if (!webPages.isEmpty()) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.didReceivedWebpagesInUpdates, webPages); + } + if (!messages.isEmpty()) { for (HashMap.Entry> entry : messages.entrySet()) { Long key = entry.getKey(); @@ -3394,15 +3537,27 @@ public class MessagesController implements NotificationCenter.NotificationCenter @Override public void run() { int updateMask = 0; - if (!markAsReadMessages.isEmpty()) { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesRead, markAsReadMessages); - NotificationsController.getInstance().processReadMessages(markAsReadMessages, 0, 0, 0, false); - - for (Integer id : markAsReadMessages) { - MessageObject obj = dialogMessage.get(id); - if (obj != null) { - obj.setIsRead(); - updateMask |= UPDATE_MASK_READ_DIALOG_MESSAGE; + if (!markAsReadMessagesInbox.isEmpty() || !markAsReadMessagesOutbox.isEmpty()) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesRead, markAsReadMessagesInbox, markAsReadMessagesOutbox); + NotificationsController.getInstance().processReadMessages(markAsReadMessagesInbox, 0, 0, 0, false); + for (HashMap.Entry entry : markAsReadMessagesInbox.entrySet()) { + TLRPC.TL_dialog dialog = dialogs_dict.get((long) entry.getKey()); + if (dialog != null && dialog.top_message <= entry.getValue()) { + MessageObject obj = dialogMessage.get(dialog.top_message); + if (obj != null) { + obj.setIsRead(); + updateMask |= UPDATE_MASK_READ_DIALOG_MESSAGE; + } + } + } + for (HashMap.Entry entry : markAsReadMessagesOutbox.entrySet()) { + TLRPC.TL_dialog dialog = dialogs_dict.get((long) entry.getKey()); + if (dialog != null && dialog.top_message <= entry.getValue()) { + MessageObject obj = dialogMessage.get(dialog.top_message); + if (obj != null) { + obj.setIsRead(); + updateMask |= UPDATE_MASK_READ_DIALOG_MESSAGE; + } } } } @@ -3437,11 +3592,14 @@ public class MessagesController implements NotificationCenter.NotificationCenter } }); - if (!markAsReadMessages.isEmpty() || !markAsReadEncrypted.isEmpty()) { - if (!markAsReadMessages.isEmpty()) { - MessagesStorage.getInstance().updateDialogsWithReadedMessages(markAsReadMessages, true); + if (!webPages.isEmpty()) { + MessagesStorage.getInstance().putWebPages(webPages); + } + if (!markAsReadMessagesInbox.isEmpty() || !markAsReadMessagesOutbox.isEmpty() || !markAsReadEncrypted.isEmpty()) { + if (!markAsReadMessagesInbox.isEmpty() || !markAsReadMessagesOutbox.isEmpty()) { + MessagesStorage.getInstance().updateDialogsWithReadedMessages(markAsReadMessagesInbox, true); } - MessagesStorage.getInstance().markMessagesAsRead(markAsReadMessages, markAsReadEncrypted, true); + MessagesStorage.getInstance().markMessagesAsRead(markAsReadMessagesInbox, markAsReadMessagesOutbox, markAsReadEncrypted, true); } if (!deletedMessages.isEmpty()) { MessagesStorage.getInstance().markMessagesAsDeleted(deletedMessages, true); @@ -3458,6 +3616,24 @@ public class MessagesController implements NotificationCenter.NotificationCenter return true; } + private boolean isNotifySettingsMuted(TLRPC.PeerNotifySettings settings) { + return settings instanceof TLRPC.TL_peerNotifySettings && settings.mute_until > ConnectionsManager.getInstance().getCurrentTime(); + } + + public boolean isDialogMuted(long dialog_id) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + int mute_type = preferences.getInt("notify2_" + dialog_id, 0); + if (mute_type == 2) { + return true; + } else if (mute_type == 3) { + int mute_until = preferences.getInt("notifyuntil_" + dialog_id, 0); + if (mute_until >= ConnectionsManager.getInstance().getCurrentTime()) { + return true; + } + } + return false; + } + private boolean updatePrintingUsersWithNewMessages(long uid, ArrayList messages) { if (uid > 0) { ArrayList arr = printingUsers.get(uid); @@ -3508,7 +3684,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter NotificationCenter.getInstance().postNotificationName(NotificationCenter.didReceivedNewMessages, uid, messages); for (MessageObject message : messages) { - if (lastMessage == null || (!isEncryptedChat && message.messageOwner.id > lastMessage.messageOwner.id || isEncryptedChat && message.messageOwner.id < lastMessage.messageOwner.id) || message.messageOwner.date > lastMessage.messageOwner.date) { + if (lastMessage == null || (!isEncryptedChat && message.getId() > lastMessage.getId() || isEncryptedChat && message.getId() < lastMessage.getId()) || message.messageOwner.date > lastMessage.messageOwner.date) { lastMessage = message; } } @@ -3520,17 +3696,17 @@ public class MessagesController implements NotificationCenter.NotificationCenter dialog = new TLRPC.TL_dialog(); dialog.id = uid; dialog.unread_count = 0; - dialog.top_message = lastMessage.messageOwner.id; + dialog.top_message = lastMessage.getId(); dialog.last_message_date = lastMessage.messageOwner.date; dialogs_dict.put(uid, dialog); dialogs.add(dialog); - dialogMessage.put(lastMessage.messageOwner.id, lastMessage); + dialogMessage.put(lastMessage.getId(), lastMessage); changed = true; } } else { boolean change = false; - if (dialog.top_message > 0 && lastMessage.messageOwner.id > 0 && lastMessage.messageOwner.id > dialog.top_message || - dialog.top_message < 0 && lastMessage.messageOwner.id < 0 && lastMessage.messageOwner.id < dialog.top_message) { + if (dialog.top_message > 0 && lastMessage.getId() > 0 && lastMessage.getId() > dialog.top_message || + dialog.top_message < 0 && lastMessage.getId() < 0 && lastMessage.getId() < dialog.top_message) { change = true; } else { MessageObject currentDialogMessage = dialogMessage.get(dialog.top_message); @@ -3546,12 +3722,12 @@ public class MessagesController implements NotificationCenter.NotificationCenter } if (change) { dialogMessage.remove(dialog.top_message); - dialog.top_message = lastMessage.messageOwner.id; + dialog.top_message = lastMessage.getId(); if (!isBroadcast) { dialog.last_message_date = lastMessage.messageOwner.date; changed = true; } - dialogMessage.put(lastMessage.messageOwner.id, lastMessage); + dialogMessage.put(lastMessage.getId(), lastMessage); } } @@ -3577,4 +3753,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } } + + } diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java b/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java index 87f0e1982..d2b7981df 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java @@ -103,7 +103,7 @@ public class MessagesStorage { database.executeFast("PRAGMA temp_store = 1").stepThis().dispose(); if (createTable) { 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 messages(mid INTEGER PRIMARY KEY, uid INTEGER, read_state INTEGER, send_state INTEGER, date INTEGER, data BLOB, out INTEGER, ttl INTEGER, media INTEGER, replydata BLOB)").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, 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(); @@ -122,6 +122,8 @@ public class MessagesStorage { database.executeFast("CREATE TABLE messages_seq(mid INTEGER PRIMARY KEY, seq_in INTEGER, seq_out INTEGER);").stepThis().dispose(); database.executeFast("CREATE TABLE web_recent_v3(id TEXT, type INTEGER, image_url TEXT, thumb_url TEXT, local_url TEXT, width INTEGER, height INTEGER, size INTEGER, date INTEGER, PRIMARY KEY (id, type));").stepThis().dispose(); database.executeFast("CREATE TABLE stickers(id INTEGER PRIMARY KEY, data BLOB, date INTEGER);").stepThis().dispose(); + database.executeFast("CREATE TABLE hashtag_recent_v2(id TEXT PRIMARY KEY, date INTEGER);").stepThis().dispose(); + database.executeFast("CREATE TABLE webpage_pending(id INTEGER, mid INTEGER, PRIMARY KEY (id, mid));").stepThis().dispose(); database.executeFast("CREATE TABLE user_contacts_v6(uid INTEGER PRIMARY KEY, fname TEXT, sname TEXT)").stepThis().dispose(); database.executeFast("CREATE TABLE user_phones_v6(uid INTEGER, phone TEXT, sphone TEXT, deleted INTEGER, PRIMARY KEY (uid, phone))").stepThis().dispose(); @@ -162,7 +164,7 @@ public class MessagesStorage { database.executeFast("CREATE TABLE keyvalue(id TEXT PRIMARY KEY, value TEXT)").stepThis().dispose(); //version - database.executeFast("PRAGMA user_version = 13").stepThis().dispose(); + database.executeFast("PRAGMA user_version = 16").stepThis().dispose(); } else { try { SQLiteCursor cursor = database.queryFinalized("SELECT seq, pts, date, qts, lsv, sg, pbytes FROM params WHERE id = 1"); @@ -193,7 +195,7 @@ public class MessagesStorage { } } int version = database.executeInt("PRAGMA user_version"); - if (version < 13) { + if (version < 16) { updateDbToLastVersion(version); } } @@ -368,6 +370,21 @@ public class MessagesStorage { database.executeFast("PRAGMA user_version = 13").stepThis().dispose(); version = 13; } + if (version == 13 && version < 14) { + database.executeFast("ALTER TABLE messages ADD COLUMN replydata BLOB default NULL").stepThis().dispose(); + database.executeFast("PRAGMA user_version = 14").stepThis().dispose(); + version = 14; + } + if (version == 14 && version < 15) { + database.executeFast("CREATE TABLE IF NOT EXISTS hashtag_recent_v2(id TEXT PRIMARY KEY, date INTEGER);").stepThis().dispose(); + database.executeFast("PRAGMA user_version = 15").stepThis().dispose(); + version = 15; + } + if (version == 15 && version < 16) { + database.executeFast("CREATE TABLE IF NOT EXISTS webpage_pending(id INTEGER, mid INTEGER, PRIMARY KEY (id, mid));").stepThis().dispose(); + database.executeFast("PRAGMA user_version = 16").stepThis().dispose(); + version = 16; + } } catch (Exception e) { FileLog.e("tmessages", e); } @@ -622,7 +639,7 @@ public class MessagesStorage { @Override public void run() { try { - SQLiteCursor cursor = database.queryFinalized("SELECT id, image_url, thumb_url, local_url, width, height, size, date FROM web_recent_v3 wallpapers WHERE type = " + type); + SQLiteCursor cursor = database.queryFinalized("SELECT id, image_url, thumb_url, local_url, width, height, size, date FROM web_recent_v3 WHERE type = " + type); final ArrayList arrayList = new ArrayList<>(); while (cursor.next()) { MediaController.SearchImage searchImage = new MediaController.SearchImage(); @@ -679,6 +696,19 @@ public class MessagesStorage { }); } + public void clearWebRecent(final int type) { + storageQueue.postRunnable(new Runnable() { + @Override + public void run() { + try { + database.executeFast("DELETE FROM web_recent_v3 WHERE type = " + type).stepThis().dispose(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + } + public void putWebRecent(final ArrayList arrayList) { storageQueue.postRunnable(new Runnable() { @Override @@ -753,7 +783,7 @@ public class MessagesStorage { try { ArrayList ids = new ArrayList<>(); ArrayList users = new ArrayList<>(); - SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT * FROM blocked_users WHERE 1")); + SQLiteCursor cursor = database.queryFinalized("SELECT * FROM blocked_users WHERE 1"); StringBuilder usersToLoad = new StringBuilder(); while (cursor.next()) { int user_id = cursor.intValue(0); @@ -838,6 +868,59 @@ public class MessagesStorage { //database.executeFast("DELETE FROM secret_holes WHERE uid = " + high_id).stepThis().dispose(); } } + + if ((int) did == 0) { + SQLiteCursor cursor = database.queryFinalized("SELECT data FROM messages WHERE uid = " + did); + ArrayList filesToDelete = new ArrayList<>(); + try { + while (cursor.next()) { + ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0)); + if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { + TLRPC.Message message = (TLRPC.Message) TLClassStore.Instance().TLdeserialize(data, data.readInt32()); + if (message == null || message.media == null) { + continue; + } + if (message.media instanceof TLRPC.TL_messageMediaAudio) { + File file = FileLoader.getPathToAttach(message.media.audio); + if (file != null && file.toString().length() > 0) { + filesToDelete.add(file); + } + } else if (message.media instanceof TLRPC.TL_messageMediaPhoto) { + for (TLRPC.PhotoSize photoSize : message.media.photo.sizes) { + File file = FileLoader.getPathToAttach(photoSize); + if (file != null && file.toString().length() > 0) { + filesToDelete.add(file); + } + } + } else if (message.media instanceof TLRPC.TL_messageMediaVideo) { + File file = FileLoader.getPathToAttach(message.media.video); + if (file != null && file.toString().length() > 0) { + filesToDelete.add(file); + } + file = FileLoader.getPathToAttach(message.media.video.thumb); + if (file != null && file.toString().length() > 0) { + filesToDelete.add(file); + } + } else if (message.media instanceof TLRPC.TL_messageMediaDocument) { + File file = FileLoader.getPathToAttach(message.media.document); + if (file != null && file.toString().length() > 0) { + filesToDelete.add(file); + } + file = FileLoader.getPathToAttach(message.media.document.thumb); + if (file != null && file.toString().length() > 0) { + filesToDelete.add(file); + } + } + } + buffersStorage.reuseFreeBuffer(data); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + cursor.dispose(); + FileLoader.getInstance().deleteFiles(filesToDelete); + } + database.executeFast("UPDATE dialogs SET unread_count = 0 WHERE did = " + did).stepThis().dispose(); database.executeFast("DELETE FROM messages WHERE uid = " + did).stepThis().dispose(); database.executeFast("DELETE FROM media_counts_v2 WHERE uid = " + did).stepThis().dispose(); @@ -1032,20 +1115,16 @@ public class MessagesStorage { }); } - private void updateDialogsWithReadedMessagesInternal(final ArrayList messages) { - if (Thread.currentThread().getId() != storageQueue.getId()) { - throw new RuntimeException("wrong db thread"); - } + private void updateDialogsWithReadedMessagesInternal(final ArrayList messages, final HashMap inbox) { try { HashMap dialogsToUpdate = new HashMap<>(); + StringBuilder dialogsToReload = new StringBuilder(); + if (messages != null && !messages.isEmpty()) { - StringBuilder dialogsToReload = new StringBuilder(); String ids = TextUtils.join(",", messages); - int totalCount = 0; SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT uid, read_state, out FROM messages WHERE mid IN(%s)", ids)); while (cursor.next()) { int out = cursor.intValue(2); - totalCount++; if (out != 0) { continue; } @@ -1066,8 +1145,26 @@ public class MessagesStorage { } } cursor.dispose(); + } else if (inbox != null && !inbox.isEmpty()) { + for (HashMap.Entry entry : inbox.entrySet()) { + SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(mid) FROM messages WHERE uid = %d AND mid <= %d AND read_state = 0 AND out = 0", entry.getKey(), entry.getValue())); + if (cursor.next()) { + int count = cursor.intValue(0); + if (count == 0) { + continue; + } + dialogsToUpdate.put((long) entry.getKey(), count); + if (dialogsToReload.length() != 0) { + dialogsToReload.append(","); + } + dialogsToReload.append(entry.getKey()); + } + cursor.dispose(); + } + } - cursor = database.queryFinalized(String.format(Locale.US, "SELECT did, unread_count FROM dialogs WHERE did IN(%s)", dialogsToReload.toString())); + if (dialogsToReload.length() > 0) { + SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT did, unread_count FROM dialogs WHERE did IN(%s)", dialogsToReload.toString())); while (cursor.next()) { long did = cursor.longValue(0); int count = cursor.intValue(1); @@ -1100,19 +1197,19 @@ public class MessagesStorage { } } - public void updateDialogsWithReadedMessages(final ArrayList messages, boolean useQueue) { - if (messages.isEmpty()) { + public void updateDialogsWithReadedMessages(final HashMap inbox, boolean useQueue) { + if (inbox.isEmpty()) { return; } if (useQueue) { storageQueue.postRunnable(new Runnable() { @Override public void run() { - updateDialogsWithReadedMessagesInternal(messages); + updateDialogsWithReadedMessagesInternal(null, inbox); } }); } else { - updateDialogsWithReadedMessagesInternal(messages); + updateDialogsWithReadedMessagesInternal(null, inbox); } } @@ -1657,6 +1754,8 @@ public class MessagesStorage { try { ArrayList loadedUsers = new ArrayList<>(); ArrayList fromUser = new ArrayList<>(); + ArrayList replyMessages = new ArrayList<>(); + HashMap> replyMessageOwners = new HashMap<>(); SQLiteCursor cursor = null; int lower_id = (int)dialog_id; @@ -1678,18 +1777,18 @@ public class MessagesStorage { cursor.dispose(); if (containMessage) { - cursor = database.queryFinalized(String.format(Locale.US, "SELECT * FROM (SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid <= %d ORDER BY m.date DESC, m.mid DESC LIMIT %d) UNION " + - "SELECT * FROM (SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid > %d ORDER BY m.date ASC, m.mid ASC LIMIT %d)", dialog_id, max_id, count_query / 2, dialog_id, max_id, count_query / 2 - 1)); + cursor = database.queryFinalized(String.format(Locale.US, "SELECT * FROM (SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid <= %d ORDER BY m.date DESC, m.mid DESC LIMIT %d) UNION " + + "SELECT * FROM (SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid > %d ORDER BY m.date ASC, m.mid ASC LIMIT %d)", dialog_id, max_id, count_query / 2, dialog_id, max_id, count_query / 2 - 1)); } else { cursor = null; } } else if (load_type == 1) { - cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date >= %d AND m.mid > %d ORDER BY m.date ASC, m.mid ASC LIMIT %d", dialog_id, minDate, max_id, count_query)); + cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date >= %d AND m.mid > %d ORDER BY m.date ASC, m.mid ASC LIMIT %d", dialog_id, minDate, max_id, count_query)); } else if (minDate != 0) { if (max_id != 0) { - cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date <= %d AND m.mid < %d ORDER BY m.date DESC, m.mid DESC LIMIT %d", dialog_id, minDate, max_id, count_query)); + cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date <= %d AND m.mid < %d ORDER BY m.date DESC, m.mid DESC LIMIT %d", dialog_id, minDate, max_id, count_query)); } else { - cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date <= %d ORDER BY m.date DESC, m.mid DESC LIMIT %d,%d", dialog_id, minDate, offset_query, count_query)); + cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date <= %d ORDER BY m.date DESC, m.mid DESC LIMIT %d,%d", dialog_id, minDate, offset_query, count_query)); } } else { if (load_type == 2) { @@ -1725,16 +1824,16 @@ public class MessagesStorage { offset_query = count_unread - count_query; count_query += 10; } - cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d ORDER BY m.date DESC, m.mid DESC LIMIT %d,%d", dialog_id, offset_query, count_query)); + cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d ORDER BY m.date DESC, m.mid DESC LIMIT %d,%d", dialog_id, offset_query, count_query)); } } else { if (load_type == 1) { - cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid < %d ORDER BY m.mid DESC LIMIT %d", dialog_id, max_id, count_query)); + cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid < %d ORDER BY m.mid DESC LIMIT %d", dialog_id, max_id, count_query)); } else if (minDate != 0) { if (max_id != 0) { - cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid > %d ORDER BY m.mid ASC LIMIT %d", dialog_id, max_id, count_query)); + cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid > %d ORDER BY m.mid ASC LIMIT %d", dialog_id, max_id, count_query)); } else { - cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date <= %d ORDER BY m.mid ASC LIMIT %d,%d", dialog_id, minDate, offset_query, count_query)); + cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date <= %d ORDER BY m.mid ASC LIMIT %d,%d", dialog_id, minDate, offset_query, count_query)); } } else { if (load_type == 2) { @@ -1770,7 +1869,7 @@ public class MessagesStorage { offset_query = count_unread - count_query; count_query += 10; } - cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d ORDER BY m.mid ASC LIMIT %d,%d", dialog_id, offset_query, count_query)); + cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d ORDER BY m.mid ASC LIMIT %d,%d", dialog_id, offset_query, count_query)); } } if (cursor != null) { @@ -1796,6 +1895,43 @@ public class MessagesStorage { if (message.fwd_from_id != 0) { fromUser.add(message.fwd_from_id); } + if (message.reply_to_msg_id != 0) { + boolean ok = false; + if (!cursor.isNull(6)) { + ByteBufferDesc data2 = buffersStorage.getFreeBuffer(cursor.byteArrayLength(6)); + if (data2 != null && cursor.byteBufferValue(6, data2.buffer) != 0) { + message.replyMessage = (TLRPC.Message) TLClassStore.Instance().TLdeserialize(data2, data2.readInt32()); + if (message.replyMessage != null) { + fromUser.add(message.replyMessage.from_id); + if (message.replyMessage.action != null && message.replyMessage.action.user_id != 0) { + fromUser.add(message.replyMessage.action.user_id); + } + if (message.replyMessage.media != null && message.replyMessage.media.user_id != 0) { + fromUser.add(message.replyMessage.media.user_id); + } + if (message.replyMessage.media != null && message.replyMessage.media.audio != null && message.replyMessage.media.audio.user_id != 0) { + fromUser.add(message.replyMessage.media.audio.user_id); + } + if (message.replyMessage.fwd_from_id != 0) { + fromUser.add(message.replyMessage.fwd_from_id); + } + ok = true; + } + } + buffersStorage.reuseFreeBuffer(data2); + } + if (!ok) { + if (!replyMessages.contains(message.reply_to_msg_id)) { + replyMessages.add(message.reply_to_msg_id); + } + ArrayList messages = replyMessageOwners.get(message.reply_to_msg_id); + if (messages == null) { + messages = new ArrayList<>(); + replyMessageOwners.put(message.reply_to_msg_id, messages); + } + messages.add(message); + } + } message.send_state = cursor.intValue(2); if (!MessageObject.isUnread(message) && lower_id != 0 || message.id > 0) { message.send_state = 0; @@ -1846,33 +1982,39 @@ public class MessagesStorage { } }); - /*ArrayList> holes = getHoles(dialog_id); - if (holes != null && !res.messages.isEmpty()) { - int start = res.messages.get(res.messages.size() - 1).id; - int end = res.messages.get(0).id; - for (Range range : holes) { - if (range.contains(start) && range.contains(end)) { - res.messages.clear(); - } else if (range.contains(start)) { - while (!res.messages.isEmpty() && range.contains(res.messages.get(res.messages.size() - 1).id)) { - res.messages.remove(res.messages.size() - 1); + if (!replyMessages.isEmpty()) { + cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid, date FROM messages WHERE mid IN(%s)", TextUtils.join(",", replyMessages))); + while (cursor.next()) { + ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0)); + if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { + TLRPC.Message message = (TLRPC.Message) TLClassStore.Instance().TLdeserialize(data, data.readInt32()); + message.id = cursor.intValue(1); + message.date = cursor.intValue(2); + message.dialog_id = dialog_id; + fromUser.add(message.from_id); + if (message.action != null && message.action.user_id != 0) { + fromUser.add(message.action.user_id); } - if (!res.messages.isEmpty()) { - start = res.messages.get(res.messages.size() - 1).id; + if (message.media != null && message.media.user_id != 0) { + fromUser.add(message.media.user_id); } - } else if (range.contains(end)) { - while (!res.messages.isEmpty() && range.contains(res.messages.get(0).id)) { - res.messages.remove(0); + if (message.media != null && message.media.audio != null && message.media.audio.user_id != 0) { + fromUser.add(message.media.audio.user_id); } - if (!res.messages.isEmpty()) { - end = res.messages.get(0).id; + if (message.fwd_from_id != 0) { + fromUser.add(message.fwd_from_id); + } + ArrayList arrayList = replyMessageOwners.get(message.id); + if (arrayList != null) { + for (TLRPC.Message m : arrayList) { + m.replyMessage = message; + } } - } else if (start >= ) - if (res.messages.isEmpty()) { - break; } + buffersStorage.reuseFreeBuffer(data); } - }*/ + cursor.dispose(); + } StringBuilder usersToLoad = new StringBuilder(); for (int uid : fromUser) { @@ -2524,6 +2666,79 @@ public class MessagesStorage { return -1; } + public void putWebPages(final HashMap webPages) { + if (webPages == null || webPages.isEmpty()) { + return; + } + storageQueue.postRunnable(new Runnable() { + @Override + public void run() { + try { + String ids = TextUtils.join(",", webPages.keySet()); + SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid FROM webpage_pending WHERE id IN (%s)", ids)); + ArrayList mids = new ArrayList<>(); + while (cursor.next()) { + mids.add(cursor.intValue(0)); + } + cursor.dispose(); + + if (mids.isEmpty()) { + return; + } + final ArrayList messages = new ArrayList<>(); + cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid, data FROM messages WHERE mid IN (%s)", TextUtils.join(",", mids))); + while (cursor.next()) { + int mid = cursor.intValue(0); + ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(1)); + if (data != null && cursor.byteBufferValue(1, data.buffer) != 0) { + TLRPC.Message message = (TLRPC.Message)TLClassStore.Instance().TLdeserialize(data, data.readInt32()); + if (message.media instanceof TLRPC.TL_messageMediaWebPage) { + message.id = mid; + message.media.webpage = webPages.get(message.media.webpage.id); + messages.add(message); + } + } + buffersStorage.reuseFreeBuffer(data); + } + cursor.dispose(); + + database.executeFast(String.format(Locale.US, "DELETE FROM webpage_pending WHERE id IN (%s)", ids)).stepThis().dispose(); + + if (messages.isEmpty()) { + return; + } + + database.beginTransaction(); + + SQLitePreparedStatement state = database.executeFast("UPDATE messages SET data = ? WHERE mid = ?"); + for (TLRPC.Message message : messages) { + ByteBufferDesc data = buffersStorage.getFreeBuffer(message.getObjectSize()); + message.serializeToStream(data); + + state.requery(); + state.bindByteBuffer(1, data.buffer); + state.bindInteger(2, message.id); + state.step(); + + buffersStorage.reuseFreeBuffer(data); + } + state.dispose(); + + database.commitTransaction(); + + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.didReceivedWebpages, messages); + } + }); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + } + private void putMessagesInternal(final ArrayList messages, final boolean withTransaction, final boolean isBroadcast, final int downloadMask) { try { if (withTransaction) { @@ -2537,10 +2752,11 @@ public class MessagesStorage { HashMap messagesMediaIdsMap = new HashMap<>(); StringBuilder messageIds = new StringBuilder(); StringBuilder messageMediaIds = new StringBuilder(); - SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)"); + SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)"); SQLitePreparedStatement state2 = database.executeFast("REPLACE INTO media_v2 VALUES(?, ?, ?, ?, ?)"); SQLitePreparedStatement state3 = database.executeFast("REPLACE INTO randoms VALUES(?, ?)"); SQLitePreparedStatement state4 = database.executeFast("REPLACE INTO download_queue VALUES(?, ?, ?, ?)"); + SQLitePreparedStatement state5 = database.executeFast("REPLACE INTO webpage_pending VALUES(?, ?)"); for (TLRPC.Message message : messages) { long dialog_id = message.dialog_id; @@ -2674,15 +2890,23 @@ public class MessagesStorage { state2.bindByteBuffer(5, data.buffer); state2.step(); } + + if (message.media instanceof TLRPC.TL_messageMediaWebPage && message.media.webpage instanceof TLRPC.TL_webPagePending) { + state5.requery(); + state5.bindLong(1, message.media.webpage.id); + state5.bindInteger(2, message.id); + state5.step(); + } + buffersStorage.reuseFreeBuffer(data); - if (downloadMask != 0) { + if (message.date >= ConnectionsManager.getInstance().getCurrentTime() - 60 * 60 * 24 && downloadMask != 0) { if (message.media instanceof TLRPC.TL_messageMediaAudio || message.media instanceof TLRPC.TL_messageMediaPhoto || message.media instanceof TLRPC.TL_messageMediaVideo || message.media instanceof TLRPC.TL_messageMediaDocument) { int type = 0; long id = 0; TLObject object = null; if (message.media instanceof TLRPC.TL_messageMediaAudio) { - if ((downloadMask & MediaController.AUTODOWNLOAD_MASK_AUDIO) != 0) { + if ((downloadMask & MediaController.AUTODOWNLOAD_MASK_AUDIO) != 0 && message.media.audio.size < 1024 * 1024 * 5) { id = message.media.audio.id; type = MediaController.AUTODOWNLOAD_MASK_AUDIO; object = message.media.audio; @@ -2728,6 +2952,7 @@ public class MessagesStorage { state2.dispose(); state3.dispose(); state4.dispose(); + state5.dispose(); state = database.executeFast("REPLACE INTO dialogs(did, date, unread_count, last_mid) VALUES(?, ?, ?, ?)"); for (HashMap.Entry pair : messagesMap.entrySet()) { @@ -3111,14 +3336,20 @@ public class MessagesStorage { } } - private void markMessagesAsReadInternal(final ArrayList messages, HashMap encryptedMessages) { + private void markMessagesAsReadInternal(HashMap inbox, HashMap outbox, HashMap encryptedMessages) { if (Thread.currentThread().getId() != storageQueue.getId()) { throw new RuntimeException("wrong db thread"); } try { - if (messages != null && !messages.isEmpty()) { - String ids = TextUtils.join(",", messages); - database.executeFast(String.format(Locale.US, "UPDATE messages SET read_state = 1 WHERE mid IN(%s)", ids)).stepThis().dispose(); + if (inbox != null) { + for (HashMap.Entry entry : inbox.entrySet()) { + database.executeFast(String.format(Locale.US, "UPDATE messages SET read_state = 1 WHERE uid = %d AND mid <= %d AND read_state = 0 AND out = 0", entry.getKey(), entry.getValue())).stepThis().dispose(); + } + } + if (outbox != null) { + for (HashMap.Entry entry : outbox.entrySet()) { + database.executeFast(String.format(Locale.US, "UPDATE messages SET read_state = 1 WHERE uid = %d AND mid <= %d AND read_state = 0 AND out = 1", entry.getKey(), entry.getValue())).stepThis().dispose(); + } } if (encryptedMessages != null && !encryptedMessages.isEmpty()) { for (HashMap.Entry entry : encryptedMessages.entrySet()) { @@ -3137,16 +3368,16 @@ public class MessagesStorage { } } - public void markMessagesAsRead(final ArrayList messages, final HashMap encryptedMessages, boolean useQueue) { + public void markMessagesAsRead(final HashMap inbox, final HashMap outbox, final HashMap encryptedMessages, boolean useQueue) { if (useQueue) { storageQueue.postRunnable(new Runnable() { @Override public void run() { - markMessagesAsReadInternal(messages, encryptedMessages); + markMessagesAsReadInternal(inbox, outbox, encryptedMessages); } }); } else { - markMessagesAsReadInternal(messages, encryptedMessages); + markMessagesAsReadInternal(inbox, outbox, encryptedMessages); } } @@ -3178,6 +3409,7 @@ public class MessagesStorage { NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesDeleted, mids); } }); + MessagesStorage.getInstance().updateDialogsWithReadedMessagesInternal(mids, null); MessagesStorage.getInstance().markMessagesAsDeletedInternal(mids); MessagesStorage.getInstance().updateDialogsWithDeletedMessagesInternal(mids); } @@ -3189,9 +3421,6 @@ public class MessagesStorage { } private void markMessagesAsDeletedInternal(final ArrayList messages) { - if (Thread.currentThread().getId() != storageQueue.getId()) { - throw new RuntimeException("wrong db thread"); - } try { String ids = TextUtils.join(",", messages); SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT uid, data FROM messages WHERE mid IN(%s)", ids)); @@ -3287,7 +3516,7 @@ public class MessagesStorage { ArrayList usersToLoad = new ArrayList<>(); ArrayList chatsToLoad = new ArrayList<>(); ArrayList encryptedToLoad = new ArrayList<>(); - cursor = database.queryFinalized(String.format(Locale.US, "SELECT d.did, d.last_mid, d.unread_count, d.date, m.data, m.read_state, m.mid, m.send_state FROM dialogs as d LEFT JOIN messages as m ON d.last_mid = m.mid WHERE d.did IN(%s)", ids)); + cursor = database.queryFinalized(String.format(Locale.US, "SELECT d.did, d.last_mid, d.unread_count, d.date, m.data, m.read_state, m.mid, m.send_state, m.date FROM dialogs as d LEFT JOIN messages as m ON d.last_mid = m.mid WHERE d.did IN(%s)", ids)); while (cursor.next()) { TLRPC.TL_dialog dialog = new TLRPC.TL_dialog(); dialog.id = cursor.longValue(0); @@ -3302,6 +3531,10 @@ public class MessagesStorage { MessageObject.setIsUnread(message, cursor.intValue(5) != 1); message.id = cursor.intValue(6); message.send_state = cursor.intValue(7); + int date = cursor.intValue(8); + if (date != 0) { + dialog.last_message_date = date; + } dialogs.messages.add(message); if (!usersToLoad.contains(message.from_id)) { @@ -3399,11 +3632,19 @@ public class MessagesStorage { } private void fixUnsupportedMedia(TLRPC.Message message) { - if (message != null && message.media instanceof TLRPC.TL_messageMediaUnsupported && message.media.bytes != null) { + if (message == null) { + return; + } + boolean ok = false; + if (message.media instanceof TLRPC.TL_messageMediaUnsupported_old) { if (message.media.bytes.length == 0) { message.media.bytes = new byte[1]; message.media.bytes[0] = TLRPC.LAYER; } + } else if (message.media instanceof TLRPC.TL_messageMediaUnsupported) { + message.media = new TLRPC.TL_messageMediaUnsupported_old(); + message.media.bytes = new byte[1]; + message.media.bytes[0] = TLRPC.LAYER; } } @@ -3417,7 +3658,7 @@ public class MessagesStorage { try { database.beginTransaction(); if (!messages.messages.isEmpty()) { - SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)"); + SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)"); SQLitePreparedStatement state2 = database.executeFast("REPLACE INTO media_v2 VALUES(?, ?, ?, ?, ?)"); for (TLRPC.Message message : messages.messages) { fixUnsupportedMedia(message); @@ -3471,7 +3712,7 @@ public class MessagesStorage { usersToLoad.add(UserConfig.getClientUserId()); ArrayList chatsToLoad = new ArrayList<>(); ArrayList encryptedToLoad = new ArrayList<>(); - SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT d.did, d.last_mid, d.unread_count, d.date, m.data, m.read_state, m.mid, m.send_state, s.flags FROM dialogs as d LEFT JOIN messages as m ON d.last_mid = m.mid LEFT JOIN dialog_settings as s ON d.did = s.did ORDER BY d.date DESC LIMIT %d,%d", offset, count)); + SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT d.did, d.last_mid, d.unread_count, d.date, m.data, m.read_state, m.mid, m.send_state, s.flags, m.date FROM dialogs as d LEFT JOIN messages as m ON d.last_mid = m.mid LEFT JOIN dialog_settings as s ON d.did = s.did ORDER BY d.date DESC LIMIT %d,%d", offset, count)); while (cursor.next()) { TLRPC.TL_dialog dialog = new TLRPC.TL_dialog(); dialog.id = cursor.longValue(0); @@ -3495,6 +3736,10 @@ public class MessagesStorage { if (message != null) { MessageObject.setIsUnread(message, cursor.intValue(5) != 1); message.id = cursor.intValue(6); + int date = cursor.intValue(9); + if (date != 0) { + dialog.last_message_date = date; + } message.send_state = cursor.intValue(7); dialogs.messages.add(message); @@ -3585,7 +3830,7 @@ public class MessagesStorage { } if (!dialogs.dialogs.isEmpty()) { - SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)"); + SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)"); SQLitePreparedStatement state2 = database.executeFast("REPLACE INTO dialogs(did, date, unread_count, last_mid) VALUES(?, ?, ?, ?)"); SQLitePreparedStatement state3 = database.executeFast("REPLACE INTO media_v2 VALUES(?, ?, ?, ?, ?)"); SQLitePreparedStatement state4 = database.executeFast("REPLACE INTO dialog_settings VALUES(?, ?)"); @@ -3654,6 +3899,42 @@ public class MessagesStorage { }); } + public TLRPC.User getUserSync(final int user_id) { + final Semaphore semaphore = new Semaphore(0); + final TLRPC.User[] user = new TLRPC.User[1]; + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { + @Override + public void run() { + user[0] = getUser(user_id); + semaphore.release(); + } + }); + try { + semaphore.acquire(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + return user[0]; + } + + public TLRPC.Chat getChatSync(final int user_id) { + final Semaphore semaphore = new Semaphore(0); + final TLRPC.Chat[] chat = new TLRPC.Chat[1]; + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { + @Override + public void run() { + chat[0] = getChat(user_id); + semaphore.release(); + } + }); + try { + semaphore.acquire(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + return chat[0]; + } + public TLRPC.User getUser(final int user_id) { TLRPC.User user = null; try { diff --git a/TMessagesProj/src/main/java/org/telegram/android/NativeLoader.java b/TMessagesProj/src/main/java/org/telegram/android/NativeLoader.java index eecbbb175..6eab0a11b 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 = 5; + private final static int LIB_VERSION = 7; 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/NotificationCenter.java b/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java index 6e045c321..962de6977 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java +++ b/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java @@ -48,6 +48,14 @@ public class NotificationCenter { public static final int updateMessageMedia = totalEvents++; public static final int recentImagesDidLoaded = totalEvents++; public static final int replaceMessagesObjects = totalEvents++; + public static final int didSetPasscode = totalEvents++; + public static final int didSetTwoStepPassword = totalEvents++; + public static final int screenStateChanged = totalEvents++; + public static final int appSwitchedToForeground = totalEvents++; + public static final int didLoadedReplyMessages = totalEvents++; + public static final int newSessionReceived = totalEvents++; + public static final int didReceivedWebpages = totalEvents++; + public static final int didReceivedWebpagesInUpdates = totalEvents++; public static final int httpFileDidLoaded = totalEvents++; public static final int httpFileDidFailedLoad = totalEvents++; @@ -60,7 +68,6 @@ public class NotificationCenter { public static final int didReceiveSmsCode = totalEvents++; public static final int emojiDidLoaded = totalEvents++; public static final int appDidLogout = totalEvents++; - public static final int needPasswordEnter = totalEvents++; public static final int FileDidUpload = totalEvents++; public static final int FileDidFailUpload = totalEvents++; @@ -106,7 +113,7 @@ public class NotificationCenter { } public interface NotificationCenterDelegate { - public abstract void didReceivedNotification(int id, Object... args); + void didReceivedNotification(int id, Object... args); } public void postNotificationName(int id, Object... args) { diff --git a/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java b/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java index c0cc5d4f9..1f31a687b 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java @@ -11,13 +11,16 @@ package org.telegram.android; import android.app.Activity; import android.app.AlarmManager; import android.app.PendingIntent; +import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.content.res.AssetFileDescriptor; import android.graphics.drawable.BitmapDrawable; import android.media.AudioManager; +import android.media.MediaPlayer; import android.net.Uri; import android.os.Build; import android.os.SystemClock; @@ -29,6 +32,7 @@ import android.support.v4.app.RemoteInput; import org.json.JSONArray; import org.json.JSONObject; import org.telegram.messenger.ConnectionsManager; +import org.telegram.messenger.DispatchQueue; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.RPCRequest; @@ -48,11 +52,13 @@ public class NotificationsController { public static final String EXTRA_VOICE_REPLY = "extra_voice_reply"; + private DispatchQueue notificationsQueue = new DispatchQueue("notificationsQueue"); private ArrayList pushMessages = new ArrayList<>(); private HashMap pushMessagesDict = new HashMap<>(); private NotificationManagerCompat notificationManager = null; private HashMap pushDialogs = new HashMap<>(); private HashMap wearNoticationsIds = new HashMap<>(); + private HashMap pushDialogsOverrideMention = new HashMap<>(); private int wearNotificationId = 10000; public ArrayList popupMessages = new ArrayList<>(); private long openned_dialog_id = 0; @@ -60,6 +66,12 @@ public class NotificationsController { private int personal_count = 0; private boolean notifyCheck = false; private int lastOnlineFromOtherDevice = 0; + private boolean inChatSoundEnabled = true; + + private long lastSoundPlay; + private MediaPlayer mediaPlayerIn; + private MediaPlayer mediaPlayerOut; + protected AudioManager audioManager; private static volatile NotificationsController Instance = null; public static NotificationsController getInstance() { @@ -77,6 +89,15 @@ public class NotificationsController { public NotificationsController() { notificationManager = NotificationManagerCompat.from(ApplicationLoader.applicationContext); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE); + inChatSoundEnabled = preferences.getBoolean("EnableInChatSound", true); + + try { + audioManager = (AudioManager) ApplicationLoader.applicationContext.getSystemService(Context.AUDIO_SERVICE); + //mediaPlayer = new MediaPlayer(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } } public void cleanup() { @@ -95,6 +116,10 @@ public class NotificationsController { editor.commit(); } + public void setInChatSoundEnabled(boolean value) { + inChatSoundEnabled = value; + } + public void setOpennedDialogId(long dialog_id) { openned_dialog_id = dialog_id; } @@ -130,7 +155,9 @@ public class NotificationsController { } String msg = null; - if ((int)dialog_id != 0) { + if ((int)dialog_id == 0 || AndroidUtilities.needShowPasscode(false) || UserConfig.isWaitingForPasscodeEnter) { + msg = LocaleController.getString("YouHaveNewMessage", R.string.YouHaveNewMessage); + } else { if (chat_id == 0 && user_id != 0) { SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE); if (preferences.getBoolean("EnablePreviewAll", true)) { @@ -144,7 +171,7 @@ public class NotificationsController { msg = LocaleController.formatString("NotificationUnrecognizedDevice", R.string.NotificationUnrecognizedDevice, UserConfig.getCurrentUser().first_name, date, messageObject.messageOwner.action.title, messageObject.messageOwner.action.address); } } else { - if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty) { + if (messageObject.isMediaEmpty()) { if (!shortMessage) { if (messageObject.messageOwner.message != null && messageObject.messageOwner.message.length() != 0) { msg = LocaleController.formatString("NotificationMessageText", R.string.NotificationMessageText, ContactsController.formatName(user.first_name, user.last_name), messageObject.messageOwner.message); @@ -209,7 +236,7 @@ public class NotificationsController { msg = messageObject.messageText.toString(); } } else { - if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty) { + if (messageObject.isMediaEmpty()) { if (!shortMessage && messageObject.messageOwner.message != null && messageObject.messageOwner.message.length() != 0) { msg = LocaleController.formatString("NotificationMessageGroupText", R.string.NotificationMessageGroupText, ContactsController.formatName(user.first_name, user.last_name), chat.title, messageObject.messageOwner.message); } else { @@ -237,8 +264,6 @@ public class NotificationsController { msg = LocaleController.formatString("NotificationMessageGroupNoText", R.string.NotificationMessageGroupNoText, ContactsController.formatName(user.first_name, user.last_name), chat.title); } } - } else { - msg = LocaleController.getString("YouHaveNewMessage", R.string.YouHaveNewMessage); } return msg; } @@ -250,7 +275,7 @@ public class NotificationsController { SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); int minutes = preferences.getInt("repeat_messages", 60); if (minutes > 0 && personal_count > 0) { - alarm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + minutes * 60 * 1000, pintent); + alarm.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + minutes * 60 * 1000, pintent); } else { alarm.cancel(pintent); } @@ -266,9 +291,9 @@ public class NotificationsController { PendingIntent pintent = PendingIntent.getService(ApplicationLoader.applicationContext, 0, new Intent(ApplicationLoader.applicationContext, NotificationDelay.class), 0); SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); if (onlineReason) { - alarm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 3 * 1000, pintent); + alarm.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 3 * 1000, pintent); } else { - alarm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 500, pintent); + alarm.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 500, pintent); } } catch (Exception e) { FileLog.e("tmessages", e); @@ -310,7 +335,11 @@ public class NotificationsController { MessageObject lastMessageObject = pushMessages.get(0); long dialog_id = lastMessageObject.getDialogId(); - int mid = lastMessageObject.messageOwner.id; + long override_dialog_id = dialog_id; + if ((lastMessageObject.messageOwner.flags & TLRPC.MESSAGE_FLAG_MENTION) != 0) { + override_dialog_id = lastMessageObject.messageOwner.from_id; + } + int mid = lastMessageObject.getId(); int chat_id = lastMessageObject.messageOwner.to_id.chat_id; int user_id = lastMessageObject.messageOwner.to_id.user_id; if (user_id == 0) { @@ -339,9 +368,9 @@ public class NotificationsController { int vibrate_override = 0; SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE); - int notify_override = preferences.getInt("notify2_" + dialog_id, 0); + int notify_override = preferences.getInt("notify2_" + override_dialog_id, 0); if (notify_override == 3) { - int mute_until = preferences.getInt("notifyuntil_" + dialog_id, 0); + int mute_until = preferences.getInt("notifyuntil_" + override_dialog_id, 0); if (mute_until >= ConnectionsManager.getInstance().getCurrentTime()) { notify_override = 2; } @@ -358,6 +387,7 @@ public class NotificationsController { inAppPriority = preferences.getBoolean("EnableInAppPriority", false); vibrate_override = preferences.getInt("vibrate_" + dialog_id, 0); priority_override = preferences.getInt("priority_" + dialog_id, 3); + boolean vibrateOnlyIfSilent = false; choosenSoundPath = preferences.getString("sound_path_" + dialog_id, null); if (chat_id != 0) { @@ -387,6 +417,10 @@ public class NotificationsController { priority = priority_override; } + if (needVibrate == 4) { + vibrateOnlyIfSilent = true; + needVibrate = 0; + } if (needVibrate == 2 && (vibrate_override == 1 || vibrate_override == 3 || vibrate_override == 5) || needVibrate != 2 && vibrate_override == 2 || vibrate_override != 0) { needVibrate = vibrate_override; } @@ -403,6 +437,16 @@ public class NotificationsController { priority = 1; } } + if (vibrateOnlyIfSilent && needVibrate != 2) { + try { + int mode = audioManager.getRingerMode(); + if (mode != AudioManager.RINGER_MODE_SILENT && mode != AudioManager.RINGER_MODE_VIBRATE) { + needVibrate = 2; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } } Intent intent = new Intent(ApplicationLoader.applicationContext, LaunchActivity.class); @@ -416,14 +460,18 @@ public class NotificationsController { intent.putExtra("userId", user_id); } } - if (pushDialogs.size() == 1) { - if (chat != null) { - if (chat.photo != null && chat.photo.photo_small != null && chat.photo.photo_small.volume_id != 0 && chat.photo.photo_small.local_id != 0) { - photoPath = chat.photo.photo_small; - } - } else { - if (user.photo != null && user.photo.photo_small != null && user.photo.photo_small.volume_id != 0 && user.photo.photo_small.local_id != 0) { - photoPath = user.photo.photo_small; + if (AndroidUtilities.needShowPasscode(false) || UserConfig.isWaitingForPasscodeEnter) { + photoPath = null; + } else { + if (pushDialogs.size() == 1) { + if (chat != null) { + if (chat.photo != null && chat.photo.photo_small != null && chat.photo.photo_small.volume_id != 0 && chat.photo.photo_small.local_id != 0) { + photoPath = chat.photo.photo_small; + } + } else { + if (user.photo != null && user.photo.photo_small != null && user.photo.photo_small.volume_id != 0 && user.photo.photo_small.local_id != 0) { + photoPath = user.photo.photo_small; + } } } } @@ -436,7 +484,7 @@ public class NotificationsController { String name = null; boolean replace = true; - if ((int)dialog_id == 0 || pushDialogs.size() > 1) { + if ((int)dialog_id == 0 || pushDialogs.size() > 1 || AndroidUtilities.needShowPasscode(false) || UserConfig.isWaitingForPasscodeEnter) { name = LocaleController.getString("AppName", R.string.AppName); replace = false; } else { @@ -451,7 +499,7 @@ public class NotificationsController { if (pushDialogs.size() == 1) { detailText = LocaleController.formatPluralString("NewMessages", total_unread_count); } else { - detailText = LocaleController.formatString("NotificationMessagesPeopleDisplayOrder", R.string.NotificationMessagesPeopleDisplayOrder, LocaleController.formatPluralString("NewMessages", total_unread_count), LocaleController.formatPluralString("FromContacts", pushDialogs.size())); + detailText = LocaleController.formatString("NotificationMessagesPeopleDisplayOrder", R.string.NotificationMessagesPeopleDisplayOrder, LocaleController.formatPluralString("NewMessages", total_unread_count), LocaleController.formatPluralString("FromChats", pushDialogs.size())); } NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(ApplicationLoader.applicationContext) @@ -608,7 +656,7 @@ public class NotificationsController { for (long dialog_id : sortedDialogs) { ArrayList messageObjects = messagesByDialogs.get(dialog_id); - int max_id = messageObjects.get(0).messageOwner.id; + int max_id = messageObjects.get(0).getId(); TLRPC.Chat chat = null; TLRPC.User user = null; String name = null; @@ -730,19 +778,21 @@ public class NotificationsController { } } - public void processReadMessages(ArrayList readMessages, long dialog_id, int max_date, int max_id, boolean isPopup) { + public void processReadMessages(HashMap inbox, long dialog_id, int max_date, int max_id, boolean isPopup) { int oldCount = popupMessages.size(); - int oldCount2 = pushMessages.size(); - if (readMessages != null) { - for (Integer id : readMessages) { - MessageObject messageObject = pushMessagesDict.get(id); - if (messageObject != null) { - if (isPersonalMessage(messageObject)) { - personal_count--; + if (inbox != null) { + for (HashMap.Entry entry : inbox.entrySet()) { + for (int a = 0; a < pushMessages.size(); a++) { + MessageObject messageObject = pushMessages.get(a); + if (messageObject.getDialogId() == entry.getKey() && messageObject.getId() <= entry.getValue()) { + if (isPersonalMessage(messageObject)) { + personal_count--; + } + popupMessages.remove(messageObject); + pushMessagesDict.remove(messageObject.getId()); + pushMessages.remove(a); + a--; } - pushMessages.remove(messageObject); - popupMessages.remove(messageObject); - pushMessagesDict.remove(id); } } } @@ -757,11 +807,11 @@ public class NotificationsController { } } else { if (!isPopup) { - if (messageObject.messageOwner.id <= max_id || max_id < 0) { + if (messageObject.getId() <= max_id || max_id < 0) { remove = true; } } else { - if (messageObject.messageOwner.id == max_id || max_id < 0) { + if (messageObject.getId() == max_id || max_id < 0) { remove = true; } } @@ -772,7 +822,7 @@ public class NotificationsController { } pushMessages.remove(a); popupMessages.remove(messageObject); - pushMessagesDict.remove(messageObject.messageOwner.id); + pushMessagesDict.remove(messageObject.getId()); a--; } } @@ -783,6 +833,126 @@ public class NotificationsController { } } + private void playInChatSound() { + if (!inChatSoundEnabled) { + return; + } + try { + if (audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT) { + return; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + + try { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE); + int notify_override = preferences.getInt("notify2_" + openned_dialog_id, 0); + if (notify_override == 3) { + int mute_until = preferences.getInt("notifyuntil_" + openned_dialog_id, 0); + if (mute_until >= ConnectionsManager.getInstance().getCurrentTime()) { + notify_override = 2; + } + } + if (notify_override == 2) { + return; + } + notificationsQueue.postRunnable(new Runnable() { + @Override + public void run() { + if (lastSoundPlay > System.currentTimeMillis() - 500) { + return; + } + try { + if (mediaPlayerIn == null) { + AssetFileDescriptor assetFileDescriptor = ApplicationLoader.applicationContext.getResources().openRawResourceFd(R.raw.sound_in); + if (assetFileDescriptor != null) { + mediaPlayerIn = new MediaPlayer(); + mediaPlayerIn.setAudioStreamType(AudioManager.STREAM_SYSTEM); + mediaPlayerIn.setDataSource(assetFileDescriptor.getFileDescriptor(), assetFileDescriptor.getStartOffset(), assetFileDescriptor.getLength()); + mediaPlayerIn.setLooping(false); + assetFileDescriptor.close(); + mediaPlayerIn.prepare(); + } + } + mediaPlayerIn.start(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + /*String choosenSoundPath = null; + String defaultPath = Settings.System.DEFAULT_NOTIFICATION_URI.getPath(); + + choosenSoundPath = preferences.getString("sound_path_" + openned_dialog_id, null); + boolean isChat = (int)(openned_dialog_id) < 0; + if (isChat) { + if (choosenSoundPath != null && choosenSoundPath.equals(defaultPath)) { + choosenSoundPath = null; + } else if (choosenSoundPath == null) { + choosenSoundPath = preferences.getString("GroupSoundPath", defaultPath); + } + } else { + if (choosenSoundPath != null && choosenSoundPath.equals(defaultPath)) { + choosenSoundPath = null; + } else if (choosenSoundPath == null) { + choosenSoundPath = preferences.getString("GlobalSoundPath", defaultPath); + } + } + + if (choosenSoundPath != null && !choosenSoundPath.equals("NoSound")) { + if (lastMediaPlayerUri == null || !choosenSoundPath.equals(lastMediaPlayerUri)) { + lastMediaPlayerUri = choosenSoundPath; + mediaPlayer.reset(); + mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION); + if (choosenSoundPath.equals(defaultPath)) { + mediaPlayer.setDataSource(ApplicationLoader.applicationContext, Settings.System.DEFAULT_NOTIFICATION_URI); + } else { + mediaPlayer.setDataSource(ApplicationLoader.applicationContext, Uri.parse(choosenSoundPath)); + } + mediaPlayer.prepare(); + } + mediaPlayer.start(); + }*/ + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + + public void playOutChatSound() { + if (!inChatSoundEnabled) { + return; + } + try { + if (audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT) { + return; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + notificationsQueue.postRunnable(new Runnable() { + @Override + public void run() { + try { + if (mediaPlayerOut == null) { + AssetFileDescriptor assetFileDescriptor = ApplicationLoader.applicationContext.getResources().openRawResourceFd(R.raw.sound_out); + if (assetFileDescriptor != null) { + mediaPlayerOut = new MediaPlayer(); + mediaPlayerOut.setAudioStreamType(AudioManager.STREAM_SYSTEM); + mediaPlayerOut.setDataSource(assetFileDescriptor.getFileDescriptor(), assetFileDescriptor.getStartOffset(), assetFileDescriptor.getLength()); + mediaPlayerOut.setLooping(false); + assetFileDescriptor.close(); + mediaPlayerOut.prepare(); + } + } + mediaPlayerOut.start(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + } + public void processNewMessages(ArrayList messageObjects, boolean isLast) { if (messageObjects.isEmpty()) { return; @@ -795,13 +965,18 @@ public class NotificationsController { int popup = 0; for (MessageObject messageObject : messageObjects) { - if (pushMessagesDict.containsKey(messageObject.messageOwner.id)) { + if (pushMessagesDict.containsKey(messageObject.getId())) { continue; } long dialog_id = messageObject.getDialogId(); + long original_dialog_id = dialog_id; if (dialog_id == openned_dialog_id && ApplicationLoader.isScreenOn) { + playInChatSound(); continue; } + if ((messageObject.messageOwner.flags & TLRPC.MESSAGE_FLAG_MENTION) != 0) { + dialog_id = messageObject.messageOwner.from_id; + } if (isPersonalMessage(messageObject)) { personal_count++; } @@ -826,7 +1001,10 @@ public class NotificationsController { popupMessages.add(0, messageObject); } pushMessages.add(0, messageObject); - pushMessagesDict.put(messageObject.messageOwner.id, messageObject); + pushMessagesDict.put(messageObject.getId(), messageObject); + if (original_dialog_id != dialog_id) { + pushDialogsOverrideMention.put(original_dialog_id, 1); + } } } @@ -834,7 +1012,7 @@ public class NotificationsController { notifyCheck = isLast; } - if (!popupMessages.isEmpty() && oldCount != popupMessages.size()) { + if (!popupMessages.isEmpty() && oldCount != popupMessages.size() && !AndroidUtilities.needShowPasscode(false) && !UserConfig.isWaitingForPasscodeEnter) { if (ApplicationLoader.mainInterfacePaused || !ApplicationLoader.isScreenOn) { MessageObject messageObject = messageObjects.get(0); if (popup == 3 || popup == 1 && ApplicationLoader.isScreenOn || popup == 2 && !ApplicationLoader.isScreenOn) { @@ -859,6 +1037,13 @@ public class NotificationsController { notify_override = 2; } } + if (notifyCheck) { + Integer override = pushDialogsOverrideMention.get(dialog_id); + if (override != null && override == 1) { + pushDialogsOverrideMention.put(dialog_id, 0); + notify_override = 1; + } + } boolean canAddValue = !(notify_override == 2 || (!preferences.getBoolean("EnableAll", true) || ((int)dialog_id < 0) && !preferences.getBoolean("EnableGroup", true)) && notify_override == 0); Integer currentCount = pushDialogs.get(dialog_id); @@ -876,6 +1061,7 @@ public class NotificationsController { } if (newCount == 0) { pushDialogs.remove(dialog_id); + pushDialogsOverrideMention.remove(dialog_id); for (int a = 0; a < pushMessages.size(); a++) { MessageObject messageObject = pushMessages.get(a); if (messageObject.getDialogId() == dialog_id) { @@ -884,7 +1070,7 @@ public class NotificationsController { } pushMessages.remove(a); a--; - pushMessagesDict.remove(messageObject.messageOwner.id); + pushMessagesDict.remove(messageObject.getId()); popupMessages.remove(messageObject); } } @@ -923,27 +1109,6 @@ public class NotificationsController { SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE); HashMap settingsCache = new HashMap<>(); - for (HashMap.Entry entry : dialogs.entrySet()) { - long dialog_id = entry.getKey(); - Boolean value = settingsCache.get(dialog_id); - if (value == null) { - int notify_override = preferences.getInt("notify2_" + dialog_id, 0); - if (notify_override == 3) { - int mute_until = preferences.getInt("notifyuntil_" + dialog_id, 0); - if (mute_until >= ConnectionsManager.getInstance().getCurrentTime()) { - notify_override = 2; - } - } - value = !(notify_override == 2 || (!preferences.getBoolean("EnableAll", true) || ((int) dialog_id < 0) && !preferences.getBoolean("EnableGroup", true)) && notify_override == 0); - settingsCache.put(dialog_id, value); - } - if (!value) { - continue; - } - int count = entry.getValue(); - pushDialogs.put(dialog_id, count); - total_unread_count += count; - } if (messages != null) { for (TLRPC.Message message : messages) { if (pushMessagesDict.containsKey(message.id)) { @@ -954,6 +1119,10 @@ public class NotificationsController { personal_count++; } long dialog_id = messageObject.getDialogId(); + long original_dialog_id = dialog_id; + if ((messageObject.messageOwner.flags & TLRPC.MESSAGE_FLAG_MENTION) != 0) { + dialog_id = messageObject.messageOwner.from_id; + } Boolean value = settingsCache.get(dialog_id); if (value == null) { int notify_override = preferences.getInt("notify2_" + dialog_id, 0); @@ -969,10 +1138,39 @@ public class NotificationsController { if (!value || dialog_id == openned_dialog_id && ApplicationLoader.isScreenOn) { continue; } - pushMessagesDict.put(messageObject.messageOwner.id, messageObject); + pushMessagesDict.put(messageObject.getId(), messageObject); pushMessages.add(0, messageObject); + if (original_dialog_id != dialog_id) { + pushDialogsOverrideMention.put(original_dialog_id, 1); + } } } + for (HashMap.Entry entry : dialogs.entrySet()) { + long dialog_id = entry.getKey(); + Boolean value = settingsCache.get(dialog_id); + if (value == null) { + int notify_override = preferences.getInt("notify2_" + dialog_id, 0); + if (notify_override == 3) { + int mute_until = preferences.getInt("notifyuntil_" + dialog_id, 0); + if (mute_until >= ConnectionsManager.getInstance().getCurrentTime()) { + notify_override = 2; + } + } + Integer override = pushDialogsOverrideMention.get(dialog_id); + if (override != null && override == 1) { + pushDialogsOverrideMention.put(dialog_id, 0); + notify_override = 1; + } + value = !(notify_override == 2 || (!preferences.getBoolean("EnableAll", true) || ((int) dialog_id < 0) && !preferences.getBoolean("EnableGroup", true)) && notify_override == 0); + settingsCache.put(dialog_id, value); + } + if (!value) { + continue; + } + int count = entry.getValue(); + pushDialogs.put(dialog_id, count); + total_unread_count += count; + } if (total_unread_count == 0) { popupMessages.clear(); NotificationCenter.getInstance().postNotificationName(NotificationCenter.pushMessagesUpdated); @@ -988,20 +1186,33 @@ public class NotificationsController { setBadge(ApplicationLoader.applicationContext, enabled ? total_unread_count : 0); } - private void setBadge(Context context, int count) { - try { - String launcherClassName = getLauncherClassName(context); - if (launcherClassName == null) { - return; + private void setBadge(final Context context, final int count) { + notificationsQueue.postRunnable(new Runnable() { + @Override + public void run() { + try { + ContentValues cv = new ContentValues(); + cv.put("tag", "org.telegram.messenger/org.telegram.ui.LaunchActivity"); + cv.put("count", count); + context.getContentResolver().insert(Uri.parse("content://com.teslacoilsw.notifier/unread_count"), cv); + } catch (Throwable e) { + //ignore + } + try { + String launcherClassName = getLauncherClassName(context); + if (launcherClassName == null) { + return; + } + Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE"); + intent.putExtra("badge_count", count); + intent.putExtra("badge_count_package_name", context.getPackageName()); + intent.putExtra("badge_count_class_name", launcherClassName); + context.sendBroadcast(intent); + } catch (Throwable e) { + FileLog.e("tmessages", e); + } } - Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE"); - intent.putExtra("badge_count", count); - intent.putExtra("badge_count_package_name", context.getPackageName()); - intent.putExtra("badge_count_class_name", launcherClassName); - context.sendBroadcast(intent); - } catch (Throwable e) { - FileLog.e("tmessages", e); - } + }); } public static String getLauncherClassName(Context context) { diff --git a/TMessagesProj/src/main/java/org/telegram/android/ScreenReceiver.java b/TMessagesProj/src/main/java/org/telegram/android/ScreenReceiver.java index e6b6c7572..d7824f18b 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/ScreenReceiver.java +++ b/TMessagesProj/src/main/java/org/telegram/android/ScreenReceiver.java @@ -28,5 +28,6 @@ public class ScreenReceiver extends BroadcastReceiver { ConnectionsManager.getInstance().setAppPaused(false, true); ApplicationLoader.isScreenOn = true; } + NotificationCenter.getInstance().postNotificationName(NotificationCenter.screenStateChanged); } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/SecretChatHelper.java b/TMessagesProj/src/main/java/org/telegram/android/SecretChatHelper.java index 6a1140245..6a34ea267 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/SecretChatHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/android/SecretChatHelper.java @@ -119,7 +119,7 @@ public class SecretChatHelper { 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))]; + reqSend.random_bytes = new byte[15]; Utilities.random.nextBytes(reqSend.random_bytes); } @@ -224,7 +224,7 @@ public class SecretChatHelper { 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))]; + reqSend.random_bytes = new byte[15]; Utilities.random.nextBytes(reqSend.random_bytes); } @@ -252,7 +252,7 @@ public class SecretChatHelper { 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))]; + reqSend.random_bytes = new byte[15]; Utilities.random.nextBytes(reqSend.random_bytes); } @@ -283,7 +283,7 @@ public class SecretChatHelper { 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))]; + reqSend.random_bytes = new byte[15]; Utilities.random.nextBytes(reqSend.random_bytes); } @@ -312,7 +312,7 @@ public class SecretChatHelper { 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))]; + reqSend.random_bytes = new byte[15]; Utilities.random.nextBytes(reqSend.random_bytes); } @@ -343,7 +343,7 @@ public class SecretChatHelper { 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))]; + reqSend.random_bytes = new byte[15]; Utilities.random.nextBytes(reqSend.random_bytes); } @@ -375,7 +375,7 @@ public class SecretChatHelper { 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))]; + reqSend.random_bytes = new byte[15]; Utilities.random.nextBytes(reqSend.random_bytes); } @@ -406,7 +406,7 @@ public class SecretChatHelper { 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))]; + reqSend.random_bytes = new byte[15]; Utilities.random.nextBytes(reqSend.random_bytes); } @@ -436,7 +436,7 @@ public class SecretChatHelper { 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))]; + reqSend.random_bytes = new byte[15]; Utilities.random.nextBytes(reqSend.random_bytes); } @@ -464,7 +464,7 @@ public class SecretChatHelper { 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))]; + reqSend.random_bytes = new byte[15]; Utilities.random.nextBytes(reqSend.random_bytes); } @@ -500,7 +500,7 @@ public class SecretChatHelper { 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))]; + reqSend.random_bytes = new byte[15]; Utilities.random.nextBytes(reqSend.random_bytes); } @@ -659,7 +659,7 @@ public class SecretChatHelper { int myLayer = Math.max(17, AndroidUtilities.getMyLayerVersion(chat.layer)); layer.layer = Math.min(myLayer, AndroidUtilities.getPeerLayerVersion(chat.layer)); layer.message = req; - layer.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; + layer.random_bytes = new byte[15]; Utilities.random.nextBytes(layer.random_bytes); toEncryptObject = layer; @@ -795,7 +795,7 @@ public class SecretChatHelper { @Override public void run() { newMsgObj.send_state = MessageObject.MESSAGE_SEND_STATE_SENT; - NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, newMsgObj.id, newMsgObj.id, newMsgObj); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, newMsgObj.id, newMsgObj.id, newMsgObj, false); SendMessagesHelper.getInstance().processSentMessage(newMsgObj.id); if (newMsgObj.media instanceof TLRPC.TL_messageMediaVideo) { SendMessagesHelper.getInstance().stopVideoService(attachPath); @@ -1072,8 +1072,8 @@ public class SecretChatHelper { } }); MessagesStorage.getInstance().deleteDialog(did, true); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.removeAllMessagesFromDialog, did); NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.removeAllMessagesFromDialog, did); } }); return null; @@ -1104,10 +1104,7 @@ public class SecretChatHelper { } byte[] salt = new byte[256]; - for (int a = 0; a < 256; a++) { - salt[a] = (byte) (Utilities.random.nextDouble() * 256); - } - + Utilities.random.nextBytes(salt); BigInteger p = new BigInteger(1, MessagesStorage.secretPBytes); BigInteger g_b = BigInteger.valueOf(MessagesStorage.secretG); g_b = g_b.modPow(new BigInteger(1, salt), p); @@ -1409,9 +1406,7 @@ public class SecretChatHelper { return; } final byte[] salt = new byte[256]; - for (int a = 0; a < 256; a++) { - salt[a] = (byte) (Utilities.random.nextDouble() * 256); - } + Utilities.random.nextBytes(salt); BigInteger i_g_a = BigInteger.valueOf(MessagesStorage.secretG); i_g_a = i_g_a.modPow(new BigInteger(1, salt), new BigInteger(1, MessagesStorage.secretPBytes)); @@ -1616,7 +1611,7 @@ public class SecretChatHelper { } public void startSecretChat(final Context context, final TLRPC.User user) { - if (user == null) { + if (user == null || context == null) { return; } startingSecretChat = true; @@ -1777,6 +1772,10 @@ public class SecretChatHelper { } } }); - progressDialog.show(); + try { + progressDialog.show(); + } catch (Exception e) { + //don't promt + } } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java b/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java index b7dc050d7..35e6bedea 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java @@ -174,12 +174,12 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter for (int a = 0; a < arr.size(); a++) { DelayedMessage obj = arr.get(a); if (enc && obj.sendEncryptedRequest != null || !enc && obj.sendRequest != null) { - MessagesStorage.getInstance().markMessageAsSendError(obj.obj.messageOwner.id); + MessagesStorage.getInstance().markMessageAsSendError(obj.obj.getId()); obj.obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR; arr.remove(a); a--; - NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, obj.obj.messageOwner.id); - processSentMessage(obj.obj.messageOwner.id); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, obj.obj.getId()); + processSentMessage(obj.obj.getId()); } } if (arr.isEmpty()) { @@ -244,12 +244,12 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter for (int a = 0; a < arr.size(); a++) { DelayedMessage message = arr.get(a); if (message.obj == messageObject) { - MessagesStorage.getInstance().markMessageAsSendError(message.obj.messageOwner.id); + MessagesStorage.getInstance().markMessageAsSendError(message.obj.getId()); message.obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR; arr.remove(a); a--; - NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, message.obj.messageOwner.id); - processSentMessage(message.obj.messageOwner.id); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, message.obj.getId()); + processSentMessage(message.obj.getId()); } } if (arr.isEmpty()) { @@ -284,10 +284,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateMessageMedia, message.obj); } else { FileLog.e("tmessages", "can't load image " + message.httpLocation + " to file " + cacheFile.toString()); - MessagesStorage.getInstance().markMessageAsSendError(message.obj.messageOwner.id); + MessagesStorage.getInstance().markMessageAsSendError(message.obj.getId()); message.obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR; - NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, message.obj.messageOwner.id); - processSentMessage(message.obj.messageOwner.id); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, message.obj.getId()); + processSentMessage(message.obj.getId()); } } }); @@ -339,10 +339,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter ArrayList arr = delayedMessages.get(path); if (arr != null) { for (DelayedMessage message : arr) { - MessagesStorage.getInstance().markMessageAsSendError(message.obj.messageOwner.id); + MessagesStorage.getInstance().markMessageAsSendError(message.obj.getId()); message.obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR; - NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, message.obj.messageOwner.id); - processSentMessage(message.obj.messageOwner.id); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, message.obj.getId()); + processSentMessage(message.obj.getId()); } delayedMessages.remove(path); } @@ -356,7 +356,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter ArrayList messages = entry.getValue(); for (int a = 0; a < messages.size(); a++) { DelayedMessage message = messages.get(a); - if (message.obj.messageOwner.id == object.messageOwner.id) { + if (message.obj.getId() == object.getId()) { messages.remove(a); MediaController.getInstance().cancelVideoConvert(message.obj); if (messages.size() == 0) { @@ -378,22 +378,22 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter stopVideoService(keyToRemvoe); } ArrayList messages = new ArrayList<>(); - messages.add(object.messageOwner.id); + messages.add(object.getId()); MessagesController.getInstance().deleteMessages(messages, null, null); } public boolean retrySendMessage(MessageObject messageObject, boolean unsent) { - if (messageObject.messageOwner.id >= 0) { + if (messageObject.getId() >= 0) { return false; } if (messageObject.messageOwner.action instanceof TLRPC.TL_messageEncryptedAction) { int enc_id = (int) (messageObject.getDialogId() >> 32); TLRPC.EncryptedChat encryptedChat = MessagesController.getInstance().getEncryptedChat(enc_id); if (encryptedChat == null) { - MessagesStorage.getInstance().markMessageAsSendError(messageObject.messageOwner.id); + MessagesStorage.getInstance().markMessageAsSendError(messageObject.getId()); messageObject.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR; - NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, messageObject.messageOwner.id); - processSentMessage(messageObject.messageOwner.id); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, messageObject.getId()); + processSentMessage(messageObject.getId()); return false; } if (messageObject.messageOwner.random_id == 0) { @@ -429,7 +429,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter return true; } if (unsent) { - unsentMessages.put(messageObject.messageOwner.id, messageObject); + unsentMessages.put(messageObject.getId(), messageObject); } sendMessage(messageObject); return true; @@ -447,73 +447,246 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter if (messageObject == null) { return; } - if (messageObject.messageOwner.media != null && !(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) { + if (messageObject.messageOwner.media != null && !(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty) && !(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage)) { if (messageObject.messageOwner.media.photo instanceof TLRPC.TL_photo) { - sendMessage((TLRPC.TL_photo) messageObject.messageOwner.media.photo, null, null, did); + sendMessage((TLRPC.TL_photo) messageObject.messageOwner.media.photo, null, null, did, messageObject.replyMessageObject); } else if (messageObject.messageOwner.media.audio instanceof TLRPC.TL_audio) { - sendMessage((TLRPC.TL_audio) messageObject.messageOwner.media.audio, messageObject.messageOwner.attachPath, did); + sendMessage((TLRPC.TL_audio) messageObject.messageOwner.media.audio, messageObject.messageOwner.attachPath, did, messageObject.replyMessageObject); } else if (messageObject.messageOwner.media.video instanceof TLRPC.TL_video) { TLRPC.TL_video video = (TLRPC.TL_video) messageObject.messageOwner.media.video; video.videoEditedInfo = messageObject.messageOwner.videoEditedInfo; - sendMessage(video, null, messageObject.messageOwner.attachPath, did); + sendMessage(video, null, messageObject.messageOwner.attachPath, did, messageObject.replyMessageObject); } else if (messageObject.messageOwner.media.document instanceof TLRPC.TL_document) { - sendMessage((TLRPC.TL_document) messageObject.messageOwner.media.document, null, messageObject.messageOwner.attachPath, did); + sendMessage((TLRPC.TL_document) messageObject.messageOwner.media.document, null, messageObject.messageOwner.attachPath, did, messageObject.replyMessageObject); } else if (messageObject.messageOwner.media.geo instanceof TLRPC.TL_geoPoint) { - sendMessage(messageObject.messageOwner.media.geo.lat, messageObject.messageOwner.media.geo._long, did); + sendMessage(messageObject.messageOwner.media.geo.lat, messageObject.messageOwner.media.geo._long, did, messageObject.replyMessageObject); } else if (messageObject.messageOwner.media.phone_number != null) { TLRPC.User user = new TLRPC.TL_userContact(); user.phone = messageObject.messageOwner.media.phone_number; user.first_name = messageObject.messageOwner.media.first_name; user.last_name = messageObject.messageOwner.media.last_name; user.id = messageObject.messageOwner.media.user_id; - sendMessage(user, did); + sendMessage(user, did, messageObject.replyMessageObject); } else { sendMessage(messageObject, did); } } else if (messageObject.messageOwner.message != null) { - sendMessage(messageObject.messageOwner.message, did); + TLRPC.WebPage webPage = null; + if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) { + webPage = messageObject.messageOwner.media.webpage; + } + sendMessage(messageObject.messageOwner.message, did, messageObject.replyMessageObject, webPage, true); } else { sendMessage(messageObject, did); } } - public void sendMessage(TLRPC.User user, long peer) { - sendMessage(null, null, null, null, null, null, user, null, null, null, peer, false, null); + public void sendMessage(TLRPC.User user, long peer, MessageObject reply_to_msg) { + sendMessage(null, null, null, null, null, null, user, null, null, null, peer, false, null, reply_to_msg, null, true); + } + + public void sendMessage(ArrayList messages, long peer) { + if ((int) peer == 0 || messages == null || messages.isEmpty()) { + return; + } + int lower_id = (int) peer; + TLRPC.Peer to_id; + TLRPC.InputPeer sendToPeer; + if (lower_id < 0) { + to_id = new TLRPC.TL_peerChat(); + to_id.chat_id = -lower_id; + sendToPeer = new TLRPC.TL_inputPeerChat(); + sendToPeer.chat_id = -lower_id; + } else { + to_id = new TLRPC.TL_peerUser(); + to_id.user_id = lower_id; + TLRPC.User sendToUser = MessagesController.getInstance().getUser(lower_id); + if (sendToUser == null) { + return; + } + if (sendToUser instanceof TLRPC.TL_userForeign || sendToUser instanceof TLRPC.TL_userRequest) { + sendToPeer = new TLRPC.TL_inputPeerForeign(); + sendToPeer.user_id = sendToUser.id; + sendToPeer.access_hash = sendToUser.access_hash; + } else { + sendToPeer = new TLRPC.TL_inputPeerContact(); + sendToPeer.user_id = sendToUser.id; + } + } + + ArrayList objArr = new ArrayList<>(); + ArrayList arr = new ArrayList<>(); + ArrayList randomIds = new ArrayList<>(); + ArrayList ids = new ArrayList<>(); + HashMap messagesByRandomIds = new HashMap<>(); + + for (int a = 0; a < messages.size(); a++) { + MessageObject msgObj = messages.get(a); + + final TLRPC.Message newMsg = new TLRPC.TL_message(); + newMsg.flags |= TLRPC.MESSAGE_FLAG_FWD; + if (msgObj.isForwarded()) { + newMsg.fwd_from_id = msgObj.messageOwner.fwd_from_id; + newMsg.fwd_date = msgObj.messageOwner.fwd_date; + } else { + newMsg.fwd_from_id = msgObj.messageOwner.from_id; + newMsg.fwd_date = msgObj.messageOwner.date; + } + newMsg.media = msgObj.messageOwner.media; + newMsg.message = msgObj.messageOwner.message; + newMsg.fwd_msg_id = msgObj.getId(); + newMsg.attachPath = msgObj.messageOwner.attachPath; + if (newMsg.attachPath == null) { + newMsg.attachPath = ""; + } + newMsg.local_id = newMsg.id = UserConfig.getNewMessageId(); + newMsg.from_id = UserConfig.getClientUserId(); + newMsg.flags |= TLRPC.MESSAGE_FLAG_OUT; + if (newMsg.random_id == 0) { + newMsg.random_id = getNextRandomId(); + } + randomIds.add(newMsg.random_id); + messagesByRandomIds.put(newMsg.random_id, newMsg); + ids.add(newMsg.fwd_msg_id); + newMsg.date = ConnectionsManager.getInstance().getCurrentTime(); + newMsg.flags |= TLRPC.MESSAGE_FLAG_UNREAD; + newMsg.dialog_id = peer; + newMsg.to_id = to_id; + MessageObject newMsgObj = new MessageObject(newMsg, null, true); + newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING; + objArr.add(newMsgObj); + arr.add(newMsg); + + putToSendingMessages(newMsg); + + if (arr.size() == 100 || a == messages.size() - 1) { + MessagesStorage.getInstance().putMessages(arr, false, true, false, 0); + MessagesController.getInstance().updateInterfaceWithMessages(peer, objArr); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); + UserConfig.saveConfig(false); + + TLRPC.TL_messages_forwardMessages req = new TLRPC.TL_messages_forwardMessages(); + req.peer = sendToPeer; + req.random_id = randomIds; + req.id = ids; + + final ArrayList newMsgObjArr = arr; + final HashMap messagesByRandomIdsFinal = messagesByRandomIds; + ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, TLRPC.TL_error error) { + if (error == null) { + HashMap newMessagesByIds = new HashMap<>(); + TLRPC.Updates updates = (TLRPC.Updates) response; + for (int a = 0; a < updates.updates.size(); a++) { + TLRPC.Update update = updates.updates.get(a); + if (update instanceof TLRPC.TL_updateMessageID) { + newMessagesByIds.put(update.id, update.random_id); + updates.updates.remove(a); + a--; + } + } + for (TLRPC.Update update : updates.updates) { + if (update instanceof TLRPC.TL_updateNewMessage) { + MessagesController.getInstance().processNewDifferenceParams(-1, update.pts, -1, update.pts_count); + TLRPC.Message message = ((TLRPC.TL_updateNewMessage) update).message; + Long random_id = newMessagesByIds.get(message.id); + if (random_id != null) { + final TLRPC.Message newMsgObj = messagesByRandomIdsFinal.get(random_id); + if (newMsgObj == null) { + continue; + } + newMsgObjArr.remove(newMsgObj); + final int oldId = newMsgObj.id; + final ArrayList sentMessages = new ArrayList<>(); + sentMessages.add(message); + newMsgObj.id = message.id; + processSentMessage(newMsgObj, message, null); + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { + @Override + public void run() { + MessagesStorage.getInstance().updateMessageStateAndId(newMsgObj.random_id, oldId, newMsgObj.id, 0, false); + MessagesStorage.getInstance().putMessages(sentMessages, true, false, false, 0); + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + newMsgObj.send_state = MessageObject.MESSAGE_SEND_STATE_SENT; + NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, oldId, newMsgObj.id, newMsgObj, false); + processSentMessage(oldId); + removeFromSendingMessages(oldId); + } + }); + if (newMsgObj.media instanceof TLRPC.TL_messageMediaVideo) { + stopVideoService(newMsgObj.attachPath); + } + } + }); + } + } + } + } + for (final TLRPC.Message newMsgObj : newMsgObjArr) { + 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); + } + removeFromSendingMessages(newMsgObj.id); + } + }); + } + } + }, null, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassCanCompress, ConnectionsManager.DEFAULT_DATACENTER_ID); + + if (a != messages.size() - 1) { + objArr = new ArrayList<>(); + arr = new ArrayList<>(); + randomIds = new ArrayList<>(); + ids = new ArrayList<>(); + messagesByRandomIds = new HashMap<>(); + } + } + } } public void sendMessage(MessageObject message) { - sendMessage(null, null, null, null, null, message, null, null, null, null, message.getDialogId(), true, message.messageOwner.attachPath); + sendMessage(null, null, null, null, null, message, null, null, null, null, message.getDialogId(), true, message.messageOwner.attachPath, null, null, true); } public void sendMessage(MessageObject message, long peer) { - sendMessage(null, null, null, null, null, message, null, null, null, null, peer, false, message.messageOwner.attachPath); + sendMessage(null, null, null, null, null, message, null, null, null, null, peer, false, message.messageOwner.attachPath, null, null, true); } - public void sendMessage(TLRPC.TL_document document, String originalPath, String path, long peer) { - sendMessage(null, null, null, null, null, null, null, document, null, originalPath, peer, false, path); + public void sendMessage(TLRPC.TL_document document, String originalPath, String path, long peer, MessageObject reply_to_msg) { + sendMessage(null, null, null, null, null, null, null, document, null, originalPath, peer, false, path, reply_to_msg, null, true); } - public void sendMessage(String message, long peer) { - sendMessage(message, null, null, null, null, null, null, null, null, null, peer, false, null); + public void sendMessage(String message, long peer, MessageObject reply_to_msg, TLRPC.WebPage webPage, boolean searchLinks) { + sendMessage(message, null, null, null, null, null, null, null, null, null, peer, false, null, reply_to_msg, webPage, searchLinks); } - public void sendMessage(double lat, double lon, long peer) { - sendMessage(null, lat, lon, null, null, null, null, null, null, null, peer, false, null); + public void sendMessage(double lat, double lon, long peer, MessageObject reply_to_msg) { + sendMessage(null, lat, lon, null, null, null, null, null, null, null, peer, false, null, reply_to_msg, null, true); } - public void sendMessage(TLRPC.TL_photo photo, String originalPath, String path, long peer) { - sendMessage(null, null, null, photo, null, null, null, null, null, originalPath, peer, false, path); + public void sendMessage(TLRPC.TL_photo photo, String originalPath, String path, long peer, MessageObject reply_to_msg) { + sendMessage(null, null, null, photo, null, null, null, null, null, originalPath, peer, false, path, reply_to_msg, null, true); } - public void sendMessage(TLRPC.TL_video video, String originalPath, String path, long peer) { - sendMessage(null, null, null, null, video, null, null, null, null, originalPath, peer, false, path); + public void sendMessage(TLRPC.TL_video video, String originalPath, String path, long peer, MessageObject reply_to_msg) { + sendMessage(null, null, null, null, video, null, null, null, null, originalPath, peer, false, path, reply_to_msg, null, true); } - public void sendMessage(TLRPC.TL_audio audio, String path, long peer) { - sendMessage(null, null, null, null, null, null, null, null, audio, null, peer, false, path); + public void sendMessage(TLRPC.TL_audio audio, String path, long peer, MessageObject reply_to_msg) { + sendMessage(null, null, null, null, null, null, null, null, audio, null, peer, false, path, reply_to_msg, null, true); } - private void sendMessage(String message, Double lat, Double lon, TLRPC.TL_photo photo, TLRPC.TL_video video, MessageObject msgObj, TLRPC.User user, TLRPC.TL_document document, TLRPC.TL_audio audio, String originalPath, long peer, boolean retry, String path) { + private void sendMessage(String message, Double lat, Double lon, TLRPC.TL_photo photo, TLRPC.TL_video video, MessageObject msgObj, TLRPC.User user, TLRPC.TL_document document, TLRPC.TL_audio audio, String originalPath, long peer, boolean retry, String path, MessageObject reply_to_msg, TLRPC.WebPage webPage, boolean searchLinks) { if (peer == 0) { return; } @@ -533,7 +706,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter newMsg = msgObj.messageOwner; if (msgObj.type == 0) { - if (msgObj.messageOwner instanceof TLRPC.TL_messageForwarded) { + if (msgObj.isForwarded()) { type = 4; } else { message = newMsg.message; @@ -544,14 +717,14 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter lon = newMsg.media.geo._long; type = 1; } else if (msgObj.type == 1) { - if (msgObj.messageOwner instanceof TLRPC.TL_messageForwarded) { + if (msgObj.isForwarded()) { type = 4; } else { photo = (TLRPC.TL_photo) newMsg.media.photo; type = 2; } } else if (msgObj.type == 3) { - if (msgObj.messageOwner instanceof TLRPC.TL_messageForwarded) { + if (msgObj.isForwarded()) { type = 4; } else { type = 3; @@ -579,7 +752,12 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter } else { newMsg = new TLRPC.TL_message(); } - newMsg.media = new TLRPC.TL_messageMediaEmpty(); + if (encryptedChat != null || webPage == null) { + newMsg.media = new TLRPC.TL_messageMediaEmpty(); + } else { + newMsg.media = new TLRPC.TL_messageMediaWebPage(); + newMsg.media.webpage = webPage; + } type = 0; newMsg.message = message; } else if (lat != null && lon != null) { @@ -627,24 +805,20 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter } newMsg.attachPath = path; } else if (msgObj != null) { - newMsg = new TLRPC.TL_messageForwarded(); - if (msgObj.messageOwner instanceof TLRPC.TL_messageForwarded) { + newMsg = new TLRPC.TL_message(); + newMsg.flags |= TLRPC.MESSAGE_FLAG_FWD; + if (msgObj.isForwarded()) { newMsg.fwd_from_id = msgObj.messageOwner.fwd_from_id; newMsg.fwd_date = msgObj.messageOwner.fwd_date; - newMsg.media = msgObj.messageOwner.media; - newMsg.message = msgObj.messageOwner.message; - newMsg.fwd_msg_id = msgObj.messageOwner.id; - newMsg.attachPath = msgObj.messageOwner.attachPath; - type = 4; } else { newMsg.fwd_from_id = msgObj.messageOwner.from_id; newMsg.fwd_date = msgObj.messageOwner.date; - newMsg.media = msgObj.messageOwner.media; - newMsg.message = msgObj.messageOwner.message; - newMsg.fwd_msg_id = msgObj.messageOwner.id; - newMsg.attachPath = msgObj.messageOwner.attachPath; - type = 4; } + newMsg.media = msgObj.messageOwner.media; + newMsg.message = msgObj.messageOwner.message; + newMsg.fwd_msg_id = msgObj.getId(); + newMsg.attachPath = msgObj.messageOwner.attachPath; + type = 4; } else if (user != null) { if (encryptedChat != null && AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) { newMsg = new TLRPC.TL_message_secret(); @@ -695,9 +869,15 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter newMsg.date = ConnectionsManager.getInstance().getCurrentTime(); newMsg.flags |= TLRPC.MESSAGE_FLAG_UNREAD; newMsg.dialog_id = peer; + if (reply_to_msg != null) { + newMsg.flags |= TLRPC.MESSAGE_FLAG_REPLY; + newMsg.reply_to_msg_id = reply_to_msg.getId(); + } if (lower_id != 0) { if (high_id == 1) { if (currentChatInfo == null) { + MessagesStorage.getInstance().markMessageAsSendError(newMsg.id); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, newMsg.id); processSentMessage(newMsg.id); return; } @@ -754,6 +934,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter } MessageObject newMsgObj = new MessageObject(newMsg, null, true); + newMsgObj.replyMessageObject = reply_to_msg; newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING; ArrayList objArr = new ArrayList<>(); @@ -769,15 +950,27 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter if (encryptedChat == null) { if (sendToPeers != null) { TLRPC.TL_messages_sendBroadcast reqSend = new TLRPC.TL_messages_sendBroadcast(); + ArrayList random_ids = new ArrayList<>(); + for (int a = 0; a < sendToPeers.size(); a++) { + random_ids.add(Utilities.random.nextLong()); + } reqSend.message = message; reqSend.contacts = sendToPeers; reqSend.media = new TLRPC.TL_inputMediaEmpty(); + reqSend.random_id = random_ids; performSendMessageRequest(reqSend, newMsgObj.messageOwner, null); } else { TLRPC.TL_messages_sendMessage reqSend = new TLRPC.TL_messages_sendMessage(); reqSend.message = message; reqSend.peer = sendToPeer; reqSend.random_id = newMsg.random_id; + if (reply_to_msg != null) { + reqSend.flags |= 1; + reqSend.reply_to_msg_id = reply_to_msg.getId(); + } + if (!searchLinks) { + reqSend.flags |= 2; + } performSendMessageRequest(reqSend, newMsgObj.messageOwner, null); } } else { @@ -787,7 +980,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter reqSend.ttl = newMsg.ttl; } else { reqSend = new TLRPC.TL_decryptedMessage_old(); - reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; + reqSend.random_bytes = new byte[15]; Utilities.random.nextBytes(reqSend.random_bytes); } reqSend.random_id = newMsg.random_id; @@ -899,8 +1092,13 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter if (sendToPeers != null) { TLRPC.TL_messages_sendBroadcast request = new TLRPC.TL_messages_sendBroadcast(); + ArrayList random_ids = new ArrayList<>(); + for (int a = 0; a < sendToPeers.size(); a++) { + random_ids.add(Utilities.random.nextLong()); + } request.contacts = sendToPeers; request.media = inputMedia; + request.random_id = random_ids; request.message = ""; if (delayedMessage != null) { delayedMessage.sendRequest = request; @@ -911,6 +1109,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter request.peer = sendToPeer; request.random_id = newMsg.random_id; request.media = inputMedia; + if (reply_to_msg != null) { + request.flags |= 1; + request.reply_to_msg_id = reply_to_msg.getId(); + } if (delayedMessage != null) { delayedMessage.sendRequest = request; } @@ -952,7 +1154,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter reqSend.ttl = newMsg.ttl; } else { reqSend = new TLRPC.TL_decryptedMessage_old(); - reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; + reqSend.random_bytes = new byte[15]; Utilities.random.nextBytes(reqSend.random_bytes); } reqSend.random_id = newMsg.random_id; @@ -1107,8 +1309,8 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter TLRPC.TL_messages_forwardMessage reqSend = new TLRPC.TL_messages_forwardMessage(); reqSend.peer = sendToPeer; reqSend.random_id = newMsg.random_id; - if (msgObj.messageOwner.id >= 0) { - reqSend.id = msgObj.messageOwner.id; + if (msgObj.getId() >= 0) { + reqSend.id = msgObj.getId(); } else { reqSend.id = msgObj.messageOwner.fwd_msg_id; } @@ -1116,10 +1318,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter } } catch (Exception e) { FileLog.e("tmessages", e); - MessagesStorage.getInstance().markMessageAsSendError(newMsgObj.messageOwner.id); + MessagesStorage.getInstance().markMessageAsSendError(newMsgObj.getId()); newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR; - NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, newMsgObj.messageOwner.id); - processSentMessage(newMsgObj.messageOwner.id); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, newMsgObj.getId()); + processSentMessage(newMsgObj.getId()); } } @@ -1255,70 +1457,82 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { @Override public void run(TLObject response, TLRPC.TL_error error) { + boolean isSentError = false; if (error == null) { final int oldId = newMsgObj.id; final boolean isBroadcast = req instanceof TLRPC.TL_messages_sendBroadcast; final ArrayList sentMessages = new ArrayList<>(); final String attachPath = newMsgObj.attachPath; - + final boolean mediaUpdated = response instanceof TLRPC.messages_SentMessage && !(((TLRPC.messages_SentMessage) response).media instanceof TLRPC.TL_messageMediaEmpty); if (response instanceof TLRPC.messages_SentMessage) { TLRPC.messages_SentMessage res = (TLRPC.messages_SentMessage) response; - newMsgObj.id = res.id; + newMsgObj.local_id = newMsgObj.id = res.id; newMsgObj.date = res.date; - MessagesController.getInstance().processNewDifferenceParams(res.seq, res.pts, res.date); - } else if (response instanceof TLRPC.messages_StatedMessage) { - TLRPC.messages_StatedMessage res = (TLRPC.messages_StatedMessage) response; - sentMessages.add(res.message); - newMsgObj.id = res.message.id; - 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; - if (!res.messages.isEmpty()) { - sentMessages.addAll(res.messages); - TLRPC.Message message = res.messages.get(0); - if (!isBroadcast) { - newMsgObj.id = message.id; - } - processSentMessage(newMsgObj, message, originalPath); + newMsgObj.media = res.media; + if (res instanceof TLRPC.TL_messages_sentMessage) { + MessagesController.getInstance().processNewDifferenceParams(-1, res.pts, res.date, res.pts_count); + } else if (res instanceof TLRPC.TL_messages_sentMessageLink) { + MessagesController.getInstance().processNewDifferenceParams(res.seq, res.pts, res.date, res.pts_count); + } + sentMessages.add(newMsgObj); + } else if (response instanceof TLRPC.Updates) { + TLRPC.TL_updateNewMessage newMessage = null; + for (TLRPC.Update update : ((TLRPC.Updates) response).updates) { + if (update instanceof TLRPC.TL_updateNewMessage) { + newMessage = (TLRPC.TL_updateNewMessage) update; + break; + } + } + if (newMessage != null) { + sentMessages.add(newMessage.message); + newMsgObj.id = newMessage.message.id; + processSentMessage(newMsgObj, newMessage.message, originalPath); + MessagesController.getInstance().processNewDifferenceParams(-1, newMessage.pts, -1, newMessage.pts_count); + } else { + isSentError = true; } - MessagesController.getInstance().processNewDifferenceParams(res.seq, res.pts, -1); } - MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { - @Override - public void run() { - MessagesStorage.getInstance().updateMessageStateAndId(newMsgObj.random_id, oldId, (isBroadcast ? oldId : newMsgObj.id), 0, false); - MessagesStorage.getInstance().putMessages(sentMessages, true, false, isBroadcast, 0); - if (isBroadcast) { - ArrayList currentMessage = new ArrayList<>(); - currentMessage.add(newMsgObj); - newMsgObj.send_state = MessageObject.MESSAGE_SEND_STATE_SENT; - MessagesStorage.getInstance().putMessages(currentMessage, true, false, false, 0); - } - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { + + if (!isSentError) { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { + @Override + public void run() { + MessagesStorage.getInstance().updateMessageStateAndId(newMsgObj.random_id, oldId, (isBroadcast ? oldId : newMsgObj.id), 0, false); + MessagesStorage.getInstance().putMessages(sentMessages, true, false, isBroadcast, 0); + if (isBroadcast) { + ArrayList currentMessage = new ArrayList<>(); + currentMessage.add(newMsgObj); newMsgObj.send_state = MessageObject.MESSAGE_SEND_STATE_SENT; - if (isBroadcast) { - for (TLRPC.Message message : sentMessages) { - ArrayList arr = new ArrayList<>(); - MessageObject messageObject = new MessageObject(message, null, false); - arr.add(messageObject); - MessagesController.getInstance().updateInterfaceWithMessages(messageObject.getDialogId(), arr, isBroadcast); - } - NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); - } - NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, oldId, (isBroadcast ? oldId : newMsgObj.id), newMsgObj); - processSentMessage(oldId); - removeFromSendingMessages(oldId); + MessagesStorage.getInstance().putMessages(currentMessage, true, false, false, 0); + } + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + newMsgObj.send_state = MessageObject.MESSAGE_SEND_STATE_SENT; + if (isBroadcast) { + for (TLRPC.Message message : sentMessages) { + ArrayList arr = new ArrayList<>(); + MessageObject messageObject = new MessageObject(message, null, false); + arr.add(messageObject); + MessagesController.getInstance().updateInterfaceWithMessages(messageObject.getDialogId(), arr, isBroadcast); + } + NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); + } + NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, oldId, (isBroadcast ? oldId : newMsgObj.id), newMsgObj, mediaUpdated); + processSentMessage(oldId); + removeFromSendingMessages(oldId); + } + }); + if (newMsgObj.media instanceof TLRPC.TL_messageMediaVideo) { + stopVideoService(attachPath); } - }); - if (newMsgObj.media instanceof TLRPC.TL_messageMediaVideo) { - stopVideoService(attachPath); } - } - }); + }); + } } else { + isSentError = true; + } + if (isSentError) { MessagesStorage.getInstance().markMessageAsSendError(newMsgObj.id); AndroidUtilities.runOnUIThread(new Runnable() { @Override @@ -1334,7 +1548,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter }); } } - }, (req instanceof TLRPC.TL_messages_forwardMessages ? null : new RPCRequest.RPCQuickAckDelegate() { + }, new RPCRequest.RPCQuickAckDelegate() { @Override public void quickAck() { final int msg_id = newMsgObj.id; @@ -1346,7 +1560,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter } }); } - }), true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassCanCompress, ConnectionsManager.DEFAULT_DATACENTER_ID); + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassCanCompress, ConnectionsManager.DEFAULT_DATACENTER_ID); } private void processSentMessage(TLRPC.Message newMsg, TLRPC.Message sentMessage, String originalPath) { @@ -1541,7 +1755,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter } } - private static boolean prepareSendingDocumentInternal(String path, String originalPath, Uri uri, String mime, final long dialog_id) { + private static boolean prepareSendingDocumentInternal(String path, String originalPath, Uri uri, String mime, final long dialog_id, final MessageObject reply_to_msg) { if ((path == null || path.length() == 0) && uri == null) { return false; } @@ -1610,6 +1824,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter try { Bitmap bitmap = ImageLoader.loadBitmap(f.getAbsolutePath(), null, 90, 90, true); if (bitmap != null) { + fileName.file_name = "animation.gif"; document.thumb = ImageLoader.scaleAndSaveImage(bitmap, 90, 90, 55, isEncrypted); } } catch (Exception e) { @@ -1628,7 +1843,13 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter FileLog.e("tmessages", e); } if (bmOptions.outWidth != 0 && bmOptions.outHeight != 0 && bmOptions.outWidth <= 800 && bmOptions.outHeight <= 800) { - TLRPC.TL_documentAttributeSticker attributeSticker = new TLRPC.TL_documentAttributeSticker(); + TLRPC.TL_documentAttributeSticker attributeSticker = null; + if (isEncrypted) { + attributeSticker = new TLRPC.TL_documentAttributeSticker_old(); + } else { + attributeSticker = new TLRPC.TL_documentAttributeSticker(); + attributeSticker.alt = ""; + } document.attributes.add(attributeSticker); TLRPC.TL_documentAttributeImageSize attributeImageSize = new TLRPC.TL_documentAttributeImageSize(); attributeImageSize.w = bmOptions.outWidth; @@ -1648,13 +1869,13 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter AndroidUtilities.runOnUIThread(new Runnable() { @Override public void run() { - SendMessagesHelper.getInstance().sendMessage(documentFinal, originalPathFinal, pathFinal, dialog_id); + SendMessagesHelper.getInstance().sendMessage(documentFinal, originalPathFinal, pathFinal, dialog_id, reply_to_msg); } }); return true; } - public static void prepareSendingDocument(String path, String originalPath, Uri uri, String mine, long dialog_id) { + public static void prepareSendingDocument(String path, String originalPath, Uri uri, String mine, long dialog_id, MessageObject reply_to_msg) { if ((path == null || originalPath == null) && uri == null) { return; } @@ -1666,10 +1887,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter } paths.add(path); originalPaths.add(originalPath); - prepareSendingDocuments(paths, originalPaths, uris, mine, dialog_id); + prepareSendingDocuments(paths, originalPaths, uris, mine, dialog_id, reply_to_msg); } - public static void prepareSendingDocuments(final ArrayList paths, final ArrayList originalPaths, final ArrayList uris, final String mime, final long dialog_id) { + public static void prepareSendingDocuments(final ArrayList paths, final ArrayList originalPaths, final ArrayList uris, final String mime, final long dialog_id, final MessageObject reply_to_msg) { if (paths == null && originalPaths == null && uris == null || paths != null && originalPaths != null && paths.size() != originalPaths.size()) { return; } @@ -1679,14 +1900,14 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter boolean error = false; if (paths != null) { for (int a = 0; a < paths.size(); a++) { - if (!prepareSendingDocumentInternal(paths.get(a), originalPaths.get(a), null, mime, dialog_id)) { + if (!prepareSendingDocumentInternal(paths.get(a), originalPaths.get(a), null, mime, dialog_id, reply_to_msg)) { error = true; } } } if (uris != null) { for (int a = 0; a < uris.size(); a++) { - if (!prepareSendingDocumentInternal(null, null, uris.get(a), mime, dialog_id)) { + if (!prepareSendingDocumentInternal(null, null, uris.get(a), mime, dialog_id, reply_to_msg)) { error = true; } } @@ -1708,7 +1929,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter }).start(); } - public static void prepareSendingPhoto(String imageFilePath, Uri imageUri, long dialog_id) { + public static void prepareSendingPhoto(String imageFilePath, Uri imageUri, long dialog_id, MessageObject reply_to_msg) { ArrayList paths = null; ArrayList uris = null; if (imageFilePath != null && imageFilePath.length() != 0) { @@ -1719,10 +1940,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter uris = new ArrayList<>(); uris.add(imageUri); } - prepareSendingPhotos(paths, uris, dialog_id); + prepareSendingPhotos(paths, uris, dialog_id, reply_to_msg); } - public static void prepareSendingPhotosSearch(final ArrayList photos, final long dialog_id) { + public static void prepareSendingPhotosSearch(final ArrayList photos, final long dialog_id, final MessageObject reply_to_msg) { if (photos == null || photos.isEmpty()) { return; } @@ -1744,7 +1965,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter document.id = 0; document.date = ConnectionsManager.getInstance().getCurrentTime(); TLRPC.TL_documentAttributeFilename fileName = new TLRPC.TL_documentAttributeFilename(); - fileName.file_name = md5; + fileName.file_name = "animation.gif"; document.attributes.add(fileName); document.size = searchImage.size; document.dc_id = 0; @@ -1784,7 +2005,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter AndroidUtilities.runOnUIThread(new Runnable() { @Override public void run() { - SendMessagesHelper.getInstance().sendMessage(documentFinal, originalPathFinal, pathFinal, dialog_id); + SendMessagesHelper.getInstance().sendMessage(documentFinal, originalPathFinal, pathFinal, dialog_id, reply_to_msg); } }); } else { @@ -1827,7 +2048,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter AndroidUtilities.runOnUIThread(new Runnable() { @Override public void run() { - SendMessagesHelper.getInstance().sendMessage(photoFinal, originalPathFinal, needDownloadHttpFinal ? searchImage.imageUrl : null, dialog_id); + SendMessagesHelper.getInstance().sendMessage(photoFinal, originalPathFinal, needDownloadHttpFinal ? searchImage.imageUrl : null, dialog_id, reply_to_msg); } }); } @@ -1837,7 +2058,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter }).start(); } - public static void prepareSendingPhotos(ArrayList paths, ArrayList uris, final long dialog_id) { + public static void prepareSendingPhotos(ArrayList paths, ArrayList uris, final long dialog_id, final MessageObject reply_to_msg) { if (paths == null && uris == null || paths != null && paths.isEmpty() || uris != null && uris.isEmpty()) { return; } @@ -1918,7 +2139,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter AndroidUtilities.runOnUIThread(new Runnable() { @Override public void run() { - SendMessagesHelper.getInstance().sendMessage(photoFinal, originalPathFinal, null, dialog_id); + SendMessagesHelper.getInstance().sendMessage(photoFinal, originalPathFinal, null, dialog_id, reply_to_msg); } }); } @@ -1926,126 +2147,133 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter } if (sendAsDocuments != null && !sendAsDocuments.isEmpty()) { for (int a = 0; a < sendAsDocuments.size(); a++) { - prepareSendingDocumentInternal(sendAsDocuments.get(a), sendAsDocumentsOriginal.get(a), null, "gif", dialog_id); + prepareSendingDocumentInternal(sendAsDocuments.get(a), sendAsDocumentsOriginal.get(a), null, "gif", dialog_id, reply_to_msg); } } } }).start(); } - public static void prepareSendingVideo(final String videoPath, final long estimatedSize, final long duration, final int width, final int height, final TLRPC.VideoEditedInfo videoEditedInfo, final long dialog_id) { + public static void prepareSendingVideo(final String videoPath, final long estimatedSize, final long duration, final int width, final int height, final TLRPC.VideoEditedInfo videoEditedInfo, final long dialog_id, final MessageObject reply_to_msg) { if (videoPath == null || videoPath.length() == 0) { return; } new Thread(new Runnable() { @Override public void run() { + boolean isEncrypted = (int)dialog_id == 0; - String path = videoPath; - String originalPath = videoPath; - File temp = new File(originalPath); - originalPath += temp.length() + "_" + temp.lastModified(); - if (videoEditedInfo != null) { - originalPath += duration + "_" + videoEditedInfo.startTime + "_" + videoEditedInfo.endTime; - } - TLRPC.TL_video video = null; - if (!isEncrypted) { - video = (TLRPC.TL_video) MessagesStorage.getInstance().getSentFile(originalPath, !isEncrypted ? 2 : 5); - } - if (video == null) { - Bitmap thumb = ThumbnailUtils.createVideoThumbnail(videoPath, MediaStore.Video.Thumbnails.MINI_KIND); - TLRPC.PhotoSize size = ImageLoader.scaleAndSaveImage(thumb, 90, 90, 55, isEncrypted); - video = new TLRPC.TL_video(); - video.thumb = size; - if (video.thumb == null) { - video.thumb = new TLRPC.TL_photoSizeEmpty(); - video.thumb.type = "s"; - } else { - video.thumb.type = "s"; - } - video.caption = ""; - video.mime_type = "video/mp4"; - video.id = 0; - UserConfig.saveConfig(false); - + if (videoEditedInfo != null || videoPath.endsWith("mp4")) { + String path = videoPath; + String originalPath = videoPath; + File temp = new File(originalPath); + originalPath += temp.length() + "_" + temp.lastModified(); if (videoEditedInfo != null) { - video.duration = (int)(duration / 1000); - if (videoEditedInfo.rotationValue == 90 || videoEditedInfo.rotationValue == 270) { - video.w = height; - video.h = width; + originalPath += duration + "_" + videoEditedInfo.startTime + "_" + videoEditedInfo.endTime; + if (videoEditedInfo.resultWidth == videoEditedInfo.originalWidth) { + originalPath += "_" + videoEditedInfo.resultWidth; + } + } + TLRPC.TL_video video = null; + if (!isEncrypted) { + video = (TLRPC.TL_video) MessagesStorage.getInstance().getSentFile(originalPath, !isEncrypted ? 2 : 5); + } + if (video == null) { + Bitmap thumb = ThumbnailUtils.createVideoThumbnail(videoPath, MediaStore.Video.Thumbnails.MINI_KIND); + TLRPC.PhotoSize size = ImageLoader.scaleAndSaveImage(thumb, 90, 90, 55, isEncrypted); + video = new TLRPC.TL_video(); + video.thumb = size; + if (video.thumb == null) { + video.thumb = new TLRPC.TL_photoSizeEmpty(); + video.thumb.type = "s"; } else { - video.w = width; - video.h = height; + video.thumb.type = "s"; } - video.size = (int)estimatedSize; - video.videoEditedInfo = videoEditedInfo; - String fileName = Integer.MIN_VALUE + "_" + UserConfig.lastLocalId + ".mp4"; - UserConfig.lastLocalId--; - File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName); + video.caption = ""; + video.mime_type = "video/mp4"; + video.id = 0; UserConfig.saveConfig(false); - path = cacheFile.getAbsolutePath(); - } else { - if (temp != null && temp.exists()) { - video.size = (int) temp.length(); - } - boolean infoObtained = false; - if (Build.VERSION.SDK_INT >= 14) { - MediaMetadataRetriever mediaMetadataRetriever = null; - try { - mediaMetadataRetriever = new MediaMetadataRetriever(); - mediaMetadataRetriever.setDataSource(videoPath); - String width = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH); - if (width != null) { - video.w = Integer.parseInt(width); - } - String height = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT); - if (height != null) { - video.h = Integer.parseInt(height); - } - String duration = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); - if (duration != null) { - video.duration = (int) Math.ceil(Long.parseLong(duration) / 1000.0f); - } - infoObtained = true; - } catch (Exception e) { - FileLog.e("tmessages", e); - } finally { + + if (videoEditedInfo != null) { + video.duration = (int) (duration / 1000); + if (videoEditedInfo.rotationValue == 90 || videoEditedInfo.rotationValue == 270) { + video.w = height; + video.h = width; + } else { + video.w = width; + video.h = height; + } + video.size = (int) estimatedSize; + video.videoEditedInfo = videoEditedInfo; + String fileName = Integer.MIN_VALUE + "_" + UserConfig.lastLocalId + ".mp4"; + UserConfig.lastLocalId--; + File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName); + UserConfig.saveConfig(false); + path = cacheFile.getAbsolutePath(); + } else { + if (temp != null && temp.exists()) { + video.size = (int) temp.length(); + } + boolean infoObtained = false; + if (Build.VERSION.SDK_INT >= 14) { + MediaMetadataRetriever mediaMetadataRetriever = null; try { - if (mediaMetadataRetriever != null) { - mediaMetadataRetriever.release(); - mediaMetadataRetriever = null; + mediaMetadataRetriever = new MediaMetadataRetriever(); + mediaMetadataRetriever.setDataSource(videoPath); + String width = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH); + if (width != null) { + video.w = Integer.parseInt(width); + } + String height = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT); + if (height != null) { + video.h = Integer.parseInt(height); + } + String duration = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); + if (duration != null) { + video.duration = (int) Math.ceil(Long.parseLong(duration) / 1000.0f); + } + infoObtained = true; + } catch (Exception e) { + FileLog.e("tmessages", e); + } finally { + try { + if (mediaMetadataRetriever != null) { + mediaMetadataRetriever.release(); + mediaMetadataRetriever = null; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + } + if (!infoObtained) { + try { + MediaPlayer mp = MediaPlayer.create(ApplicationLoader.applicationContext, Uri.fromFile(new File(videoPath))); + if (mp != null) { + video.duration = (int) Math.ceil(mp.getDuration() / 1000.0f); + video.w = mp.getVideoWidth(); + video.h = mp.getVideoHeight(); + mp.release(); } } catch (Exception e) { FileLog.e("tmessages", e); } } } - if (!infoObtained) { - try { - MediaPlayer mp = MediaPlayer.create(ApplicationLoader.applicationContext, Uri.fromFile(new File(videoPath))); - if (mp != null) { - video.duration = (int) Math.ceil(mp.getDuration() / 1000.0f); - video.w = mp.getVideoWidth(); - video.h = mp.getVideoHeight(); - mp.release(); - } - } catch (Exception e) { - FileLog.e("tmessages", e); - } + } + final TLRPC.TL_video videoFinal = video; + final String originalPathFinal = originalPath; + final String finalPath = path; + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + SendMessagesHelper.getInstance().sendMessage(videoFinal, originalPathFinal, finalPath, dialog_id, reply_to_msg); } - } + }); + } else { + prepareSendingDocumentInternal(videoPath, videoPath, null, null, dialog_id, reply_to_msg); } - - final TLRPC.TL_video videoFinal = video; - final String originalPathFinal = originalPath; - final String finalPath = path; - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - SendMessagesHelper.getInstance().sendMessage(videoFinal, originalPathFinal, finalPath, dialog_id); - } - }); } }).start(); } diff --git a/TMessagesProj/src/main/java/org/telegram/android/SmsListener.java b/TMessagesProj/src/main/java/org/telegram/android/SmsListener.java index c4470fa41..78e179605 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/SmsListener.java +++ b/TMessagesProj/src/main/java/org/telegram/android/SmsListener.java @@ -51,11 +51,11 @@ public class SmsListener extends BroadcastReceiver { NotificationCenter.getInstance().postNotificationName(NotificationCenter.didReceiveSmsCode, matcher.group(0)); } } - } catch (Exception e) { + } catch (Throwable e) { FileLog.e("tmessages", e); } - } catch(Exception e) { + } catch(Throwable e) { FileLog.e("tmessages", e); } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/WearReplyReceiver.java b/TMessagesProj/src/main/java/org/telegram/android/WearReplyReceiver.java index 9e32dc6a6..dfde54421 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/WearReplyReceiver.java +++ b/TMessagesProj/src/main/java/org/telegram/android/WearReplyReceiver.java @@ -31,7 +31,7 @@ public class WearReplyReceiver extends BroadcastReceiver { if (dialog_id == 0 || max_id == 0) { return; } - SendMessagesHelper.getInstance().sendMessage(text.toString(), dialog_id); + SendMessagesHelper.getInstance().sendMessage(text.toString(), dialog_id, null, null, true); MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, 0, true, false); } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/query/ReplyMessageQuery.java b/TMessagesProj/src/main/java/org/telegram/android/query/ReplyMessageQuery.java new file mode 100644 index 000000000..da9717dd1 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/android/query/ReplyMessageQuery.java @@ -0,0 +1,185 @@ +/* + * This is the source code of Telegram for Android v. 2.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-2015. + */ + +package org.telegram.android.query; + +import android.text.TextUtils; + +import org.telegram.SQLite.SQLiteCursor; +import org.telegram.SQLite.SQLitePreparedStatement; +import org.telegram.android.AndroidUtilities; +import org.telegram.android.ImageLoader; +import org.telegram.android.MessageObject; +import org.telegram.android.MessagesStorage; +import org.telegram.android.NotificationCenter; +import org.telegram.messenger.ByteBufferDesc; +import org.telegram.messenger.ConnectionsManager; +import org.telegram.messenger.FileLog; +import org.telegram.messenger.RPCRequest; +import org.telegram.messenger.TLClassStore; +import org.telegram.messenger.TLObject; +import org.telegram.messenger.TLRPC; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Locale; + +public class ReplyMessageQuery { + + public static void loadReplyMessagesForMessages(final ArrayList messages, final long dialog_id) { + final ArrayList replyMessages = new ArrayList<>(); + final HashMap> replyMessageOwners = new HashMap<>(); + for (MessageObject messageObject : messages) { + if (messageObject.getId() > 0 && messageObject.isReply() && messageObject.replyMessageObject == null) { + Integer id = messageObject.messageOwner.reply_to_msg_id; + ArrayList messageObjects = replyMessageOwners.get(id); + if (messageObjects == null) { + messageObjects = new ArrayList<>(); + replyMessageOwners.put(id, messageObjects); + } + messageObjects.add(messageObject); + if (!replyMessages.contains(id)) { + replyMessages.add(id); + } + } + } + if (replyMessages.isEmpty()) { + return; + } + + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { + @Override + public void run() { + try { + final ArrayList result = new ArrayList<>(); + final ArrayList users = new ArrayList<>(); + ArrayList loadedUsers = new ArrayList<>(); + ArrayList fromUser = new ArrayList<>(); + + SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, mid, date FROM messages WHERE mid IN(%s)", TextUtils.join(",", replyMessages))); + while (cursor.next()) { + ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0)); + if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { + TLRPC.Message message = (TLRPC.Message) TLClassStore.Instance().TLdeserialize(data, data.readInt32()); + message.id = cursor.intValue(1); + message.date = cursor.intValue(2); + message.dialog_id = dialog_id; + fromUser.add(message.from_id); + if (message.action != null && message.action.user_id != 0) { + fromUser.add(message.action.user_id); + } + if (message.media != null && message.media.user_id != 0) { + fromUser.add(message.media.user_id); + } + if (message.media != null && message.media.audio != null && message.media.audio.user_id != 0) { + fromUser.add(message.media.audio.user_id); + } + if (message.fwd_from_id != 0) { + fromUser.add(message.fwd_from_id); + } + result.add(message); + replyMessages.remove((Integer) message.id); + } + MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data); + } + cursor.dispose(); + + StringBuilder usersToLoad = new StringBuilder(); + for (int uid : fromUser) { + if (!loadedUsers.contains(uid)) { + if (usersToLoad.length() != 0) { + usersToLoad.append(","); + } + usersToLoad.append(uid); + loadedUsers.add(uid); + } + } + if (usersToLoad.length() != 0) { + MessagesStorage.getInstance().getUsersInternal(usersToLoad.toString(), users); + } + broadcastReplyMessages(result, replyMessageOwners, users, dialog_id); + + if (!replyMessages.isEmpty()) { + TLRPC.TL_messages_getMessages req = new TLRPC.TL_messages_getMessages(); + req.id = replyMessages; + ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, TLRPC.TL_error error) { + if (error == null) { + TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response; + ImageLoader.saveMessagesThumbs(messagesRes.messages); + broadcastReplyMessages(messagesRes.messages, replyMessageOwners, messagesRes.users, dialog_id); + MessagesStorage.getInstance().putUsersAndChats(messagesRes.users, null, true, true); + saveReplyMessages(replyMessageOwners, messagesRes.messages); + } + } + }); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + } + + private static void saveReplyMessages(final HashMap> replyMessageOwners, final ArrayList result) { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { + @Override + public void run() { + try { + MessagesStorage.getInstance().getDatabase().beginTransaction(); + SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("UPDATE messages SET replydata = ? WHERE mid = ?"); + for (TLRPC.Message message : result) { + ArrayList messageObjects = replyMessageOwners.get(message.id); + if (messageObjects != null) { + ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(message.getObjectSize()); + message.serializeToStream(data); + for (MessageObject messageObject : messageObjects) { + state.requery(); + state.bindByteBuffer(1, data.buffer); + state.bindInteger(2, messageObject.getId()); + state.step(); + } + MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data); + } + } + state.dispose(); + MessagesStorage.getInstance().getDatabase().commitTransaction(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + } + + private static void broadcastReplyMessages(final ArrayList result, final HashMap> replyMessageOwners, ArrayList users, final long dialog_id) { + final HashMap usersHashMap = new HashMap<>(); + for (TLRPC.User user : users) { + usersHashMap.put(user.id, user); + } + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + boolean changed = false; + for (TLRPC.Message message : result) { + ArrayList arrayList = replyMessageOwners.get(message.id); + if (arrayList != null) { + MessageObject messageObject = new MessageObject(message, usersHashMap, false); + for (MessageObject m : arrayList) { + m.replyMessageObject = messageObject; + } + changed = true; + } + } + if (changed) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.didLoadedReplyMessages, dialog_id); + } + } + }); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/android/video/MP4Builder.java b/TMessagesProj/src/main/java/org/telegram/android/video/MP4Builder.java index 9d9eca96d..917d8c53d 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/video/MP4Builder.java +++ b/TMessagesProj/src/main/java/org/telegram/android/video/MP4Builder.java @@ -59,7 +59,7 @@ public class MP4Builder { private long dataOffset = 0; private long writedSinceLastMdat = 0; private boolean writeNewMdat = true; - private HashMap track2SampleSizes = new HashMap(); + private HashMap track2SampleSizes = new HashMap<>(); private ByteBuffer sizeBuffer = null; public MP4Builder createMovie(Mp4Movie mp4Movie) throws Exception { @@ -158,7 +158,7 @@ public class MP4Builder { } protected FileTypeBox createFileTypeBox() { - LinkedList minorBrands = new LinkedList(); + LinkedList minorBrands = new LinkedList<>(); minorBrands.add("isom"); minorBrands.add("3gp4"); return new FileTypeBox("isom", 0, minorBrands); @@ -237,7 +237,10 @@ public class MP4Builder { } public long getTimescale(Mp4Movie mp4Movie) { - long timescale = mp4Movie.getTracks().iterator().next().getTimeScale(); + long timescale = 0; + if (!mp4Movie.getTracks().isEmpty()) { + timescale = mp4Movie.getTracks().iterator().next().getTimeScale(); + } for (Track track : mp4Movie.getTracks()) { timescale = gcd(track.getTimeScale(), timescale); } @@ -347,7 +350,7 @@ public class MP4Builder { protected void createStts(Track track, SampleTableBox stbl) { TimeToSampleBox.Entry lastEntry = null; - List entries = new ArrayList(); + List entries = new ArrayList<>(); for (long delta : track.getSampleDurations()) { if (lastEntry != null && lastEntry.getDelta() == delta) { @@ -418,7 +421,7 @@ public class MP4Builder { } protected void createStco(Track track, SampleTableBox stbl) { - ArrayList chunksOffsets = new ArrayList(); + ArrayList chunksOffsets = new ArrayList<>(); long lastOffset = -1; for (Sample sample : track.getSamples()) { long offset = sample.getOffset(); diff --git a/TMessagesProj/src/main/java/org/telegram/android/volley/Cache.java b/TMessagesProj/src/main/java/org/telegram/android/volley/Cache.java index e64e69b2a..90433e7ef 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/volley/Cache.java +++ b/TMessagesProj/src/main/java/org/telegram/android/volley/Cache.java @@ -28,43 +28,43 @@ public interface Cache { * @param key Cache key * @return An {@link Entry} or null in the event of a cache miss */ - public Entry get(String key); + Entry get(String key); /** * Adds or replaces an entry to the cache. * @param key Cache key * @param entry Data to store and metadata for cache coherency, TTL, etc. */ - public void put(String key, Entry entry); + void put(String key, Entry entry); /** * Performs any potentially long-running actions needed to initialize the cache; * will be called from a worker thread. */ - public void initialize(); + void initialize(); /** * Invalidates an entry in the cache. * @param key Cache key * @param fullExpire True to fully expire the entry, false to soft expire */ - public void invalidate(String key, boolean fullExpire); + void invalidate(String key, boolean fullExpire); /** * Removes an entry from the cache. * @param key Cache key */ - public void remove(String key); + void remove(String key); /** * Empties the cache. */ - public void clear(); + void clear(); /** * Data and metadata for an entry returned by the cache. */ - public static class Entry { + class Entry { /** The data returned from cache. */ public byte[] data; diff --git a/TMessagesProj/src/main/java/org/telegram/android/volley/Network.java b/TMessagesProj/src/main/java/org/telegram/android/volley/Network.java index ac3c24b12..f43165409 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/volley/Network.java +++ b/TMessagesProj/src/main/java/org/telegram/android/volley/Network.java @@ -26,5 +26,5 @@ public interface Network { * @return A {@link NetworkResponse} with data and caching metadata; will never be null * @throws VolleyError on errors */ - public NetworkResponse performRequest(Request request) throws VolleyError; + NetworkResponse performRequest(Request request) throws VolleyError; } diff --git a/TMessagesProj/src/main/java/org/telegram/android/volley/RequestQueue.java b/TMessagesProj/src/main/java/org/telegram/android/volley/RequestQueue.java index bec780aec..869c29965 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/volley/RequestQueue.java +++ b/TMessagesProj/src/main/java/org/telegram/android/volley/RequestQueue.java @@ -175,7 +175,7 @@ public class RequestQueue { * {@link RequestQueue#cancelAll(RequestFilter)}. */ public interface RequestFilter { - public boolean apply(Request request); + boolean apply(Request request); } /** diff --git a/TMessagesProj/src/main/java/org/telegram/android/volley/Response.java b/TMessagesProj/src/main/java/org/telegram/android/volley/Response.java index c2dd5419e..af7d96f69 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/volley/Response.java +++ b/TMessagesProj/src/main/java/org/telegram/android/volley/Response.java @@ -26,7 +26,7 @@ public class Response { /** Callback interface for delivering parsed responses. */ public interface Listener { /** Called when a response is received. */ - public void onResponse(T response); + void onResponse(T response); } /** Callback interface for delivering error responses. */ @@ -35,7 +35,7 @@ public class Response { * Callback method that an error has been occurred with the * provided error code and optional user-readable message. */ - public void onErrorResponse(VolleyError error); + void onErrorResponse(VolleyError error); } /** Returns a successful response containing the parsed result. */ diff --git a/TMessagesProj/src/main/java/org/telegram/android/volley/ResponseDelivery.java b/TMessagesProj/src/main/java/org/telegram/android/volley/ResponseDelivery.java index 6eb35eb12..9ad24f355 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/volley/ResponseDelivery.java +++ b/TMessagesProj/src/main/java/org/telegram/android/volley/ResponseDelivery.java @@ -20,16 +20,16 @@ public interface ResponseDelivery { /** * Parses a response from the network or cache and delivers it. */ - public void postResponse(Request request, Response response); + void postResponse(Request request, Response response); /** * Parses a response from the network or cache and delivers it. The provided * Runnable will be executed after delivery. */ - public void postResponse(Request request, Response response, Runnable runnable); + void postResponse(Request request, Response response, Runnable runnable); /** * Posts an error for the given request. */ - public void postError(Request request, VolleyError error); + void postError(Request request, VolleyError error); } diff --git a/TMessagesProj/src/main/java/org/telegram/android/volley/RetryPolicy.java b/TMessagesProj/src/main/java/org/telegram/android/volley/RetryPolicy.java index 7218777a1..c2c1d24d5 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/volley/RetryPolicy.java +++ b/TMessagesProj/src/main/java/org/telegram/android/volley/RetryPolicy.java @@ -24,12 +24,12 @@ public interface RetryPolicy { /** * Returns the current timeout (used for logging). */ - public int getCurrentTimeout(); + int getCurrentTimeout(); /** * Returns the current retry count (used for logging). */ - public int getCurrentRetryCount(); + int getCurrentRetryCount(); /** * Prepares for the next retry by applying a backoff to the timeout. @@ -37,5 +37,5 @@ public interface RetryPolicy { * @throws VolleyError In the event that the retry could not be performed (for example if we * ran out of attempts), the passed in error is thrown. */ - public void retry(VolleyError error) throws VolleyError; + void retry(VolleyError error) throws VolleyError; } diff --git a/TMessagesProj/src/main/java/org/telegram/android/volley/toolbox/Authenticator.java b/TMessagesProj/src/main/java/org/telegram/android/volley/toolbox/Authenticator.java index e87dfc100..f0d4845b1 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/volley/toolbox/Authenticator.java +++ b/TMessagesProj/src/main/java/org/telegram/android/volley/toolbox/Authenticator.java @@ -27,10 +27,10 @@ public interface Authenticator { * * @throws AuthFailureError If authentication did not succeed */ - public String getAuthToken() throws AuthFailureError; + String getAuthToken() throws AuthFailureError; /** * Invalidates the provided auth token. */ - public void invalidateAuthToken(String authToken); + void invalidateAuthToken(String authToken); } diff --git a/TMessagesProj/src/main/java/org/telegram/android/volley/toolbox/HttpStack.java b/TMessagesProj/src/main/java/org/telegram/android/volley/toolbox/HttpStack.java index 74a326d9e..97816eda7 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/volley/toolbox/HttpStack.java +++ b/TMessagesProj/src/main/java/org/telegram/android/volley/toolbox/HttpStack.java @@ -38,7 +38,7 @@ public interface HttpStack { * {@link Request#getHeaders()} * @return the HTTP response */ - public HttpResponse performRequest(Request request, Map additionalHeaders) + HttpResponse performRequest(Request request, Map additionalHeaders) throws IOException, AuthFailureError; } diff --git a/TMessagesProj/src/main/java/org/telegram/android/volley/toolbox/HurlStack.java b/TMessagesProj/src/main/java/org/telegram/android/volley/toolbox/HurlStack.java index 435fd675c..e374fbaf4 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/volley/toolbox/HurlStack.java +++ b/TMessagesProj/src/main/java/org/telegram/android/volley/toolbox/HurlStack.java @@ -56,7 +56,7 @@ public class HurlStack implements HttpStack { * Returns a URL to use instead of the provided one, or null to indicate * this URL should not be used at all. */ - public String rewriteUrl(String originalUrl); + String rewriteUrl(String originalUrl); } private final UrlRewriter mUrlRewriter; diff --git a/TMessagesProj/src/main/java/org/telegram/android/volley/toolbox/ImageLoader.java b/TMessagesProj/src/main/java/org/telegram/android/volley/toolbox/ImageLoader.java index 64105a84f..f22b65d80 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/volley/toolbox/ImageLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/android/volley/toolbox/ImageLoader.java @@ -71,8 +71,8 @@ public class ImageLoader { * must not block. Implementation with an LruCache is recommended. */ public interface ImageCache { - public Bitmap getBitmap(String url); - public void putBitmap(String url, Bitmap bitmap); + Bitmap getBitmap(String url); + void putBitmap(String url, Bitmap bitmap); } /** @@ -138,7 +138,7 @@ public class ImageLoader { * image loading in order to, for example, run an animation to fade in network loaded * images. */ - public void onResponse(ImageContainer response, boolean isImmediate); + void onResponse(ImageContainer response, boolean isImmediate); } /** diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java index b788712c3..481be8415 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java @@ -8,6 +8,7 @@ package org.telegram.messenger; +import android.app.Activity; import android.app.AlarmManager; import android.app.Application; import android.app.PendingIntent; @@ -19,6 +20,7 @@ import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Build; @@ -38,10 +40,13 @@ import org.telegram.android.LocaleController; import org.telegram.android.MessagesController; import org.telegram.android.NativeLoader; import org.telegram.android.ScreenReceiver; +import org.telegram.ui.Components.ForegroundDetector; +import java.io.File; import java.util.concurrent.atomic.AtomicInteger; public class ApplicationLoader extends Application { + private GoogleCloudMessaging gcm; private AtomicInteger msgId = new AtomicInteger(); private String regid; @@ -49,15 +54,80 @@ public class ApplicationLoader extends Application { public static final String PROPERTY_REG_ID = "registration_id"; private static final String PROPERTY_APP_VERSION = "appVersion"; private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000; - public static Drawable cachedWallpaper = null; + private static Drawable cachedWallpaper; + private static int selectedColor; + private static boolean isCustomTheme; + private static final Object sync = new Object(); - public static volatile Context applicationContext = null; - public static volatile Handler applicationHandler = null; + public static volatile Context applicationContext; + public static volatile Handler applicationHandler; private static volatile boolean applicationInited = false; public static volatile boolean isScreenOn = false; public static volatile boolean mainInterfacePaused = true; + public static boolean isCustomTheme() { + return isCustomTheme; + } + + public static int getSelectedColor() { + return selectedColor; + } + + public static void reloadWallpaper() { + cachedWallpaper = null; + loadWallpaper(); + } + + public static void loadWallpaper() { + if (cachedWallpaper != null) { + return; + } + Utilities.searchQueue.postRunnable(new Runnable() { + @Override + public void run() { + synchronized (sync) { + int selectedColor = 0; + try { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + int selectedBackground = preferences.getInt("selectedBackground", 1000001); + selectedColor = preferences.getInt("selectedColor", 0); + int cacheColorHint = 0; + if (selectedColor == 0) { + if (selectedBackground == 1000001) { + cachedWallpaper = applicationContext.getResources().getDrawable(R.drawable.background_hd); + isCustomTheme = false; + } else { + File toFile = new File(ApplicationLoader.applicationContext.getFilesDir(), "wallpaper.jpg"); + if (toFile.exists()) { + cachedWallpaper = Drawable.createFromPath(toFile.getAbsolutePath()); + isCustomTheme = true; + } else { + cachedWallpaper = applicationContext.getResources().getDrawable(R.drawable.background_hd); + isCustomTheme = false; + } + } + } + } catch (Throwable throwable) { + //ignore + } + if (cachedWallpaper == null) { + if (selectedColor == 0) { + selectedColor = -2693905; + } + cachedWallpaper = new ColorDrawable(selectedColor); + } + } + } + }); + } + + public static Drawable getCachedWallpaper() { + synchronized (sync) { + return cachedWallpaper; + } + } + public static void postInitApplication() { if (applicationInited) { return; @@ -117,6 +187,10 @@ public class ApplicationLoader extends Application { applicationContext = getApplicationContext(); NativeLoader.initNativeLibs(ApplicationLoader.applicationContext); + if (Build.VERSION.SDK_INT >= 14) { + new ForegroundDetector(this); + } + applicationHandler = new Handler(applicationContext.getMainLooper()); startPushService(); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java b/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java index bc3dd2995..3d8fa2a10 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java @@ -366,6 +366,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. datacenters.put(datacenter.datacenterId, datacenter); } currentDatacenterId = data.readInt32(); + data.cleanup(); } catch (Exception e) { UserConfig.clearConfig(); } @@ -388,6 +389,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. for (int a = 0; a < count; a++) { sessionsToDestroy.add(data.readInt64()); } + data.cleanup(); } } } catch (Exception e) { @@ -405,6 +407,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. Datacenter datacenter = new Datacenter(data, 1); datacenters.put(datacenter.datacenterId, datacenter); } + data.cleanup(); } } } catch (Exception e) { @@ -452,7 +455,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. datacenter = new Datacenter(); datacenter.datacenterId = 3; - datacenter.addAddressAndPort("174.140.142.6", 443); + datacenter.addAddressAndPort("149.154.175.100", 443); datacenters.put(datacenter.datacenterId, datacenter); datacenter = new Datacenter(); @@ -477,7 +480,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. datacenter = new Datacenter(); datacenter.datacenterId = 3; - datacenter.addAddressAndPort("174.140.142.5", 443); + datacenter.addAddressAndPort("149.154.175.117", 443); datacenters.put(datacenter.datacenterId, datacenter); } } else if (datacenters.size() == 1) { @@ -488,7 +491,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. datacenter = new Datacenter(); datacenter.datacenterId = 3; - datacenter.addAddressAndPort("174.140.142.6", 443); + datacenter.addAddressAndPort("149.154.175.100", 443); datacenters.put(datacenter.datacenterId, datacenter); datacenter = new Datacenter(); @@ -528,6 +531,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. data.writeInt64(session); } editor.putString("sessionsToDestroy", Base64.encodeToString(data.toByteArray(), Base64.DEFAULT)); + data.cleanup(); } else { editor.remove("sessionsToDestroy"); } @@ -539,6 +543,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. datacenter.SerializeToStream(data); } editor.putString("datacenters", Base64.encodeToString(data.toByteArray(), Base64.DEFAULT)); + data.cleanup(); } else { editor.remove("datacenters"); } @@ -641,8 +646,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. int lastClassGuid = 1; public int generateClassGuid() { int guid = lastClassGuid++; - ArrayList requests = new ArrayList<>(); - requestsByGuids.put(guid, requests); + requestsByGuids.put(guid, new ArrayList()); return guid; } @@ -763,8 +767,12 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. return; } if (error == null) { - lastDcUpdateTime = (int)(System.currentTimeMillis() / 1000); TLRPC.TL_config config = (TLRPC.TL_config)response; + int updateIn = config.expires - getCurrentTime(); + if (updateIn <= 0) { + updateIn = 120; + } + lastDcUpdateTime = (int)(System.currentTimeMillis() / 1000) - DC_UPDATE_TIME + updateIn; ArrayList datacentersArr = new ArrayList<>(); HashMap datacenterMap = new HashMap<>(); for (TLRPC.TL_dcOption datacenterDesc : config.dc_options) { @@ -1029,11 +1037,6 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. for (int i = 0; i < runningRequests.size(); i++) { RPCRequest request = runningRequests.get(i); - if (UserConfig.waitingForPasswordEnter && (request.flags & RPCRequest.RPCRequestClassWithoutLogin) == 0) { - FileLog.e("tmessages", "skip request " + request.rawRequest + ", need password enter"); - continue; - } - int datacenterId = request.runningDatacenterId; if (datacenterId == DEFAULT_DATACENTER_ID) { if (movingToDatacenterId != DEFAULT_DATACENTER_ID) { @@ -1236,11 +1239,6 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. continue; } - if (UserConfig.waitingForPasswordEnter && (request.flags & RPCRequest.RPCRequestClassWithoutLogin) == 0) { - FileLog.e("tmessages", "skip request " + request.rawRequest + ", need password enter"); - continue; - } - int datacenterId = request.runningDatacenterId; if (datacenterId == DEFAULT_DATACENTER_ID) { if (movingToDatacenterId != DEFAULT_DATACENTER_ID && (request.flags & RPCRequest.RPCRequestClassEnableUnauthorized) == 0) { @@ -1338,6 +1336,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. if (canCompress) { try { byte[] data = Utilities.compress(os.toByteArray()); + os.cleanup(); if (data.length < requestLength) { TLRPC.TL_gzip_packed packed = new TLRPC.TL_gzip_packed(); packed.packed_data = data; @@ -1345,6 +1344,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. os = new SerializedData(true); packed.serializeToStream(os); requestLength = os.length(); + os.cleanup(); } } catch (Exception e) { FileLog.e("tmessages", e); @@ -1406,6 +1406,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. if (rawRequest != null && (rawRequest instanceof TLRPC.TL_messages_sendMessage || rawRequest instanceof TLRPC.TL_messages_sendMedia || rawRequest instanceof TLRPC.TL_messages_forwardMessages || + rawRequest instanceof TLRPC.TL_messages_forwardMessage || rawRequest instanceof TLRPC.TL_messages_sendEncrypted || rawRequest instanceof TLRPC.TL_messages_sendEncryptedFile || rawRequest instanceof TLRPC.TL_messages_sendEncryptedService)) { @@ -1426,6 +1427,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. if (currentRawRequest instanceof TLRPC.TL_messages_sendMessage || currentRawRequest instanceof TLRPC.TL_messages_sendMedia || currentRawRequest instanceof TLRPC.TL_messages_forwardMessages || + currentRawRequest instanceof TLRPC.TL_messages_forwardMessage || currentRawRequest instanceof TLRPC.TL_messages_sendEncrypted || currentRawRequest instanceof TLRPC.TL_messages_sendEncryptedFile || currentRawRequest instanceof TLRPC.TL_messages_sendEncryptedService) { @@ -1438,6 +1440,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. if (request.rawRequest instanceof TLRPC.TL_messages_sendMessage || request.rawRequest instanceof TLRPC.TL_messages_sendMedia || request.rawRequest instanceof TLRPC.TL_messages_forwardMessages || + request.rawRequest instanceof TLRPC.TL_messages_forwardMessage || request.rawRequest instanceof TLRPC.TL_messages_sendEncrypted || request.rawRequest instanceof TLRPC.TL_messages_sendEncryptedFile || request.rawRequest instanceof TLRPC.TL_messages_sendEncryptedService) { @@ -1720,6 +1723,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. if (quickAckId != null) { SerializedData data = new SerializedData(messageKeyFull); quickAckId.add(data.readInt32() & 0x7fffffff); + data.cleanup(); } MessageKeyData keyData = Utilities.generateMessageKeyData(datacenter.authKey, messageKey, false); @@ -2140,7 +2144,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. implicitError.code = ((TLRPC.RpcError)resultContainer.result).error_code; implicitError.text = ((TLRPC.RpcError)resultContainer.result).error_message; } else if (!(resultContainer.result instanceof TLRPC.TL_error)) { - if (request.rawRequest == null || !request.rawRequest.responseClass().isAssignableFrom(resultContainer.result.getClass())) { + if (request.rawRequest == null || resultContainer.result == null || !request.rawRequest.responseClass().isAssignableFrom(resultContainer.result.getClass())) { if (request.rawRequest == null) { FileLog.e("tmessages", "rawRequest is null"); } else { @@ -2169,10 +2173,6 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } }); } - if (request.rawRequest instanceof TLRPC.TL_auth_checkPassword) { - UserConfig.setWaitingForPasswordEnter(false); - UserConfig.saveConfig(false); - } request.completionBlock.run(resultContainer.result, null); } } @@ -2180,7 +2180,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. if (implicitError != null && implicitError.code == 401) { isError = true; if (implicitError.text != null && implicitError.text.contains("SESSION_PASSWORD_NEEDED")) { - UserConfig.setWaitingForPasswordEnter(true); + /*UserConfig.setWaitingForPasswordEnter(true); TODO UserConfig.saveConfig(false); if (UserConfig.isClientActivated()) { discardResponse = true; @@ -2190,7 +2190,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. NotificationCenter.getInstance().postNotificationName(NotificationCenter.needPasswordEnter); } }); - } + }*/ } else if (datacenter.datacenterId == currentDatacenterId || datacenter.datacenterId == movingToDatacenterId) { if ((request.flags & RPCRequest.RPCRequestClassGeneric) != 0 && UserConfig.isClientActivated()) { UserConfig.clearConfig(); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java index 462098cc7..62f217442 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java @@ -54,10 +54,10 @@ public class FileLoadOperation { private File tempPath = null; private boolean isForceRequest = false; - public static interface FileLoadOperationDelegate { - public abstract void didFinishLoadingFile(FileLoadOperation operation, File finalFile); - public abstract void didFailedLoadingFile(FileLoadOperation operation, int state); - public abstract void didChangedLoadProgress(FileLoadOperation operation, float progress); + public interface FileLoadOperationDelegate { + void didFinishLoadingFile(FileLoadOperation operation, File finalFile); + void didFailedLoadingFile(FileLoadOperation operation, int state); + void didChangedLoadProgress(FileLoadOperation operation, float progress); } public FileLoadOperation(TLRPC.FileLocation photoLocation, int size) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java index b0e1ac4e9..af3ae922c 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java @@ -19,13 +19,13 @@ import java.util.concurrent.Semaphore; public class FileLoader { - public static interface FileLoaderDelegate { - public abstract void fileUploadProgressChanged(String location, float progress, boolean isEncrypted); - public abstract void fileDidUploaded(String location, TLRPC.InputFile inputFile, TLRPC.InputEncryptedFile inputEncryptedFile); - public abstract void fileDidFailedUpload(String location, boolean isEncrypted); - public abstract void fileDidLoaded(String location, File finalFile, int type); - public abstract void fileDidFailedLoad(String location, int state); - public abstract void fileLoadProgressChanged(String location, float progress); + public interface FileLoaderDelegate { + void fileUploadProgressChanged(String location, float progress, boolean isEncrypted); + void fileDidUploaded(String location, TLRPC.InputFile inputFile, TLRPC.InputEncryptedFile inputEncryptedFile); + void fileDidFailedUpload(String location, boolean isEncrypted); + void fileDidLoaded(String location, File finalFile, int type); + void fileDidFailedLoad(String location, int state); + void fileLoadProgressChanged(String location, float progress); } public static final int MEDIA_DIR_IMAGE = 0; @@ -132,6 +132,9 @@ public class FileLoader { } public void uploadFile(final String location, final boolean encrypted, final boolean small, final int estimatedSize) { + if (location == null) { + return; + } fileLoaderQueue.postRunnable(new Runnable() { @Override public void run() { @@ -628,7 +631,7 @@ public class FileLoader { } public static TLRPC.PhotoSize getClosestPhotoSizeWithSize(ArrayList sizes, int side) { - if (sizes == null) { + if (sizes == null || sizes.isEmpty()) { return null; } int lastSide = 0; @@ -638,7 +641,7 @@ public class FileLoader { continue; } int currentSide = obj.w >= obj.h ? obj.w : obj.h; - if (closestObject == null || obj instanceof TLRPC.TL_photoCachedSize || currentSide <= side && lastSide < currentSide) { + if (closestObject == null || side > 100 && closestObject.location != null && closestObject.location.dc_id == Integer.MIN_VALUE || obj instanceof TLRPC.TL_photoCachedSize || currentSide <= side && lastSide < currentSide) { closestObject = obj; lastSide = currentSide; } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java index 3d01798f4..e72408acc 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java @@ -181,7 +181,7 @@ public class FileLog { } public static void cleanupLogs() { - ArrayList uris = new ArrayList(); + ArrayList uris = new ArrayList<>(); File sdCard = ApplicationLoader.applicationContext.getExternalFilesDir(null); File dir = new File (sdCard.getAbsolutePath() + "/logs"); File[] files = dir.listFiles(); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java index 157103bec..788a202a4 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java @@ -45,10 +45,10 @@ public class FileUploadOperation { private MessageDigest mdEnc = null; private boolean started = false; - public static interface FileUploadOperationDelegate { - public abstract void didFinishUploadingFile(FileUploadOperation operation, TLRPC.InputFile inputFile, TLRPC.InputEncryptedFile inputEncryptedFile); - public abstract void didFailedUploadingFile(FileUploadOperation operation); - public abstract void didChangedUploadProgress(FileUploadOperation operation, float progress); + public interface FileUploadOperationDelegate { + void didFinishUploadingFile(FileUploadOperation operation, TLRPC.InputFile inputFile, TLRPC.InputEncryptedFile inputEncryptedFile); + void didFailedUploadingFile(FileUploadOperation operation); + void didChangedUploadProgress(FileUploadOperation operation, float progress); } public FileUploadOperation(String location, boolean encrypted, int estimated) { @@ -91,6 +91,14 @@ public class FileUploadOperation { remove(fileKey + "_iv"). remove(fileKey + "_key"). remove(fileKey + "_ivc").commit(); + try { + if (stream != null) { + stream.close(); + stream = null; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } } protected void checkNewDataAvailable(final long finalSize) { @@ -100,7 +108,7 @@ public class FileUploadOperation { if (estimatedSize != 0 && finalSize != 0) { estimatedSize = 0; totalFileSize = finalSize; - totalPartsCount = (int) Math.ceil((float) totalFileSize / (float) uploadChunkSize); + totalPartsCount = (int) (totalFileSize + uploadChunkSize - 1) / uploadChunkSize; if (started) { SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("uploadinfo", Activity.MODE_PRIVATE); storeFileUploadInfo(preferences); @@ -154,7 +162,7 @@ public class FileUploadOperation { } } - uploadChunkSize = (int) Math.max(32, Math.ceil(totalFileSize / (1024.0f * 3000))); + uploadChunkSize = (int) Math.max(32, (totalFileSize + 1024 * 3000 - 1) / (1024 * 3000)); if (1024 % uploadChunkSize != 0) { int chunkSize = 64; while (uploadChunkSize > chunkSize) { @@ -164,7 +172,7 @@ public class FileUploadOperation { } uploadChunkSize *= 1024; - totalPartsCount = (int) Math.ceil((float) totalFileSize / (float) uploadChunkSize); + totalPartsCount = (int) (totalFileSize + uploadChunkSize - 1) / uploadChunkSize; readBuffer = new byte[uploadChunkSize]; fileKey = Utilities.MD5(uploadingFilePath + (isEncrypted ? "enc" : "")); @@ -347,7 +355,7 @@ public class FileUploadOperation { if (error == null) { if (response instanceof TLRPC.TL_boolTrue) { currentPartNum++; - delegate.didChangedUploadProgress(FileUploadOperation.this, (float) currentUploaded / (float) totalFileSize); + delegate.didChangedUploadProgress(FileUploadOperation.this, currentUploaded / (float) totalFileSize); if (isLastPart) { state = 3; if (key == null) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/HandshakeAction.java b/TMessagesProj/src/main/java/org/telegram/messenger/HandshakeAction.java index 770dbd6f3..dc5f426d1 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/HandshakeAction.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/HandshakeAction.java @@ -55,7 +55,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti } datacenter.connection.delegate = this; - processedMessageIds = new ArrayList(); + processedMessageIds = new ArrayList<>(); authNonce = null; authServerNonce = null; authNewNonce = null; @@ -92,10 +92,10 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti HashMap selectPublicKey(ArrayList fingerprints) { synchronized (lock) { if (serverPublicKeys == null) { - serverPublicKeys = new ArrayList>(); + serverPublicKeys = new ArrayList<>(); HashMap map; - map = new HashMap(); + map = new HashMap<>(); map.put("key", new BigInteger[]{ new BigInteger("c150023e2f70db7985ded064759cfecf0af328e69a41daf4d6f01b538135" + "a6f91f8f8b2a0ec9ba9720ce352efcf6c5680ffc424bd634864902de0b4bd6d49f4e580230e" + @@ -108,7 +108,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti map.put("fingerprint", 0xc3b42b026ce86b21L); serverPublicKeys.add(map); - map = new HashMap(); + map = new HashMap<>(); map.put("key", new BigInteger[]{ new BigInteger("c6aeda78b02a251db4b6441031f467fa871faed32526c436524b1fb3b5dc" + "a28efb8c089dd1b46d92c895993d87108254951c5f001a0f055f3063dcd14d431a300eb9e29" + @@ -121,7 +121,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti map.put("fingerprint", 0x9a996a1db11c729bL); serverPublicKeys.add(map); - map = new HashMap(); + map = new HashMap<>(); map.put("key", new BigInteger[]{ new BigInteger("b1066749655935f0a5936f517034c943bea7f3365a8931ae52c8bcb14856" + "f004b83d26cf2839be0f22607470d67481771c1ce5ec31de16b20bbaa4ecd2f7d2ecf6b6356" + @@ -134,7 +134,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti map.put("fingerprint", 0xb05b2a6f70cdea78L); serverPublicKeys.add(map); - map = new HashMap(); + map = new HashMap<>(); map.put("key", new BigInteger[]{ new BigInteger("c2a8c55b4a62e2b78a19b91cf692bcdc4ba7c23fe4d06f194e2a0c30f6d9" + "996f7d1a2bcc89bc1ac4333d44359a6c433252d1a8402d9970378b5912b75bc8cc3fa76710a" + @@ -190,7 +190,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti if (message instanceof TLRPC.TL_resPQ) { if (processedPQRes) { TLRPC.TL_msgs_ack msgsAck = new TLRPC.TL_msgs_ack(); - msgsAck.msg_ids = new ArrayList(); + msgsAck.msg_ids = new ArrayList<>(); msgsAck.msg_ids.add(messageId); sendMessageData(msgsAck, generateMessageId()); return; @@ -250,6 +250,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti innerData.serializeToStream(os); byte[] innerDataBytes = os.toByteArray(); + os.cleanup(); SerializedData dataWithHash = new SerializedData(); dataWithHash.writeRaw(Utilities.computeSHA1(innerDataBytes)); @@ -261,6 +262,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti } byte[] encryptedBytes = Utilities.encryptWithRSA((BigInteger[])publicKey.get("key"), dataWithHash.toByteArray()); + dataWithHash.cleanup(); SerializedData encryptedData = new SerializedData(); encryptedData.writeRaw(encryptedBytes); if (encryptedData.length() < 256) { @@ -269,12 +271,14 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti newEncryptedData.writeByte(0); } newEncryptedData.writeRaw(encryptedData.toByteArray()); + encryptedData.cleanup(); encryptedData = newEncryptedData; } reqDH.encrypted_data = encryptedData.toByteArray(); + encryptedData.cleanup(); TLRPC.TL_msgs_ack msgsAck = new TLRPC.TL_msgs_ack(); - msgsAck.msg_ids = new ArrayList(); + msgsAck.msg_ids = new ArrayList<>(); msgsAck.msg_ids.add(messageIdf); sendMessageData(msgsAck, generateMessageId()); @@ -305,8 +309,10 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti serverNonceAndNewNonce.writeRaw(authServerNonce); serverNonceAndNewNonce.writeRaw(authNewNonce); tmpAesKey.writeRaw(Utilities.computeSHA1(newNonceAndServerNonce.toByteArray())); + newNonceAndServerNonce.cleanup(); byte[] serverNonceAndNewNonceHash = Utilities.computeSHA1(serverNonceAndNewNonce.toByteArray()); + serverNonceAndNewNonce.cleanup(); byte[] serverNonceAndNewNonceHash0_12 = new byte[12]; System.arraycopy(serverNonceAndNewNonceHash, 0, serverNonceAndNewNonceHash0_12, 0, 12); @@ -322,6 +328,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti newNonceAndNewNonce.writeRaw(authNewNonce); newNonceAndNewNonce.writeRaw(authNewNonce); tmpAesIv.writeRaw(Utilities.computeSHA1(newNonceAndNewNonce.toByteArray())); + newNonceAndNewNonce.cleanup(); byte[] newNonce0_4 = new byte[4]; System.arraycopy(authNewNonce, 0, newNonce0_4, 0, 4); @@ -417,6 +424,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti serverSaltData.writeByte(x); } ByteBuffer saltBuffer = ByteBuffer.wrap(serverSaltData.toByteArray()); + serverSaltData.cleanup(); timeDifference = dhInnerData.server_time - (int)(System.currentTimeMillis() / 1000); @@ -455,8 +463,11 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti Utilities.aesIgeEncryption(clientDataWithHash.buffer, tmpAesKey.toByteArray(), tmpAesIv.toByteArray(), true, false, 0, clientDataWithHash.length()); setClientDhParams.encrypted_data = clientDataWithHash; + tmpAesKey.cleanup(); + tmpAesIv.cleanup(); + TLRPC.TL_msgs_ack msgsAck = new TLRPC.TL_msgs_ack(); - msgsAck.msg_ids = new ArrayList(); + msgsAck.msg_ids = new ArrayList<>(); msgsAck.msg_ids.add(messageId); sendMessageData(msgsAck, generateMessageId()); @@ -494,7 +505,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti } TLRPC.TL_msgs_ack msgsAck = new TLRPC.TL_msgs_ack(); - msgsAck.msg_ids = new ArrayList(); + msgsAck.msg_ids = new ArrayList<>(); msgsAck.msg_ids.add(messageId); sendMessageData(msgsAck, generateMessageId()); @@ -507,6 +518,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti newNonce1.writeByte(1); newNonce1.writeRaw(authKeyAuxHash); byte[] newNonceHash1Full = Utilities.computeSHA1(newNonce1.toByteArray()); + newNonce1.cleanup(); byte[] newNonceHash1 = new byte[16]; System.arraycopy(newNonceHash1Full, newNonceHash1Full.length - 16, newNonceHash1, 0, 16); @@ -515,6 +527,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti newNonce2.writeByte(2); newNonce2.writeRaw(authKeyAuxHash); byte[] newNonceHash2Full = Utilities.computeSHA1(newNonce2.toByteArray()); + newNonce2.cleanup(); byte[] newNonceHash2 = new byte[16]; System.arraycopy(newNonceHash2Full, newNonceHash2Full.length - 16, newNonceHash2, 0, 16); @@ -523,6 +536,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti newNonce3.writeByte(3); newNonce3.writeRaw(authKeyAuxHash); byte[] newNonceHash3Full = Utilities.computeSHA1(newNonce3.toByteArray()); + newNonce3.cleanup(); byte[] newNonceHash3 = new byte[16]; System.arraycopy(newNonceHash3Full, newNonceHash3Full.length - 16, newNonceHash3, 0, 16); @@ -544,7 +558,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti datacenter.authKey = authKey; datacenter.authKeyId = authKeyId; datacenter.addServerSalt(serverSalt); - HashMap resultDict = new HashMap(); + HashMap resultDict = new HashMap<>(); resultDict.put("timeDifference", timeDifference); if (delegate != null) { delegate.ActionDidFinishExecution(parent, resultDict); @@ -575,7 +589,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti } } else { TLRPC.TL_msgs_ack msgsAck = new TLRPC.TL_msgs_ack(); - msgsAck.msg_ids = new ArrayList(); + msgsAck.msg_ids = new ArrayList<>(); msgsAck.msg_ids.add(messageId); sendMessageData(msgsAck, generateMessageId()); } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java b/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java index 4e7454e07..180c9446b 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java @@ -63,7 +63,7 @@ public class RPCRequest { boolean initRequest = false; - ArrayList respondsToMessageIds = new ArrayList(); + ArrayList respondsToMessageIds = new ArrayList<>(); public void addRespondMessageId(long messageId) { respondsToMessageIds.add(messageId); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/SerializedData.java b/TMessagesProj/src/main/java/org/telegram/messenger/SerializedData.java index 59b59e6d5..40847dabb 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/SerializedData.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/SerializedData.java @@ -49,6 +49,41 @@ public class SerializedData extends AbsSerializedData { in = new DataInputStream(inbuf); } + public void cleanup() { + try { + if (inbuf != null) { + inbuf.close(); + inbuf = null; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + try { + if (in != null) { + in.close(); + in = null; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + try { + if (outbuf != null) { + outbuf.close(); + outbuf = null; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + try { + if (out != null) { + out.close(); + out = null; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + public SerializedData(File file) throws Exception { FileInputStream is = new FileInputStream(file); byte[] data = new byte[(int)file.length()]; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/TLClassStore.java b/TMessagesProj/src/main/java/org/telegram/messenger/TLClassStore.java index 6d51db703..c3e862ad6 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/TLClassStore.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/TLClassStore.java @@ -61,7 +61,6 @@ public class TLClassStore { classStore.put(TLRPC.TL_account_privacyRules.constructor, TLRPC.TL_account_privacyRules.class); classStore.put(TLRPC.TL_help_appUpdate.constructor, TLRPC.TL_help_appUpdate.class); classStore.put(TLRPC.TL_help_noAppUpdate.constructor, TLRPC.TL_help_noAppUpdate.class); - classStore.put(TLRPC.TL_messageForwarded.constructor, TLRPC.TL_messageForwarded.class); classStore.put(TLRPC.TL_messageEmpty.constructor, TLRPC.TL_messageEmpty.class); classStore.put(TLRPC.TL_message.constructor, TLRPC.TL_message.class); classStore.put(TLRPC.TL_messageService.constructor, TLRPC.TL_messageService.class); @@ -125,8 +124,6 @@ public class TLClassStore { classStore.put(TLRPC.TL_boolTrue.constructor, TLRPC.TL_boolTrue.class); classStore.put(TLRPC.TL_boolFalse.constructor, TLRPC.TL_boolFalse.class); classStore.put(TLRPC.TL_auth_exportedAuthorization.constructor, TLRPC.TL_auth_exportedAuthorization.class); - classStore.put(TLRPC.TL_messages_statedMessagesLinks.constructor, TLRPC.TL_messages_statedMessagesLinks.class); - classStore.put(TLRPC.TL_messages_statedMessages.constructor, TLRPC.TL_messages_statedMessages.class); classStore.put(TLRPC.TL_inputNotifyChats.constructor, TLRPC.TL_inputNotifyChats.class); classStore.put(TLRPC.TL_inputNotifyPeer.constructor, TLRPC.TL_inputNotifyPeer.class); classStore.put(TLRPC.TL_inputNotifyUsers.constructor, TLRPC.TL_inputNotifyUsers.class); @@ -157,9 +154,6 @@ public class TLClassStore { classStore.put(TLRPC.TL_messageActionChatEditTitle.constructor, TLRPC.TL_messageActionChatEditTitle.class); classStore.put(TLRPC.TL_messageActionGeoChatCreate.constructor, TLRPC.TL_messageActionGeoChatCreate.class); classStore.put(TLRPC.TL_messageActionGeoChatCheckin.constructor, TLRPC.TL_messageActionGeoChatCheckin.class); - classStore.put(TLRPC.TL_contacts_foreignLinkMutual.constructor, TLRPC.TL_contacts_foreignLinkMutual.class); - classStore.put(TLRPC.TL_contacts_foreignLinkUnknown.constructor, TLRPC.TL_contacts_foreignLinkUnknown.class); - classStore.put(TLRPC.TL_contacts_foreignLinkRequested.constructor, TLRPC.TL_contacts_foreignLinkRequested.class); classStore.put(TLRPC.TL_dh_gen_retry.constructor, TLRPC.TL_dh_gen_retry.class); classStore.put(TLRPC.TL_dh_gen_fail.constructor, TLRPC.TL_dh_gen_fail.class); classStore.put(TLRPC.TL_dh_gen_ok.constructor, TLRPC.TL_dh_gen_ok.class); @@ -216,12 +210,12 @@ public class TLClassStore { classStore.put(TLRPC.TL_userStatusRecently.constructor, TLRPC.TL_userStatusRecently.class); classStore.put(TLRPC.TL_msg_copy.constructor, TLRPC.TL_msg_copy.class); classStore.put(TLRPC.TL_contacts_importedContacts.constructor, TLRPC.TL_contacts_importedContacts.class); + classStore.put(TLRPC.TL_disabledFeature.constructor, TLRPC.TL_disabledFeature.class); classStore.put(TLRPC.TL_futureSalt.constructor, TLRPC.TL_futureSalt.class); classStore.put(TLRPC.TL_updateEncryptedMessagesRead.constructor, TLRPC.TL_updateEncryptedMessagesRead.class); classStore.put(TLRPC.TL_updateContactLink.constructor, TLRPC.TL_updateContactLink.class); classStore.put(TLRPC.TL_updateReadMessages.constructor, TLRPC.TL_updateReadMessages.class); classStore.put(TLRPC.TL_updateChatParticipantDelete.constructor, TLRPC.TL_updateChatParticipantDelete.class); - classStore.put(TLRPC.TL_updateRestoreMessages.constructor, TLRPC.TL_updateRestoreMessages.class); classStore.put(TLRPC.TL_updateServiceNotification.constructor, TLRPC.TL_updateServiceNotification.class); classStore.put(TLRPC.TL_updateNotifySettings.constructor, TLRPC.TL_updateNotifySettings.class); classStore.put(TLRPC.TL_updateUserTyping.constructor, TLRPC.TL_updateUserTyping.class); @@ -259,9 +253,6 @@ public class TLClassStore { classStore.put(TLRPC.TL_decryptedMessageActionTyping.constructor, TLRPC.TL_decryptedMessageActionTyping.class); classStore.put(TLRPC.TL_decryptedMessageActionReadMessages.constructor, TLRPC.TL_decryptedMessageActionReadMessages.class); classStore.put(TLRPC.TL_decryptedMessageActionScreenshotMessages.constructor, TLRPC.TL_decryptedMessageActionScreenshotMessages.class); - classStore.put(TLRPC.TL_contacts_myLinkRequested.constructor, TLRPC.TL_contacts_myLinkRequested.class); - classStore.put(TLRPC.TL_contacts_myLinkContact.constructor, TLRPC.TL_contacts_myLinkContact.class); - classStore.put(TLRPC.TL_contacts_myLinkEmpty.constructor, TLRPC.TL_contacts_myLinkEmpty.class); classStore.put(TLRPC.TL_server_DH_inner_data.constructor, TLRPC.TL_server_DH_inner_data.class); classStore.put(TLRPC.TL_new_session_created.constructor, TLRPC.TL_new_session_created.class); classStore.put(TLRPC.TL_account_password.constructor, TLRPC.TL_account_password.class); @@ -329,8 +320,6 @@ public class TLClassStore { classStore.put(TLRPC.TL_contactFound.constructor, TLRPC.TL_contactFound.class); classStore.put(TLRPC.TL_inputFileBig.constructor, TLRPC.TL_inputFileBig.class); classStore.put(TLRPC.TL_inputFile.constructor, TLRPC.TL_inputFile.class); - classStore.put(TLRPC.TL_messages_statedMessageLink.constructor, TLRPC.TL_messages_statedMessageLink.class); - classStore.put(TLRPC.TL_messages_statedMessage.constructor, TLRPC.TL_messages_statedMessage.class); classStore.put(TLRPC.TL_userFull.constructor, TLRPC.TL_userFull.class); classStore.put(TLRPC.TL_updates_state.constructor, TLRPC.TL_updates_state.class); classStore.put(TLRPC.TL_resPQ.constructor, TLRPC.TL_resPQ.class); @@ -340,7 +329,6 @@ public class TLClassStore { classStore.put(TLRPC.TL_updateShort.constructor, TLRPC.TL_updateShort.class); classStore.put(TLRPC.TL_updatesCombined.constructor, TLRPC.TL_updatesCombined.class); classStore.put(TLRPC.TL_updatesTooLong.constructor, TLRPC.TL_updatesTooLong.class); - classStore.put(TLRPC.TL_messages_chat.constructor, TLRPC.TL_messages_chat.class); classStore.put(TLRPC.TL_wallPaper.constructor, TLRPC.TL_wallPaper.class); classStore.put(TLRPC.TL_wallPaperSolid.constructor, TLRPC.TL_wallPaperSolid.class); classStore.put(TLRPC.TL_msg_new_detailed_info.constructor, TLRPC.TL_msg_new_detailed_info.class); @@ -378,7 +366,27 @@ public class TLClassStore { classStore.put(TLRPC.TL_decryptedMessageActionAbortKey.constructor, TLRPC.TL_decryptedMessageActionAbortKey.class); classStore.put(TLRPC.TL_decryptedMessageActionNoop.constructor, TLRPC.TL_decryptedMessageActionNoop.class); classStore.put(TLRPC.TL_decryptedMessageMediaExternalDocument.constructor, TLRPC.TL_decryptedMessageMediaExternalDocument.class); + classStore.put(TLRPC.TL_updateReadHistoryInbox.constructor, TLRPC.TL_updateReadHistoryInbox.class); + classStore.put(TLRPC.TL_updateReadHistoryOutbox.constructor, TLRPC.TL_updateReadHistoryOutbox.class); + classStore.put(TLRPC.TL_contactLinkUnknown.constructor, TLRPC.TL_contactLinkUnknown.class); + classStore.put(TLRPC.TL_contactLinkNone.constructor, TLRPC.TL_contactLinkNone.class); + classStore.put(TLRPC.TL_contactLinkHasPhone.constructor, TLRPC.TL_contactLinkHasPhone.class); + classStore.put(TLRPC.TL_contactLinkContact.constructor, TLRPC.TL_contactLinkContact.class); + classStore.put(TLRPC.TL_messages_affectedMessages.constructor, TLRPC.TL_messages_affectedMessages.class); + classStore.put(TLRPC.TL_updateWebPage.constructor, TLRPC.TL_updateWebPage.class); + classStore.put(TLRPC.TL_webPagePending.constructor, TLRPC.TL_webPagePending.class); + classStore.put(TLRPC.TL_webPageEmpty.constructor, TLRPC.TL_webPageEmpty.class); + classStore.put(TLRPC.TL_webPage.constructor, TLRPC.TL_webPage.class); + classStore.put(TLRPC.TL_messageMediaWebPage.constructor, TLRPC.TL_messageMediaWebPage.class); + classStore.put(TLRPC.TL_authorization.constructor, TLRPC.TL_authorization.class); + classStore.put(TLRPC.TL_account_authorizations.constructor, TLRPC.TL_account_authorizations.class); + classStore.put(TLRPC.TL_account_passwordSettings.constructor, TLRPC.TL_account_passwordSettings.class); + classStore.put(TLRPC.TL_account_passwordInputSettings.constructor, TLRPC.TL_account_passwordInputSettings.class); + classStore.put(TLRPC.TL_auth_passwordRecovery.constructor, TLRPC.TL_auth_passwordRecovery.class); + classStore.put(TLRPC.TL_messages_getWebPagePreview.constructor, TLRPC.TL_messages_getWebPagePreview.class); + classStore.put(TLRPC.TL_messageMediaUnsupported_old.constructor, TLRPC.TL_messageMediaUnsupported_old.class); + classStore.put(TLRPC.TL_userSelf_old2.constructor, TLRPC.TL_userSelf_old2.class); classStore.put(TLRPC.TL_msg_container.constructor, TLRPC.TL_msg_container.class); classStore.put(TLRPC.TL_fileEncryptedLocation.constructor, TLRPC.TL_fileEncryptedLocation.class); classStore.put(TLRPC.TL_messageActionTTLChange.constructor, TLRPC.TL_messageActionTTLChange.class); @@ -413,6 +421,10 @@ public class TLClassStore { classStore.put(TLRPC.TL_decryptedMessageHolder.constructor, TLRPC.TL_decryptedMessageHolder.class); classStore.put(TLRPC.TL_documentEncrypted_old.constructor, TLRPC.TL_documentEncrypted_old.class); classStore.put(TLRPC.TL_document_old.constructor, TLRPC.TL_document_old.class); + classStore.put(TLRPC.TL_config_old.constructor, TLRPC.TL_config_old.class); + classStore.put(TLRPC.TL_messageForwarded_old2.constructor, TLRPC.TL_messageForwarded_old2.class); + classStore.put(TLRPC.TL_message_old2.constructor, TLRPC.TL_message_old2.class); + classStore.put(TLRPC.TL_documentAttributeSticker_old.constructor, TLRPC.TL_documentAttributeSticker_old.class); } static TLClassStore store = null; @@ -459,8 +471,11 @@ public class TLClassStore { } } else { FileLog.e("tmessages", String.format("unknown class %x", constructor)); - return null; - //throw new RuntimeException(String.format("unknown class %x", constructor)); + if (BuildVars.DEBUG_VERSION) { + throw new RuntimeException(String.format("unknown class %x", constructor)); + } else { + return null; + } } } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java b/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java index 2348395b5..0789e6cbe 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java @@ -16,7 +16,10 @@ public class TLRPC { public static final int MESSAGE_FLAG_UNREAD = 1; public static final int MESSAGE_FLAG_OUT = 2; - public static final int LAYER = 22; + public static final int MESSAGE_FLAG_FWD = 4; + public static final int MESSAGE_FLAG_REPLY = 8; + public static final int MESSAGE_FLAG_MENTION = 16; + public static final int LAYER = 27; public static class ChatPhoto extends TLObject { public FileLocation photo_small; @@ -192,20 +195,17 @@ public class TLRPC { } public static class TL_auth_checkedPhone extends TLObject { - public static int constructor = 0xe300cc3b; + public static int constructor = 0x811ea28e; public boolean phone_registered; - public boolean phone_invited; public void readParams(AbsSerializedData stream) { phone_registered = stream.readBool(); - phone_invited = stream.readBool(); } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); stream.writeBool(phone_registered); - stream.writeBool(phone_invited); } } @@ -272,9 +272,25 @@ public class TLRPC { } } + public static class TL_account_passwordSettings extends TLObject { + public static int constructor = 0xb7b72ab3; + + public String email; + + public void readParams(AbsSerializedData stream) { + email = stream.readString(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeString(email); + } + } + public static class DocumentAttribute extends TLObject { public int duration; public String file_name; + public String alt; public int w; public int h; } @@ -335,11 +351,16 @@ public class TLRPC { } public static class TL_documentAttributeSticker extends DocumentAttribute { - public static int constructor = 0xfb0a5727; + public static int constructor = 0x994c9882; + public void readParams(AbsSerializedData stream) { + alt = stream.readString(); + } + public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); + stream.writeString(alt); } } @@ -537,15 +558,15 @@ public class TLRPC { } public static class TL_contacts_link extends TLObject { - public static int constructor = 0xeccea3f5; + public static int constructor = 0x3ace484c; - public contacts_MyLink my_link; - public contacts_ForeignLink foreign_link; + public ContactLink my_link; + public ContactLink foreign_link; public User user; public void readParams(AbsSerializedData stream) { - my_link = (contacts_MyLink)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); - foreign_link = (contacts_ForeignLink)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); + my_link = (ContactLink)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); + foreign_link = (ContactLink)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); user = (User)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); } @@ -629,6 +650,75 @@ public class TLRPC { } } + public static class TL_messages_affectedMessages extends TLObject { + public static int constructor = 0x84d19185; + + public int pts; + public int pts_count; + + public void readParams(AbsSerializedData stream) { + pts = stream.readInt32(); + pts_count = stream.readInt32(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(pts); + stream.writeInt32(pts_count); + } + } + + public static class TL_authorization extends TLObject { + public static int constructor = 0x7bf2e6f6; + + public long hash; + public int flags; + public String device_model; + public String platform; + public String system_version; + public int api_id; + public String app_name; + public String app_version; + public int date_created; + public int date_active; + public String ip; + public String country; + public String region; + + public void readParams(AbsSerializedData stream) { + hash = stream.readInt64(); + flags = stream.readInt32(); + device_model = stream.readString(); + platform = stream.readString(); + system_version = stream.readString(); + api_id = stream.readInt32(); + app_name = stream.readString(); + app_version = stream.readString(); + date_created = stream.readInt32(); + date_active = stream.readInt32(); + ip = stream.readString(); + country = stream.readString(); + region = stream.readString(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt64(hash); + stream.writeInt32(flags); + stream.writeString(device_model); + stream.writeString(platform); + stream.writeString(system_version); + stream.writeInt32(api_id); + stream.writeString(app_name); + stream.writeString(app_version); + stream.writeInt32(date_created); + stream.writeInt32(date_active); + stream.writeString(ip); + stream.writeString(country); + stream.writeString(region); + } + } + public static class DestroySessionRes extends TLObject { public long session_id; } @@ -1090,6 +1180,7 @@ public class TLRPC { public static class MessageMedia extends TLObject { public Video video; public Photo photo; + public WebPage webpage; public Document document; public GeoPoint geo; public Audio audio; @@ -1128,6 +1219,20 @@ public class TLRPC { } } + public static class TL_messageMediaWebPage extends MessageMedia { + public static int constructor = 0xa32dd600; + + + public void readParams(AbsSerializedData stream) { + webpage = (WebPage)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + webpage.serializeToStream(stream); + } + } + public static class TL_messageMediaDocument extends MessageMedia { public static int constructor = 0x2fda2204; @@ -1200,16 +1305,11 @@ public class TLRPC { } public static class TL_messageMediaUnsupported extends MessageMedia { - public static int constructor = 0x29632a36; + public static int constructor = 0x9f84f49e; - public void readParams(AbsSerializedData stream) { - bytes = stream.readByteArray(); - } - public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); - stream.writeByteArray(bytes); } } @@ -2016,121 +2116,144 @@ public class TLRPC { } } - public static class messages_StatedMessages extends TLObject { - public ArrayList messages = new ArrayList<>(); - public ArrayList chats = new ArrayList<>(); - public ArrayList users = new ArrayList<>(); - public ArrayList links = new ArrayList<>(); - public int pts; - public int seq; + public static class WebPage extends TLObject { + public long id; + public int date; + public int flags; + public String url; + public String display_url; + public String type; + public String site_name; + public String title; + public String description; + public Photo photo; + public String embed_url; + public String embed_type; + public int embed_width; + public int embed_height; + public int duration; + public String author; } - public static class TL_messages_statedMessagesLinks extends messages_StatedMessages { - public static int constructor = 0x3e74f5c6; + public static class TL_webPagePending extends WebPage { + public static int constructor = 0xc586da1c; public void readParams(AbsSerializedData stream) { - stream.readInt32(); - int count = stream.readInt32(); - for (int a = 0; a < count; a++) { - messages.add((Message)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); - } - stream.readInt32(); - count = stream.readInt32(); - for (int a = 0; a < count; a++) { - chats.add((Chat)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); - } - stream.readInt32(); - count = stream.readInt32(); - for (int a = 0; a < count; a++) { - users.add((User)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); - } - stream.readInt32(); - count = stream.readInt32(); - for (int a = 0; a < count; a++) { - links.add((TL_contacts_link)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); - } - pts = stream.readInt32(); - seq = stream.readInt32(); + id = stream.readInt64(); + date = stream.readInt32(); } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); - stream.writeInt32(0x1cb5c415); - int count = messages.size(); - stream.writeInt32(count); - for (int a = 0; a < count; a++) { - messages.get(a).serializeToStream(stream); - } - stream.writeInt32(0x1cb5c415); - count = chats.size(); - stream.writeInt32(count); - for (int a = 0; a < count; a++) { - chats.get(a).serializeToStream(stream); - } - stream.writeInt32(0x1cb5c415); - count = users.size(); - stream.writeInt32(count); - for (int a = 0; a < count; a++) { - users.get(a).serializeToStream(stream); - } - stream.writeInt32(0x1cb5c415); - count = links.size(); - stream.writeInt32(count); - for (int a = 0; a < count; a++) { - links.get(a).serializeToStream(stream); - } - stream.writeInt32(pts); - stream.writeInt32(seq); + stream.writeInt64(id); + stream.writeInt32(date); } } - public static class TL_messages_statedMessages extends messages_StatedMessages { - public static int constructor = 0x969478bb; + public static class TL_webPageEmpty extends WebPage { + public static int constructor = 0xeb1477e8; public void readParams(AbsSerializedData stream) { - stream.readInt32(); - int count = stream.readInt32(); - for (int a = 0; a < count; a++) { - messages.add((Message)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); - } - stream.readInt32(); - count = stream.readInt32(); - for (int a = 0; a < count; a++) { - chats.add((Chat)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); - } - stream.readInt32(); - count = stream.readInt32(); - for (int a = 0; a < count; a++) { - users.add((User)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); - } - pts = stream.readInt32(); - seq = stream.readInt32(); + id = stream.readInt64(); } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); - stream.writeInt32(0x1cb5c415); - int count = messages.size(); - stream.writeInt32(count); - for (int a = 0; a < count; a++) { - messages.get(a).serializeToStream(stream); + stream.writeInt64(id); + } + } + + public static class TL_auth_passwordRecovery extends TLObject { + public static int constructor = 0x137948a5; + + public String email_pattern; + + public void readParams(AbsSerializedData stream) { + email_pattern = stream.readString(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeString(email_pattern); + } + } + + public static class TL_webPage extends WebPage { + public static int constructor = 0xa31ea0b5; + + public void readParams(AbsSerializedData stream) { + flags = stream.readInt32(); + id = stream.readInt64(); + url = stream.readString(); + display_url = stream.readString(); + if ((flags & 1) != 0) { + type = stream.readString(); } - stream.writeInt32(0x1cb5c415); - count = chats.size(); - stream.writeInt32(count); - for (int a = 0; a < count; a++) { - chats.get(a).serializeToStream(stream); + if ((flags & 2) != 0) { + site_name = stream.readString(); } - stream.writeInt32(0x1cb5c415); - count = users.size(); - stream.writeInt32(count); - for (int a = 0; a < count; a++) { - users.get(a).serializeToStream(stream); + if ((flags & 4) != 0) { + title = stream.readString(); + } + if ((flags & 8) != 0) { + description = stream.readString(); + } + if ((flags & 16) != 0) { + photo = (Photo) TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); + } + if ((flags & 32) != 0) { + embed_url = stream.readString(); + embed_type = stream.readString(); + } + if ((flags & 64) != 0) { + embed_width = stream.readInt32(); + embed_height = stream.readInt32(); + } + if ((flags & 128) != 0) { + duration = stream.readInt32(); + } + if ((flags & 256) != 0) { + author = stream.readString(); + } + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(flags); + stream.writeInt64(id); + stream.writeString(url); + stream.writeString(display_url); + if ((flags & 1) != 0) { + stream.writeString(type); + } + if ((flags & 2) != 0) { + stream.writeString(site_name); + } + if ((flags & 4) != 0) { + stream.writeString(title); + } + if ((flags & 8) != 0) { + stream.writeString(description); + } + if ((flags & 16) != 0) { + photo.serializeToStream(stream); + } + if ((flags & 32) != 0) { + stream.writeString(embed_url); + stream.writeString(embed_type); + } + if ((flags & 64) != 0) { + stream.writeInt32(embed_width); + stream.writeInt32(embed_height); + } + if ((flags & 128) != 0) { + stream.writeInt32(duration); + } + if ((flags & 256) != 0) { + stream.writeString(author); } - stream.writeInt32(pts); - stream.writeInt32(seq); } } @@ -2295,7 +2418,7 @@ public class TLRPC { stream.readInt32(); int count = stream.readInt32(); for (int a = 0; a < count; a++) { - users.add((User)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); + users.add((User) TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); } } @@ -2414,7 +2537,7 @@ public class TLRPC { } public static class TL_userSelf extends User { - public static int constructor = 0x7007b451; + public static int constructor = 0x1c60e608; public void readParams(AbsSerializedData stream) { @@ -2425,7 +2548,6 @@ public class TLRPC { phone = stream.readString(); photo = (UserProfilePhoto)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); status = (UserStatus)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); - inactive = stream.readBool(); } public void serializeToStream(AbsSerializedData stream) { @@ -2437,7 +2559,6 @@ public class TLRPC { stream.writeString(phone); photo.serializeToStream(stream); status.serializeToStream(stream); - stream.writeBool(inactive); } } @@ -2655,42 +2776,6 @@ public class TLRPC { } } - public static class contacts_ForeignLink extends TLObject { - public boolean has_phone; - } - - public static class TL_contacts_foreignLinkMutual extends contacts_ForeignLink { - public static int constructor = 0x1bea8ce1; - - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - } - } - - public static class TL_contacts_foreignLinkUnknown extends contacts_ForeignLink { - public static int constructor = 0x133421f8; - - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - } - } - - public static class TL_contacts_foreignLinkRequested extends contacts_ForeignLink { - public static int constructor = 0xa7801f47; - - - public void readParams(AbsSerializedData stream) { - has_phone = stream.readBool(); - } - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - stream.writeBool(has_phone); - } - } - public static class Set_client_DH_params_answer extends TLObject { public byte[] nonce; public byte[] server_nonce; @@ -3005,22 +3090,22 @@ public class TLRPC { } public static class TL_messages_affectedHistory extends TLObject { - public static int constructor = 0xb7de36f2; + public static int constructor = 0xb45c69d1; public int pts; - public int seq; + public int pts_count; public int offset; public void readParams(AbsSerializedData stream) { pts = stream.readInt32(); - seq = stream.readInt32(); + pts_count = stream.readInt32(); offset = stream.readInt32(); } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); stream.writeInt32(pts); - stream.writeInt32(seq); + stream.writeInt32(pts_count); stream.writeInt32(offset); } } @@ -3076,6 +3161,45 @@ public class TLRPC { } } + public static class ContactLink extends TLObject { + } + + public static class TL_contactLinkNone extends ContactLink { + public static int constructor = 0xfeedd3ad; + + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + } + } + + public static class TL_contactLinkContact extends ContactLink { + public static int constructor = 0xd502c2d0; + + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + } + } + + public static class TL_contactLinkHasPhone extends ContactLink { + public static int constructor = 0x268f3f59; + + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + } + } + + public static class TL_contactLinkUnknown extends ContactLink { + public static int constructor = 0x5f4f9247; + + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + } + } + public static class InputPrivacyRule extends TLObject { public ArrayList users = new ArrayList<>(); } @@ -3513,59 +3637,67 @@ public class TLRPC { public static class messages_SentMessage extends TLObject { public int id; public int date; + public MessageMedia media; public int pts; - public int seq; + public int pts_count; public ArrayList links = new ArrayList<>(); + public int seq; } public static class TL_messages_sentMessage extends messages_SentMessage { - public static int constructor = 0xd1f4d35c; + public static int constructor = 0x4c3d47f3; public void readParams(AbsSerializedData stream) { id = stream.readInt32(); date = stream.readInt32(); + media = (MessageMedia)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); pts = stream.readInt32(); - seq = stream.readInt32(); + pts_count = stream.readInt32(); } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); stream.writeInt32(id); stream.writeInt32(date); + media.serializeToStream(stream); stream.writeInt32(pts); - stream.writeInt32(seq); + stream.writeInt32(pts_count); } } public static class TL_messages_sentMessageLink extends messages_SentMessage { - public static int constructor = 0xe9db4a3f; + public static int constructor = 0x35a1a663; public void readParams(AbsSerializedData stream) { id = stream.readInt32(); date = stream.readInt32(); + media = (MessageMedia)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); pts = stream.readInt32(); - seq = stream.readInt32(); + pts_count = stream.readInt32(); stream.readInt32(); int count = stream.readInt32(); for (int a = 0; a < count; a++) { links.add((TL_contacts_link)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); } + seq = stream.readInt32(); } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); stream.writeInt32(id); stream.writeInt32(date); + media.serializeToStream(stream); stream.writeInt32(pts); - stream.writeInt32(seq); + stream.writeInt32(pts_count); stream.writeInt32(0x1cb5c415); int count = links.size(); stream.writeInt32(count); - for (TL_contacts_link link : links) { - link.serializeToStream(stream); + for (int a = 0; a < count; a++) { + links.get(a).serializeToStream(stream); } + stream.writeInt32(seq); } } @@ -3743,6 +3875,24 @@ public class TLRPC { } } + public static class TL_disabledFeature extends TLObject { + public static int constructor = 0xae636f24; + + public String feature; + public String description; + + public void readParams(AbsSerializedData stream) { + feature = stream.readString(); + description = stream.readString(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeString(feature); + stream.writeString(description); + } + } + public static class TL_futureSalt extends TLObject { public static int constructor = 0x0949d9dc; @@ -3769,11 +3919,14 @@ public class TLRPC { public int max_date; public int date; public int user_id; - public contacts_MyLink my_link; - public contacts_ForeignLink foreign_link; + public ContactLink my_link; + public ContactLink foreign_link; public ArrayList messages = new ArrayList<>(); public int pts; + public int pts_count; + public int max_id; public int version; + public WebPage webpage; public String type; public MessageMedia media; public boolean popup; @@ -3783,12 +3936,12 @@ public class TLRPC { public String first_name; public String last_name; public String username; + public String phone; public int qts; public int id; 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; @@ -3821,13 +3974,13 @@ public class TLRPC { } public static class TL_updateContactLink extends Update { - public static int constructor = 0x51a48a9a; + public static int constructor = 0x9d2e67c5; public void readParams(AbsSerializedData stream) { user_id = stream.readInt32(); - my_link = (contacts_MyLink)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); - foreign_link = (contacts_ForeignLink)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); + my_link = (ContactLink)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); + foreign_link = (ContactLink)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); } public void serializeToStream(AbsSerializedData stream) { @@ -3839,7 +3992,7 @@ public class TLRPC { } public static class TL_updateReadMessages extends Update { - public static int constructor = 0xc6649e31; + public static int constructor = 0x2e5ab668; public void readParams(AbsSerializedData stream) { @@ -3849,6 +4002,7 @@ public class TLRPC { messages.add(stream.readInt32()); } pts = stream.readInt32(); + pts_count = stream.readInt32(); } public void serializeToStream(AbsSerializedData stream) { @@ -3856,10 +4010,32 @@ public class TLRPC { stream.writeInt32(0x1cb5c415); int count = messages.size(); stream.writeInt32(count); - for (Integer message : messages) { - stream.writeInt32(message); + for (int a = 0; a < count; a++) { + stream.writeInt32(messages.get(a)); } stream.writeInt32(pts); + stream.writeInt32(pts_count); + } + } + + public static class TL_updateReadHistoryInbox extends Update { + public static int constructor = 0x9961fd5c; + + public Peer peer; + + public void readParams(AbsSerializedData stream) { + peer = (Peer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); + max_id = stream.readInt32(); + pts = stream.readInt32(); + pts_count = stream.readInt32(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + peer.serializeToStream(stream); + stream.writeInt32(max_id); + stream.writeInt32(pts); + stream.writeInt32(pts_count); } } @@ -3881,28 +4057,38 @@ public class TLRPC { } } - public static class TL_updateRestoreMessages extends Update { - public static int constructor = 0xd15de04d; + public static class TL_updateReadHistoryOutbox extends Update { + public static int constructor = 0x2f2f21bf; + public Peer peer; public void readParams(AbsSerializedData stream) { - stream.readInt32(); - int count = stream.readInt32(); - for (int a = 0; a < count; a++) { - messages.add(stream.readInt32()); - } + peer = (Peer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); + max_id = stream.readInt32(); pts = stream.readInt32(); + pts_count = stream.readInt32(); } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); - stream.writeInt32(0x1cb5c415); - int count = messages.size(); - stream.writeInt32(count); - for (Integer message : messages) { - stream.writeInt32(message); - } + peer.serializeToStream(stream); + stream.writeInt32(max_id); stream.writeInt32(pts); + stream.writeInt32(pts_count); + } + } + + public static class TL_updateWebPage extends Update { + public static int constructor = 0x2cc36971; + + + public void readParams(AbsSerializedData stream) { + webpage = (WebPage)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + webpage.serializeToStream(stream); } } @@ -3966,7 +4152,7 @@ public class TLRPC { public void readParams(AbsSerializedData stream) { chat_id = stream.readInt32(); user_id = stream.readInt32(); - action = (SendMessageAction)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); + action = (SendMessageAction) TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); } public void serializeToStream(AbsSerializedData stream) { @@ -4015,19 +4201,21 @@ public class TLRPC { } public static class TL_updateNewMessage extends Update { - public static int constructor = 0x13abdb3; + public static int constructor = 0x1f2b0afd; public Message message; public void readParams(AbsSerializedData stream) { message = (Message)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); pts = stream.readInt32(); + pts_count = stream.readInt32(); } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); message.serializeToStream(stream); stream.writeInt32(pts); + stream.writeInt32(pts_count); } } @@ -4048,8 +4236,7 @@ public class TLRPC { } public static class TL_updateDeleteMessages extends Update { - public static int constructor = 0xa92bfe26; - + public static int constructor = 0xa20db0e5; public void readParams(AbsSerializedData stream) { stream.readInt32(); @@ -4058,6 +4245,7 @@ public class TLRPC { messages.add(stream.readInt32()); } pts = stream.readInt32(); + pts_count = stream.readInt32(); } public void serializeToStream(AbsSerializedData stream) { @@ -4065,10 +4253,11 @@ public class TLRPC { stream.writeInt32(0x1cb5c415); int count = messages.size(); stream.writeInt32(count); - for (Integer message : messages) { - stream.writeInt32(message); + for (int a = 0; a < count; a++) { + stream.writeInt32(messages.get(a)); } stream.writeInt32(pts); + stream.writeInt32(pts_count); } } @@ -4591,42 +4780,6 @@ public class TLRPC { } } - public static class contacts_MyLink extends TLObject { - public boolean contact; - } - - public static class TL_contacts_myLinkRequested extends contacts_MyLink { - public static int constructor = 0x6c69efee; - - - public void readParams(AbsSerializedData stream) { - contact = stream.readBool(); - } - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - stream.writeBool(contact); - } - } - - public static class TL_contacts_myLinkContact extends contacts_MyLink { - public static int constructor = 0xc240ebd9; - - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - } - } - - public static class TL_contacts_myLinkEmpty extends contacts_MyLink { - public static int constructor = 0xd22a1c60; - - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - } - } - public static class TL_server_DH_inner_data extends TLObject { public static int constructor = 0xb5890dba; @@ -4733,16 +4886,20 @@ public class TLRPC { public byte[] current_salt; public byte[] new_salt; public String hint; + public boolean has_recovery; + public String email_unconfirmed_pattern; } public static class TL_account_password extends account_Password { - public static int constructor = 0x739e5f72; + public static int constructor = 0x7c18141c; public void readParams(AbsSerializedData stream) { current_salt = stream.readByteArray(); new_salt = stream.readByteArray(); hint = stream.readString(); + has_recovery = stream.readBool(); + email_unconfirmed_pattern = stream.readString(); } public void serializeToStream(AbsSerializedData stream) { @@ -4750,20 +4907,24 @@ public class TLRPC { stream.writeByteArray(current_salt); stream.writeByteArray(new_salt); stream.writeString(hint); + stream.writeBool(has_recovery); + stream.writeString(email_unconfirmed_pattern); } } public static class TL_account_noPassword extends account_Password { - public static int constructor = 0x5770e7a9; + public static int constructor = 0x96dabc18; public void readParams(AbsSerializedData stream) { new_salt = stream.readByteArray(); + email_unconfirmed_pattern = stream.readString(); } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); stream.writeByteArray(new_salt); + stream.writeString(email_unconfirmed_pattern); } } @@ -5023,17 +5184,28 @@ public class TLRPC { } public static class TL_config extends TLObject { - public static int constructor = 0x2e54dd74; + public static int constructor = 0x68bac247; public int date; + public int expires; public boolean test_mode; public int this_dc; public ArrayList dc_options = new ArrayList<>(); public int chat_size_max; public int broadcast_size_max; + public int forwarded_count_max; + public int online_update_period_ms; + public int offline_blur_timeout_ms; + public int offline_idle_timeout_ms; + public int online_cloud_timeout_ms; + public int notify_cloud_delay_ms; + public int notify_default_delay_ms; + public int chat_big_size; + public ArrayList disabled_features = new ArrayList<>(); public void readParams(AbsSerializedData stream) { date = stream.readInt32(); + expires = stream.readInt32(); test_mode = stream.readBool(); this_dc = stream.readInt32(); stream.readInt32(); @@ -5043,21 +5215,49 @@ public class TLRPC { } chat_size_max = stream.readInt32(); broadcast_size_max = stream.readInt32(); + forwarded_count_max = stream.readInt32(); + online_update_period_ms = stream.readInt32(); + offline_blur_timeout_ms = stream.readInt32(); + offline_idle_timeout_ms = stream.readInt32(); + online_cloud_timeout_ms = stream.readInt32(); + notify_cloud_delay_ms = stream.readInt32(); + notify_default_delay_ms = stream.readInt32(); + chat_big_size = stream.readInt32(); + stream.readInt32(); + count = stream.readInt32(); + for (int a = 0; a < count; a++) { + disabled_features.add((TL_disabledFeature)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); + } } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); stream.writeInt32(date); + stream.writeInt32(expires); stream.writeBool(test_mode); stream.writeInt32(this_dc); stream.writeInt32(0x1cb5c415); int count = dc_options.size(); stream.writeInt32(count); - for (TL_dcOption dc_option : dc_options) { - dc_option.serializeToStream(stream); + for (int a = 0; a < count; a++) { + dc_options.get(a).serializeToStream(stream); } stream.writeInt32(chat_size_max); stream.writeInt32(broadcast_size_max); + stream.writeInt32(forwarded_count_max); + stream.writeInt32(online_update_period_ms); + stream.writeInt32(offline_blur_timeout_ms); + stream.writeInt32(offline_idle_timeout_ms); + stream.writeInt32(online_cloud_timeout_ms); + stream.writeInt32(notify_cloud_delay_ms); + stream.writeInt32(notify_default_delay_ms); + stream.writeInt32(chat_big_size); + stream.writeInt32(0x1cb5c415); + count = disabled_features.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + disabled_features.get(a).serializeToStream(stream); + } } } @@ -5114,10 +5314,14 @@ public class TLRPC { } public static class TL_messages_readMessageContents extends TLObject { - public static int constructor = 0x354b5bc2; + public static int constructor = 0x36a73f77; public ArrayList id = new ArrayList<>(); + public Class responseClass () { + return TL_messages_affectedMessages.class; + } + public void readParams(AbsSerializedData stream) { stream.readInt32(); int count = stream.readInt32(); @@ -5131,8 +5335,8 @@ public class TLRPC { stream.writeInt32(0x1cb5c415); int count = id.size(); stream.writeInt32(count); - for (Integer anId : id) { - stream.writeInt32(anId); + for (int a = 0; a < count; a++) { + stream.writeInt32(id.get(a)); } } } @@ -5243,7 +5447,7 @@ public class TLRPC { public String phone_number; - public Class responseClass () { + public Class responseClass() { return TL_account_sentChangePhoneCode.class; } @@ -5282,63 +5486,54 @@ public class TLRPC { } } - public static class TL_account_getPassword extends TLObject { - public static int constructor = 0x548a30f5; + public static class TL_account_updateDeviceLocked extends TLObject { + public static int constructor = 0x38df3532; - - public Class responseClass () { - return account_Password.class; - } - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - } - } - - public static class TL_account_setPassword extends TLObject { - public static int constructor = 0xdd2a4d8f; - - public byte[] current_password_hash; - public byte[] new_salt; - public byte[] new_password_hash; - public String hint; + public int period; public Class responseClass () { return Bool.class; } public void readParams(AbsSerializedData stream) { - current_password_hash = stream.readByteArray(); - new_salt = stream.readByteArray(); - new_password_hash = stream.readByteArray(); - hint = stream.readString(); + period = stream.readInt32(); } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); - stream.writeByteArray(current_password_hash); - stream.writeByteArray(new_salt); - stream.writeByteArray(new_password_hash); - stream.writeString(hint); + stream.writeInt32(period); } } - public static class TL_auth_checkPassword extends TLObject { - public static int constructor = 0xa63011e; + public static class TL_account_getAuthorizations extends TLObject { + public static int constructor = 0xe320c158; - public byte[] password_hash; public Class responseClass () { - return TL_auth_authorization.class; - } - - public void readParams(AbsSerializedData stream) { - password_hash = stream.readByteArray(); + return TL_account_authorizations.class; } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); - stream.writeByteArray(password_hash); + } + } + + public static class TL_account_resetAuthorization extends TLObject { + public static int constructor = 0xdf77f3bc; + + public long hash; + + public Class responseClass () { + return Bool.class; + } + + public void readParams(AbsSerializedData stream) { + hash = stream.readInt64(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt64(hash); } } @@ -5361,6 +5556,25 @@ public class TLRPC { } } + public static class TL_messages_getWebPagePreview extends TLObject { + public static int constructor = 0x25223e24; + + public String message; + + public Class responseClass () { + return MessageMedia.class; + } + + public void readParams(AbsSerializedData stream) { + message = stream.readString(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeString(message); + } + } + public static class TL_account_checkUsername extends TLObject { public static int constructor = 0x2714d86c; @@ -5449,10 +5663,9 @@ public class TLRPC { } public static class TL_messages_chats extends TLObject { - public static int constructor = 0x8150cbd8; + public static int constructor = 0x64ff9fd5; public ArrayList chats = new ArrayList<>(); - public ArrayList users = new ArrayList<>(); public void readParams(AbsSerializedData stream) { stream.readInt32(); @@ -5460,11 +5673,6 @@ public class TLRPC { for (int a = 0; a < count; a++) { chats.add((Chat)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); } - stream.readInt32(); - count = stream.readInt32(); - for (int a = 0; a < count; a++) { - users.add((User)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); - } } public void serializeToStream(AbsSerializedData stream) { @@ -5475,12 +5683,6 @@ public class TLRPC { for (int a = 0; a < count; a++) { chats.get(a).serializeToStream(stream); } - stream.writeInt32(0x1cb5c415); - count = users.size(); - stream.writeInt32(count); - for (int a = 0; a < count; a++) { - users.get(a).serializeToStream(stream); - } } } @@ -6404,106 +6606,6 @@ public class TLRPC { } } - public static class messages_StatedMessage extends TLObject { - public Message message; - public ArrayList chats = new ArrayList<>(); - public ArrayList users = new ArrayList<>(); - public ArrayList links = new ArrayList<>(); - public int pts; - public int seq; - } - - public static class TL_messages_statedMessageLink extends messages_StatedMessage { - public static int constructor = 0xa9af2881; - - - public void readParams(AbsSerializedData stream) { - message = (Message)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); - stream.readInt32(); - int count = stream.readInt32(); - for (int a = 0; a < count; a++) { - chats.add((Chat)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); - } - stream.readInt32(); - count = stream.readInt32(); - for (int a = 0; a < count; a++) { - users.add((User)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); - } - stream.readInt32(); - count = stream.readInt32(); - for (int a = 0; a < count; a++) { - links.add((TL_contacts_link)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); - } - pts = stream.readInt32(); - seq = stream.readInt32(); - } - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - message.serializeToStream(stream); - stream.writeInt32(0x1cb5c415); - int count = chats.size(); - stream.writeInt32(count); - for (int a = 0; a < count; a++) { - chats.get(a).serializeToStream(stream); - } - stream.writeInt32(0x1cb5c415); - count = users.size(); - stream.writeInt32(count); - for (int a = 0; a < count; a++) { - users.get(a).serializeToStream(stream); - } - stream.writeInt32(0x1cb5c415); - count = links.size(); - stream.writeInt32(count); - for (int a = 0; a < count; a++) { - links.get(a).serializeToStream(stream); - } - stream.writeInt32(pts); - stream.writeInt32(seq); - } - } - - public static class TL_messages_statedMessage extends messages_StatedMessage { - public static int constructor = 0xd07ae726; - - - public void readParams(AbsSerializedData stream) { - message = (Message)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); - stream.readInt32(); - int count = stream.readInt32(); - for (int a = 0; a < count; a++) { - chats.add((Chat)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); - } - stream.readInt32(); - count = stream.readInt32(); - for (int a = 0; a < count; a++) { - users.add((User)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); - } - pts = stream.readInt32(); - seq = stream.readInt32(); - } - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - message.serializeToStream(stream); - stream.writeInt32(0x1cb5c415); - int count = chats.size(); - stream.writeInt32(count); - for (int a = 0; a < count; a++) { - chats.get(a).serializeToStream(stream); - } - stream.writeInt32(0x1cb5c415); - count = users.size(); - stream.writeInt32(count); - for (int a = 0; a < count; a++) { - users.get(a).serializeToStream(stream); - } - stream.writeInt32(pts); - stream.writeInt32(seq); - } - } - public static class TL_userFull extends TLObject { public static int constructor = 0x771095da; @@ -6598,43 +6700,65 @@ public class TLRPC { } public static class Updates extends TLObject { + public int flags; public int id; - public int from_id; public int chat_id; public String message; public int pts; + public int pts_count; public int date; - public int seq; + public int fwd_from_id; + public int fwd_date; + public int reply_to_msg_id; public ArrayList updates = new ArrayList<>(); public ArrayList users = new ArrayList<>(); public ArrayList chats = new ArrayList<>(); + public int seq; + public int user_id; public Update update; public int seq_start; + public int qts; } public static class TL_updateShortChatMessage extends Updates { - public static int constructor = 0x2b2fbd4e; + public static int constructor = 0x52238b3c; public void readParams(AbsSerializedData stream) { + flags = stream.readInt32(); id = stream.readInt32(); - from_id = stream.readInt32(); + user_id = stream.readInt32(); chat_id = stream.readInt32(); message = stream.readString(); pts = stream.readInt32(); + pts_count = stream.readInt32(); date = stream.readInt32(); - seq = stream.readInt32(); + if ((flags & MESSAGE_FLAG_FWD) != 0) { + fwd_from_id = stream.readInt32(); + fwd_date = stream.readInt32(); + } + if ((flags & MESSAGE_FLAG_REPLY) != 0) { + reply_to_msg_id = stream.readInt32(); + } } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); + stream.writeInt32(flags); stream.writeInt32(id); - stream.writeInt32(from_id); + stream.writeInt32(user_id); stream.writeInt32(chat_id); stream.writeString(message); stream.writeInt32(pts); + stream.writeInt32(pts_count); stream.writeInt32(date); - stream.writeInt32(seq); + if ((flags & MESSAGE_FLAG_FWD) != 0) { + stream.writeInt32(fwd_from_id); + stream.writeInt32(fwd_date); + } + if ((flags & MESSAGE_FLAG_REPLY) != 0) { + stream.writeInt32(reply_to_msg_id); + } } } @@ -6688,26 +6812,42 @@ public class TLRPC { } public static class TL_updateShortMessage extends Updates { - public static int constructor = 0xd3f45784; + public static int constructor = 0xed5c2127; public void readParams(AbsSerializedData stream) { + flags = stream.readInt32(); id = stream.readInt32(); - from_id = stream.readInt32(); + user_id = stream.readInt32(); message = stream.readString(); pts = stream.readInt32(); + pts_count = stream.readInt32(); date = stream.readInt32(); - seq = stream.readInt32(); + if ((flags & MESSAGE_FLAG_FWD) != 0) { + fwd_from_id = stream.readInt32(); + fwd_date = stream.readInt32(); + } + if ((flags & MESSAGE_FLAG_REPLY) != 0) { + reply_to_msg_id = stream.readInt32(); + } } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); + stream.writeInt32(flags); stream.writeInt32(id); - stream.writeInt32(from_id); + stream.writeInt32(user_id); stream.writeString(message); stream.writeInt32(pts); + stream.writeInt32(pts_count); stream.writeInt32(date); - stream.writeInt32(seq); + if ((flags & MESSAGE_FLAG_FWD) != 0) { + stream.writeInt32(fwd_from_id); + stream.writeInt32(fwd_date); + } + if ((flags & MESSAGE_FLAG_REPLY) != 0) { + stream.writeInt32(reply_to_msg_id); + } } } @@ -6787,33 +6927,6 @@ public class TLRPC { } } - public static class TL_messages_chat extends TLObject { - public static int constructor = 0x40e9002a; - - public Chat chat; - public ArrayList users = new ArrayList<>(); - - public void readParams(AbsSerializedData stream) { - chat = (Chat)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); - stream.readInt32(); - int count = stream.readInt32(); - for (int a = 0; a < count; a++) { - users.add((User)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); - } - } - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - chat.serializeToStream(stream); - stream.writeInt32(0x1cb5c415); - int count = users.size(); - stream.writeInt32(count); - for (User user : users) { - user.serializeToStream(stream); - } - } - } - public static class WallPaper extends TLObject { public int id; public String title; @@ -7190,6 +7303,41 @@ public class TLRPC { } } + public static class TL_account_passwordInputSettings extends TLObject { + public static int constructor = 0xbcfc532c; + + public int flags; + public byte[] new_salt; + public byte[] new_password_hash; + public String hint; + public String email; + + public void readParams(AbsSerializedData stream) { + flags = stream.readInt32(); + if ((flags & 1) != 0) { + new_salt = stream.readByteArray(); + new_password_hash = stream.readByteArray(); + hint = stream.readString(); + } + if ((flags & 2) != 0) { + email = stream.readString(); + } + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(flags); + if ((flags & 1) != 0) { + stream.writeByteArray(new_salt); + stream.writeByteArray(new_password_hash); + stream.writeString(hint); + } + if ((flags & 2) != 0) { + stream.writeString(email); + } + } + } + public static class TL_dcOption extends TLObject { public static int constructor = 0x2ec2a43c; @@ -7396,6 +7544,30 @@ public class TLRPC { } } + public static class TL_account_authorizations extends TLObject { + public static int constructor = 0x1250abde; + + public ArrayList authorizations = new ArrayList<>(); + + public void readParams(AbsSerializedData stream) { + stream.readInt32(); + int count = stream.readInt32(); + for (int a = 0; a < count; a++) { + authorizations.add((TL_authorization)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); + } + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(0x1cb5c415); + int count = authorizations.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + authorizations.get(a).serializeToStream(stream); + } + } + } + public static class TL_req_pq extends TLObject { public static int constructor = 0x60469778; @@ -8213,12 +8385,11 @@ public class TLRPC { } public static class TL_messages_readHistory extends TLObject { - public static int constructor = 0xeed884c6; + public static int constructor = 0xb04f2510; public InputPeer peer; public int max_id; public int offset; - public boolean read_contents; public Class responseClass () { return TL_messages_affectedHistory.class; @@ -8228,7 +8399,6 @@ public class TLRPC { peer = (InputPeer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); max_id = stream.readInt32(); offset = stream.readInt32(); - read_contents = stream.readBool(); } public void serializeToStream(AbsSerializedData stream) { @@ -8236,7 +8406,6 @@ public class TLRPC { peer.serializeToStream(stream); stream.writeInt32(max_id); stream.writeInt32(offset); - stream.writeBool(read_contents); } } @@ -8285,9 +8454,11 @@ public class TLRPC { } public static class TL_messages_sendMessage extends TLObject { - public static int constructor = 0x4cde0aab; + public static int constructor = 0x9add8f26; + public int flags; public InputPeer peer; + public int reply_to_msg_id; public String message; public long random_id; @@ -8296,52 +8467,71 @@ public class TLRPC { } public void readParams(AbsSerializedData stream) { + flags = stream.readInt32(); peer = (InputPeer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); + if ((flags & 1) != 0) { + reply_to_msg_id = stream.readInt32(); + } message = stream.readString(); random_id = stream.readInt64(); } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); + stream.writeInt32(flags); peer.serializeToStream(stream); + if ((flags & 1) != 0) { + stream.writeInt32(reply_to_msg_id); + } stream.writeString(message); stream.writeInt64(random_id); } } public static class TL_messages_sendMedia extends TLObject { - public static int constructor = 0xa3c85d76; + public static int constructor = 0x2d7923b1; + public int flags; public InputPeer peer; + public int reply_to_msg_id; public InputMedia media; public long random_id; public Class responseClass () { - return messages_StatedMessage.class; + return Updates.class; } public void readParams(AbsSerializedData stream) { + flags = stream.readInt32(); peer = (InputPeer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); + if ((flags & 1) != 0) { + reply_to_msg_id = stream.readInt32(); + } media = (InputMedia)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); random_id = stream.readInt64(); } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); + stream.writeInt32(flags); peer.serializeToStream(stream); + if ((flags & 1) != 0) { + stream.writeInt32(reply_to_msg_id); + } media.serializeToStream(stream); stream.writeInt64(random_id); } } public static class TL_messages_forwardMessages extends TLObject { - public static int constructor = 0x514cd10f; + public static int constructor = 0x55e1728d; public InputPeer peer; public ArrayList id = new ArrayList<>(); + public ArrayList random_id = new ArrayList<>(); public Class responseClass () { - return messages_StatedMessages.class; + return Updates.class; } public void readParams(AbsSerializedData stream) { @@ -8351,6 +8541,11 @@ public class TLRPC { for (int a = 0; a < count; a++) { id.add(stream.readInt32()); } + stream.readInt32(); + count = stream.readInt32(); + for (int a = 0; a < count; a++) { + random_id.add(stream.readInt64()); + } } public void serializeToStream(AbsSerializedData stream) { @@ -8359,8 +8554,14 @@ public class TLRPC { stream.writeInt32(0x1cb5c415); int count = id.size(); stream.writeInt32(count); - for (Integer anId : id) { - stream.writeInt32(anId); + for (int a = 0; a < count; a++) { + stream.writeInt32(id.get(a)); + } + stream.writeInt32(0x1cb5c415); + count = random_id.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + stream.writeInt64(random_id.get(a)); } } } @@ -8413,13 +8614,13 @@ public class TLRPC { } public static class TL_messages_editChatTitle extends TLObject { - public static int constructor = 0xb4bc68b5; + public static int constructor = 0xdc452855; public int chat_id; public String title; public Class responseClass () { - return messages_StatedMessage.class; + return Updates.class; } public void readParams(AbsSerializedData stream) { @@ -8435,13 +8636,13 @@ public class TLRPC { } public static class TL_messages_editChatPhoto extends TLObject { - public static int constructor = 0xd881821d; + public static int constructor = 0xca4c79d8; public int chat_id; public InputChatPhoto photo; public Class responseClass () { - return messages_StatedMessage.class; + return Updates.class; } public void readParams(AbsSerializedData stream) { @@ -8457,14 +8658,14 @@ public class TLRPC { } public static class TL_messages_addChatUser extends TLObject { - public static int constructor = 0x2ee9ee9e; + public static int constructor = 0xf9a0aa09; public int chat_id; public InputUser user_id; public int fwd_limit; public Class responseClass () { - return messages_StatedMessage.class; + return Updates.class; } public void readParams(AbsSerializedData stream) { @@ -8482,13 +8683,13 @@ public class TLRPC { } public static class TL_messages_deleteChatUser extends TLObject { - public static int constructor = 0xc3c5cd23; + public static int constructor = 0xe0611f16; public int chat_id; public InputUser user_id; public Class responseClass () { - return messages_StatedMessage.class; + return Updates.class; } public void readParams(AbsSerializedData stream) { @@ -8504,13 +8705,13 @@ public class TLRPC { } public static class TL_messages_createChat extends TLObject { - public static int constructor = 0x419d9aee; + public static int constructor = 0x9cb126e; public ArrayList users = new ArrayList<>(); public String title; public Class responseClass () { - return messages_StatedMessage.class; + return Updates.class; } public void readParams(AbsSerializedData stream) { @@ -8527,8 +8728,8 @@ public class TLRPC { stream.writeInt32(0x1cb5c415); int count = users.size(); stream.writeInt32(count); - for (InputUser user : users) { - user.serializeToStream(stream); + for (int a = 0; a < count; a++) { + users.get(a).serializeToStream(stream); } stream.writeString(title); } @@ -8655,7 +8856,7 @@ public class TLRPC { public int offset; public int limit; - public Class responseClass () { + public Class responseClass() { return TL_upload_file.class; } @@ -8803,14 +9004,14 @@ public class TLRPC { } public static class TL_messages_forwardMessage extends TLObject { - public static int constructor = 0x3f3f4f2; + public static int constructor = 0x33963bf9; public InputPeer peer; public int id; public long random_id; public Class responseClass () { - return messages_StatedMessage.class; + return Updates.class; } public void readParams(AbsSerializedData stream) { @@ -8828,14 +9029,15 @@ public class TLRPC { } public static class TL_messages_sendBroadcast extends TLObject { - public static int constructor = 0x41bb0972; + public static int constructor = 0xbf73f4da; public ArrayList contacts = new ArrayList<>(); + public ArrayList random_id = new ArrayList<>(); public String message; public InputMedia media; public Class responseClass () { - return messages_StatedMessages.class; + return Updates.class; } public void readParams(AbsSerializedData stream) { @@ -8844,6 +9046,11 @@ public class TLRPC { for (int a = 0; a < count; a++) { contacts.add((InputUser)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); } + stream.readInt32(); + count = stream.readInt32(); + for (int a = 0; a < count; a++) { + random_id.add(stream.readInt64()); + } message = stream.readString(); media = (InputMedia)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); } @@ -8853,8 +9060,14 @@ public class TLRPC { stream.writeInt32(0x1cb5c415); int count = contacts.size(); stream.writeInt32(count); - for (InputUser contact : contacts) { - contact.serializeToStream(stream); + for (int a = 0; a < count; a++) { + contacts.get(a).serializeToStream(stream); + } + stream.writeInt32(0x1cb5c415); + count = random_id.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + stream.writeInt64(random_id.get(a)); } stream.writeString(message); media.serializeToStream(stream); @@ -8932,7 +9145,7 @@ public class TLRPC { public TL_inputGeoChat peer; - public Class responseClass () { + public Class responseClass() { return TL_messages_chatFull.class; } @@ -9258,7 +9471,7 @@ public class TLRPC { public TL_inputEncryptedChat peer; public boolean typing; - public Class responseClass () { + public Class responseClass() { return Bool.class; } @@ -9296,8 +9509,201 @@ public class TLRPC { } } + public static class TL_messages_deleteMessages extends TLObject { + public static int constructor = 0xa5f18925; + + public ArrayList id = new ArrayList<>(); + + public Class responseClass () { + return TL_messages_affectedMessages.class; + } + + public void readParams(AbsSerializedData stream) { + stream.readInt32(); + int count = stream.readInt32(); + for (int a = 0; a < count; a++) { + id.add(stream.readInt32()); + } + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(0x1cb5c415); + int count = id.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + stream.writeInt32(id.get(a)); + } + } + } + + public static class TL_account_getPassword extends TLObject { + public static int constructor = 0x548a30f5; + + + public Class responseClass () { + return account_Password.class; + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + } + } + + public static class TL_account_getPasswordSettings extends TLObject { + public static int constructor = 0xbc8d11bb; + + public byte[] current_password_hash; + + public Class responseClass () { + return TL_account_passwordSettings.class; + } + + public void readParams(AbsSerializedData stream) { + current_password_hash = stream.readByteArray(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeByteArray(current_password_hash); + } + } + + public static class TL_account_updatePasswordSettings extends TLObject { + public static int constructor = 0xfa7c4b86; + + public byte[] current_password_hash; + public TL_account_passwordInputSettings new_settings; + + public Class responseClass () { + return Bool.class; + } + + public void readParams(AbsSerializedData stream) { + current_password_hash = stream.readByteArray(); + new_settings = (TL_account_passwordInputSettings)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeByteArray(current_password_hash); + new_settings.serializeToStream(stream); + } + } + + public static class TL_auth_checkPassword extends TLObject { + public static int constructor = 0xa63011e; + + public byte[] password_hash; + + public Class responseClass () { + return TL_auth_authorization.class; + } + + public void readParams(AbsSerializedData stream) { + password_hash = stream.readByteArray(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeByteArray(password_hash); + } + } + + public static class TL_auth_requestPasswordRecovery extends TLObject { + public static int constructor = 0xd897bc66; + + + public Class responseClass () { + return TL_auth_passwordRecovery.class; + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + } + } + + public static class TL_auth_recoverPassword extends TLObject { + public static int constructor = 0x4ea56e92; + + public String code; + + public Class responseClass () { + return TL_auth_authorization.class; + } + + public void readParams(AbsSerializedData stream) { + code = stream.readString(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeString(code); + } + } + //manually created + public static class TL_documentAttributeSticker_old extends TL_documentAttributeSticker { + public static int constructor = 0xfb0a5727; + + public void readParams(AbsSerializedData stream) { + + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + } + } + + public static class TL_messageMediaUnsupported_old extends TL_messageMediaUnsupported { + public static int constructor = 0x29632a36; + + + public void readParams(AbsSerializedData stream) { + bytes = stream.readByteArray(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeByteArray(bytes); + } + } + + public static class TL_config_old extends TL_config { + public static int constructor = 0x2e54dd74; + + public void readParams(AbsSerializedData stream) { + date = stream.readInt32(); + test_mode = stream.readBool(); + this_dc = stream.readInt32(); + stream.readInt32(); + int count = stream.readInt32(); + for (int a = 0; a < count; a++) { + dc_options.add((TL_dcOption) TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); + } + chat_size_max = stream.readInt32(); + broadcast_size_max = stream.readInt32(); + expires = (int) (System.currentTimeMillis() / 1000) + 3600; + chat_big_size = 10; + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(date); + stream.writeBool(test_mode); + stream.writeInt32(this_dc); + stream.writeInt32(0x1cb5c415); + int count = dc_options.size(); + stream.writeInt32(count); + for (TL_dcOption dc_option : dc_options) { + dc_option.serializeToStream(stream); + } + stream.writeInt32(chat_size_max); + stream.writeInt32(broadcast_size_max); + } + } + public static class TL_document_old extends TL_document { public static int constructor = 0x9efc6326; @@ -9473,6 +9879,34 @@ public class TLRPC { } } + public static class TL_userSelf_old2 extends TL_userSelf { + public static int constructor = 0x7007b451; + + + public void readParams(AbsSerializedData stream) { + id = stream.readInt32(); + first_name = stream.readString(); + last_name = stream.readString(); + username = stream.readString(); + phone = stream.readString(); + photo = (UserProfilePhoto)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); + status = (UserStatus)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); + inactive = stream.readBool(); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(id); + stream.writeString(first_name); + stream.writeString(last_name); + stream.writeString(username); + stream.writeString(phone); + photo.serializeToStream(stream); + status.serializeToStream(stream); + stream.writeBool(inactive); + } + } + public static class TL_userSelf_old extends TL_userSelf { public static int constructor = 0x720535ec; @@ -9799,7 +10233,7 @@ public class TLRPC { return 0; } - public Class responseClass () { + public Class responseClass() { return RpcDropAnswer.class; } @@ -9930,6 +10364,7 @@ public class TLRPC { public int date; public String message; public MessageMedia media; + public int reply_to_msg_id; public MessageAction action; public int send_state = 0; public int fwd_msg_id = 0; @@ -9942,10 +10377,11 @@ public class TLRPC { public int layer; public int seq_in; public int seq_out; + public TLRPC.Message replyMessage; public VideoEditedInfo videoEditedInfo = null; } - public static class TL_messageForwarded extends Message { + public static class TL_messageForwarded_old2 extends Message { public static int constructor = 0xa367e716; @@ -9958,6 +10394,7 @@ public class TLRPC { to_id = (Peer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); date = stream.readInt32(); message = stream.readString(); + flags |= MESSAGE_FLAG_FWD; media = (MessageMedia)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); if (id < 0) { fwd_msg_id = stream.readInt32(); @@ -9990,6 +10427,60 @@ public class TLRPC { } public static class TL_message extends Message { + public static int constructor = 0xa7ab1991; + + + public void readParams(AbsSerializedData stream) { + flags = stream.readInt32(); + id = stream.readInt32(); + from_id = stream.readInt32(); + to_id = (Peer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); + if ((flags & MESSAGE_FLAG_FWD) != 0) { + fwd_from_id = stream.readInt32(); + fwd_date = stream.readInt32(); + } + if ((flags & MESSAGE_FLAG_REPLY) != 0) { + reply_to_msg_id = stream.readInt32(); + } + date = stream.readInt32(); + message = stream.readString(); + media = (MessageMedia)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); + if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && message != null && message.length() != 0 && message.startsWith("-1"))) { + attachPath = stream.readString(); + } + if (id < 0 && message.length() > 6 && media instanceof TL_messageMediaVideo) { + videoEditedInfo = new VideoEditedInfo(); + videoEditedInfo.parseString(message); + } + if ((flags & MESSAGE_FLAG_FWD) != 0 && id < 0) { + fwd_msg_id = stream.readInt32(); + } + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(flags); + stream.writeInt32(id); + stream.writeInt32(from_id); + to_id.serializeToStream(stream); + if ((flags & MESSAGE_FLAG_FWD) != 0) { + stream.writeInt32(fwd_from_id); + stream.writeInt32(fwd_date); + } + if ((flags & MESSAGE_FLAG_REPLY) != 0) { + stream.writeInt32(reply_to_msg_id); + } + stream.writeInt32(date); + stream.writeString(message); + media.serializeToStream(stream); + stream.writeString(attachPath); + if ((flags & MESSAGE_FLAG_FWD) != 0 && id < 0) { + stream.writeInt32(fwd_msg_id); + } + } + } + + public static class TL_message_old2 extends TL_message { public static int constructor = 0x567699b3; @@ -10073,7 +10564,7 @@ public class TLRPC { } } - public static class TL_messageForwarded_old extends TL_messageForwarded { + public static class TL_messageForwarded_old extends TL_messageForwarded_old2 { public static int constructor = 0x5f46804; @@ -10085,6 +10576,7 @@ public class TLRPC { to_id = (Peer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); flags |= stream.readBool() ? MESSAGE_FLAG_OUT : 0; flags |= stream.readBool() ? MESSAGE_FLAG_UNREAD : 0; + flags |= MESSAGE_FLAG_FWD; date = stream.readInt32(); message = stream.readString(); media = (MessageMedia)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); @@ -10189,102 +10681,6 @@ public class TLRPC { } } - public static class TL_messages_deleteMessages extends TLObject { - public static int constructor = 0x14f2dd0a; - - public ArrayList id = new ArrayList<>(); - - public Class responseClass () { - return Vector.class; - } - - public void readParams(AbsSerializedData stream) { - stream.readInt32(); - int count = stream.readInt32(); - for (int a = 0; a < count; a++) { - id.add(stream.readInt32()); - } - } - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - stream.writeInt32(0x1cb5c415); - int count = id.size(); - stream.writeInt32(count); - for (Integer anId : id) { - stream.writeInt32(anId); - } - } - - public void parseVector(Vector vector, AbsSerializedData data) { - int size = data.readInt32(); - for (int a = 0; a < size; a++) { - vector.objects.add(data.readInt32()); - } - } - } - - public static class TL_messages_restoreMessages extends TLObject { - public static int constructor = 0x395f9d7e; - - public ArrayList id = new ArrayList<>(); - - public Class responseClass () { - return Vector.class; - } - - public void readParams(AbsSerializedData stream) { - stream.readInt32(); - int count = stream.readInt32(); - for (int a = 0; a < count; a++) { - id.add(stream.readInt32()); - } - } - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - stream.writeInt32(0x1cb5c415); - int count = id.size(); - stream.writeInt32(count); - for (Integer anId : id) { - stream.writeInt32(anId); - } - } - - public void parseVector(Vector vector, AbsSerializedData data) { - int size = data.readInt32(); - for (int a = 0; a < size; a++) { - vector.objects.add(data.readInt32()); - } - } - } - - public static class TL_messages_receivedMessages extends TLObject { - public static int constructor = 0x28abcb68; - - public int max_id; - - public Class responseClass () { - return Vector.class; - } - - public void readParams(AbsSerializedData stream) { - max_id = stream.readInt32(); - } - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - stream.writeInt32(max_id); - } - - public void parseVector(Vector vector, AbsSerializedData data) { - int size = data.readInt32(); - for (int a = 0; a < size; a++) { - vector.objects.add(data.readInt32()); - } - } - } - public static class Vector extends TLObject { public static int constructor = 0x1cb5c415; public ArrayList objects = new ArrayList<>(); @@ -10456,11 +10852,12 @@ public class TLRPC { } public static class TL_dialog extends TLObject { - public static int constructor = 0xab3a99ac; + public static int constructor = 0xc1dd804a; public Peer peer; public int top_message; public int unread_count; + public int read_inbox_max_id; public PeerNotifySettings notify_settings; public int last_message_date; public long id; @@ -10469,6 +10866,7 @@ public class TLRPC { public void readParams(AbsSerializedData stream) { peer = (Peer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); top_message = stream.readInt32(); + read_inbox_max_id = stream.readInt32(); unread_count = stream.readInt32(); notify_settings = (PeerNotifySettings)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); } @@ -10477,6 +10875,7 @@ public class TLRPC { stream.writeInt32(constructor); peer.serializeToStream(stream); stream.writeInt32(top_message); + stream.writeInt32(read_inbox_max_id); stream.writeInt32(unread_count); notify_settings.serializeToStream(stream); } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/TcpConnection.java b/TMessagesProj/src/main/java/org/telegram/messenger/TcpConnection.java index 406c05139..3772ed52c 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/TcpConnection.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/TcpConnection.java @@ -28,11 +28,11 @@ public class TcpConnection extends ConnectionContext { TcpConnectionStageSuspended } - public abstract static interface TcpConnectionDelegate { - public abstract void tcpConnectionClosed(TcpConnection connection); - public abstract void tcpConnectionConnected(TcpConnection connection); - public abstract void tcpConnectionQuiackAckReceived(TcpConnection connection, int ack); - public abstract void tcpConnectionReceivedData(TcpConnection connection, ByteBufferDesc data, int length); + public interface TcpConnectionDelegate { + void tcpConnectionClosed(TcpConnection connection); + void tcpConnectionConnected(TcpConnection connection); + void tcpConnectionQuiackAckReceived(TcpConnection connection, int ack); + void tcpConnectionReceivedData(TcpConnection connection, ByteBufferDesc data, int length); } private static PyroSelector selector; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java index 0cd098656..42e44a7ca 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java @@ -30,7 +30,12 @@ public class UserConfig { private final static Object sync = new Object(); public static boolean saveIncomingPhotos = false; public static int contactsVersion = 1; - public static boolean waitingForPasswordEnter = false; + public static String passcodeHash = ""; + public static boolean appLocked = false; + public static int passcodeType = 0; + public static int autoLockIn = 60 * 60; + public static int lastPauseTime = 0; + public static boolean isWaitingForPasscodeEnter = false; public static int getNewMessageId() { int id; @@ -61,13 +66,19 @@ public class UserConfig { editor.putInt("lastBroadcastId", lastBroadcastId); editor.putBoolean("registeredForInternalPush", registeredForInternalPush); editor.putBoolean("blockedUsersLoaded", blockedUsersLoaded); - editor.putBoolean("waitingForPasswordEnter", waitingForPasswordEnter); + editor.putString("passcodeHash1", passcodeHash); + editor.putBoolean("appLocked", appLocked); + editor.putInt("passcodeType", passcodeType); + editor.putInt("autoLockIn", autoLockIn); + editor.putInt("lastPauseTime", lastPauseTime); + if (currentUser != null) { if (withFile) { SerializedData data = new SerializedData(); currentUser.serializeToStream(data); String userString = Base64.encodeToString(data.toByteArray(), Base64.DEFAULT); editor.putString("user", userString); + data.cleanup(); } } else { editor.remove("user"); @@ -88,18 +99,6 @@ public class UserConfig { } } - public static boolean isWaitingForPasswordEnter() { - synchronized (sync) { - return waitingForPasswordEnter; - } - } - - public static void setWaitingForPasswordEnter(boolean value) { - synchronized (sync) { - waitingForPasswordEnter = value; - } - } - public static int getClientUserId() { synchronized (sync) { return currentUser != null ? currentUser.id : 0; @@ -172,6 +171,7 @@ public class UserConfig { if (lastSendMessageId > -210000) { lastSendMessageId = -210000; } + data.cleanup(); Utilities.stageQueue.postRunnable(new Runnable() { @Override public void run() { @@ -194,13 +194,18 @@ public class UserConfig { lastBroadcastId = preferences.getInt("lastBroadcastId", -1); registeredForInternalPush = preferences.getBoolean("registeredForInternalPush", false); blockedUsersLoaded = preferences.getBoolean("blockedUsersLoaded", false); - waitingForPasswordEnter = preferences.getBoolean("waitingForPasswordEnter", false); + passcodeHash = preferences.getString("passcodeHash1", ""); + appLocked = preferences.getBoolean("appLocked", false); + passcodeType = preferences.getInt("passcodeType", 0); + autoLockIn = preferences.getInt("autoLockIn", 60 * 60); + lastPauseTime = preferences.getInt("lastPauseTime", 0); String user = preferences.getString("user", null); if (user != null) { byte[] userBytes = Base64.decode(user, Base64.DEFAULT); if (userBytes != null) { SerializedData data = new SerializedData(userBytes); currentUser = (TLRPC.TL_userSelf)TLClassStore.Instance().TLdeserialize(data, data.readInt32()); + data.cleanup(); } } } @@ -211,15 +216,19 @@ public class UserConfig { currentUser = null; registeredForInternalPush = false; registeredForPush = false; - waitingForPasswordEnter = false; contactsHash = ""; importHash = ""; - lastLocalId = -210000; lastSendMessageId = -210000; contactsVersion = 1; lastBroadcastId = -1; saveIncomingPhotos = false; blockedUsersLoaded = false; + appLocked = false; + passcodeType = 0; + passcodeHash = ""; + autoLockIn = 60 * 60; + lastPauseTime = 0; + isWaitingForPasscodeEnter = false; saveConfig(true); } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java b/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java index f1c865a9d..3a42f6c6f 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java @@ -21,7 +21,6 @@ import android.os.Build; import android.os.Environment; import android.provider.DocumentsContract; import android.provider.MediaStore; -import android.text.Html; import android.text.SpannableStringBuilder; import android.util.Base64; @@ -29,6 +28,8 @@ import net.hockeyapp.android.CrashManager; import net.hockeyapp.android.CrashManagerListener; import net.hockeyapp.android.UpdateManager; +import org.telegram.android.AndroidUtilities; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -39,7 +40,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; import java.security.KeyFactory; import java.security.MessageDigest; import java.security.PublicKey; @@ -97,6 +97,7 @@ public class Utilities { for (int a = 0; a < count; a++) { goodPrimes.add(data.readString()); } + data.cleanup(); } } catch (Exception e) { FileLog.e("tmessages", e); @@ -108,7 +109,9 @@ public class Utilities { public native static long doPQNative(long _what); public native static void loadBitmap(String path, Bitmap bitmap, int scale, int width, int height, int stride); + public native static int pinBitmap(Bitmap bitmap); public native static void blurBitmap(Object bitmap, int radius); + public native static void calcCDT(ByteBuffer hsvBuffer, int width, int height, ByteBuffer buffer); public native static Bitmap loadWebpImage(ByteBuffer buffer, int len, BitmapFactory.Options options); public native static Bitmap loadBpgImage(ByteBuffer buffer, int len, BitmapFactory.Options options); public native static int convertVideoFrame(ByteBuffer src, ByteBuffer dest, int destFormat, int width, int height, int padding, int swap); @@ -144,6 +147,9 @@ public class Utilities { } public static String bytesToHex(byte[] bytes) { + if (bytes == null) { + return ""; + } char[] hexChars = new char[bytes.length * 2]; int v; for (int j = 0; j < bytes.length; j++) { @@ -155,6 +161,9 @@ public class Utilities { } public static byte[] hexToBytes(String hex) { + if (hex == null) { + return null; + } int len = hex.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { @@ -228,6 +237,7 @@ public class Utilities { data.writeString(pr); } byte[] bytes = data.toByteArray(); + data.cleanup(); SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("primes", Context.MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); editor.putString("primes", Base64.encodeToString(bytes, Base64.DEFAULT)); @@ -363,35 +373,41 @@ public class Utilities { data.writeRaw(messageKey); data.writeRaw(authKey, x, 32); byte[] sha1_a = Utilities.computeSHA1(data.toByteArray()); + data.cleanup(); data = new SerializedData(); data.writeRaw(authKey, 32 + x, 16); data.writeRaw(messageKey); data.writeRaw(authKey, 48 + x, 16); byte[] sha1_b = Utilities.computeSHA1(data.toByteArray()); + data.cleanup(); data = new SerializedData(); data.writeRaw(authKey, 64 + x, 32); data.writeRaw(messageKey); byte[] sha1_c = Utilities.computeSHA1(data.toByteArray()); + data.cleanup(); data = new SerializedData(); data.writeRaw(messageKey); data.writeRaw(authKey, 96 + x, 32); byte[] sha1_d = Utilities.computeSHA1(data.toByteArray()); + data.cleanup(); - SerializedData aesKey = new SerializedData(); - aesKey.writeRaw(sha1_a, 0, 8); - aesKey.writeRaw(sha1_b, 8, 12); - aesKey.writeRaw(sha1_c, 4, 12); - keyData.aesKey = aesKey.toByteArray(); + data = new SerializedData(); + data.writeRaw(sha1_a, 0, 8); + data.writeRaw(sha1_b, 8, 12); + data.writeRaw(sha1_c, 4, 12); + keyData.aesKey = data.toByteArray(); + data.cleanup(); - SerializedData aesIv = new SerializedData(); - aesIv.writeRaw(sha1_a, 8, 12); - aesIv.writeRaw(sha1_b, 0, 8); - aesIv.writeRaw(sha1_c, 16, 4); - aesIv.writeRaw(sha1_d, 0, 8); - keyData.aesIv = aesIv.toByteArray(); + data = new SerializedData(); + data.writeRaw(sha1_a, 8, 12); + data.writeRaw(sha1_b, 0, 8); + data.writeRaw(sha1_c, 16, 4); + data.writeRaw(sha1_d, 0, 8); + keyData.aesIv = data.toByteArray(); + data.cleanup(); return keyData; } @@ -408,10 +424,25 @@ public class Utilities { while ((bytesRead = gis.read(data)) != -1) { bytesOutput.write(data, 0, bytesRead); } - gis.close(); - is.close(); + try { + gis.close(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + try { + is.close(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } SerializedData stream = new SerializedData(bytesOutput.toByteArray()); - return TLClassStore.Instance().TLdeserialize(stream, stream.readInt32(), parentObject); + try { + bytesOutput.close(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + TLObject object = TLClassStore.Instance().TLdeserialize(stream, stream.readInt32(), parentObject); + stream.cleanup(); + return object; } catch (IOException e) { FileLog.e("tmessages", e); } @@ -432,6 +463,12 @@ public class Utilities { packedData = bytesStream.toByteArray(); } catch (IOException e) { FileLog.e("tmessages", e); + } finally { + try { + bytesStream.close(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } } return packedData; } @@ -449,23 +486,23 @@ public class Utilities { } public static boolean copyFile(File sourceFile, File destFile) throws IOException { - if(!destFile.exists()) { + if (!destFile.exists()) { destFile.createNewFile(); } - FileChannel source = null; - FileChannel destination = null; + FileInputStream source = null; + FileOutputStream destination = null; try { - source = new FileInputStream(sourceFile).getChannel(); - destination = new FileOutputStream(destFile).getChannel(); - destination.transferFrom(source, 0, source.size()); + source = new FileInputStream(sourceFile); + destination = new FileOutputStream(destFile); + destination.getChannel().transferFrom(source.getChannel(), 0, source.getChannel().size()); } catch (Exception e) { FileLog.e("tmessages", e); return false; } finally { - if(source != null) { + if (source != null) { source.close(); } - if(destination != null) { + if (destination != null) { destination.close(); } } @@ -656,7 +693,7 @@ public class Utilities { builder.append(" "); } query.trim(); - builder.append(Html.fromHtml("" + query + "")); + builder.append(AndroidUtilities.replaceTags("" + query + "")); lastIndex = end; } @@ -711,7 +748,13 @@ public class Utilities { buffer.write(b); } } - return buffer.toByteArray(); + byte[] array = buffer.toByteArray(); + try { + buffer.close(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + return array; } public static void checkForCrashes(Activity context) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/AccountPasswordActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/AccountPasswordActivity.java deleted file mode 100644 index 348d20ee9..000000000 --- a/TMessagesProj/src/main/java/org/telegram/ui/AccountPasswordActivity.java +++ /dev/null @@ -1,629 +0,0 @@ -/* - * 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.Activity; -import android.app.AlertDialog; -import android.app.ProgressDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.SharedPreferences; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.FrameLayout; -import android.widget.ListView; -import android.widget.ProgressBar; - -import org.telegram.android.AndroidUtilities; -import org.telegram.android.ContactsController; -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; -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.ActionBar.ActionBar; -import org.telegram.ui.ActionBar.ActionBarMenu; -import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.Adapters.BaseFragmentAdapter; -import org.telegram.ui.Cells.HeaderCell; -import org.telegram.ui.Cells.TextFieldCell; -import org.telegram.ui.Cells.TextInfoPrivacyCell; -import org.telegram.ui.Cells.TextSettingsCell; - -import java.util.ArrayList; - -public class AccountPasswordActivity extends BaseFragment { - - private ListAdapter listAdapter; - private TextFieldCell oldPasswordCell; - private TextFieldCell newPasswordCell; - private TextFieldCell verifyPasswordCell; - private TextFieldCell hintPasswordCell; - private View doneButton; - private ProgressDialog progressDialog; - - private int type; - private boolean hasPassword; - private boolean loading; - private byte[] new_salt; - private String hint; - private byte[] current_salt; - - private int changePasswordSectionRow; - private int oldPasswordRow; - private int newPasswordRow; - private int verifyPasswordRow; - private int hintRow; - private int passwordDetailRow; - private int deleteAccountSection; - private int deleteAccountRow; - private int deleteAccountDetailRow; - private int rowCount; - - private final static int done_button = 1; - - public AccountPasswordActivity(int type) { - super(); - this.type = type; - } - - @Override - public boolean onFragmentCreate() { - super.onFragmentCreate(); - - getCurrentPassword(); - - return true; - } - - @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - if (type == 0) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - } - actionBar.setAllowOverlayTitle(true); - actionBar.setTitle(LocaleController.getString("Password", R.string.Password)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } else if (id == done_button) { - doneWithPassword(); - } - } - }); - - ActionBarMenu menu = actionBar.createMenu(); - doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); - doneButton.setVisibility(loading ? View.GONE : View.VISIBLE); - - if (type == 0) { - oldPasswordCell = new TextFieldCell(getParentActivity()); - oldPasswordCell.setFieldTitleAndHint(LocaleController.getString("OldPassword", R.string.OldPassword), LocaleController.getString("EnterOldPassword", R.string.EnterOldPassword), AndroidUtilities.dp(10), true); - oldPasswordCell.setBackgroundColor(0xffffffff); - newPasswordCell = new TextFieldCell(getParentActivity()); - newPasswordCell.setFieldTitleAndHint(LocaleController.getString("NewPassword", R.string.NewPassword), LocaleController.getString("EnterNewPassword", R.string.EnterNewPassword), 0, true); - newPasswordCell.setBackgroundColor(0xffffffff); - verifyPasswordCell = new TextFieldCell(getParentActivity()); - verifyPasswordCell.setFieldTitleAndHint(null, LocaleController.getString("VerifyNewPassword", R.string.VerifyNewPassword), AndroidUtilities.dp(10), true); - verifyPasswordCell.setBackgroundColor(0xffffffff); - hintPasswordCell = new TextFieldCell(getParentActivity()); - hintPasswordCell.setFieldTitleAndHint(LocaleController.getString("PasswordHint", R.string.PasswordHint), LocaleController.getString("EnterHint", R.string.EnterHint), AndroidUtilities.dp(22), false); - hintPasswordCell.setBackgroundColor(0xffffffff); - if (hint != null) { - hintPasswordCell.setFieldText(hint); - } - } else if (type == 1) { - oldPasswordCell = new TextFieldCell(getParentActivity()); - oldPasswordCell.setFieldTitleAndHint(null, LocaleController.getString("EnterYourPassword", R.string.EnterYourPassword), AndroidUtilities.dp(22), true); - oldPasswordCell.setBackgroundColor(0xffffffff); - } - - listAdapter = new ListAdapter(getParentActivity()); - - fragmentView = new FrameLayout(getParentActivity()); - FrameLayout frameLayout = (FrameLayout) fragmentView; - frameLayout.setBackgroundColor(0xfff0f0f0); - - FrameLayout progressView = new FrameLayout(getParentActivity()); - frameLayout.addView(progressView); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - progressView.setLayoutParams(layoutParams); - - ProgressBar progressBar = new ProgressBar(getParentActivity()); - progressView.addView(progressBar); - layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.gravity = Gravity.CENTER; - progressView.setLayoutParams(layoutParams); - - ListView listView = new ListView(getParentActivity()); - listView.setDivider(null); - listView.setDividerHeight(0); - listView.setVerticalScrollBarEnabled(false); - listView.setDrawSelectorOnTop(true); - listView.setEmptyView(progressView); - frameLayout.addView(listView); - layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.gravity = Gravity.TOP; - listView.setLayoutParams(layoutParams); - listView.setAdapter(listAdapter); - listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, final int i, long l) { - if (i == deleteAccountRow) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setMessage(LocaleController.getString("AreYouSureDeleteAccount", R.string.AreYouSureDeleteAccount)); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setMessage(LocaleController.getString("AreYouSureDeleteAccount2", R.string.AreYouSureDeleteAccount2)); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - TLRPC.TL_account_deleteAccount req = new TLRPC.TL_account_deleteAccount(); - req.reason = "Forgot password"; - ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { - @Override - public void run(TLObject response, TLRPC.TL_error error) { - if (error == null) { - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - editor.clear().commit(); - MessagesController.getInstance().unregistedPush(); - MessagesController.getInstance().logOut(); - UserConfig.clearConfig(); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.appDidLogout); - MessagesStorage.getInstance().cleanUp(false); - MessagesController.getInstance().cleanUp(); - ContactsController.getInstance().deleteAllAppAccounts(); - } - }); - } - } - }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassWithoutLogin); - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } - } - }); - - updateRows(); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); - } - } - return fragmentView; - } - - @Override - public void onResume() { - super.onResume(); - if (listAdapter != null) { - listAdapter.notifyDataSetChanged(); - } - } - - private void updateRows() { - rowCount = 0; - if (!loading) { - if (type == 0) { - changePasswordSectionRow = rowCount++; - oldPasswordRow = hasPassword ? rowCount++ : -1; - newPasswordRow = rowCount++; - verifyPasswordRow = rowCount++; - hintRow = rowCount++; - passwordDetailRow = rowCount++; - deleteAccountSection = -1; - deleteAccountRow = -1; - deleteAccountDetailRow = -1; - } else if (type == 1) { - changePasswordSectionRow = rowCount++; - oldPasswordRow = rowCount++; - passwordDetailRow = rowCount++; - deleteAccountSection = rowCount++; - deleteAccountDetailRow = rowCount++; - verifyPasswordRow = -1; - newPasswordRow = -1; - hintRow = -1; - deleteAccountRow = -1; - } - doneButton.setVisibility(View.VISIBLE); - } - listAdapter.notifyDataSetChanged(); - } - - private 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); - } - - private 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(); - } - - private void needHideProgress() { - if (progressDialog == null) { - return; - } - try { - progressDialog.dismiss(); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - progressDialog = null; - } - - private void getCurrentPassword() { - loading = true; - TLRPC.TL_account_getPassword req = new TLRPC.TL_account_getPassword(); - 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() { - loading = false; - TLRPC.account_Password res = (TLRPC.account_Password) response; - if (res instanceof TLRPC.TL_account_noPassword) { - hasPassword = false; - new_salt = res.new_salt; - hint = null; - current_salt = null; - } else if (res instanceof TLRPC.TL_account_password) { - hasPassword = true; - new_salt = res.new_salt; - hint = res.hint; - current_salt = res.current_salt; - } else { - new_salt = null; - hint = null; - current_salt = null; - } - if (new_salt != null) { - byte[] salt = new byte[new_salt.length + 16]; - Utilities.random.nextBytes(salt); - System.arraycopy(new_salt, 0, salt, 0, new_salt.length); - new_salt = salt; - } - if (type == 0 && hintPasswordCell != null && hint != null) { - hintPasswordCell.setFieldText(hint); - } - updateRows(); - } - }); - } - }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors | RPCRequest.RPCRequestClassWithoutLogin); - } - - private void doneWithPassword() { - if (type == 0) { - String oldPassword = oldPasswordCell.getFieldText(); - String newPassword = newPasswordCell.getFieldText(); - String verifyPasswrod = verifyPasswordCell.getFieldText(); - String hint = hintPasswordCell.getFieldText(); - if (hasPassword) { - if (oldPassword.length() == 0) { - needShowAlert(LocaleController.getString("PasswordOldIncorrect", R.string.PasswordOldIncorrect)); - return; - } - } - if (newPassword.length() == 0) { - needShowAlert(LocaleController.getString("PasswordNewIncorrect", R.string.PasswordNewIncorrect)); - return; - } - if (!newPassword.equals(verifyPasswrod)) { - needShowAlert(LocaleController.getString("PasswordDoNotMatch", R.string.PasswordDoNotMatch)); - return; - } - if (hint.toLowerCase().contains(newPassword.toLowerCase())) { - needShowAlert(LocaleController.getString("HintIncorrect", R.string.HintIncorrect)); - return; - } - byte[] oldPasswordBytes = null; - byte[] newPasswordBytes = null; - try { - oldPasswordBytes = oldPassword.getBytes("UTF-8"); - newPasswordBytes = newPassword.getBytes("UTF-8"); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - - TLRPC.TL_account_setPassword req = new TLRPC.TL_account_setPassword(); - req.hint = hintPasswordCell.getFieldText(); - if (req.hint == null) { - req.hint = ""; - } - if (hasPassword) { - byte[] hash = new byte[current_salt.length * 2 + oldPasswordBytes.length]; - System.arraycopy(current_salt, 0, hash, 0, current_salt.length); - System.arraycopy(oldPasswordBytes, 0, hash, oldPasswordBytes.length, oldPasswordBytes.length); - System.arraycopy(current_salt, 0, hash, hash.length - current_salt.length, current_salt.length); - req.current_password_hash = Utilities.computeSHA256(hash, 0, hash.length); - } else { - req.current_password_hash = new byte[0]; - } - - needShowProgress(); - byte[] hash = new byte[new_salt.length * 2 + newPasswordBytes.length]; - System.arraycopy(new_salt, 0, hash, 0, new_salt.length); - System.arraycopy(newPasswordBytes, 0, hash, newPasswordBytes.length, newPasswordBytes.length); - System.arraycopy(new_salt, 0, hash, hash.length - new_salt.length, new_salt.length); - req.new_password_hash = Utilities.computeSHA256(hash, 0, hash.length); - req.new_salt = new_salt; - 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(); - if (error == null) { - UserConfig.registeredForPush = false; - UserConfig.registeredForInternalPush = false; - UserConfig.saveConfig(false); - MessagesController.getInstance().registerForPush(UserConfig.pushString); - ConnectionsManager.getInstance().initPushConnection(); - finishFragment(); - } else { - if (error.text.contains("PASSWORD_HASH_INVALID")) { - needShowAlert(LocaleController.getString("PasswordOldIncorrect", R.string.PasswordOldIncorrect)); - } else if (error.text.contains("NEW_PASSWORD_BAD")) { - needShowAlert(LocaleController.getString("PasswordNewIncorrect", R.string.PasswordNewIncorrect)); - } else if (error.text.startsWith("FLOOD_WAIT")) { - needShowAlert(LocaleController.getString("FloodWait", R.string.FloodWait)); - } else { - needShowAlert(error.text); - } - } - } - }); - } - }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors); - } else if (type == 1) { - String oldPassword = oldPasswordCell.getFieldText(); - if (oldPassword.length() == 0) { - needShowAlert(LocaleController.getString("PasswordIncorrect", R.string.PasswordIncorrect)); - return; - } - byte[] oldPasswordBytes = null; - try { - oldPasswordBytes = oldPassword.getBytes("UTF-8"); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - - needShowProgress(); - byte[] hash = new byte[current_salt.length * 2 + oldPasswordBytes.length]; - System.arraycopy(current_salt, 0, hash, 0, current_salt.length); - System.arraycopy(oldPasswordBytes, 0, hash, oldPasswordBytes.length, oldPasswordBytes.length); - System.arraycopy(current_salt, 0, hash, hash.length - current_salt.length, current_salt.length); - - TLRPC.TL_auth_checkPassword req = new TLRPC.TL_auth_checkPassword(); - req.password_hash = Utilities.computeSHA256(hash, 0, hash.length); - 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(); - if (error == null) { - if (UserConfig.isClientActivated()) { - presentFragment(new MessagesActivity(null), true); - UserConfig.registeredForPush = false; - UserConfig.registeredForInternalPush = false; - UserConfig.saveConfig(false); - MessagesController.getInstance().registerForPush(UserConfig.pushString); - ConnectionsManager.getInstance().initPushConnection(); - } else { - TLRPC.TL_auth_authorization res = (TLRPC.TL_auth_authorization)response; - UserConfig.clearConfig(); - MessagesController.getInstance().cleanUp(); - UserConfig.setCurrentUser(res.user); - UserConfig.saveConfig(true); - MessagesStorage.getInstance().cleanUp(true); - ArrayList users = new ArrayList<>(); - users.add(res.user); - MessagesStorage.getInstance().putUsersAndChats(users, null, true, true); - MessagesController.getInstance().putUser(res.user, false); - ContactsController.getInstance().checkAppAccount(); - MessagesController.getInstance().getBlockedUsers(true); - presentFragment(new MessagesActivity(null), true); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.mainUserInfoChanged); - ConnectionsManager.getInstance().initPushConnection(); - } - } else { - if (error.text.contains("PASSWORD_HASH_INVALID")) { - needShowAlert(LocaleController.getString("PasswordOldIncorrect", R.string.PasswordOldIncorrect)); - } 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); - } - } - - private class ListAdapter extends BaseFragmentAdapter { - private Context mContext; - - public ListAdapter(Context context) { - mContext = context; - } - - @Override - public boolean areAllItemsEnabled() { - return false; - } - - @Override - public boolean isEnabled(int i) { - return i == deleteAccountRow; - } - - @Override - public int getCount() { - return rowCount; - } - - @Override - public Object getItem(int i) { - return null; - } - - @Override - public long getItemId(int i) { - return i; - } - - @Override - public boolean hasStableIds() { - return false; - } - - @Override - public View getView(int i, View view, ViewGroup viewGroup) { - int viewType = getItemViewType(i); - if (viewType == 0) { - if (view == null) { - view = new TextInfoPrivacyCell(mContext); - } - if (i == passwordDetailRow) { - if (type == 0) { - ((TextInfoPrivacyCell) view).setText(LocaleController.getString("PasswordImportant", R.string.PasswordImportant)); - } else if (type == 1) { - ((TextInfoPrivacyCell) view).setText(hint == null || hint.length() == 0 ? "" : LocaleController.formatString("PasswordHintDetail", R.string.PasswordHintDetail, hint)); - } - ((TextInfoPrivacyCell) view).setTextColor(0xffcf3030); - if (deleteAccountDetailRow != -1) { - view.setBackgroundResource(R.drawable.greydivider); - } else { - view.setBackgroundResource(R.drawable.greydivider_bottom); - } - } else if (i == deleteAccountDetailRow) { - ((TextInfoPrivacyCell) view).setText(LocaleController.getString("DeleteAccountImportant", R.string.DeleteAccountImportant)); - ((TextInfoPrivacyCell) view).setTextColor(0xffcf3030); - view.setBackgroundResource(R.drawable.greydivider_bottom); - } - } else if (viewType == 1) { - if (view == null) { - view = new HeaderCell(mContext); - view.setBackgroundColor(0xffffffff); - } - if (i == changePasswordSectionRow) { - if (type == 0) { - ((HeaderCell) view).setText(LocaleController.getString("ChangePassword", R.string.ChangePassword)); - } else if (type == 1) { - ((HeaderCell) view).setText(LocaleController.getString("EnterPassword", R.string.EnterPassword)); - } - } else if (i == deleteAccountSection) { - ((HeaderCell) view).setText(LocaleController.getString("PasswordDeleteAccountTitle", R.string.PasswordDeleteAccountTitle)); - } - } else if (viewType == 2) { - return newPasswordCell; - } else if (viewType == 3) { - return oldPasswordCell; - } else if (viewType == 4) { - return verifyPasswordCell; - } else if (viewType == 5) { - return hintPasswordCell; - } else if (viewType == 6) { - if (view == null) { - view = new TextSettingsCell(mContext); - view.setBackgroundColor(0xffffffff); - } - TextSettingsCell textCell = (TextSettingsCell) view; - if (i == deleteAccountRow) { - textCell.setText(LocaleController.getString("PasswordDeleteAccount", R.string.PasswordDeleteAccount), false); - } - } - return view; - } - - @Override - public int getItemViewType(int i) { - if (i == passwordDetailRow || i == deleteAccountDetailRow) { - return 0; - } else if (i == changePasswordSectionRow || i == deleteAccountSection) { - return 1; - } else if (i == newPasswordRow) { - return 2; - } else if (i == oldPasswordRow) { - return 3; - } else if (i == verifyPasswordRow) { - return 4; - } else if (i == hintRow) { - return 5; - } else if (i == deleteAccountRow) { - return 6; - } - return 0; - } - - @Override - public int getViewTypeCount() { - return 7; - } - - @Override - public boolean isEmpty() { - return rowCount == 0; - } - } -} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBar.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBar.java index 188fdf767..8c94548bf 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBar.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBar.java @@ -13,6 +13,7 @@ import android.content.res.Configuration; import android.graphics.drawable.Drawable; import android.os.Build; import android.text.TextUtils; +import android.util.TypedValue; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -47,7 +48,6 @@ public class ActionBar extends FrameLayout { private boolean allowOverlayTitle; private CharSequence lastTitle; - private boolean showingOverlayTitle; private boolean castShadows = true; protected boolean isSearchFieldVisible; @@ -91,9 +91,9 @@ public class ActionBar extends FrameLayout { if (titleTextView != null && titleTextView.getVisibility() == VISIBLE) { if (!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { - titleTextView.setTextSize(18); + titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); } else { - titleTextView.setTextSize(20); + titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); } layoutParams = (LayoutParams) titleTextView.getLayoutParams(); @@ -106,9 +106,9 @@ public class ActionBar extends FrameLayout { } if (subTitleTextView != null && subTitleTextView.getVisibility() == VISIBLE) { if (!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { - subTitleTextView.setTextSize(14); + subTitleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); } else { - subTitleTextView.setTextSize(16); + subTitleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); } layoutParams = (LayoutParams) subTitleTextView.getLayoutParams(); @@ -121,22 +121,14 @@ public class ActionBar extends FrameLayout { } int x = 0; - if (backButtonImageView != null) { - if (AndroidUtilities.isTablet()) { - x = AndroidUtilities.dp(80); - } else { - x = AndroidUtilities.dp(72); - } + if (backButtonImageView != null && backButtonImageView.getVisibility() == VISIBLE) { + x = AndroidUtilities.dp(AndroidUtilities.isTablet() ? 80 : 72); } else { - if (AndroidUtilities.isTablet()) { - x = AndroidUtilities.dp(26); - } else { - x = AndroidUtilities.dp(18); - } + x = AndroidUtilities.dp(AndroidUtilities.isTablet() ? 26 : 18); } if (menu != null) { - maxTextWidth = Math.min(maxTextWidth, width - menu.getMeasuredWidth() - AndroidUtilities.dp(16)); + maxTextWidth = Math.min(maxTextWidth, width - menu.getMeasuredWidth() - AndroidUtilities.dp(16) - x); } if (titleTextView != null && titleTextView.getVisibility() == VISIBLE) { @@ -173,7 +165,7 @@ public class ActionBar extends FrameLayout { FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)menu.getLayoutParams(); layoutParams.width = isSearchFieldVisible ? LayoutParams.MATCH_PARENT : LayoutParams.WRAP_CONTENT; layoutParams.height = height; - layoutParams.leftMargin = isSearchFieldVisible ? AndroidUtilities.dp(54) : 0; + layoutParams.leftMargin = isSearchFieldVisible ? AndroidUtilities.dp(AndroidUtilities.isTablet() ? 74 : 66) : 0; layoutParams.topMargin = occupyStatusBar ? AndroidUtilities.statusBarHeight : 0; menu.setLayoutParams(layoutParams); menu.measure(width, height); @@ -202,17 +194,31 @@ public class ActionBar extends FrameLayout { } public void setBackButtonDrawable(Drawable drawable) { + boolean reposition = false; if (backButtonImageView == null) { createBackButtonImage(); + } else { + reposition = true; } + backButtonImageView.setVisibility(drawable == null ? GONE : VISIBLE); backButtonImageView.setImageDrawable(drawable); + if (reposition) { + positionTitle(getMeasuredWidth(), getMeasuredHeight()); + } } public void setBackButtonImage(int resource) { + boolean reposition = false; if (backButtonImageView == null) { createBackButtonImage(); + } else { + reposition = true; } + backButtonImageView.setVisibility(resource == 0 ? GONE : VISIBLE); backButtonImageView.setImageResource(resource); + if (reposition) { + positionTitle(getMeasuredWidth(), getMeasuredHeight()); + } } private void createSubtitleTextView() { @@ -234,7 +240,7 @@ public class ActionBar extends FrameLayout { createSubtitleTextView(); } if (subTitleTextView != null) { - subTitleTextView.setVisibility(value != null && !isSearchFieldVisible ? VISIBLE : GONE); + subTitleTextView.setVisibility(value != null && !isSearchFieldVisible ? VISIBLE : INVISIBLE); subTitleTextView.setText(value); positionTitle(getMeasuredWidth(), getMeasuredHeight()); } @@ -276,7 +282,7 @@ public class ActionBar extends FrameLayout { } if (titleTextView != null) { lastTitle = value; - titleTextView.setVisibility(value != null && !isSearchFieldVisible ? VISIBLE : GONE); + titleTextView.setVisibility(value != null && !isSearchFieldVisible ? VISIBLE : INVISIBLE); titleTextView.setText(value); positionTitle(getMeasuredWidth(), getMeasuredHeight()); } @@ -344,7 +350,7 @@ public class ActionBar extends FrameLayout { layoutParams.width = LayoutParams.FILL_PARENT; layoutParams.gravity = Gravity.RIGHT; actionMode.setLayoutParams(layoutParams); - actionMode.setVisibility(GONE); + actionMode.setVisibility(INVISIBLE); if (occupyStatusBar) { actionModeTop = new View(getContext()); @@ -355,7 +361,7 @@ public class ActionBar extends FrameLayout { layoutParams.width = LayoutParams.FILL_PARENT; layoutParams.gravity = Gravity.TOP | Gravity.LEFT; actionModeTop.setLayoutParams(layoutParams); - actionModeTop.setVisibility(GONE); + actionModeTop.setVisibility(INVISIBLE); } return actionMode; @@ -366,7 +372,7 @@ public class ActionBar extends FrameLayout { return; } actionMode.setVisibility(VISIBLE); - if (actionModeTop != null) { + if (occupyStatusBar && actionModeTop != null) { actionModeTop.setVisibility(VISIBLE); } if (titleFrameLayout != null) { @@ -381,9 +387,9 @@ public class ActionBar extends FrameLayout { if (actionMode == null) { return; } - actionMode.setVisibility(GONE); - if (actionModeTop != null) { - actionModeTop.setVisibility(GONE); + actionMode.setVisibility(INVISIBLE); + if (occupyStatusBar && actionModeTop != null) { + actionModeTop.setVisibility(INVISIBLE); } if (titleFrameLayout != null) { titleFrameLayout.setVisibility(VISIBLE); @@ -400,10 +406,10 @@ public class ActionBar extends FrameLayout { protected void onSearchFieldVisibilityChanged(boolean visible) { isSearchFieldVisible = visible; if (titleTextView != null) { - titleTextView.setVisibility(visible ? GONE : VISIBLE); + titleTextView.setVisibility(visible ? INVISIBLE : VISIBLE); } if (subTitleTextView != null) { - subTitleTextView.setVisibility(visible ? GONE : VISIBLE); + subTitleTextView.setVisibility(visible ? INVISIBLE : VISIBLE); } Drawable drawable = backButtonImageView.getDrawable(); if (drawable != null && drawable instanceof MenuDrawable) { @@ -418,6 +424,13 @@ public class ActionBar extends FrameLayout { menu.closeSearchField(); } + public void openSearchField(String text) { + if (menu == null || text == null) { + return; + } + menu.openSearchField(!isSearchFieldVisible, text); + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int actionBarHeight = AndroidUtilities.getCurrentActionBarHeight(); @@ -445,16 +458,15 @@ public class ActionBar extends FrameLayout { } public void setTitleOverlayText(String text) { - if (showingOverlayTitle == (text != null) || !allowOverlayTitle || parentFragment.parentLayout == null) { + if (!allowOverlayTitle || parentFragment.parentLayout == null) { return; } - showingOverlayTitle = text != null; CharSequence textToSet = text != null ? text : lastTitle; if (textToSet != null && titleTextView == null) { createTitleTextView(); } if (titleTextView != null) { - titleTextView.setVisibility(textToSet != null && !isSearchFieldVisible ? VISIBLE : GONE); + titleTextView.setVisibility(textToSet != null && !isSearchFieldVisible ? VISIBLE : INVISIBLE); titleTextView.setText(textToSet); positionTitle(getMeasuredWidth(), getMeasuredHeight()); } @@ -473,6 +485,9 @@ public class ActionBar extends FrameLayout { public void setOccupyStatusBar(boolean value) { occupyStatusBar = value; + if (actionMode != null) { + actionMode.setPadding(0, occupyStatusBar ? AndroidUtilities.statusBarHeight : 0, 0, 0); + } } public boolean getOccupyStatusBar() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java index bf295a531..c49768f8a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java @@ -39,12 +39,12 @@ import java.util.ArrayList; public class ActionBarLayout extends FrameLayout { - public static interface ActionBarLayoutDelegate { - public abstract boolean onPreIme(); - public abstract boolean needPresentFragment(BaseFragment fragment, boolean removeLast, boolean forceWithoutAnimation, ActionBarLayout layout); - public abstract boolean needAddFragmentToStack(BaseFragment fragment, ActionBarLayout layout); - public abstract boolean needCloseLastFragment(ActionBarLayout layout); - public abstract void onRebuildAllFragments(ActionBarLayout layout); + public interface ActionBarLayoutDelegate { + boolean onPreIme(); + boolean needPresentFragment(BaseFragment fragment, boolean removeLast, boolean forceWithoutAnimation, ActionBarLayout layout); + boolean needAddFragmentToStack(BaseFragment fragment, ActionBarLayout layout); + boolean needCloseLastFragment(ActionBarLayout layout); + void onRebuildAllFragments(ActionBarLayout layout); } public class LinearLayoutContainer extends LinearLayout { @@ -225,7 +225,7 @@ public class ActionBarLayout extends FrameLayout { @Override public boolean dispatchKeyEventPreIme(KeyEvent event) { - if (event != null && event.getKeyCode() == KeyEvent.KEYCODE_BACK) { + if (event != null && event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) { return delegate != null && delegate.onPreIme() || super.dispatchKeyEventPreIme(event); } return super.dispatchKeyEventPreIme(event); @@ -303,7 +303,7 @@ public class ActionBarLayout extends FrameLayout { } } } - containerViewBack.setVisibility(View.GONE); + containerViewBack.setVisibility(View.INVISIBLE); //AndroidUtilities.unlockOrientation(parentActivity); startedTracking = false; animationInProgress = false; @@ -321,7 +321,15 @@ public class ActionBarLayout extends FrameLayout { beginTrackingSent = false; BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 2); - View fragmentView = lastFragment.createView(parentActivity.getLayoutInflater(), null); + View fragmentView = lastFragment.fragmentView; + if (fragmentView == null) { + fragmentView = lastFragment.createView(parentActivity, parentActivity.getLayoutInflater()); + } else { + ViewGroup parent = (ViewGroup) fragmentView.getParent(); + if (parent != null) { + parent.removeView(fragmentView); + } + } ViewGroup parent = (ViewGroup) fragmentView.getParent(); if (parent != null) { parent.removeView(fragmentView); @@ -342,7 +350,7 @@ public class ActionBarLayout extends FrameLayout { layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; fragmentView.setLayoutParams(layoutParams); - if (fragmentView.getBackground() == null) { + if (!lastFragment.hasOwnBackground && fragmentView.getBackground() == null) { fragmentView.setBackgroundColor(0xffffffff); } lastFragment.onResume(); @@ -372,7 +380,7 @@ public class ActionBarLayout extends FrameLayout { int dx = Math.max(0, (int) (ev.getX() - startedTrackingX)); int dy = Math.abs((int) ev.getY() - startedTrackingY); velocityTracker.addMovement(ev); - if (maybeStartTracking && !startedTracking && dx >= AndroidUtilities.dp(10) && Math.abs(dx) / 3 > dy) { + if (maybeStartTracking && !startedTracking && dx >= AndroidUtilities.getPixelsInCM(0.3f, true) && Math.abs(dx) / 3 > dy) { prepareForMoving(ev); } else if (startedTracking) { if (!beginTrackingSent) { @@ -502,8 +510,7 @@ public class ActionBarLayout extends FrameLayout { } public boolean checkTransitionAnimation() { - if (transitionAnimationInProgress && transitionAnimationStartTime < System.currentTimeMillis() - 400) { - transitionAnimationInProgress = false; + if (transitionAnimationInProgress && transitionAnimationStartTime < System.currentTimeMillis() - 1000) { onAnimationEndCheck(true); } return transitionAnimationInProgress; @@ -532,7 +539,7 @@ public class ActionBarLayout extends FrameLayout { } } } - containerViewBack.setVisibility(View.GONE); + containerViewBack.setVisibility(View.INVISIBLE); } public boolean presentFragment(BaseFragment fragment) { @@ -556,7 +563,15 @@ public class ActionBarLayout extends FrameLayout { final BaseFragment currentFragment = !fragmentsStack.isEmpty() ? fragmentsStack.get(fragmentsStack.size() - 1) : null; fragment.setParentLayout(this); - View fragmentView = fragment.createView(parentActivity.getLayoutInflater(), null); + View fragmentView = fragment.fragmentView; + if (fragmentView == null) { + fragmentView = fragment.createView(parentActivity, parentActivity.getLayoutInflater()); + } else { + ViewGroup parent = (ViewGroup) fragmentView.getParent(); + if (parent != null) { + parent.removeView(fragmentView); + } + } if (fragment.needAddActionBar() && fragment.actionBar != null) { if (removeActionBarExtraHeight) { fragment.actionBar.setOccupyStatusBar(false); @@ -577,7 +592,7 @@ public class ActionBarLayout extends FrameLayout { fragmentsStack.add(fragment); fragment.onResume(); currentActionBar = fragment.actionBar; - if (fragmentView.getBackground() == null) { + if (!fragment.hasOwnBackground && fragmentView.getBackground() == null) { fragmentView.setBackgroundColor(0xffffffff); } @@ -585,6 +600,7 @@ public class ActionBarLayout extends FrameLayout { containerView = containerViewBack; containerViewBack = temp; containerView.setVisibility(View.VISIBLE); + setInnerTranslationX(0); bringChildToFront(containerView); @@ -633,6 +649,8 @@ public class ActionBarLayout extends FrameLayout { ViewProxy.setTranslationX(containerView, 0); } }; + ViewProxy.setAlpha(containerView, 0.0f); + ViewProxy.setTranslationX(containerView, 48.0f); currentAnimation = new AnimatorSetProxy(); currentAnimation.playTogether( ObjectAnimatorProxy.ofFloat(containerView, "alpha", 0.0f, 1.0f), @@ -640,6 +658,11 @@ public class ActionBarLayout extends FrameLayout { currentAnimation.setInterpolator(new DecelerateInterpolator(1.5f)); currentAnimation.setDuration(200); currentAnimation.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationStart(Object animation) { + transitionAnimationStartTime = System.currentTimeMillis(); + } + @Override public void onAnimationEnd(Object animation) { onAnimationEndCheck(false); @@ -672,6 +695,22 @@ public class ActionBarLayout extends FrameLayout { } fragment.setParentLayout(this); if (position == -1) { + if (!fragmentsStack.isEmpty()) { + BaseFragment previousFragment = fragmentsStack.get(fragmentsStack.size() - 1); + previousFragment.onPause(); + if (previousFragment.actionBar != null) { + ViewGroup parent = (ViewGroup) previousFragment.actionBar.getParent(); + if (parent != null) { + parent.removeView(previousFragment.actionBar); + } + } + if (previousFragment.fragmentView != null) { + ViewGroup parent = (ViewGroup) previousFragment.fragmentView.getParent(); + if (parent != null) { + parent.removeView(previousFragment.fragmentView); + } + } + } fragmentsStack.add(fragment); } else { fragmentsStack.add(position, fragment); @@ -684,17 +723,18 @@ public class ActionBarLayout extends FrameLayout { fragment.onFragmentDestroy(); fragment.setParentLayout(null); fragmentsStack.remove(fragment); - containerViewBack.setVisibility(View.GONE); + containerViewBack.setVisibility(View.INVISIBLE); bringChildToFront(containerView); } public void closeLastFragment(boolean animated) { - if (delegate != null && !delegate.needCloseLastFragment(this) || checkTransitionAnimation()) { + if (delegate != null && !delegate.needCloseLastFragment(this) || checkTransitionAnimation() || fragmentsStack.isEmpty()) { return; } if (parentActivity.getCurrentFocus() != null) { AndroidUtilities.hideKeyboard(parentActivity.getCurrentFocus()); } + setInnerTranslationX(0); boolean needAnimation = Build.VERSION.SDK_INT > 10 && animated && parentActivity.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).getBoolean("view_animations", true); final BaseFragment currentFragment = fragmentsStack.get(fragmentsStack.size() - 1); BaseFragment previousFragment = null; @@ -709,7 +749,15 @@ public class ActionBarLayout extends FrameLayout { containerView.setVisibility(View.VISIBLE); previousFragment.setParentLayout(this); - View fragmentView = previousFragment.createView(parentActivity.getLayoutInflater(), null); + View fragmentView = previousFragment.fragmentView; + if (fragmentView == null) { + fragmentView = previousFragment.createView(parentActivity, parentActivity.getLayoutInflater()); + } else { + ViewGroup parent = (ViewGroup) fragmentView.getParent(); + if (parent != null) { + parent.removeView(fragmentView); + } + } if (previousFragment.needAddActionBar() && previousFragment.actionBar != null) { if (removeActionBarExtraHeight) { previousFragment.actionBar.setOccupyStatusBar(false); @@ -728,7 +776,7 @@ public class ActionBarLayout extends FrameLayout { fragmentView.setLayoutParams(layoutParams); previousFragment.onResume(); currentActionBar = previousFragment.actionBar; - if (fragmentView.getBackground() == null) { + if (!previousFragment.hasOwnBackground && fragmentView.getBackground() == null) { fragmentView.setBackgroundColor(0xffffffff); } @@ -754,6 +802,11 @@ public class ActionBarLayout extends FrameLayout { currentAnimation.setInterpolator(new DecelerateInterpolator(1.5f)); currentAnimation.setDuration(200); currentAnimation.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationStart(Object animation) { + transitionAnimationStartTime = System.currentTimeMillis(); + } + @Override public void onAnimationEnd(Object animation) { onAnimationEndCheck(false); @@ -775,12 +828,12 @@ public class ActionBarLayout extends FrameLayout { @Override public void run() { removeFragmentFromStack(currentFragment); - setVisibility(GONE); + setVisibility(INVISIBLE); if (backgroundView != null) { - backgroundView.setVisibility(GONE); + backgroundView.setVisibility(INVISIBLE); } if (drawerLayoutContainer != null) { - drawerLayoutContainer.setAllowOpenDrawer(true); + drawerLayoutContainer.setAllowOpenDrawer(true, false); } } }; @@ -796,6 +849,11 @@ public class ActionBarLayout extends FrameLayout { currentAnimation.setInterpolator(new AccelerateDecelerateInterpolator()); currentAnimation.setDuration(200); currentAnimation.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationStart(Object animation) { + transitionAnimationStartTime = System.currentTimeMillis(); + } + @Override public void onAnimationEnd(Object animation) { onAnimationEndCheck(false); @@ -809,9 +867,9 @@ public class ActionBarLayout extends FrameLayout { currentAnimation.start(); } else { removeFragmentFromStack(currentFragment); - setVisibility(GONE); + setVisibility(INVISIBLE); if (backgroundView != null) { - backgroundView.setVisibility(GONE); + backgroundView.setVisibility(INVISIBLE); } } } @@ -823,7 +881,15 @@ public class ActionBarLayout extends FrameLayout { } BaseFragment previousFragment = fragmentsStack.get(fragmentsStack.size() - 1); previousFragment.setParentLayout(this); - View fragmentView = previousFragment.createView(parentActivity.getLayoutInflater(), null); + View fragmentView = previousFragment.fragmentView; + if (fragmentView == null) { + fragmentView = previousFragment.createView(parentActivity, parentActivity.getLayoutInflater()); + } else { + ViewGroup parent = (ViewGroup) fragmentView.getParent(); + if (parent != null) { + parent.removeView(fragmentView); + } + } if (previousFragment.needAddActionBar() && previousFragment.actionBar != null) { if (removeActionBarExtraHeight) { previousFragment.actionBar.setOccupyStatusBar(false); @@ -842,7 +908,7 @@ public class ActionBarLayout extends FrameLayout { fragmentView.setLayoutParams(layoutParams); previousFragment.onResume(); currentActionBar = previousFragment.actionBar; - if (fragmentView.getBackground() == null) { + if (!previousFragment.hasOwnBackground && fragmentView.getBackground() == null) { fragmentView.setBackgroundColor(0xffffffff); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenu.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenu.java index 188804be6..3a63dd188 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenu.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenu.java @@ -52,7 +52,7 @@ public class ActionBarMenu extends LinearLayout { view.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { - onItemClick((Integer)view.getTag()); + onItemClick((Integer) view.getTag()); } }); return view; @@ -147,6 +147,24 @@ public class ActionBarMenu extends LinearLayout { ActionBarMenuItem item = (ActionBarMenuItem)view; if (item.isSearchField()) { parentActionBar.onSearchFieldVisibilityChanged(item.toggleSearch()); + break; + } + } + } + } + + public void openSearchField(boolean toggle, String text) { + for (int a = 0; a < getChildCount(); a++) { + View view = getChildAt(a); + if (view instanceof ActionBarMenuItem) { + ActionBarMenuItem item = (ActionBarMenuItem)view; + if (item.isSearchField()) { + if (toggle) { + parentActionBar.onSearchFieldVisibilityChanged(item.toggleSearch()); + } + item.getSearchField().setText(text); + item.getSearchField().setSelection(text.length()); + break; } } } 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 966505486..e8991c227 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenuItem.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenuItem.java @@ -42,7 +42,7 @@ public class ActionBarMenuItem extends FrameLayoutFixed { public static class ActionBarMenuItemSearchListener { public void onSearchExpand() { } - public void onSearchCollapse() { } + public boolean onSearchCollapse() { return true; } public void onTextChanged(EditText editText) { } public void onSearchPressed(EditText editText) { } } @@ -322,11 +322,10 @@ public class ActionBarMenuItem extends FrameLayoutFixed { return false; } if (searchContainer.getVisibility() == VISIBLE) { - searchContainer.setVisibility(GONE); - setVisibility(VISIBLE); - AndroidUtilities.hideKeyboard(searchField); - if (listener != null) { - listener.onSearchCollapse(); + if (listener == null || listener != null && listener.onSearchCollapse()) { + searchContainer.setVisibility(GONE); + setVisibility(VISIBLE); + AndroidUtilities.hideKeyboard(searchField); } return false; } else { @@ -348,6 +347,10 @@ public class ActionBarMenuItem extends FrameLayoutFixed { } } + public void setIcon(int resId) { + iconView.setImageResource(resId); + } + public EditText getSearchField() { return searchField; } @@ -399,7 +402,7 @@ public class ActionBarMenuItem extends FrameLayoutFixed { searchField.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - if (actionId == EditorInfo.IME_ACTION_SEARCH || event != null && event.getAction() == KeyEvent.ACTION_UP && event.getKeyCode() == KeyEvent.KEYCODE_SEARCH) { + if (actionId == EditorInfo.IME_ACTION_SEARCH || event != null && (event.getAction() == KeyEvent.ACTION_UP && event.getKeyCode() == KeyEvent.KEYCODE_SEARCH || event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) { AndroidUtilities.hideKeyboard(searchField); if (listener != null) { listener.onSearchPressed(searchField); 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 e67c9c640..479ab5512 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarPopupWindow.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarPopupWindow.java @@ -48,8 +48,8 @@ public class ActionBarPopupWindow extends PopupWindow { private ViewTreeObserver.OnScrollChangedListener mSuperScrollListener; private ViewTreeObserver mViewTreeObserver; - public static interface OnDispatchKeyEventListener { - public void onDispatchKeyEvent(KeyEvent keyEvent); + public interface OnDispatchKeyEventListener { + void onDispatchKeyEvent(KeyEvent keyEvent); } public static class ActionBarPopupWindowLayout extends LinearLayout { @@ -200,7 +200,11 @@ public class ActionBarPopupWindow extends PopupWindow { @Override public void dismiss() { setFocusable(false); - super.dismiss(); + try { + super.dismiss(); + } catch (Exception e) { + //don't promt + } unregisterListener(); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BaseFragment.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BaseFragment.java index 9270ca1ca..b6592a2d9 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BaseFragment.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BaseFragment.java @@ -10,6 +10,7 @@ package org.telegram.ui.ActionBar; import android.app.Activity; import android.app.AlertDialog; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; @@ -23,7 +24,7 @@ import org.telegram.messenger.R; public class BaseFragment { private boolean isFinished = false; - private AlertDialog visibleDialog = null; + protected AlertDialog visibleDialog = null; protected View fragmentView; protected ActionBarLayout parentLayout; @@ -31,6 +32,7 @@ public class BaseFragment { protected int classGuid = 0; protected Bundle arguments; protected boolean swipeBackEnabled = true; + protected boolean hasOwnBackground = false; public BaseFragment() { classGuid = ConnectionsManager.getInstance().generateClassGuid(); @@ -41,7 +43,7 @@ public class BaseFragment { classGuid = ConnectionsManager.getInstance().generateClassGuid(); } - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(Context context, LayoutInflater inflater) { return null; } @@ -76,7 +78,7 @@ public class BaseFragment { if (parentLayout != null) { actionBar = new ActionBar(parentLayout.getContext()); actionBar.parentFragment = this; - actionBar.setBackgroundResource(R.color.header); + actionBar.setBackgroundColor(0xff54759e); actionBar.setItemsBackground(R.drawable.bar_selector); } } @@ -201,9 +203,9 @@ public class BaseFragment { return true; } - protected void showAlertDialog(AlertDialog.Builder builder) { + public AlertDialog showAlertDialog(AlertDialog.Builder builder) { if (parentLayout == null || parentLayout.checkTransitionAnimation() || parentLayout.animationInProgress || parentLayout.startedTracking) { - return; + return null; } try { if (visibleDialog != null) { @@ -223,9 +225,11 @@ public class BaseFragment { onDialogDismiss(); } }); + return visibleDialog; } catch (Exception e) { FileLog.e("tmessages", e); } + return null; } protected void onDialogDismiss() { 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 1c607dd5f..aa136bf16 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/DrawerLayoutContainer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/DrawerLayoutContainer.java @@ -165,6 +165,9 @@ public class DrawerLayoutContainer extends FrameLayout { } public void openDrawer(boolean fast) { + if (!allowOpenDrawer) { + return; + } if (AndroidUtilities.isTablet() && parentActionBarLayout != null && parentActionBarLayout.parentActivity != null) { AndroidUtilities.hideKeyboard(parentActionBarLayout.parentActivity.getCurrentFocus()); } @@ -248,11 +251,15 @@ public class DrawerLayoutContainer extends FrameLayout { parentActionBarLayout = layout; } - public void setAllowOpenDrawer(boolean value) { + public void setAllowOpenDrawer(boolean value, boolean animated) { allowOpenDrawer = value; if (!allowOpenDrawer && drawerPosition != 0) { - setDrawerPosition(0); - onDrawerAnimationEnd(false); + if (!animated) { + setDrawerPosition(0); + onDrawerAnimationEnd(false); + } else { + closeDrawer(true); + } } } @@ -294,7 +301,7 @@ public class DrawerLayoutContainer extends FrameLayout { float dx = (int) (ev.getX() - startedTrackingX); float dy = Math.abs((int) ev.getY() - startedTrackingY); velocityTracker.addMovement(ev); - 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))) { + if (maybeStartTracking && !startedTracking && (dx > 0 && dx / 3.0f > Math.abs(dy) && Math.abs(dx) >= AndroidUtilities.getPixelsInCM(0.2f, true) || dx < 0 && Math.abs(dx) >= Math.abs(dy) && Math.abs(dx) >= AndroidUtilities.getPixelsInCM(0.3f, true))) { prepareForDrawerOpen(ev); startedTrackingX = (int) ev.getX(); requestDisallowInterceptTouchEvent(true); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/BaseContactsSearchAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/BaseContactsSearchAdapter.java deleted file mode 100644 index e125d0a28..000000000 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/BaseContactsSearchAdapter.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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.Adapters; - -import org.telegram.android.AndroidUtilities; -import org.telegram.messenger.ConnectionsManager; -import org.telegram.messenger.RPCRequest; -import org.telegram.messenger.TLObject; -import org.telegram.messenger.TLRPC; - -import java.util.ArrayList; - -public class BaseContactsSearchAdapter extends BaseFragmentAdapter { - - protected ArrayList globalSearch = new ArrayList<>(); - private long reqId = 0; - private int lastReqId; - protected String lastFoundUsername = null; - - public void queryServerSearch(final String query) { - if (reqId != 0) { - ConnectionsManager.getInstance().cancelRpc(reqId, true); - reqId = 0; - } - if (query == null || query.length() < 5) { - globalSearch.clear(); - lastReqId = 0; - notifyDataSetChanged(); - return; - } - TLRPC.TL_contacts_search req = new TLRPC.TL_contacts_search(); - req.q = query; - req.limit = 50; - final int currentReqId = ++lastReqId; - 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 (currentReqId == lastReqId) { - if (error == null) { - TLRPC.TL_contacts_found res = (TLRPC.TL_contacts_found) response; - globalSearch = res.users; - lastFoundUsername = query; - notifyDataSetChanged(); - } - } - reqId = 0; - } - }); - } - }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors); - } -} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/BaseSearchAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/BaseSearchAdapter.java new file mode 100644 index 000000000..66ddd338b --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/BaseSearchAdapter.java @@ -0,0 +1,209 @@ +/* + * 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.Adapters; + +import org.telegram.SQLite.SQLiteCursor; +import org.telegram.SQLite.SQLitePreparedStatement; +import org.telegram.android.AndroidUtilities; +import org.telegram.android.MessagesStorage; +import org.telegram.messenger.ConnectionsManager; +import org.telegram.messenger.FileLog; +import org.telegram.messenger.RPCRequest; +import org.telegram.messenger.TLObject; +import org.telegram.messenger.TLRPC; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class BaseSearchAdapter extends BaseFragmentAdapter { + + protected static class HashtagObject { + String hashtag; + int date; + } + + protected ArrayList globalSearch = new ArrayList<>(); + private long reqId = 0; + private int lastReqId; + protected String lastFoundUsername = null; + + protected ArrayList hashtags; + protected HashMap hashtagsByText; + protected boolean hashtagsLoadedFromDb = false; + + public void queryServerSearch(final String query) { + if (reqId != 0) { + ConnectionsManager.getInstance().cancelRpc(reqId, true); + reqId = 0; + } + if (query == null || query.length() < 5) { + globalSearch.clear(); + lastReqId = 0; + notifyDataSetChanged(); + return; + } + TLRPC.TL_contacts_search req = new TLRPC.TL_contacts_search(); + req.q = query; + req.limit = 50; + final int currentReqId = ++lastReqId; + 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 (currentReqId == lastReqId) { + if (error == null) { + TLRPC.TL_contacts_found res = (TLRPC.TL_contacts_found) response; + globalSearch = res.users; + lastFoundUsername = query; + notifyDataSetChanged(); + } + } + reqId = 0; + } + }); + } + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors); + } + + public void loadRecentHashtags() { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { + @Override + public void run() { + try { + SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT id, date FROM hashtag_recent_v2 WHERE 1"); + final ArrayList arrayList = new ArrayList<>(); + final HashMap hashMap = new HashMap<>(); + while (cursor.next()) { + HashtagObject hashtagObject = new HashtagObject(); + hashtagObject.hashtag = cursor.stringValue(0); + hashtagObject.date = cursor.intValue(1); + arrayList.add(hashtagObject); + hashMap.put(hashtagObject.hashtag, hashtagObject); + } + cursor.dispose(); + Collections.sort(arrayList, new Comparator() { + @Override + public int compare(HashtagObject lhs, HashtagObject rhs) { + if (lhs.date < rhs.date) { + return 1; + } else if (lhs.date > rhs.date) { + return -1; + } else { + return 0; + } + } + }); + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + setHashtags(arrayList, hashMap); + } + }); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + } + + public void addHashtagsFromMessage(String message) { + if (message == null) { + return; + } + boolean changed = false; + Pattern pattern = Pattern.compile("(^|\\s)#[\\w@\\.]+"); + Matcher matcher = pattern.matcher(message); + while (matcher.find()) { + int start = matcher.start(); + int end = matcher.end(); + if (message.charAt(start) != '@' && message.charAt(start) != '#') { + start++; + } + String hashtag = message.substring(start, end); + if (hashtagsByText == null) { + hashtagsByText = new HashMap<>(); + hashtags = new ArrayList<>(); + } + HashtagObject hashtagObject = hashtagsByText.get(hashtag); + if (hashtagObject == null) { + hashtagObject = new HashtagObject(); + hashtagObject.hashtag = hashtag; + hashtagsByText.put(hashtagObject.hashtag, hashtagObject); + } else { + hashtags.remove(hashtagObject); + } + hashtagObject.date = (int) (System.currentTimeMillis() / 1000); + hashtags.add(0, hashtagObject); + changed = true; + } + if (changed) { + putRecentHashtags(hashtags); + } + } + + private void putRecentHashtags(final ArrayList arrayList) { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { + @Override + public void run() { + try { + MessagesStorage.getInstance().getDatabase().beginTransaction(); + SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO hashtag_recent_v2 VALUES(?, ?)"); + for (int a = 0; a < arrayList.size(); a++) { + if (a == 100) { + break; + } + HashtagObject hashtagObject = arrayList.get(a); + state.requery(); + state.bindString(1, hashtagObject.hashtag); + state.bindInteger(2, hashtagObject.date); + state.step(); + } + state.dispose(); + MessagesStorage.getInstance().getDatabase().commitTransaction(); + if (arrayList.size() >= 100) { + MessagesStorage.getInstance().getDatabase().beginTransaction(); + for (int a = 100; a < arrayList.size(); a++) { + MessagesStorage.getInstance().getDatabase().executeFast("DELETE FROM hashtag_recent_v2 WHERE id = '" + arrayList.get(a).hashtag + "'").stepThis().dispose(); + } + MessagesStorage.getInstance().getDatabase().commitTransaction(); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + } + + public void clearRecentHashtags() { + hashtags = new ArrayList<>(); + hashtagsByText = new HashMap<>(); + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { + @Override + public void run() { + try { + MessagesStorage.getInstance().getDatabase().executeFast("DELETE FROM hashtag_recent_v2 WHERE 1").stepThis().dispose(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + } + + protected void setHashtags(ArrayList arrayList, HashMap hashMap) { + hashtags = arrayList; + hashtagsByText = hashMap; + hashtagsLoadedFromDb = true; + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/CountrySearchAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/CountrySearchAdapter.java index 8414dd5bd..8c39b844a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/CountrySearchAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/CountrySearchAdapter.java @@ -73,7 +73,7 @@ public class CountrySearchAdapter extends BaseFragmentAdapter { return; } long time = System.currentTimeMillis(); - ArrayList resultArray = new ArrayList(); + ArrayList resultArray = new ArrayList<>(); String n = query.substring(0, 1); ArrayList arr = countries.get(n.toUpperCase()); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java index 6031ed215..e8884689c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java @@ -13,7 +13,6 @@ import android.view.View; import android.view.ViewGroup; import org.telegram.android.AndroidUtilities; -import org.telegram.android.MessageObject; import org.telegram.android.MessagesController; import org.telegram.messenger.TLRPC; import org.telegram.ui.Cells.DialogCell; @@ -24,6 +23,7 @@ public class DialogsAdapter extends BaseFragmentAdapter { private Context mContext; private boolean serverOnly; private long openedDialogId; + private int currentCount; public DialogsAdapter(Context context, boolean onlyFromServer) { mContext = context; @@ -34,6 +34,11 @@ public class DialogsAdapter extends BaseFragmentAdapter { openedDialogId = id; } + public boolean isDataSetChanged() { + int current = currentCount; + return current != getCount(); + } + @Override public boolean areAllItemsEnabled() { return true; @@ -58,6 +63,7 @@ public class DialogsAdapter extends BaseFragmentAdapter { if (!MessagesController.getInstance().dialogsEndReached) { count++; } + currentCount = count; return count; } @@ -97,22 +103,23 @@ public class DialogsAdapter extends BaseFragmentAdapter { if (view == null) { view = new DialogCell(mContext); } - ((DialogCell) view).useSeparator = (i != getCount() - 1); - TLRPC.TL_dialog dialog = null; - if (serverOnly) { - dialog = MessagesController.getInstance().dialogsServerOnly.get(i); - } else { - dialog = MessagesController.getInstance().dialogs.get(i); - if (AndroidUtilities.isTablet()) { - if (dialog.id == openedDialogId) { - view.setBackgroundColor(0x0f000000); - } else { - view.setBackgroundColor(0); + if (view instanceof DialogCell) { //TODO finally i need to find this crash + ((DialogCell) view).useSeparator = (i != getCount() - 1); + TLRPC.TL_dialog dialog = null; + if (serverOnly) { + dialog = MessagesController.getInstance().dialogsServerOnly.get(i); + } else { + dialog = MessagesController.getInstance().dialogs.get(i); + if (AndroidUtilities.isTablet()) { + if (dialog.id == openedDialogId) { + view.setBackgroundColor(0x0f000000); + } else { + view.setBackgroundColor(0); + } } } + ((DialogCell) view).setDialog(dialog, i, serverOnly); } - MessageObject message = MessagesController.getInstance().dialogMessage.get(dialog.top_message); - ((DialogCell) view).setDialog(dialog.id, message, true, dialog.last_message_date, dialog.unread_count, MessagesController.getInstance().isDialogMuted(dialog.id)); } return view; @@ -133,9 +140,6 @@ public class DialogsAdapter extends BaseFragmentAdapter { @Override public boolean isEmpty() { - if (MessagesController.getInstance().loadingDialogs && MessagesController.getInstance().dialogs.isEmpty()) { - return true; - } int count; if (serverOnly) { count = MessagesController.getInstance().dialogsServerOnly.size(); 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 2424062cd..9a426aeb2 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsSearchAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsSearchAdapter.java @@ -9,7 +9,6 @@ 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; @@ -33,6 +32,7 @@ import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; import org.telegram.ui.Cells.DialogCell; import org.telegram.ui.Cells.GreySectionCell; +import org.telegram.ui.Cells.HashtagSearchCell; import org.telegram.ui.Cells.LoadingCell; import org.telegram.ui.Cells.ProfileSearchCell; @@ -44,18 +44,19 @@ import java.util.Locale; import java.util.Timer; import java.util.TimerTask; -public class DialogsSearchAdapter extends BaseContactsSearchAdapter { +public class DialogsSearchAdapter extends BaseSearchAdapter { private Context mContext; private Timer searchTimer; private ArrayList searchResult = new ArrayList<>(); private ArrayList searchResultNames = new ArrayList<>(); private ArrayList searchResultMessages = new ArrayList<>(); + private ArrayList searchResultHashtags = new ArrayList<>(); private String lastSearchText; private long reqId = 0; private int lastReqId; private MessagesActivitySearchAdapterDelegate delegate; - private boolean needMessagesSearch; + private int needMessagesSearch; private boolean messagesSearchEndReached; private String lastMessagesSearchString; private int lastSearchId = 0; @@ -66,11 +67,11 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { public CharSequence name; } - public static interface MessagesActivitySearchAdapterDelegate { - public abstract void searchStateChanged(boolean searching); + public interface MessagesActivitySearchAdapterDelegate { + void searchStateChanged(boolean searching); } - public DialogsSearchAdapter(Context context, boolean messagesSearch) { + public DialogsSearchAdapter(Context context, int messagesSearch) { mContext = context; needMessagesSearch = messagesSearch; } @@ -87,8 +88,12 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { searchMessagesInternal(lastMessagesSearchString); } + public String getLastSearchString() { + return lastMessagesSearchString; + } + private void searchMessagesInternal(final String query) { - if (!needMessagesSearch) { + if (needMessagesSearch == 0) { return; } if (reqId != 0) { @@ -110,7 +115,7 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { req.peer = new TLRPC.TL_inputPeerEmpty(); req.q = query; if (lastMessagesSearchString != null && query.equals(lastMessagesSearchString) && !searchResultMessages.isEmpty()) { - req.max_id = searchResultMessages.get(searchResultMessages.size() - 1).messageOwner.id; + req.max_id = searchResultMessages.get(searchResultMessages.size() - 1).getId(); } lastMessagesSearchString = query; req.filter = new TLRPC.TL_inputMessagesFilterEmpty(); @@ -151,6 +156,9 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { } private void searchDialogsInternal(final String query, final boolean serverOnly, final int searchId) { + if (needMessagesSearch == 2) { + return; + } MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { @@ -178,15 +186,15 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { 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")); + SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("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); + 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)) { @@ -215,6 +223,10 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { 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 tName = LocaleController.getInstance().getTranslitString(name); + if (name.equals(tName)) { + tName = null; + } String username = null; int usernamePos = name.lastIndexOf(";;;"); if (usernamePos != -1) { @@ -222,7 +234,7 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { } int found = 0; for (String q : search) { - if (name.startsWith(q) || name.contains(" " + q)) { + if (name.startsWith(q) || name.contains(" " + q) || tName != null && (tName.startsWith(q) || tName.contains(" " + q))) { found = 1; } else if (username != null && username.startsWith(q)) { found = 2; @@ -257,8 +269,12 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { 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 tName = LocaleController.getInstance().getTranslitString(name); + if (name.equals(tName)) { + tName = null; + } for (String q : search) { - if (name.startsWith(q) || name.contains(" " + q)) { + if (name.startsWith(q) || name.contains(" " + q) || tName != null && (tName.startsWith(q) || tName.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()); @@ -285,6 +301,10 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { 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 tName = LocaleController.getInstance().getTranslitString(name); + if (name.equals(tName)) { + tName = null; + } String username = null; int usernamePos = name.lastIndexOf(";;;"); @@ -293,7 +313,7 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { } int found = 0; for (String q : search) { - if (name.startsWith(q) || name.contains(" " + q)) { + if (name.startsWith(q) || name.contains(" " + q) || tName != null && (tName.startsWith(q) || tName.contains(" " + q))) { found = 1; } else if (username != null && username.startsWith(q)) { found = 2; @@ -327,7 +347,7 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { user.status.expires = cursor.intValue(7); } if (found == 1) { - dialogSearchResult.name = Html.fromHtml("" + ContactsController.formatName(user.first_name, user.last_name) + ""); + dialogSearchResult.name = AndroidUtilities.replaceTags("" + ContactsController.formatName(user.first_name, user.last_name) + ""); } else { dialogSearchResult.name = Utilities.generateSearchName("@" + user.username, null, "@" + q); } @@ -374,10 +394,14 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { 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)) { + if (dialogsResult.containsKey((long) uid)) { continue; } String name = cursor.stringValue(2); + String tName = LocaleController.getInstance().getTranslitString(name); + if (name.equals(tName)) { + tName = null; + } String username = null; int usernamePos = name.lastIndexOf(";;;"); if (usernamePos != -1) { @@ -385,7 +409,7 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { } int found = 0; for (String q : search) { - if (name.startsWith(q) || name.contains(" " + q)) { + if (name.startsWith(q) || name.contains(" " + q) || tName != null && (tName.startsWith(q) || tName.contains(" " + q))) { found = 1; } else if (username != null && username.startsWith(q)) { found = 2; @@ -458,6 +482,25 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { return i > searchResult.size() && i <= globalSearch.size() + searchResult.size(); } + @Override + public void clearRecentHashtags() { + super.clearRecentHashtags(); + searchResultHashtags.clear(); + notifyDataSetChanged(); + } + + @Override + protected void setHashtags(ArrayList arrayList, HashMap hashMap) { + super.setHashtags(arrayList, hashMap); + for (HashtagObject hashtagObject : arrayList) { + searchResultHashtags.add(hashtagObject.hashtag); + } + if (delegate != null) { + delegate.searchStateChanged(false); + } + notifyDataSetChanged(); + } + public void searchDialogs(final String query, final boolean serverOnly) { if (query != null && lastSearchText != null && query.equals(lastSearchText)) { return; @@ -470,12 +513,39 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { FileLog.e("tmessages", e); } if (query == null || query.length() == 0) { + hashtagsLoadedFromDb = false; searchResult.clear(); searchResultNames.clear(); + searchResultHashtags.clear(); + if (needMessagesSearch != 2) { + queryServerSearch(null); + } searchMessagesInternal(null); - queryServerSearch(null); notifyDataSetChanged(); } else { + if (query.startsWith("#") && query.length() == 1) { + messagesSearchEndReached = true; + if (!hashtagsLoadedFromDb) { + loadRecentHashtags(); + if (delegate != null) { + delegate.searchStateChanged(true); + } + notifyDataSetChanged(); + return; + } + searchResultMessages.clear(); + searchResultHashtags.clear(); + for (HashtagObject hashtagObject : hashtags) { + searchResultHashtags.add(hashtagObject.hashtag); + } + if (delegate != null) { + delegate.searchStateChanged(false); + } + notifyDataSetChanged(); + return; + } else { + searchResultHashtags.clear(); + } final int searchId = ++lastSearchId; searchTimer = new Timer(); searchTimer.schedule(new TimerTask() { @@ -491,7 +561,9 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { AndroidUtilities.runOnUIThread(new Runnable() { @Override public void run() { - queryServerSearch(query); + if (needMessagesSearch != 2) { + queryServerSearch(query); + } searchMessagesInternal(query); } }); @@ -507,11 +579,27 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { @Override public boolean isEnabled(int i) { - return i != searchResult.size() && i != searchResult.size() + (globalSearch.isEmpty() ? 0 : globalSearch.size() + 1); + if (!searchResultHashtags.isEmpty()) { + return i != 0; + } + int localCount = searchResult.size(); + int globalCount = globalSearch.isEmpty() ? 0 : globalSearch.size() + 1; + int messagesCount = searchResultMessages.isEmpty() ? 0 : searchResultMessages.size() + 1; + if (i >= 0 && i < localCount || i > localCount && i < globalCount + localCount) { + return true; + } else if (i > globalCount + localCount && i < globalCount + localCount + messagesCount) { + return true; + } else if (messagesCount != 0 && i == globalCount + localCount + messagesCount) { + return true; + } + return false; } @Override public int getCount() { + if (!searchResultHashtags.isEmpty()) { + return searchResultHashtags.size() + 1; + } int count = searchResult.size(); int globalCount = globalSearch.size(); int messagesCount = searchResultMessages.size(); @@ -526,6 +614,9 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { @Override public Object getItem(int i) { + if (!searchResultHashtags.isEmpty()) { + return searchResultHashtags.get(i - 1); + } int localCount = searchResult.size(); int globalCount = globalSearch.isEmpty() ? 0 : globalSearch.size() + 1; int messagesCount = searchResultMessages.isEmpty() ? 0 : searchResultMessages.size() + 1; @@ -557,7 +648,9 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { if (view == null) { view = new GreySectionCell(mContext); } - if (!globalSearch.isEmpty() && i == searchResult.size()) { + if (!searchResultHashtags.isEmpty()) { + ((GreySectionCell) view).setText(LocaleController.getString("Hashtags", R.string.Hashtags).toUpperCase()); + } else if (!globalSearch.isEmpty() && i == searchResult.size()) { ((GreySectionCell) view).setText(LocaleController.getString("GlobalSearch", R.string.GlobalSearch)); } else { ((GreySectionCell) view).setText(LocaleController.getString("SearchMessages", R.string.SearchMessages)); @@ -577,10 +670,11 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { ((ProfileSearchCell) view).useSeparator = (i != getCount() - 1 && i != localCount - 1 && i != localCount + globalCount - 1); Object obj = getItem(i); if (obj instanceof TLRPC.User) { - user = MessagesController.getInstance().getUser(((TLRPC.User) obj).id); + /*user = MessagesController.getInstance().getUser(((TLRPC.User) obj).id); if (user == null) { user = (TLRPC.User) obj; - } + }*/ + user = (TLRPC.User) obj; } else if (obj instanceof TLRPC.Chat) { chat = MessagesController.getInstance().getChat(((TLRPC.Chat) obj).id); } else if (obj instanceof TLRPC.EncryptedChat) { @@ -604,7 +698,7 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { foundUserName = foundUserName.substring(1); } try { - username = Html.fromHtml(String.format("@%s%s", user.username.substring(0, foundUserName.length()), user.username.substring(foundUserName.length()))); + username = AndroidUtilities.replaceTags(String.format("@%s%s", user.username.substring(0, foundUserName.length()), user.username.substring(foundUserName.length()))); } catch (Exception e) { username = user.username; FileLog.e("tmessages", e); @@ -618,11 +712,17 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { } ((DialogCell) view).useSeparator = (i != getCount() - 1); MessageObject messageObject = (MessageObject)getItem(i); - ((DialogCell) view).setDialog(messageObject.getDialogId(), messageObject, false, messageObject.messageOwner.date, 0, false); + ((DialogCell) view).setDialog(messageObject.getDialogId(), messageObject, messageObject.messageOwner.date); } else if (type == 3) { if (view == null) { view = new LoadingCell(mContext); } + } else if (type == 4) { + if (view == null) { + view = new HashtagSearchCell(mContext); + } + ((HashtagSearchCell) view).setText(searchResultHashtags.get(i - 1)); + ((HashtagSearchCell) view).setNeedDivider(i != searchResultHashtags.size()); } return view; @@ -630,6 +730,9 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { @Override public int getItemViewType(int i) { + if (!searchResultHashtags.isEmpty()) { + return i == 0 ? 1 : 4; + } int localCount = searchResult.size(); int globalCount = globalSearch.isEmpty() ? 0 : globalSearch.size() + 1; int messagesCount = searchResultMessages.isEmpty() ? 0 : searchResultMessages.size() + 1; @@ -645,11 +748,11 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { @Override public int getViewTypeCount() { - return 4; + return 5; } @Override public boolean isEmpty() { - return searchResult.isEmpty() && globalSearch.isEmpty() && searchResultMessages.isEmpty(); + return searchResult.isEmpty() && globalSearch.isEmpty() && searchResultMessages.isEmpty() && searchResultHashtags.isEmpty(); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/MentionsAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/MentionsAdapter.java new file mode 100644 index 000000000..6c500386e --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/MentionsAdapter.java @@ -0,0 +1,272 @@ +/* + * This is the source code of Telegram for Android v. 2.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-2015. + */ + +package org.telegram.ui.Adapters; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; + +import org.telegram.android.MessageObject; +import org.telegram.android.MessagesController; +import org.telegram.messenger.TLRPC; +import org.telegram.ui.Cells.MentionCell; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; + +public class MentionsAdapter extends BaseSearchAdapter { + + public interface MentionsAdapterDelegate { + void needChangePanelVisibility(boolean show); + } + + private Context mContext; + private TLRPC.ChatParticipants info; + private ArrayList searchResultUsernames; + private ArrayList searchResultHashtags; + private MentionsAdapterDelegate delegate; + private int resultStartPosition; + private int resultLength; + private String lastText; + private int lastPosition; + private ArrayList messages; + private boolean needUsernames = true; + + public MentionsAdapter(Context context, MentionsAdapterDelegate delegate) { + mContext = context; + this.delegate = delegate; + } + + public void setChatInfo(TLRPC.ChatParticipants chatParticipants) { + info = chatParticipants; + if (lastText != null) { + searchUsernameOrHashtag(lastText, lastPosition, messages); + } + } + + public void setNeedUsernames(boolean value) { + needUsernames = value; + } + + @Override + public void clearRecentHashtags() { + super.clearRecentHashtags(); + searchResultHashtags.clear(); + notifyDataSetChanged(); + if (delegate != null) { + delegate.needChangePanelVisibility(false); + } + } + + @Override + protected void setHashtags(ArrayList arrayList, HashMap hashMap) { + super.setHashtags(arrayList, hashMap); + if (lastText != null) { + searchUsernameOrHashtag(lastText, lastPosition, messages); + } + } + + public void searchUsernameOrHashtag(String text, int position, ArrayList messageObjects) { + if (text == null || text.length() == 0) { + delegate.needChangePanelVisibility(false); + lastText = null; + return; + } + int searchPostion = position; + if (text.length() > 0) { + searchPostion--; + } + lastText = null; + StringBuilder result = new StringBuilder(); + int foundType = -1; + boolean hasIllegalUsernameCharacters = false; + for (int a = searchPostion; a >= 0; a--) { + if (a >= text.length()) { + continue; + } + char ch = text.charAt(a); + if (a == 0 || text.charAt(a - 1) == ' ' || text.charAt(a - 1) == '\n') { + if (needUsernames && ch == '@') { + if (hasIllegalUsernameCharacters) { + delegate.needChangePanelVisibility(false); + return; + } + if (info == null) { + lastText = text; + lastPosition = position; + messages = messageObjects; + delegate.needChangePanelVisibility(false); + return; + } + foundType = 0; + resultStartPosition = a; + resultLength = result.length() + 1; + break; + } else if (ch == '#') { + if (!hashtagsLoadedFromDb) { + loadRecentHashtags(); + lastText = text; + lastPosition = position; + messages = messageObjects; + delegate.needChangePanelVisibility(false); + return; + } + foundType = 1; + resultStartPosition = a; + resultLength = result.length() + 1; + result.insert(0, ch); + break; + } + } + if (!(ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch == '_')) { + hasIllegalUsernameCharacters = true; + } + result.insert(0, ch); + } + if (foundType == -1) { + delegate.needChangePanelVisibility(false); + return; + } + if (foundType == 0) { + final ArrayList users = new ArrayList<>(); + for (int a = 0; a < Math.min(100, messageObjects.size()); a++) { + int from_id = messageObjects.get(a).messageOwner.from_id; + if (!users.contains(from_id)) { + users.add(from_id); + } + } + String usernameString = result.toString().toLowerCase(); + ArrayList newResult = new ArrayList<>(); + for (TLRPC.TL_chatParticipant chatParticipant : info.participants) { + TLRPC.User user = MessagesController.getInstance().getUser(chatParticipant.user_id); + if (user == null || user instanceof TLRPC.TL_userSelf) { + continue; + } + if (user.username != null && user.username.length() > 0 && (usernameString.length() > 0 && user.username.toLowerCase().startsWith(usernameString) || usernameString.length() == 0)) { + newResult.add(user); + } + } + searchResultHashtags = null; + searchResultUsernames = newResult; + Collections.sort(searchResultUsernames, new Comparator() { + @Override + public int compare(TLRPC.User lhs, TLRPC.User rhs) { + int lhsNum = users.indexOf(lhs.id); + int rhsNum = users.indexOf(rhs.id); + if (lhsNum != -1 && rhsNum != -1) { + return lhsNum < rhsNum ? -1 : (lhsNum == rhsNum ? 0 : 1); + } else if (lhsNum != -1 && rhsNum == -1) { + return -1; + } else if (lhsNum == -1 && rhsNum != -1) { + return 1; + } + return 0; + } + }); + notifyDataSetChanged(); + delegate.needChangePanelVisibility(!newResult.isEmpty()); + } else { + ArrayList newResult = new ArrayList<>(); + String hashtagString = result.toString().toLowerCase(); + for (HashtagObject hashtagObject : hashtags) { + if (hashtagString != null && hashtagObject.hashtag != null && hashtagObject.hashtag.startsWith(hashtagString)) { + newResult.add(hashtagObject.hashtag); + } + } + searchResultHashtags = newResult; + searchResultUsernames = null; + notifyDataSetChanged(); + delegate.needChangePanelVisibility(!newResult.isEmpty()); + } + } + + public int getResultStartPosition() { + return resultStartPosition; + } + + public int getResultLength() { + return resultLength; + } + + @Override + public int getViewTypeCount() { + return 1; + } + + @Override + public int getCount() { + if (searchResultUsernames != null) { + return searchResultUsernames.size(); + } else if (searchResultHashtags != null) { + return searchResultHashtags.size(); + } + return 0; + } + + @Override + public boolean isEmpty() { + if (searchResultUsernames != null) { + return searchResultUsernames.isEmpty(); + } else if (searchResultHashtags != null) { + return searchResultHashtags.isEmpty(); + } + return true; + } + + @Override + public int getItemViewType(int position) { + return 0; + } + + @Override + public boolean hasStableIds() { + return true; + } + + @Override + public boolean areAllItemsEnabled() { + return true; + } + + @Override + public boolean isEnabled(int position) { + return true; + } + + @Override + public Object getItem(int i) { + if (searchResultUsernames != null) { + if (i < 0 || i >= searchResultUsernames.size()) { + return null; + } + return searchResultUsernames.get(i); + } else if (searchResultHashtags != null) { + if (i < 0 || i >= searchResultHashtags.size()) { + return null; + } + return searchResultHashtags.get(i); + } + return null; + } + + @Override + public View getView(int i, View view, ViewGroup viewGroup) { + if (view == null) { + view = new MentionCell(mContext); + } + if (searchResultUsernames != null) { + ((MentionCell) view).setUser(searchResultUsernames.get(i)); + } else if (searchResultHashtags != null) { + ((MentionCell) view).setText(searchResultHashtags.get(i)); + } + return view; + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/ContactsSearchAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/SearchAdapter.java similarity index 94% rename from TMessagesProj/src/main/java/org/telegram/ui/Adapters/ContactsSearchAdapter.java rename to TMessagesProj/src/main/java/org/telegram/ui/Adapters/SearchAdapter.java index e68e9be57..cf7ce7c1f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/ContactsSearchAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/SearchAdapter.java @@ -9,7 +9,6 @@ package org.telegram.ui.Adapters; import android.content.Context; -import android.text.Html; import android.view.View; import android.view.ViewGroup; @@ -31,7 +30,7 @@ import java.util.HashMap; import java.util.Timer; import java.util.TimerTask; -public class ContactsSearchAdapter extends BaseContactsSearchAdapter { +public class SearchAdapter extends BaseSearchAdapter { private Context mContext; private HashMap ignoreUsers; private ArrayList searchResult = new ArrayList<>(); @@ -41,7 +40,7 @@ public class ContactsSearchAdapter extends BaseContactsSearchAdapter { private boolean allowUsernameSearch; private boolean useUserCell; - public ContactsSearchAdapter(Context context, HashMap arg1, boolean usernameSearch) { + public SearchAdapter(Context context, HashMap arg1, boolean usernameSearch) { mContext = context; ignoreUsers = arg1; allowUsernameSearch = usernameSearch; @@ -124,10 +123,14 @@ public class ContactsSearchAdapter extends BaseContactsSearchAdapter { } String name = ContactsController.formatName(user.first_name, user.last_name).toLowerCase(); + String tName = LocaleController.getInstance().getTranslitString(name); + if (name.equals(tName)) { + tName = null; + } int found = 0; for (String q : search) { - if (name.startsWith(q) || name.contains(" " + q)) { + if (name.startsWith(q) || name.contains(" " + q) || tName != null && (tName.startsWith(q) || tName.contains(" " + q))) { found = 1; } else if (user.username != null && user.username.startsWith(q)) { found = 2; @@ -253,7 +256,7 @@ public class ContactsSearchAdapter extends BaseContactsSearchAdapter { foundUserName = foundUserName.substring(1); } try { - username = Html.fromHtml(String.format("@%s%s", user.username.substring(0, foundUserName.length()), user.username.substring(foundUserName.length()))); + username = AndroidUtilities.replaceTags(String.format("@%s%s", user.username.substring(0, foundUserName.length()), user.username.substring(foundUserName.length()))); } catch (Exception e) { username = user.username; FileLog.e("tmessages", e); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/StickersAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/StickersAdapter.java index 2d52263fc..ef6f61c0f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/StickersAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/StickersAdapter.java @@ -47,8 +47,8 @@ public class StickersAdapter extends RecyclerView.Adapter implements Notificatio private String lastSticker; private boolean visible; - public static interface StickersAdapterDelegate { - public abstract void needChangePanelVisibility(boolean show); + public interface StickersAdapterDelegate { + void needChangePanelVisibility(boolean show); } private class Holder extends RecyclerView.ViewHolder { @@ -80,7 +80,7 @@ public class StickersAdapter extends RecyclerView.Adapter implements Notificatio @Override public void run() { if (stickers != null && !stickers.isEmpty() && !stickersToLoad.isEmpty() && visible) { - String fileName = (String)args[0]; + String fileName = (String) args[0]; stickersToLoad.remove(fileName); if (stickersToLoad.isEmpty()) { delegate.needChangePanelVisibility(stickers != null && !stickers.isEmpty() && stickersToLoad.isEmpty()); @@ -203,6 +203,9 @@ public class StickersAdapter extends RecyclerView.Adapter implements Notificatio } HashMap documents = new HashMap<>(); for (TLRPC.Document document : res.documents) { + if (document == null) { + continue; + } documents.put(document.id, document); if (document.thumb != null && document.thumb.location != null) { document.thumb.location.ext = "webp"; @@ -211,6 +214,7 @@ public class StickersAdapter extends RecyclerView.Adapter implements Notificatio final HashMap> result = new HashMap<>(); for (TLRPC.TL_stickerPack stickerPack : res.packs) { if (stickerPack != null && stickerPack.emoticon != null) { + stickerPack.emoticon = stickerPack.emoticon.replace("\uFE0F", ""); ArrayList arrayList = result.get(stickerPack.emoticon); for (Long id : stickerPack.documents) { TLRPC.Document document = documents.get(id); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Animation/Animator10.java b/TMessagesProj/src/main/java/org/telegram/ui/Animation/Animator10.java index 32e6ccfe1..31a6d756b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Animation/Animator10.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Animation/Animator10.java @@ -177,14 +177,14 @@ public abstract class Animator10 implements Cloneable { } - public static interface AnimatorListener { + public interface AnimatorListener { void onAnimationStart(Animator10 animation); void onAnimationEnd(Animator10 animation); void onAnimationCancel(Animator10 animation); void onAnimationRepeat(Animator10 animation); } - public static interface AnimatorPauseListener { + public interface AnimatorPauseListener { void onAnimationPause(Animator10 animation); void onAnimationResume(Animator10 animation); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Animation/AnimatorSet10.java b/TMessagesProj/src/main/java/org/telegram/ui/Animation/AnimatorSet10.java index 0f91b93b1..274dd6041 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Animation/AnimatorSet10.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Animation/AnimatorSet10.java @@ -25,10 +25,10 @@ import java.util.List; public final class AnimatorSet10 extends Animator10 { - private ArrayList mPlayingSet = new ArrayList(); - private HashMap mNodeMap = new HashMap(); - private ArrayList mNodes = new ArrayList(); - private ArrayList mSortedNodes = new ArrayList(); + private ArrayList mPlayingSet = new ArrayList<>(); + private HashMap mNodeMap = new HashMap<>(); + private ArrayList mNodes = new ArrayList<>(); + private ArrayList mSortedNodes = new ArrayList<>(); private boolean mNeedsSort = true; private AnimatorSetListener mSetListener = null; boolean mTerminated = false; @@ -89,7 +89,7 @@ public final class AnimatorSet10 extends Animator10 { } public ArrayList getChildAnimations() { - ArrayList childList = new ArrayList(); + ArrayList childList = new ArrayList<>(); for (Node node : mNodes) { childList.add(node.animation); } @@ -295,7 +295,7 @@ public final class AnimatorSet10 extends Animator10 { ArrayList oldListeners = node.animation.getListeners(); if (oldListeners != null && oldListeners.size() > 0) { final ArrayList clonedListeners = new - ArrayList(oldListeners); + ArrayList<>(oldListeners); for (AnimatorListener listener : clonedListeners) { if (listener instanceof DependencyListener || @@ -306,7 +306,7 @@ public final class AnimatorSet10 extends Animator10 { } } - final ArrayList nodesToStart = new ArrayList(); + final ArrayList nodesToStart = new ArrayList<>(); for (Node node : mSortedNodes) { if (mSetListener == null) { mSetListener = new AnimatorSetListener(this); @@ -379,12 +379,12 @@ public final class AnimatorSet10 extends Animator10 { anim.mNeedsSort = true; anim.mTerminated = false; anim.mStarted = false; - anim.mPlayingSet = new ArrayList(); - anim.mNodeMap = new HashMap(); - anim.mNodes = new ArrayList(); - anim.mSortedNodes = new ArrayList(); + anim.mPlayingSet = new ArrayList<>(); + anim.mNodeMap = new HashMap<>(); + anim.mNodes = new ArrayList<>(); + anim.mSortedNodes = new ArrayList<>(); - HashMap nodeCloneMap = new HashMap(); + HashMap nodeCloneMap = new HashMap<>(); for (Node node : mNodes) { Node nodeClone = node.clone(); nodeCloneMap.put(node, nodeClone); @@ -400,7 +400,7 @@ public final class AnimatorSet10 extends Animator10 { for (AnimatorListener listener : cloneListeners) { if (listener instanceof AnimatorSetListener) { if (listenersToRemove == null) { - listenersToRemove = new ArrayList(); + listenersToRemove = new ArrayList<>(); } listenersToRemove.add(listener); } @@ -543,14 +543,14 @@ public final class AnimatorSet10 extends Animator10 { private void sortNodes() { if (mNeedsSort) { mSortedNodes.clear(); - ArrayList roots = new ArrayList(); + ArrayList roots = new ArrayList<>(); int numNodes = mNodes.size(); for (Node node : mNodes) { if (node.dependencies == null || node.dependencies.size() == 0) { roots.add(node); } } - ArrayList tmpRoots = new ArrayList(); + ArrayList tmpRoots = new ArrayList<>(); while (roots.size() > 0) { int numRoots = roots.size(); for (Node root : roots) { @@ -582,7 +582,7 @@ public final class AnimatorSet10 extends Animator10 { for (int j = 0; j < numDependencies; ++j) { Dependency dependency = node.dependencies.get(j); if (node.nodeDependencies == null) { - node.nodeDependencies = new ArrayList(); + node.nodeDependencies = new ArrayList<>(); } if (!node.nodeDependencies.contains(dependency.node)) { node.nodeDependencies.add(dependency.node); @@ -620,8 +620,8 @@ public final class AnimatorSet10 extends Animator10 { public void addDependency(Dependency dependency) { if (dependencies == null) { - dependencies = new ArrayList(); - nodeDependencies = new ArrayList(); + dependencies = new ArrayList<>(); + nodeDependencies = new ArrayList<>(); } dependencies.add(dependency); if (!nodeDependencies.contains(dependency.node)) { @@ -629,7 +629,7 @@ public final class AnimatorSet10 extends Animator10 { } Node dependencyNode = dependency.node; if (dependencyNode.nodeDependents == null) { - dependencyNode.nodeDependents = new ArrayList(); + dependencyNode.nodeDependents = new ArrayList<>(); } dependencyNode.nodeDependents.add(this); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Animation/TypeEvaluator.java b/TMessagesProj/src/main/java/org/telegram/ui/Animation/TypeEvaluator.java index 33de5d619..db5769e0c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Animation/TypeEvaluator.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Animation/TypeEvaluator.java @@ -17,5 +17,5 @@ package org.telegram.ui.Animation; public interface TypeEvaluator { - public T evaluate(float fraction, T startValue, T endValue); + T evaluate(float fraction, T startValue, T endValue); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Animation/ValueAnimator.java b/TMessagesProj/src/main/java/org/telegram/ui/Animation/ValueAnimator.java index b4baca6de..168ff1dac 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Animation/ValueAnimator.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Animation/ValueAnimator.java @@ -646,7 +646,7 @@ public class ValueAnimator extends Animator10 { return anim; } - public static interface AnimatorUpdateListener { + public interface AnimatorUpdateListener { void onAnimationUpdate(ValueAnimator animation); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Animation/View10.java b/TMessagesProj/src/main/java/org/telegram/ui/Animation/View10.java index 0863204d0..4a89fe9c5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Animation/View10.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Animation/View10.java @@ -31,7 +31,7 @@ public class View10 extends Animation { public static boolean NEED_PROXY = Build.VERSION.SDK_INT < 11; - private static final WeakHashMap PROXIES = new WeakHashMap(); + private static final WeakHashMap PROXIES = new WeakHashMap<>(); public static View10 wrap(View view) { View10 proxy = PROXIES.get(view); @@ -68,7 +68,7 @@ public class View10 extends Animation { setDuration(0); setFillAfter(true); view.setAnimation(this); - mView = new WeakReference(view); + mView = new WeakReference<>(view); } public float getAlpha() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/BlockedUsersActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/BlockedUsersActivity.java index 0f0eb843d..5982e413b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/BlockedUsersActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/BlockedUsersActivity.java @@ -64,131 +64,124 @@ public class BlockedUsersActivity extends BaseFragment implements NotificationCe } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - actionBar.setTitle(LocaleController.getString("BlockedUsers", R.string.BlockedUsers)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } else if (id == block_user) { - Bundle args = new Bundle(); - args.putBoolean("onlyUsers", true); - args.putBoolean("destroyAfterSelect", true); - args.putBoolean("returnAsResult", true); - ContactsActivity fragment = new ContactsActivity(args); - fragment.setDelegate(BlockedUsersActivity.this); - presentFragment(fragment); - } + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + actionBar.setTitle(LocaleController.getString("BlockedUsers", R.string.BlockedUsers)); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } else if (id == block_user) { + Bundle args = new Bundle(); + args.putBoolean("onlyUsers", true); + args.putBoolean("destroyAfterSelect", true); + args.putBoolean("returnAsResult", true); + ContactsActivity fragment = new ContactsActivity(args); + fragment.setDelegate(BlockedUsersActivity.this); + presentFragment(fragment); } - }); + } + }); - ActionBarMenu menu = actionBar.createMenu(); - menu.addItem(block_user, R.drawable.plus); + ActionBarMenu menu = actionBar.createMenu(); + menu.addItem(block_user, R.drawable.plus); - fragmentView = new FrameLayout(getParentActivity()); - FrameLayout frameLayout = (FrameLayout) fragmentView; + fragmentView = new FrameLayout(context); + FrameLayout frameLayout = (FrameLayout) fragmentView; - emptyTextView = new TextView(getParentActivity()); - emptyTextView.setTextColor(0xff808080); - emptyTextView.setTextSize(20); - emptyTextView.setGravity(Gravity.CENTER); - emptyTextView.setVisibility(View.INVISIBLE); - emptyTextView.setText(LocaleController.getString("NoBlocked", R.string.NoBlocked)); - frameLayout.addView(emptyTextView); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) emptyTextView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.gravity = Gravity.TOP; - emptyTextView.setLayoutParams(layoutParams); - emptyTextView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { + emptyTextView = new TextView(context); + emptyTextView.setTextColor(0xff808080); + emptyTextView.setTextSize(20); + emptyTextView.setGravity(Gravity.CENTER); + emptyTextView.setVisibility(View.INVISIBLE); + emptyTextView.setText(LocaleController.getString("NoBlocked", R.string.NoBlocked)); + frameLayout.addView(emptyTextView); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) emptyTextView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP; + emptyTextView.setLayoutParams(layoutParams); + emptyTextView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + progressView = new FrameLayout(context); + frameLayout.addView(progressView); + layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + progressView.setLayoutParams(layoutParams); + + ProgressBar progressBar = new ProgressBar(context); + progressView.addView(progressBar); + layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.CENTER; + progressView.setLayoutParams(layoutParams); + + listView = new ListView(context); + listView.setEmptyView(emptyTextView); + listView.setVerticalScrollBarEnabled(false); + listView.setDivider(null); + listView.setDividerHeight(0); + listView.setAdapter(listViewAdapter = new ListAdapter(context)); + if (Build.VERSION.SDK_INT >= 11) { + listView.setVerticalScrollbarPosition(LocaleController.isRTL ? ListView.SCROLLBAR_POSITION_LEFT : ListView.SCROLLBAR_POSITION_RIGHT); + } + frameLayout.addView(listView); + layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + listView.setLayoutParams(layoutParams); + + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, int i, long l) { + if (i < MessagesController.getInstance().blockedUsers.size()) { + Bundle args = new Bundle(); + args.putInt("user_id", MessagesController.getInstance().blockedUsers.get(i)); + presentFragment(new ProfileActivity(args)); + } + } + }); + + listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView adapterView, View view, int i, long l) { + if (i < 0 || i >= MessagesController.getInstance().blockedUsers.size() || getParentActivity() == null) { return true; } - }); + selectedUserId = MessagesController.getInstance().blockedUsers.get(i); - progressView = new FrameLayout(getParentActivity()); - frameLayout.addView(progressView); - layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - progressView.setLayoutParams(layoutParams); - - ProgressBar progressBar = new ProgressBar(getParentActivity()); - progressView.addView(progressBar); - layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.gravity = Gravity.CENTER; - progressView.setLayoutParams(layoutParams); - - listView = new ListView(getParentActivity()); - listView.setEmptyView(emptyTextView); - listView.setVerticalScrollBarEnabled(false); - listView.setDivider(null); - listView.setDividerHeight(0); - listView.setAdapter(listViewAdapter = new ListAdapter(getParentActivity())); - if (Build.VERSION.SDK_INT >= 11) { - listView.setVerticalScrollbarPosition(LocaleController.isRTL ? ListView.SCROLLBAR_POSITION_LEFT : ListView.SCROLLBAR_POSITION_RIGHT); - } - frameLayout.addView(listView); - layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - listView.setLayoutParams(layoutParams); - - listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, int i, long l) { - if (i < MessagesController.getInstance().blockedUsers.size()) { - Bundle args = new Bundle(); - args.putInt("user_id", MessagesController.getInstance().blockedUsers.get(i)); - presentFragment(new ProfileActivity(args)); - } - } - }); - - listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { - @Override - public boolean onItemLongClick(AdapterView adapterView, View view, int i, long l) { - if (i < 0 || i >= MessagesController.getInstance().blockedUsers.size() || getParentActivity() == null) { - return true; - } - selectedUserId = MessagesController.getInstance().blockedUsers.get(i); - - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - CharSequence[] items = new CharSequence[] {LocaleController.getString("Unblock", R.string.Unblock)}; - builder.setItems(items, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - if (i == 0) { - MessagesController.getInstance().unblockUser(selectedUserId); - } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + CharSequence[] items = new CharSequence[]{LocaleController.getString("Unblock", R.string.Unblock)}; + builder.setItems(items, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + if (i == 0) { + MessagesController.getInstance().unblockUser(selectedUserId); } - }); - showAlertDialog(builder); + } + }); + showAlertDialog(builder); - return true; - } - }); - - if (MessagesController.getInstance().loadingBlockedUsers) { - progressView.setVisibility(View.VISIBLE); - emptyTextView.setVisibility(View.GONE); - listView.setEmptyView(null); - } else { - progressView.setVisibility(View.GONE); - listView.setEmptyView(emptyTextView); + return true; } + }); + + if (MessagesController.getInstance().loadingBlockedUsers) { + progressView.setVisibility(View.VISIBLE); + emptyTextView.setVisibility(View.GONE); + listView.setEmptyView(null); } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); - } + progressView.setVisibility(View.GONE); + listView.setEmptyView(emptyTextView); } return fragmentView; } 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 f07555cf2..2fcaed609 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatActionCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatActionCell.java @@ -25,6 +25,7 @@ import org.telegram.android.AndroidUtilities; import org.telegram.android.ImageReceiver; import org.telegram.android.MessageObject; import org.telegram.android.MessagesController; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; @@ -35,10 +36,10 @@ import org.telegram.ui.Components.AvatarDrawable; public class ChatActionCell extends BaseCell { - public static interface ChatActionCellDelegate { - public abstract void didClickedImage(ChatActionCell cell); - public abstract void didLongPressed(ChatActionCell cell); - public abstract void needOpenUserProfile(int uid); + public interface ChatActionCellDelegate { + void didClickedImage(ChatActionCell cell); + void didLongPressed(ChatActionCell cell); + void needOpenUserProfile(int uid); } private static Drawable backgroundBlack; @@ -55,7 +56,6 @@ public class ChatActionCell extends BaseCell { private int textX = 0; private int textY = 0; private int textXLeft = 0; - private boolean useBlackBackground = false; private int previousWidth = 0; private boolean imagePressed = false; @@ -119,10 +119,6 @@ public class ChatActionCell extends BaseCell { requestLayout(); } - public void setUseBlackBackground(boolean value) { - useBlackBackground = value; - } - public MessageObject getMessageObject() { return currentMessageObject; } @@ -267,7 +263,7 @@ public class ChatActionCell extends BaseCell { } Drawable backgroundDrawable = null; - if (useBlackBackground) { + if (ApplicationLoader.isCustomTheme()) { backgroundDrawable = backgroundBlack; } else { backgroundDrawable = backgroundBlue; 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 92b5c0dec..7a3f1a6b4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatAudioCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatAudioCell.java @@ -183,9 +183,15 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega buttonState = 3; invalidate(); } else if (buttonState == 3) { - FileLoader.getInstance().cancelLoadFile(currentMessageObject.messageOwner.media.audio); - buttonState = 2; - invalidate(); + if (currentMessageObject.isOut() && currentMessageObject.isSending()) { + if (delegate != null) { + delegate.didPressedCancelSendButton(this); + } + } else { + FileLoader.getInstance().cancelLoadFile(currentMessageObject.messageOwner.media.audio); + buttonState = 2; + invalidate(); + } } } @@ -291,12 +297,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = MeasureSpec.getSize(widthMeasureSpec); - setMeasuredDimension(width, AndroidUtilities.dp(68)); - if (isChat) { - backgroundWidth = Math.min(width - AndroidUtilities.dp(102), AndroidUtilities.dp(300)); - } else { - backgroundWidth = Math.min(width - AndroidUtilities.dp(50), AndroidUtilities.dp(300)); - } + setMeasuredDimension(width, AndroidUtilities.dp(68) + namesOffset); } @Override @@ -325,7 +326,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega } int diff = 0; if (needAvatarImage) { - avatarImage.setImageCoords(x, AndroidUtilities.dp(9), AndroidUtilities.dp(50), AndroidUtilities.dp(50)); + avatarImage.setImageCoords(x, AndroidUtilities.dp(9) + namesOffset, AndroidUtilities.dp(50), AndroidUtilities.dp(50)); } else { diff = AndroidUtilities.dp(56); seekBarX -= diff; @@ -337,8 +338,8 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega seekBar.height = AndroidUtilities.dp(30); progressView.width = backgroundWidth - AndroidUtilities.dp(136) + diff; progressView.height = AndroidUtilities.dp(30); - seekBarY = AndroidUtilities.dp(13); - buttonY = AndroidUtilities.dp(10); + seekBarY = AndroidUtilities.dp(13) + namesOffset; + buttonY = AndroidUtilities.dp(10) + namesOffset; updateProgress(); } @@ -358,6 +359,12 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega @Override public void setMessageObject(MessageObject messageObject) { if (currentMessageObject != messageObject || isUserDataChanged()) { + if (AndroidUtilities.isTablet()) { + backgroundWidth = Math.min(AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(isChat ? 102 : 50), AndroidUtilities.dp(300)); + } else { + backgroundWidth = Math.min(AndroidUtilities.displaySize.x - AndroidUtilities.dp(isChat ? 102 : 50), AndroidUtilities.dp(300)); + } + int uid = messageObject.messageOwner.media.audio.user_id; if (uid == 0) { uid = messageObject.messageOwner.from_id; @@ -430,7 +437,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega buttonDrawable.draw(canvas); canvas.save(); - canvas.translate(timeX, AndroidUtilities.dp(45)); + canvas.translate(timeX, AndroidUtilities.dp(45) + namesOffset); timeLayout.draw(canvas); canvas.restore(); } 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 ec5ac969d..a56e53678 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java @@ -10,9 +10,10 @@ package org.telegram.ui.Cells; import android.annotation.SuppressLint; import android.content.Context; +import android.content.res.Configuration; import android.graphics.Canvas; +import android.graphics.Paint; import android.graphics.drawable.Drawable; -import android.text.Html; import android.text.Layout; import android.text.StaticLayout; import android.text.TextPaint; @@ -22,7 +23,11 @@ import android.view.SoundEffectConstants; import org.telegram.android.AndroidUtilities; import org.telegram.android.ContactsController; +import org.telegram.android.Emoji; import org.telegram.android.LocaleController; +import org.telegram.messenger.ApplicationLoader; +import org.telegram.messenger.FileLoader; +import org.telegram.messenger.FileLog; import org.telegram.messenger.TLRPC; import org.telegram.android.MessagesController; import org.telegram.messenger.R; @@ -32,16 +37,19 @@ import org.telegram.ui.Components.AvatarDrawable; public class ChatBaseCell extends BaseCell { - public static interface ChatBaseCellDelegate { - public abstract void didPressedUserAvatar(ChatBaseCell cell, TLRPC.User user); - public abstract void didPressedCancelSendButton(ChatBaseCell cell); - public abstract void didLongPressed(ChatBaseCell cell); - public abstract boolean canPerformActions(); + public interface ChatBaseCellDelegate { + void didPressedUserAvatar(ChatBaseCell cell, TLRPC.User user); + void didPressedCancelSendButton(ChatBaseCell cell); + void didLongPressed(ChatBaseCell cell); + void didPressReplyMessage(ChatBaseCell cell, int id); + void didPressUrl(String url); + boolean canPerformActions(); } public boolean isChat = false; protected boolean isPressed = false; protected boolean forwardName = false; + protected boolean isHighlighted = false; protected boolean media = false; protected boolean isCheckPressed = true; private boolean wasLayout = false; @@ -66,12 +74,17 @@ public class ChatBaseCell extends BaseCell { private static Drawable clockMediaDrawable; private static Drawable broadcastMediaDrawable; private static Drawable errorDrawable; + private static Drawable backgroundBlack; + private static Drawable backgroundBlue; protected static Drawable mediaBackgroundDrawable; private static TextPaint timePaintIn; private static TextPaint timePaintOut; private static TextPaint timeMediaPaint; private static TextPaint namePaint; private static TextPaint forwardNamePaint; + protected static TextPaint replyNamePaint; + protected static TextPaint replyTextPaint; + protected static Paint replyLinePaint; protected int backgroundWidth = 100; @@ -83,6 +96,19 @@ public class ChatBaseCell extends BaseCell { private boolean avatarPressed = false; private boolean forwardNamePressed = false; + private StaticLayout replyNameLayout; + private StaticLayout replyTextLayout; + private ImageReceiver replyImageReceiver; + private int replyStartX; + private int replyStartY; + protected int replyNameWidth; + private float replyNameOffset; + protected int replyTextWidth; + private float replyTextOffset; + private boolean needReplyImage = false; + private boolean replyPressed = false; + private TLRPC.FileLocation currentReplyPhoto; + private StaticLayout nameLayout; protected int nameWidth; private float nameOffsetX = 0; @@ -137,6 +163,8 @@ public class ChatBaseCell extends BaseCell { mediaBackgroundDrawable = getResources().getDrawable(R.drawable.phototime); broadcastDrawable = getResources().getDrawable(R.drawable.broadcast3); broadcastMediaDrawable = getResources().getDrawable(R.drawable.broadcast4); + backgroundBlack = getResources().getDrawable(R.drawable.system_black); + backgroundBlue = getResources().getDrawable(R.drawable.system_blue); timePaintIn = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); timePaintIn.setTextSize(AndroidUtilities.dp(12)); @@ -155,17 +183,30 @@ public class ChatBaseCell extends BaseCell { forwardNamePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); forwardNamePaint.setTextSize(AndroidUtilities.dp(14)); + + replyNamePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); + replyNamePaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + replyNamePaint.setTextSize(AndroidUtilities.dp(14)); + + replyTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); + replyTextPaint.setTextSize(AndroidUtilities.dp(14)); + replyTextPaint.linkColor = 0xff316f9f; + + replyLinePaint = new Paint(); } avatarImage = new ImageReceiver(this); avatarImage.setRoundRadius(AndroidUtilities.dp(21)); avatarDrawable = new AvatarDrawable(); + replyImageReceiver = new ImageReceiver(this); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); avatarImage.clearImage(); + replyImageReceiver.clearImage(); currentPhoto = null; + currentReplyPhoto = null; } @Override @@ -178,6 +219,14 @@ public class ChatBaseCell extends BaseCell { this.delegate = delegate; } + public void setHighlighted(boolean value) { + if (isHighlighted == value) { + return; + } + isHighlighted = value; + invalidate(); + } + public void setCheckPressed(boolean value, boolean pressed) { isCheckPressed = value; isPressed = pressed; @@ -202,10 +251,27 @@ public class ChatBaseCell extends BaseCell { newPhoto = newUser.photo.photo_small; } + if (replyTextLayout == null && currentMessageObject.replyMessageObject != null) { + return true; + } + if (currentPhoto == null && newPhoto != null || currentPhoto != null && newPhoto == null || currentPhoto != null && newPhoto != null && (currentPhoto.local_id != newPhoto.local_id || currentPhoto.volume_id != newPhoto.volume_id)) { return true; } + TLRPC.FileLocation newReplyPhoto = null; + + if (currentMessageObject.replyMessageObject != null) { + TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(currentMessageObject.replyMessageObject.photoThumbs, 80); + if (photoSize != null && currentMessageObject.replyMessageObject.type != 13) { + newReplyPhoto = photoSize.location; + } + } + + if (currentReplyPhoto == null && newReplyPhoto != null) { + return true; + } + String newNameString = null; if (drawName && isChat && newUser != null && !currentMessageObject.isOut()) { newNameString = ContactsController.formatName(newUser.first_name, newUser.last_name); @@ -217,7 +283,7 @@ public class ChatBaseCell extends BaseCell { newUser = MessagesController.getInstance().getUser(currentMessageObject.messageOwner.fwd_from_id); newNameString = null; - if (newUser != null && drawForwardedName && currentMessageObject.messageOwner instanceof TLRPC.TL_messageForwarded) { + if (newUser != null && drawForwardedName && currentMessageObject.messageOwner.fwd_from_id != 0) { newNameString = ContactsController.formatName(newUser.first_name, newUser.last_name); } return currentForwardNameString == null && newNameString != null || currentForwardNameString != null && newNameString == null || currentForwardNameString != null && newNameString != null && !currentForwardNameString.equals(newNameString); @@ -231,6 +297,11 @@ public class ChatBaseCell extends BaseCell { isCheckPressed = true; isAvatarVisible = false; wasLayout = false; + replyNameLayout = null; + replyTextLayout = null; + replyNameWidth = 0; + replyTextWidth = 0; + currentReplyPhoto = null; currentUser = MessagesController.getInstance().getUser(messageObject.messageOwner.from_id); if (isChat && !messageObject.isOut()) { @@ -272,7 +343,7 @@ public class ChatBaseCell extends BaseCell { nameLayout = new StaticLayout(nameStringFinal, namePaint, nameWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); if (nameLayout.getLineCount() > 0) { nameWidth = (int)Math.ceil(nameLayout.getLineWidth(0)); - namesOffset += AndroidUtilities.dp(18); + namesOffset += AndroidUtilities.dp(19); nameOffsetX = nameLayout.getLineLeft(0); } else { nameWidth = 0; @@ -283,7 +354,7 @@ public class ChatBaseCell extends BaseCell { nameWidth = 0; } - if (drawForwardedName && messageObject.messageOwner instanceof TLRPC.TL_messageForwarded) { + if (drawForwardedName && messageObject.isForwarded()) { currentForwardUser = MessagesController.getInstance().getUser(messageObject.messageOwner.fwd_from_id); if (currentForwardUser != null) { currentForwardNameString = ContactsController.formatName(currentForwardUser.first_name, currentForwardUser.last_name); @@ -291,7 +362,7 @@ public class ChatBaseCell extends BaseCell { forwardedNameWidth = getMaxNameWidth(); CharSequence str = TextUtils.ellipsize(currentForwardNameString.replace("\n", " "), forwardNamePaint, forwardedNameWidth - AndroidUtilities.dp(40), TextUtils.TruncateAt.END); - str = Html.fromHtml(String.format("%s
%s %s", LocaleController.getString("ForwardedMessage", R.string.ForwardedMessage), LocaleController.getString("From", R.string.From), str)); + str = AndroidUtilities.replaceTags(String.format("%s\n%s %s", LocaleController.getString("ForwardedMessage", R.string.ForwardedMessage), LocaleController.getString("From", R.string.From), str)); forwardedNameLayout = new StaticLayout(str, forwardNamePaint, forwardedNameWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); if (forwardedNameLayout.getLineCount() > 1) { forwardedNameWidth = Math.max((int) Math.ceil(forwardedNameLayout.getLineWidth(0)), (int) Math.ceil(forwardedNameLayout.getLineWidth(1))); @@ -311,6 +382,99 @@ public class ChatBaseCell extends BaseCell { forwardedNameWidth = 0; } + if (messageObject.isReply()) { + namesOffset += AndroidUtilities.dp(42); + if (messageObject.contentType == 2 || messageObject.contentType == 3) { + namesOffset += AndroidUtilities.dp(4); + } else if (messageObject.contentType == 1) { + if (messageObject.type == 13) { + namesOffset -= AndroidUtilities.dp(42); + } else { + namesOffset += AndroidUtilities.dp(5); + } + } + + int maxWidth; + if (messageObject.type == 13) { + int width; + if (AndroidUtilities.isTablet()) { + if (AndroidUtilities.isSmallTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { + width = AndroidUtilities.displaySize.x; + } else { + int leftWidth = AndroidUtilities.displaySize.x / 100 * 35; + if (leftWidth < AndroidUtilities.dp(320)) { + leftWidth = AndroidUtilities.dp(320); + } + width = AndroidUtilities.displaySize.x - leftWidth; + } + } else { + width = AndroidUtilities.displaySize.x; + } + if (messageObject.isOut()) { + maxWidth = width - backgroundWidth - AndroidUtilities.dp(60); + } else { + maxWidth = width - backgroundWidth - AndroidUtilities.dp(56 + (isChat ? 61 : 0)); + } + } else { + maxWidth = getMaxNameWidth() - AndroidUtilities.dp(22); + } + if (!media && messageObject.contentType != 0) { + maxWidth -= AndroidUtilities.dp(8); + } + + CharSequence stringFinalName = null; + CharSequence stringFinalText = null; + if (messageObject.replyMessageObject != null) { + TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(messageObject.replyMessageObject.photoThumbs, 80); + if (photoSize == null || messageObject.replyMessageObject.type == 13 || messageObject.type == 13 && !AndroidUtilities.isTablet()) { + replyImageReceiver.setImageBitmap((Drawable) null); + needReplyImage = false; + } else { + currentReplyPhoto = photoSize.location; + replyImageReceiver.setImage(photoSize.location, "50_50", null, true); + needReplyImage = true; + maxWidth -= AndroidUtilities.dp(44); + } + + TLRPC.User user = MessagesController.getInstance().getUser(messageObject.replyMessageObject.messageOwner.from_id); + if (user != null) { + stringFinalName = TextUtils.ellipsize(ContactsController.formatName(user.first_name, user.last_name).replace("\n", " "), replyNamePaint, maxWidth - AndroidUtilities.dp(8), TextUtils.TruncateAt.END); + } + if (messageObject.replyMessageObject.messageText != null && messageObject.replyMessageObject.messageText.length() > 0) { + String mess = messageObject.replyMessageObject.messageText.toString(); + if (mess.length() > 150) { + mess = mess.substring(0, 150); + } + mess = mess.replace("\n", " "); + stringFinalText = Emoji.replaceEmoji(mess, replyTextPaint.getFontMetricsInt(), AndroidUtilities.dp(14)); + stringFinalText = TextUtils.ellipsize(stringFinalText, replyTextPaint, maxWidth - AndroidUtilities.dp(8), TextUtils.TruncateAt.END); + } + } + if (stringFinalName == null) { + stringFinalName = LocaleController.getString("Loading", R.string.Loading); + } + try { + replyNameLayout = new StaticLayout(stringFinalName, replyNamePaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); + if (replyNameLayout.getLineCount() > 0) { + replyNameWidth = (int)Math.ceil(replyNameLayout.getLineWidth(0)) + AndroidUtilities.dp(12 + (needReplyImage ? 44 : 0)); + replyNameOffset = replyNameLayout.getLineLeft(0); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + try { + if (stringFinalText != null) { + replyTextLayout = new StaticLayout(stringFinalText, replyTextPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); + if (replyTextLayout.getLineCount() > 0) { + replyTextWidth = (int) Math.ceil(replyTextLayout.getLineWidth(0)) + AndroidUtilities.dp(12 + (needReplyImage ? 44 : 0)); + replyTextOffset = replyTextLayout.getLineLeft(0); + } + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + requestLayout(); } @@ -337,6 +501,11 @@ public class ChatBaseCell extends BaseCell { forwardNamePressed = true; result = true; } + } else if (currentMessageObject.isReply()) { + if (x >= replyStartX && x <= replyStartX + Math.max(replyNameWidth, replyTextWidth) && y >= replyStartY && y <= replyStartY + AndroidUtilities.dp(35)) { + replyPressed = true; + result = true; + } } if (result) { startCheckLongPress(); @@ -374,6 +543,20 @@ public class ChatBaseCell extends BaseCell { forwardNamePressed = false; } } + } else if (replyPressed) { + if (event.getAction() == MotionEvent.ACTION_UP) { + replyPressed = false; + playSoundEffect(SoundEffectConstants.CLICK); + if (delegate != null) { + delegate.didPressReplyMessage(this, currentMessageObject.messageOwner.reply_to_msg_id); + } + } else if (event.getAction() == MotionEvent.ACTION_CANCEL) { + replyPressed = false; + } else if (event.getAction() == MotionEvent.ACTION_MOVE) { + if (!(x >= replyStartX && x <= replyStartX + Math.max(replyNameWidth, replyTextWidth) && y >= replyStartY && y <= replyStartY + AndroidUtilities.dp(35))) { + replyPressed = false; + } + } } } return result; @@ -442,7 +625,7 @@ public class ChatBaseCell extends BaseCell { Drawable currentBackgroundDrawable = null; if (currentMessageObject.isOut()) { - if (isPressed() && isCheckPressed || !isCheckPressed && isPressed) { + if (isPressed() && isCheckPressed || !isCheckPressed && isPressed || isHighlighted) { if (!media) { currentBackgroundDrawable = backgroundDrawableOutSelected; } else { @@ -457,7 +640,7 @@ public class ChatBaseCell extends BaseCell { } setDrawableBounds(currentBackgroundDrawable, layoutWidth - backgroundWidth - (!media ? 0 : AndroidUtilities.dp(9)), AndroidUtilities.dp(1), backgroundWidth, layoutHeight - AndroidUtilities.dp(2)); } else { - if (isPressed() && isCheckPressed || !isCheckPressed && isPressed) { + if (isPressed() && isCheckPressed || !isCheckPressed && isPressed || isHighlighted) { if (!media) { currentBackgroundDrawable = backgroundDrawableInSelected; } else { @@ -491,21 +674,87 @@ public class ChatBaseCell extends BaseCell { } if (drawForwardedName && forwardedNameLayout != null) { - canvas.save(); + forwardNameY = AndroidUtilities.dp(10 + (drawName ? 19 : 0)); if (currentMessageObject.isOut()) { forwardNamePaint.setColor(0xff4a923c); forwardNameX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(10); - forwardNameY = AndroidUtilities.dp(10 + (drawName ? 18 : 0)); } else { forwardNamePaint.setColor(0xff006fc8); forwardNameX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(19); - forwardNameY = AndroidUtilities.dp(10 + (drawName ? 18 : 0)); } + canvas.save(); canvas.translate(forwardNameX - forwardNameOffsetX, forwardNameY); forwardedNameLayout.draw(canvas); canvas.restore(); } + if (currentMessageObject.isReply()) { + if (currentMessageObject.type == 13) { + replyLinePaint.setColor(0xffffffff); + replyNamePaint.setColor(0xffffffff); + replyTextPaint.setColor(0xffffffff); + int backWidth; + if (currentMessageObject.isOut()) { + backWidth = currentBackgroundDrawable.getBounds().left - AndroidUtilities.dp(32); + replyStartX = currentBackgroundDrawable.getBounds().left - AndroidUtilities.dp(9) - backWidth; + } else { + backWidth = getWidth() - currentBackgroundDrawable.getBounds().right - AndroidUtilities.dp(32); + replyStartX = currentBackgroundDrawable.getBounds().right + AndroidUtilities.dp(23); + } + Drawable back; + if (ApplicationLoader.isCustomTheme()) { + back = backgroundBlack; + } else { + back = backgroundBlue; + } + replyStartY = layoutHeight - AndroidUtilities.dp(58); + back.setBounds(replyStartX - AndroidUtilities.dp(7), replyStartY - AndroidUtilities.dp(6), replyStartX - AndroidUtilities.dp(7) + backWidth, replyStartY + AndroidUtilities.dp(41)); + back.draw(canvas); + } else { + if (currentMessageObject.isOut()) { + replyLinePaint.setColor(0xff8dc97a); + replyNamePaint.setColor(0xff61a349); + if (currentMessageObject.replyMessageObject != null && currentMessageObject.replyMessageObject.type == 0) { + replyTextPaint.setColor(0xff000000); + } else { + replyTextPaint.setColor(0xff70b15c); + } + replyStartX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(11); + } else { + replyLinePaint.setColor(0xff6c9fd2); + replyNamePaint.setColor(0xff377aae); + if (currentMessageObject.replyMessageObject != null && currentMessageObject.replyMessageObject.type == 0) { + replyTextPaint.setColor(0xff000000); + } else { + replyTextPaint.setColor(0xff999999); + } + if (currentMessageObject.contentType == 1 && media) { + replyStartX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(11); + } else { + replyStartX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(20); + } + } + replyStartY = AndroidUtilities.dp(12 + (drawForwardedName && forwardedNameLayout != null ? 36 : 0) + (drawName && nameLayout != null ? 20 : 0)); + } + canvas.drawRect(replyStartX, replyStartY, replyStartX + AndroidUtilities.dp(2), replyStartY + AndroidUtilities.dp(35), replyLinePaint); + if (needReplyImage) { + replyImageReceiver.setImageCoords(replyStartX + AndroidUtilities.dp(10), replyStartY, AndroidUtilities.dp(35), AndroidUtilities.dp(35)); + replyImageReceiver.draw(canvas); + } + if (replyNameLayout != null) { + canvas.save(); + canvas.translate(replyStartX - replyNameOffset + AndroidUtilities.dp(10 + (needReplyImage ? 44 : 0)), replyStartY); + replyNameLayout.draw(canvas); + canvas.restore(); + } + if (replyTextLayout != null) { + canvas.save(); + canvas.translate(replyStartX - replyTextOffset + AndroidUtilities.dp(10 + (needReplyImage ? 44 : 0)), replyStartY + AndroidUtilities.dp(19)); + replyTextLayout.draw(canvas); + canvas.restore(); + } + } + if (drawTime) { if (media) { setDrawableBounds(mediaBackgroundDrawable, timeX - AndroidUtilities.dp(3), layoutHeight - AndroidUtilities.dp(27.5f), timeWidth + AndroidUtilities.dp(6 + (currentMessageObject.isOut() ? 20 : 0)), AndroidUtilities.dp(16.5f)); @@ -574,9 +823,9 @@ public class ChatBaseCell extends BaseCell { if (drawCheck2) { if (!media) { if (drawCheck1) { - setDrawableBounds(checkDrawable, layoutWidth - AndroidUtilities.dp(22.5f) - checkDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.5f) - checkDrawable.getIntrinsicHeight()); + setDrawableBounds(checkDrawable, layoutWidth - AndroidUtilities.dp(22.5f) - checkDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - checkDrawable.getIntrinsicHeight()); } else { - setDrawableBounds(checkDrawable, layoutWidth - AndroidUtilities.dp(18.5f) - checkDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.5f) - checkDrawable.getIntrinsicHeight()); + setDrawableBounds(checkDrawable, layoutWidth - AndroidUtilities.dp(18.5f) - checkDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - checkDrawable.getIntrinsicHeight()); } checkDrawable.draw(canvas); } else { @@ -590,7 +839,7 @@ public class ChatBaseCell extends BaseCell { } if (drawCheck1) { if (!media) { - setDrawableBounds(halfCheckDrawable, layoutWidth - AndroidUtilities.dp(18) - halfCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.5f) - halfCheckDrawable.getIntrinsicHeight()); + setDrawableBounds(halfCheckDrawable, layoutWidth - AndroidUtilities.dp(18) - halfCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - halfCheckDrawable.getIntrinsicHeight()); halfCheckDrawable.draw(canvas); } else { setDrawableBounds(halfCheckMediaDrawable, layoutWidth - AndroidUtilities.dp(20.5f) - halfCheckMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.0f) - halfCheckMediaDrawable.getIntrinsicHeight()); 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 13edf97c4..45907c708 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatContactCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatContactCell.java @@ -32,9 +32,9 @@ import org.telegram.ui.Components.AvatarDrawable; public class ChatContactCell extends ChatBaseCell { - public static interface ChatContactCellDelegate { - public abstract void didClickAddButton(ChatContactCell cell, TLRPC.User user); - public abstract void didClickPhone(ChatContactCell cell); + public interface ChatContactCellDelegate { + void didClickAddButton(ChatContactCell cell, TLRPC.User user); + void didClickPhone(ChatContactCell cell); } private static TextPaint namePaint; @@ -113,7 +113,7 @@ public class ChatContactCell extends ChatBaseCell { if (x >= avatarImage.getImageX() && x <= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(42) && y >= avatarImage.getImageY() && y <= avatarImage.getImageY() + avatarImage.getImageHeight()) { avatarPressed = true; result = true; - } else if (x >= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(52) && y >= AndroidUtilities.dp(13) && x <= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(92) && y <= AndroidUtilities.dp(52)) { + } else if (x >= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(52) && y >= AndroidUtilities.dp(13) + namesOffset && x <= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(92) && y <= AndroidUtilities.dp(52) + namesOffset) { buttonPressed = true; result = true; } @@ -154,7 +154,7 @@ public class ChatContactCell extends ChatBaseCell { } else if (event.getAction() == MotionEvent.ACTION_CANCEL) { buttonPressed = false; } else if (event.getAction() == MotionEvent.ACTION_MOVE) { - if (!(x >= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(52) && y >= AndroidUtilities.dp(13) && x <= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(92) && y <= AndroidUtilities.dp(52))) { + if (!(x >= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(52) && y >= AndroidUtilities.dp(13) + namesOffset && x <= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(92) && y <= AndroidUtilities.dp(52) + namesOffset)) { buttonPressed = false; } } @@ -235,7 +235,7 @@ public class ChatContactCell extends ChatBaseCell { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), AndroidUtilities.dp(71)); + setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), AndroidUtilities.dp(71) + namesOffset); } @Override @@ -257,7 +257,7 @@ public class ChatContactCell extends ChatBaseCell { x = AndroidUtilities.dp(16); } } - avatarImage.setImageCoords(x, AndroidUtilities.dp(9), AndroidUtilities.dp(42), AndroidUtilities.dp(42)); + avatarImage.setImageCoords(x, AndroidUtilities.dp(9) + namesOffset, AndroidUtilities.dp(42), AndroidUtilities.dp(42)); } @Override @@ -272,14 +272,14 @@ public class ChatContactCell extends ChatBaseCell { if (nameLayout != null) { canvas.save(); - canvas.translate(avatarImage.getImageX() + avatarImage.getImageWidth() + AndroidUtilities.dp(9), AndroidUtilities.dp(10)); + canvas.translate(avatarImage.getImageX() + avatarImage.getImageWidth() + AndroidUtilities.dp(9), AndroidUtilities.dp(10) + namesOffset); namePaint.setColor(AvatarDrawable.getColorForId(currentMessageObject.messageOwner.media.user_id)); nameLayout.draw(canvas); canvas.restore(); } if (phoneLayout != null) { canvas.save(); - canvas.translate(avatarImage.getImageX() + avatarImage.getImageWidth() + AndroidUtilities.dp(9), AndroidUtilities.dp(31)); + canvas.translate(avatarImage.getImageX() + avatarImage.getImageWidth() + AndroidUtilities.dp(9), AndroidUtilities.dp(31) + namesOffset); phoneLayout.draw(canvas); canvas.restore(); } @@ -291,7 +291,7 @@ public class ChatContactCell extends ChatBaseCell { } else { addContactDrawable = addContactDrawableIn; } - setDrawableBounds(addContactDrawable, avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(78), AndroidUtilities.dp(13)); + setDrawableBounds(addContactDrawable, avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(78), AndroidUtilities.dp(13) + namesOffset); addContactDrawable.draw(canvas); } } 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 87825a1c6..a2a6f9245 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java @@ -43,9 +43,9 @@ import java.util.Locale; public class ChatMediaCell extends ChatBaseCell implements MediaController.FileDownloadProgressListener { - public static interface ChatMediaCellDelegate { - public abstract void didClickedImage(ChatMediaCell cell); - public abstract void didPressedOther(ChatMediaCell cell); + public interface ChatMediaCellDelegate { + void didClickedImage(ChatMediaCell cell); + void didPressedOther(ChatMediaCell cell); } private static Drawable placeholderDocInDrawable; @@ -191,7 +191,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD otherPressed = true; result = true; } - } else { + } else if (currentMessageObject.type != 13) { if (x >= photoImage.getImageX() && x <= photoImage.getImageX() + backgroundWidth && y >= photoImage.getImageY() && y <= photoImage.getImageY() + photoImage.getImageHeight()) { imagePressed = true; result = true; @@ -359,7 +359,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD photoImage.cancelLoadImage(); } else if (currentMessageObject.type == 8 || currentMessageObject.type == 9) { FileLoader.getInstance().cancelLoadFile(currentMessageObject.messageOwner.media.document); - if (lastDownloadedGifMessage != null && lastDownloadedGifMessage.messageOwner.id == currentMessageObject.messageOwner.id) { + if (lastDownloadedGifMessage != null && lastDownloadedGifMessage.getId() == currentMessageObject.getId()) { lastDownloadedGifMessage = null; } } else if (currentMessageObject.type == 3) { @@ -413,7 +413,6 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD media = messageObject.type != 9; boolean dataChanged = currentMessageObject == messageObject && (isUserDataChanged() || photoNotSet); if (currentMessageObject != messageObject || isPhotoDataChanged(messageObject) || dataChanged) { - super.setMessageObject(messageObject); cancelLoading = false; buttonState = -1; @@ -510,13 +509,13 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD photoImage.setImageBitmap((BitmapDrawable) null); } } else if (messageObject.type == 4) { //geo - photoWidth = AndroidUtilities.dp(100); + photoWidth = AndroidUtilities.dp(200); photoHeight = AndroidUtilities.dp(100); backgroundWidth = photoWidth + AndroidUtilities.dp(12); double lat = messageObject.messageOwner.media.geo.lat; double lon = messageObject.messageOwner.media.geo._long; - 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); + currentUrl = String.format(Locale.US, "https://maps.googleapis.com/maps/api/staticmap?center=%f,%f&zoom=13&size=200x100&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); photoImage.setNeedsQualityThumb(false); photoImage.setShouldGenerateQualityThumb(false); photoImage.setParentMessageObject(null); @@ -530,15 +529,20 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD break; } } + float maxHeight = AndroidUtilities.displaySize.y * 0.4f; float maxWidth; if (AndroidUtilities.isTablet()) { - maxWidth = (int) (AndroidUtilities.getMinTabletSide() * 0.5f); + maxWidth = AndroidUtilities.getMinTabletSide() * 0.5f; } else { - maxWidth = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.5f); + maxWidth = AndroidUtilities.displaySize.x * 0.5f; } if (photoWidth == 0) { - photoWidth = (int)maxWidth; - photoHeight = photoWidth + AndroidUtilities.dp(100); + photoHeight = (int) maxHeight; + photoWidth = photoHeight + AndroidUtilities.dp(100); + } + if (photoHeight > maxHeight) { + photoWidth *= maxHeight / photoHeight; + photoHeight = (int)maxHeight; } if (photoWidth > maxWidth) { photoHeight *= maxWidth / photoWidth; @@ -549,23 +553,23 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD photoImage.setNeedsQualityThumb(false); photoImage.setShouldGenerateQualityThumb(false); photoImage.setParentMessageObject(null); - if (currentMessageObject.messageOwner.attachPath != null && currentMessageObject.messageOwner.attachPath.length() > 0) { - File f = new File(currentMessageObject.messageOwner.attachPath); + if (messageObject.messageOwner.attachPath != null && messageObject.messageOwner.attachPath.length() > 0) { + File f = new File(messageObject.messageOwner.attachPath); if (f.exists()) { - photoImage.setImage(null, currentMessageObject.messageOwner.attachPath, + photoImage.setImage(null, messageObject.messageOwner.attachPath, String.format(Locale.US, "%d_%d", photoWidth, photoHeight), null, currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null, "b1", - currentMessageObject.messageOwner.media.document.size, true); + messageObject.messageOwner.media.document.size, true); } - } else if (currentMessageObject.messageOwner.media.document.id != 0) { - photoImage.setImage(currentMessageObject.messageOwner.media.document, null, + } else if (messageObject.messageOwner.media.document.id != 0) { + photoImage.setImage(messageObject.messageOwner.media.document, null, String.format(Locale.US, "%d_%d", photoWidth, photoHeight), null, currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null, "b1", - currentMessageObject.messageOwner.media.document.size, true); + messageObject.messageOwner.media.document.size, true); } } else { if (AndroidUtilities.isTablet()) { @@ -603,7 +607,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD if (currentPhotoObject != null) { boolean noSize = false; - if (currentMessageObject.type == 3 || currentMessageObject.type == 8) { + if (messageObject.type == 3 || messageObject.type == 8) { noSize = true; } float scale = (float) currentPhotoObject.w / (float) photoWidth; @@ -636,12 +640,12 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD w = (int) (currentPhotoObject.w / hScale); } } - int timeWidthTotal = timeWidth + AndroidUtilities.dp(14 + (currentMessageObject.isOut() ? 20 : 0)); + int timeWidthTotal = timeWidth + AndroidUtilities.dp(14 + (messageObject.isOut() ? 20 : 0)); if (w < timeWidthTotal) { w = timeWidthTotal; } - if (currentMessageObject.isSecretPhoto()) { + if (messageObject.isSecretPhoto()) { if (AndroidUtilities.isTablet()) { w = h = (int) (AndroidUtilities.getMinTabletSide() * 0.5f); } else { @@ -665,7 +669,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD String fileName = FileLoader.getAttachFileName(currentPhotoObject); if (messageObject.type == 1) { boolean photoExist = true; - File cacheFile = FileLoader.getPathToMessage(currentMessageObject.messageOwner); + File cacheFile = FileLoader.getPathToMessage(messageObject.messageOwner); if (!cacheFile.exists()) { photoExist = false; } else { @@ -696,6 +700,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD photoImage.setImageBitmap((Bitmap)null); } } + super.setMessageObject(messageObject); invalidate(); } @@ -738,7 +743,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD buttonState = 1; radialProgress.setBackground(getDrawableForCurrentState(), true, animated); Float progress = ImageLoader.getInstance().getFileProgress(currentMessageObject.messageOwner.attachPath); - if (progress == null && SendMessagesHelper.getInstance().isSendingMessage(currentMessageObject.messageOwner.id)) { + if (progress == null && SendMessagesHelper.getInstance().isSendingMessage(currentMessageObject.getId())) { progress = 1.0f; } radialProgress.setProgress(progress != null ? progress : 0, false); @@ -788,7 +793,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), photoHeight + AndroidUtilities.dp(14)); + setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), photoHeight + AndroidUtilities.dp(14) + namesOffset); } @Override @@ -809,10 +814,10 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD x = AndroidUtilities.dp(15); } } - photoImage.setImageCoords(x, AndroidUtilities.dp(7), photoWidth, photoHeight); + photoImage.setImageCoords(x, AndroidUtilities.dp(7) + namesOffset, photoWidth, photoHeight); int size = AndroidUtilities.dp(48); buttonX = (int)(x + (photoWidth - size) / 2.0f); - buttonY = (int)(AndroidUtilities.dp(7) + (photoHeight - size) / 2.0f); + buttonY = (int)(AndroidUtilities.dp(7) + (photoHeight - size) / 2.0f) + namesOffset; 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)); @@ -854,12 +859,13 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD protected void onAfterBackgroundDraw(Canvas canvas) { boolean imageDrawn = false; if (gifDrawable != null) { + drawTime = !gifDrawable.isPlaying(); canvas.save(); gifDrawable.setBounds(photoImage.getImageX(), photoImage.getImageY(), photoImage.getImageX() + photoWidth, photoImage.getImageY() + photoHeight); gifDrawable.draw(canvas); canvas.restore(); } else { - photoImage.setPressed(isPressed() && isCheckPressed || !isCheckPressed && isPressed); + photoImage.setPressed(isPressed() && isCheckPressed || !isCheckPressed && isPressed || isHighlighted); photoImage.setVisible(!PhotoViewer.getInstance().isShowingImage(currentMessageObject), false); imageDrawn = photoImage.draw(canvas); drawTime = photoImage.getVisible(); @@ -870,8 +876,8 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD if (currentMessageObject.type == 9) { Drawable menuDrawable = null; if (currentMessageObject.isOut()) { - infoPaint.setColor(0xff75b166); - docBackPaint.setColor(0xffd0f3b3); + infoPaint.setColor(0xff70b15c); + docBackPaint.setColor(0xffdaf5c3); menuDrawable = docMenuOutDrawable; } else { infoPaint.setColor(0xffa1adbb); @@ -879,7 +885,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD menuDrawable = docMenuInDrawable; } - setDrawableBounds(menuDrawable, photoImage.getImageX() + backgroundWidth - AndroidUtilities.dp(44), AndroidUtilities.dp(10)); + setDrawableBounds(menuDrawable, photoImage.getImageX() + backgroundWidth - AndroidUtilities.dp(44), AndroidUtilities.dp(10) + namesOffset); menuDrawable.draw(canvas); if (buttonState >= 0 && buttonState < 4) { @@ -978,7 +984,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD @Override public void onSuccessDownload(String fileName) { radialProgress.setProgress(1, true); - if (currentMessageObject.type == 8 && lastDownloadedGifMessage != null && lastDownloadedGifMessage.messageOwner.id == currentMessageObject.messageOwner.id) { + if (currentMessageObject.type == 8 && lastDownloadedGifMessage != null && lastDownloadedGifMessage.getId() == currentMessageObject.getId()) { buttonState = 2; didPressedButton(true); } else if (!photoNotSet) { 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 ef2814c84..9098aaf1d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java @@ -9,34 +9,128 @@ package org.telegram.ui.Cells; import android.content.Context; +import android.content.Intent; import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.provider.Browser; +import android.text.Layout; import android.text.Spannable; +import android.text.SpannableStringBuilder; +import android.text.StaticLayout; +import android.text.TextPaint; +import android.text.TextUtils; import android.text.style.ClickableSpan; import android.view.MotionEvent; import org.telegram.android.AndroidUtilities; +import org.telegram.android.ImageReceiver; +import org.telegram.android.MediaController; +import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; import org.telegram.android.MessageObject; +import org.telegram.messenger.R; +import org.telegram.messenger.TLRPC; +import org.telegram.ui.Components.StaticLayoutEx; +import org.telegram.ui.Components.URLSpanNoUnderline; + +import java.util.Locale; public class ChatMessageCell extends ChatBaseCell { private int textX, textY; private int totalHeight = 0; private ClickableSpan pressedLink; + private int linkBlockNum; + private MyPath urlPath = new MyPath(); + private boolean linkPreviewPressed; + private static Paint urlPaint; private int lastVisibleBlockNum = 0; private int firstVisibleBlockNum = 0; private int totalVisibleBlocksCount = 0; + private ImageReceiver linkImageView; + private boolean isSmallImage; + private boolean drawLinkImageView; + private boolean hasLinkPreview; + private int linkPreviewHeight; + private boolean isInstagram; + private int smallImageX; + private int descriptionY; + private int durationWidth; + private StaticLayout siteNameLayout; + private StaticLayout titleLayout; + private StaticLayout descriptionLayout; + private StaticLayout durationLayout; + private StaticLayout authorLayout; + private static TextPaint durationPaint; + private TLRPC.PhotoSize currentPhotoObject; + private TLRPC.PhotoSize currentPhotoObjectThumb; + private boolean imageCleared; + + private static Drawable igvideoDrawable; + + private class MyPath extends Path { + + private StaticLayout currentLayout; + private int currentLine; + private float lastTop = -1; + + public void setCurrentLayout(StaticLayout layout, int start) { + currentLayout = layout; + currentLine = layout.getLineForOffset(start); + lastTop = -1; + } + + @Override + public void addRect(float left, float top, float right, float bottom, Direction dir) { + if (lastTop == -1) { + lastTop = top; + } else if (lastTop != top) { + lastTop = top; + currentLine++; + } + float lineRight = currentLayout.getLineRight(currentLine); + float lineLeft = currentLayout.getLineLeft(currentLine); + if (left >= lineRight) { + return; + } + if (right > lineRight) { + right = lineRight; + } + if (left < lineLeft) { + left = lineLeft; + } + super.addRect(left, top, right, bottom, dir); + } + } + public ChatMessageCell(Context context) { super(context); drawForwardedName = true; + linkImageView = new ImageReceiver(this); + if (urlPaint == null) { + urlPaint = new Paint(); + urlPaint.setColor(0x33316f9f); + } + } + + private void resetPressedLink() { + if (pressedLink != null) { + pressedLink = null; + } + linkPreviewPressed = false; + invalidate(); } @Override public boolean onTouchEvent(MotionEvent event) { + boolean result = false; if (currentMessageObject != null && currentMessageObject.textLayoutBlocks != null && !currentMessageObject.textLayoutBlocks.isEmpty() && currentMessageObject.messageText instanceof Spannable && !isPressed) { - if (event.getAction() == MotionEvent.ACTION_DOWN || pressedLink != null && event.getAction() == MotionEvent.ACTION_UP) { + if (event.getAction() == MotionEvent.ACTION_DOWN || (linkPreviewPressed || pressedLink != null) && event.getAction() == MotionEvent.ACTION_UP) { int x = (int)event.getX(); int y = (int)event.getY(); if (x >= textX && y >= textY && x <= textX + currentMessageObject.textWidth && y <= textY + currentMessageObject.textHeight) { @@ -54,42 +148,127 @@ public class ChatMessageCell extends ChatBaseCell { if (left <= x && left + block.textLayout.getLineWidth(line) >= x) { Spannable buffer = (Spannable)currentMessageObject.messageText; ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class); - if (link.length != 0) { if (event.getAction() == MotionEvent.ACTION_DOWN) { + resetPressedLink(); pressedLink = link[0]; - return true; + linkBlockNum = blockNum; + try { + int start = buffer.getSpanStart(pressedLink) - block.charactersOffset; + urlPath.setCurrentLayout(block.textLayout, start); + block.textLayout.getSelectionPath(start, buffer.getSpanEnd(pressedLink) - block.charactersOffset, urlPath); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + result = true; } else { if (link[0] == pressedLink) { try { - pressedLink.onClick(this); + if (pressedLink instanceof URLSpanNoUnderline) { + String url = ((URLSpanNoUnderline) pressedLink).getURL(); + if (url.startsWith("@") || url.startsWith("#")) { + if (delegate != null) { + delegate.didPressUrl(url); + } + } + } else { + pressedLink.onClick(this); + } } catch (Exception e) { FileLog.e("tmessages", e); } - return true; + resetPressedLink(); + result = true; } } } else { - pressedLink = null; + resetPressedLink(); } } else { - pressedLink = null; + resetPressedLink(); } } catch (Exception e) { - pressedLink = null; + resetPressedLink(); FileLog.e("tmessages", e); } } else { - pressedLink = null; + resetPressedLink(); + } + } else if (hasLinkPreview && x >= textX && x <= textX + backgroundWidth && y >= textY + currentMessageObject.textHeight && y <= textY + currentMessageObject.textHeight + linkPreviewHeight + AndroidUtilities.dp(8)) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + resetPressedLink(); + if (drawLinkImageView && linkImageView.isInsideImage(x, y)) { + linkPreviewPressed = true; + result = true; + } else { + if (descriptionLayout != null && y >= descriptionY) { + try { + x -= textX + AndroidUtilities.dp(10); + y -= descriptionY; + final int line = descriptionLayout.getLineForVertical(y); + final int off = descriptionLayout.getOffsetForHorizontal(line, x); + + final float left = descriptionLayout.getLineLeft(line); + if (left <= x && left + descriptionLayout.getLineWidth(line) >= x) { + Spannable buffer = (Spannable) currentMessageObject.linkDescription; + ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class); + if (link.length != 0) { + resetPressedLink(); + pressedLink = link[0]; + linkPreviewPressed = true; + linkBlockNum = -10; + result = true; + try { + int start = buffer.getSpanStart(pressedLink); + urlPath.setCurrentLayout(descriptionLayout, start); + descriptionLayout.getSelectionPath(start, buffer.getSpanEnd(pressedLink), urlPath); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } else { + resetPressedLink(); + } + } else { + resetPressedLink(); + } + } catch (Exception e) { + resetPressedLink(); + FileLog.e("tmessages", e); + } + } + } + } else if (linkPreviewPressed) { + try { + if (pressedLink != null) { + pressedLink.onClick(this); + } else { + Uri uri = Uri.parse(currentMessageObject.messageOwner.media.webpage.url); + Intent intent = new Intent(Intent.ACTION_VIEW, uri); + intent.putExtra(Browser.EXTRA_APPLICATION_ID, getContext().getPackageName()); + getContext().startActivity(intent); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + resetPressedLink(); + result = true; } } else { - pressedLink = null; + resetPressedLink(); } + } else if (event.getAction() == MotionEvent.ACTION_CANCEL) { + resetPressedLink(); } } else { - pressedLink = null; + resetPressedLink(); } - return super.onTouchEvent(event); + if (result && event.getAction() == MotionEvent.ACTION_DOWN) { + startCheckLongPress(); + } + if (event.getAction() != MotionEvent.ACTION_DOWN && event.getAction() != MotionEvent.ACTION_MOVE) { + cancelCheckLongPress(); + } + return result || super.onTouchEvent(event); } public void setVisiblePart(int position, int height) { @@ -127,6 +306,51 @@ public class ChatMessageCell extends ChatBaseCell { return left1 <= right2; } + private StaticLayout generateStaticLayout(CharSequence text, TextPaint paint, int maxWidth, int smallWidth, int linesCount, int maxLines) { + SpannableStringBuilder stringBuilder = new SpannableStringBuilder(text); + int addedChars = 0; + StaticLayout layout = new StaticLayout(text, paint, smallWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); + for (int a = 0; a < linesCount; a++) { + int pos = layout.getLineEnd(a); + if (pos == text.length()) { + break; + } + pos--; + if (stringBuilder.charAt(pos + addedChars) == ' ') { + stringBuilder.replace(pos + addedChars, pos + addedChars + 1, "\n"); + } else { + stringBuilder.insert(pos + addedChars, "\n"); + addedChars++; + } + if (a == layout.getLineCount() - 1 || a == maxLines - 1) { + break; + } + } + return StaticLayoutEx.createStaticLayout(stringBuilder, paint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, AndroidUtilities.dp(1), false, TextUtils.TruncateAt.END, maxWidth, maxLines); + } + + @Override + protected boolean isUserDataChanged() { + if (imageCleared || !hasLinkPreview && currentMessageObject.messageOwner.media != null && currentMessageObject.messageOwner.media.webpage instanceof TLRPC.TL_webPage) { + return true; + } + //suppress warning + return super.isUserDataChanged(); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + if (linkImageView != null) { + linkImageView.clearImage(); + if (currentPhotoObject != null) { + imageCleared = true; + currentPhotoObject = null; + currentPhotoObjectThumb = null; + } + } + } + @Override public void setMessageObject(MessageObject messageObject) { if (currentMessageObject != messageObject || isUserDataChanged()) { @@ -134,7 +358,21 @@ public class ChatMessageCell extends ChatBaseCell { firstVisibleBlockNum = 0; lastVisibleBlockNum = 0; } - pressedLink = null; + drawLinkImageView = false; + hasLinkPreview = false; + resetPressedLink(); + linkPreviewPressed = false; + linkPreviewHeight = 0; + smallImageX = 0; + isInstagram = false; + durationLayout = null; + descriptionLayout = null; + titleLayout = null; + siteNameLayout = null; + authorLayout = null; + currentPhotoObject = null; + imageCleared = false; + currentPhotoObjectThumb = null; int maxWidth; if (AndroidUtilities.isTablet()) { @@ -164,13 +402,223 @@ public class ChatMessageCell extends ChatBaseCell { int maxChildWidth = Math.max(backgroundWidth, nameWidth); maxChildWidth = Math.max(maxChildWidth, forwardedNameWidth); + maxChildWidth = Math.max(maxChildWidth, replyNameWidth); + maxChildWidth = Math.max(maxChildWidth, replyTextWidth); int timeMore = timeWidth + AndroidUtilities.dp(6); if (messageObject.isOut()) { timeMore += AndroidUtilities.dp(20.5f); } - if (maxWidth - messageObject.lastLineWidth < timeMore) { + if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage && messageObject.messageOwner.media.webpage instanceof TLRPC.TL_webPage) { + int linkPreviewMaxWidth; + if (AndroidUtilities.isTablet()) { + if (currentMessageObject.messageOwner.to_id.chat_id != 0 && !currentMessageObject.isOut()) { + linkPreviewMaxWidth = AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(122); + } else { + linkPreviewMaxWidth = AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(80); + } + } else { + if (currentMessageObject.messageOwner.to_id.chat_id != 0 && !currentMessageObject.isOut()) { + linkPreviewMaxWidth = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) - AndroidUtilities.dp(122); + } else { + linkPreviewMaxWidth = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) - AndroidUtilities.dp(80); + } + } + int additinalWidth = AndroidUtilities.dp(10); + int restLinesCount = 3; + int additionalHeight = 0; + linkPreviewMaxWidth -= additinalWidth; + + hasLinkPreview = true; + TLRPC.TL_webPage webPage = (TLRPC.TL_webPage) messageObject.messageOwner.media.webpage; + + if (currentMessageObject.photoThumbs == null && webPage.photo != null) { + currentMessageObject.generateThumbs(true); + } + + if (MediaController.getInstance().canDownloadMedia(MediaController.AUTODOWNLOAD_MASK_PHOTO)) { + isSmallImage = webPage.description != null && webPage.type != null && (webPage.type.equals("app") || webPage.type.equals("profile") || webPage.type.equals("article")) && currentMessageObject.photoThumbs != null; + } + + if (webPage.site_name != null) { + try { + int width = (int) Math.ceil(replyNamePaint.measureText(webPage.site_name)); + siteNameLayout = new StaticLayout(webPage.site_name, replyNamePaint, Math.min(width, linkPreviewMaxWidth), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); + int height = siteNameLayout.getLineBottom(siteNameLayout.getLineCount() - 1); + linkPreviewHeight += height; + totalHeight += height; + additionalHeight += height; + maxChildWidth = Math.max(maxChildWidth, width + additinalWidth); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + + if (webPage.title != null) { + try { + if (linkPreviewHeight != 0) { + linkPreviewHeight += AndroidUtilities.dp(2); + totalHeight += AndroidUtilities.dp(2); + } + int restLines = 0; + if (!isSmallImage || webPage.description == null) { + titleLayout = StaticLayoutEx.createStaticLayout(webPage.title, replyNamePaint, linkPreviewMaxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, AndroidUtilities.dp(1), false, TextUtils.TruncateAt.END, linkPreviewMaxWidth, 2); + } else { + restLines = restLinesCount; + titleLayout = generateStaticLayout(webPage.title, replyNamePaint, linkPreviewMaxWidth, linkPreviewMaxWidth - AndroidUtilities.dp(48 + 2), restLinesCount, 2); + restLinesCount -= titleLayout.getLineCount(); + } + int height = titleLayout.getLineBottom(titleLayout.getLineCount() - 1); + linkPreviewHeight += height; + totalHeight += height; + for (int a = 0; a < titleLayout.getLineCount(); a++) { + int width = (int) Math.ceil(titleLayout.getLineWidth(a)); + if (a < restLines) { + smallImageX = Math.max(smallImageX, width); + width += AndroidUtilities.dp(48 + 2); + } + maxChildWidth = Math.max(maxChildWidth, width + additinalWidth); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + + if (webPage.author != null) { + try { + if (linkPreviewHeight != 0) { + linkPreviewHeight += AndroidUtilities.dp(2); + totalHeight += AndroidUtilities.dp(2); + } + int width = Math.min((int) Math.ceil(replyNamePaint.measureText(webPage.author)), linkPreviewMaxWidth); + if (restLinesCount == 3 && (!isSmallImage || webPage.description == null)) { + authorLayout = new StaticLayout(webPage.author, replyNamePaint, width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); + } else { + authorLayout = generateStaticLayout(webPage.author, replyNamePaint, width, linkPreviewMaxWidth - AndroidUtilities.dp(48 + 2), restLinesCount, 1); + restLinesCount -= authorLayout.getLineCount(); + } + int height = authorLayout.getLineBottom(authorLayout.getLineCount() - 1); + linkPreviewHeight += height; + totalHeight += height; + maxChildWidth = Math.max(maxChildWidth, width + additinalWidth); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + + if (webPage.description != null) { + try { + currentMessageObject.generateLinkDescription(); + if (linkPreviewHeight != 0) { + linkPreviewHeight += AndroidUtilities.dp(2); + totalHeight += AndroidUtilities.dp(2); + } + int restLines = 0; + if (restLinesCount == 3 && !isSmallImage) { + descriptionLayout = StaticLayoutEx.createStaticLayout(messageObject.linkDescription, replyTextPaint, linkPreviewMaxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, AndroidUtilities.dp(1), false, TextUtils.TruncateAt.END, linkPreviewMaxWidth, 6); + } else { + restLines = restLinesCount; + descriptionLayout = generateStaticLayout(messageObject.linkDescription, replyTextPaint, linkPreviewMaxWidth, linkPreviewMaxWidth - AndroidUtilities.dp(48 + 2), restLinesCount, 6); + } + int height = descriptionLayout.getLineBottom(descriptionLayout.getLineCount() - 1); + linkPreviewHeight += height; + totalHeight += height; + for (int a = 0; a < descriptionLayout.getLineCount(); a++) { + int width = (int) Math.ceil(descriptionLayout.getLineWidth(a)); + if (a < restLines) { + smallImageX = Math.max(smallImageX, width); + width += AndroidUtilities.dp(48 + 2); + } + maxChildWidth = Math.max(maxChildWidth, width + additinalWidth); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + + if (webPage.photo != null && MediaController.getInstance().canDownloadMedia(MediaController.AUTODOWNLOAD_MASK_PHOTO)) { + boolean smallImage = webPage.type != null && (webPage.type.equals("app") || webPage.type.equals("profile") || webPage.type.equals("article")); + if (smallImage && descriptionLayout != null && descriptionLayout.getLineCount() == 1) { + smallImage = false; + isSmallImage = false; + } + int maxPhotoWidth = smallImage ? AndroidUtilities.dp(48) : linkPreviewMaxWidth; + currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, maxPhotoWidth); + currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 80); + if (currentPhotoObjectThumb == currentPhotoObject) { + currentPhotoObjectThumb = null; + } + if (currentPhotoObject != null) { + if (linkPreviewHeight != 0) { + linkPreviewHeight += AndroidUtilities.dp(2); + totalHeight += AndroidUtilities.dp(2); + } + + maxChildWidth = Math.max(maxChildWidth, maxPhotoWidth + additinalWidth); + currentPhotoObject.size = -1; + if (currentPhotoObjectThumb != null) { + currentPhotoObjectThumb.size = -1; + } + + int width; + int height; + if (smallImage) { + width = height = maxPhotoWidth; + } else { + width = currentPhotoObject.w; + height = currentPhotoObject.h; + float scale = width / (float) maxPhotoWidth; + width /= scale; + height /= scale; + if (height > AndroidUtilities.displaySize.y / 3) { + height = AndroidUtilities.displaySize.y / 3; + } + } + if (isSmallImage) { + if (AndroidUtilities.dp(50) + additionalHeight > linkPreviewHeight) { + totalHeight += AndroidUtilities.dp(50) + additionalHeight - linkPreviewHeight + AndroidUtilities.dp(8); + linkPreviewHeight = AndroidUtilities.dp(50) + additionalHeight; + } + linkPreviewHeight -= AndroidUtilities.dp(8); + } else { + totalHeight += height + AndroidUtilities.dp(12); + linkPreviewHeight += height; + } + + linkImageView.setImageCoords(0, 0, width, height); + linkImageView.setImage(currentPhotoObject.location, String.format(Locale.US, "%d_%d", width, height), currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null, String.format(Locale.US, "%d_%d_b", width, height), 0, false); + drawLinkImageView = true; + + if (webPage.site_name != null) { + if (webPage.site_name.toLowerCase().equals("instagram") && webPage.type != null && webPage.type.equals("video")) { + isInstagram = true; + if (igvideoDrawable == null) { + igvideoDrawable = getResources().getDrawable(R.drawable.igvideo); + } + } + } + } + + if (webPage.duration != 0) { + if (durationPaint == null) { + durationPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); + durationPaint.setTextSize(AndroidUtilities.dp(12)); + durationPaint.setColor(0xffffffff); + } + int minutes = webPage.duration / 60; + int seconds = webPage.duration - minutes * 60; + String str = String.format("%d:%02d", minutes, seconds); + durationWidth = (int) Math.ceil(durationPaint.measureText(str)); + durationLayout = new StaticLayout(str, durationPaint, durationWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); + } + } else { + linkPreviewHeight -= AndroidUtilities.dp(6); + totalHeight += AndroidUtilities.dp(4); + } + } + + if (hasLinkPreview || maxWidth - messageObject.lastLineWidth < timeMore) { totalHeight += AndroidUtilities.dp(14); backgroundWidth = Math.max(maxChildWidth, messageObject.lastLineWidth) + AndroidUtilities.dp(29); } else { @@ -205,7 +653,7 @@ public class ChatMessageCell extends ChatBaseCell { @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); - if (currentMessageObject == null || currentMessageObject.textLayoutBlocks == null || currentMessageObject.textLayoutBlocks.isEmpty() || firstVisibleBlockNum < 0) { + if (currentMessageObject == null || currentMessageObject.textLayoutBlocks == null || currentMessageObject.textLayoutBlocks.isEmpty()) { return; } @@ -217,19 +665,121 @@ public class ChatMessageCell extends ChatBaseCell { textY = AndroidUtilities.dp(10) + namesOffset; } - for (int a = firstVisibleBlockNum; a <= lastVisibleBlockNum; a++) { - if (a >= currentMessageObject.textLayoutBlocks.size()) { - break; + if (firstVisibleBlockNum >= 0) { + for (int a = firstVisibleBlockNum; a <= lastVisibleBlockNum; a++) { + if (a >= currentMessageObject.textLayoutBlocks.size()) { + break; + } + MessageObject.TextLayoutBlock block = currentMessageObject.textLayoutBlocks.get(a); + canvas.save(); + canvas.translate(textX - (int) Math.ceil(block.textXOffset), textY + block.textYOffset); + if (pressedLink != null && a == linkBlockNum) { + canvas.drawPath(urlPath, urlPaint); + } + try { + block.textLayout.draw(canvas); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + canvas.restore(); } - MessageObject.TextLayoutBlock block = currentMessageObject.textLayoutBlocks.get(a); - canvas.save(); - canvas.translate(textX - (int)Math.ceil(block.textXOffset), textY + block.textYOffset); - try { - block.textLayout.draw(canvas); - } catch (Exception e) { - FileLog.e("tmessages", e); + } + + if (hasLinkPreview) { + int startY = textY + currentMessageObject.textHeight + AndroidUtilities.dp(8); + int linkPreviewY = startY; + int smallImageStartY = 0; + replyLinePaint.setColor(currentMessageObject.isOut() ? 0xff8dc97a : 0xff6c9fd2); + + canvas.drawRect(textX, linkPreviewY - AndroidUtilities.dp(3), textX + AndroidUtilities.dp(2), linkPreviewY + linkPreviewHeight + AndroidUtilities.dp(3), replyLinePaint); + + if (siteNameLayout != null) { + replyNamePaint.setColor(currentMessageObject.isOut() ? 0xff70b15c : 0xff4b91cf); + canvas.save(); + canvas.translate(textX + AndroidUtilities.dp(10), linkPreviewY - AndroidUtilities.dp(3)); + siteNameLayout.draw(canvas); + canvas.restore(); + linkPreviewY += siteNameLayout.getLineBottom(siteNameLayout.getLineCount() - 1); + } + + if (titleLayout != null) { + if (linkPreviewY != startY) { + linkPreviewY += AndroidUtilities.dp(2); + } + replyNamePaint.setColor(0xff000000); + smallImageStartY = linkPreviewY - AndroidUtilities.dp(1); + canvas.save(); + canvas.translate(textX + AndroidUtilities.dp(10), linkPreviewY - AndroidUtilities.dp(3)); + titleLayout.draw(canvas); + canvas.restore(); + linkPreviewY += titleLayout.getLineBottom(titleLayout.getLineCount() - 1); + } + + if (authorLayout != null) { + if (linkPreviewY != startY) { + linkPreviewY += AndroidUtilities.dp(2); + } + if (smallImageStartY == 0) { + smallImageStartY = linkPreviewY - AndroidUtilities.dp(1); + } + replyNamePaint.setColor(0xff000000); + canvas.save(); + canvas.translate(textX + AndroidUtilities.dp(10), linkPreviewY - AndroidUtilities.dp(3)); + authorLayout.draw(canvas); + canvas.restore(); + linkPreviewY += authorLayout.getLineBottom(authorLayout.getLineCount() - 1); + } + + if (descriptionLayout != null) { + if (linkPreviewY != startY) { + linkPreviewY += AndroidUtilities.dp(2); + } + if (smallImageStartY == 0) { + smallImageStartY = linkPreviewY - AndroidUtilities.dp(1); + } + replyTextPaint.setColor(0xff000000); + descriptionY = linkPreviewY - AndroidUtilities.dp(3); + canvas.save(); + canvas.translate(textX + AndroidUtilities.dp(10), descriptionY); + if (pressedLink != null && linkBlockNum == -10) { + canvas.drawPath(urlPath, urlPaint); + } + descriptionLayout.draw(canvas); + canvas.restore(); + linkPreviewY += descriptionLayout.getLineBottom(descriptionLayout.getLineCount() - 1); + } + + if (drawLinkImageView) { + if (linkPreviewY != startY) { + linkPreviewY += AndroidUtilities.dp(2); + } + + if (isSmallImage) { + linkImageView.setImageCoords(textX + smallImageX + AndroidUtilities.dp(12), smallImageStartY, linkImageView.getImageWidth(), linkImageView.getImageHeight()); + } else { + linkImageView.setImageCoords(textX + AndroidUtilities.dp(10), linkPreviewY, linkImageView.getImageWidth(), linkImageView.getImageHeight()); + } + linkImageView.draw(canvas); + + if (isInstagram && igvideoDrawable != null) { + int x = linkImageView.getImageX() + linkImageView.getImageWidth() - igvideoDrawable.getIntrinsicWidth() - AndroidUtilities.dp(4); + int y = linkImageView.getImageY() + AndroidUtilities.dp(4); + igvideoDrawable.setBounds(x, y, x + igvideoDrawable.getIntrinsicWidth(), y + igvideoDrawable.getIntrinsicHeight()); + igvideoDrawable.draw(canvas); + } + + if (durationLayout != null) { + int x = linkImageView.getImageX() + linkImageView.getImageWidth() - AndroidUtilities.dp(8) - durationWidth; + int y = linkImageView.getImageY() + linkImageView.getImageHeight() - AndroidUtilities.dp(19); + mediaBackgroundDrawable.setBounds(x - AndroidUtilities.dp(4), y - AndroidUtilities.dp(1.5f), x + durationWidth + AndroidUtilities.dp(4), y + AndroidUtilities.dp(14.5f)); + mediaBackgroundDrawable.draw(canvas); + + canvas.save(); + canvas.translate(x, y); + durationLayout.draw(canvas); + canvas.restore(); + } } - canvas.restore(); } } } 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 d04e80cc4..85f79f6bf 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java @@ -12,7 +12,6 @@ import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.drawable.Drawable; -import android.text.Html; import android.text.Layout; import android.text.StaticLayout; import android.text.TextPaint; @@ -55,12 +54,15 @@ public class DialogCell extends BaseCell { private static Paint linePaint; private long currentDialogId; - private boolean allowPrintStrings; + private boolean isDialogCell; private int lastMessageDate; private int unreadCount; private boolean lastUnreadState; + private int lastSendState; private boolean dialogMuted; private MessageObject message; + private int index; + private boolean isServerOnly; private ImageReceiver avatarImage; private AvatarDrawable avatarDrawable; @@ -129,6 +131,7 @@ public class DialogCell extends BaseCell { messagePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); messagePaint.setTextSize(AndroidUtilities.dp(16)); messagePaint.setColor(0xff8f8f8f); + messagePaint.linkColor = 0xff8f8f8f; linePaint = new Paint(); linePaint.setColor(0xffdcdcdc); @@ -166,14 +169,24 @@ public class DialogCell extends BaseCell { avatarDrawable = new AvatarDrawable(); } - public void setDialog(long dialog_id, MessageObject messageObject, boolean usePrintStrings, int date, int unread, boolean muted) { + public void setDialog(TLRPC.TL_dialog dialog, int i, boolean server) { + currentDialogId = dialog.id; + isDialogCell = true; + index = i; + isServerOnly = server; + update(0); + } + + public void setDialog(long dialog_id, MessageObject messageObject, int date) { currentDialogId = dialog_id; message = messageObject; - allowPrintStrings = usePrintStrings; + isDialogCell = false; lastMessageDate = date; - unreadCount = unread; - dialogMuted = muted; + unreadCount = 0; lastUnreadState = messageObject != null && messageObject.isUnread(); + if (message != null) { + lastSendState = message.messageOwner.send_state; + } update(0); } @@ -211,7 +224,7 @@ public class DialogCell extends BaseCell { String countString = null; CharSequence messageString = ""; CharSequence printingString = null; - if (allowPrintStrings) { + if (isDialogCell) { printingString = MessagesController.getInstance().printingStrings.get(currentDialogId); } TextPaint currentNamePaint = namePaint; @@ -226,10 +239,10 @@ public class DialogCell extends BaseCell { drawNameLock = true; nameLockTop = AndroidUtilities.dp(16.5f); if (!LocaleController.isRTL) { - nameLockLeft = AndroidUtilities.dp(72); - nameLeft = AndroidUtilities.dp(76) + lockDrawable.getIntrinsicWidth(); + nameLockLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline); + nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline + 4) + lockDrawable.getIntrinsicWidth(); } else { - nameLockLeft = getMeasuredWidth() - AndroidUtilities.dp(72) - lockDrawable.getIntrinsicWidth(); + nameLockLeft = getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline) - lockDrawable.getIntrinsicWidth(); nameLeft = AndroidUtilities.dp(14); } } else { @@ -243,15 +256,15 @@ public class DialogCell extends BaseCell { } if (!LocaleController.isRTL) { - nameLockLeft = AndroidUtilities.dp(72); - nameLeft = AndroidUtilities.dp(76) + (drawNameGroup ? groupDrawable.getIntrinsicWidth() : broadcastDrawable.getIntrinsicWidth()); + nameLockLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline); + nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline + 4) + (drawNameGroup ? groupDrawable.getIntrinsicWidth() : broadcastDrawable.getIntrinsicWidth()); } else { - nameLockLeft = getMeasuredWidth() - AndroidUtilities.dp(72) - (drawNameGroup ? groupDrawable.getIntrinsicWidth() : broadcastDrawable.getIntrinsicWidth()); + nameLockLeft = getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline) - (drawNameGroup ? groupDrawable.getIntrinsicWidth() : broadcastDrawable.getIntrinsicWidth()); nameLeft = AndroidUtilities.dp(14); } } else { if (!LocaleController.isRTL) { - nameLeft = AndroidUtilities.dp(72); + nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline); } else { nameLeft = AndroidUtilities.dp(14); } @@ -316,7 +329,7 @@ public class DialogCell extends BaseCell { } else { if (chat != null && chat.id > 0) { String name = ""; - if (message.isFromMe()) { + if (message.isOut()) { name = LocaleController.getString("FromYou", R.string.FromYou); } else { if (fromUser != null) { @@ -328,9 +341,9 @@ public class DialogCell extends BaseCell { } } checkMessage = false; - if (message.messageOwner.media != null && !(message.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) { + if (message.messageOwner.media != null && !message.isMediaEmpty()) { currentMessagePaint = messagePrintingPaint; - messageString = Emoji.replaceEmoji(Html.fromHtml(String.format("%s: %s", name, message.messageText)), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20)); + messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("%s: %s", name, message.messageText)), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20)); } else { if (message.messageOwner.message != null) { String mess = message.messageOwner.message; @@ -338,12 +351,12 @@ public class DialogCell extends BaseCell { mess = mess.substring(0, 150); } mess = mess.replace("\n", " "); - messageString = Emoji.replaceEmoji(Html.fromHtml(String.format("%s: %s", name, mess.replace("<", "<").replace(">", ">"))), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20)); + messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("%s: %s", name, mess.replace("<", "<").replace(">", ">"))), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20)); } } } else { messageString = message.messageText; - if (message.messageOwner.media != null && !(message.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) { + if (message.messageOwner.media != null && !message.isMediaEmpty()) { currentMessagePaint = messagePrintingPaint; } } @@ -357,7 +370,7 @@ public class DialogCell extends BaseCell { drawCount = false; } - if (message.isFromMe() && message.isOut()) { + if (message.isOut()) { if (message.isSending()) { drawCheck1 = false; drawCheck2 = false; @@ -426,7 +439,7 @@ public class DialogCell extends BaseCell { if (!LocaleController.isRTL) { nameWidth = getMeasuredWidth() - nameLeft - AndroidUtilities.dp(14) - timeWidth; } else { - nameWidth = getMeasuredWidth() - nameLeft - AndroidUtilities.dp(72) - timeWidth; + nameWidth = getMeasuredWidth() - nameLeft - AndroidUtilities.dp(AndroidUtilities.leftBaseline) - timeWidth; nameLeft += timeWidth; } if (drawNameLock) { @@ -484,14 +497,14 @@ public class DialogCell extends BaseCell { FileLog.e("tmessages", e); } - int messageWidth = getMeasuredWidth() - AndroidUtilities.dp(88); + int messageWidth = getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline + 16); int avatarLeft; if (!LocaleController.isRTL) { - messageLeft = AndroidUtilities.dp(72); - avatarLeft = AndroidUtilities.dp(9); + messageLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline); + avatarLeft = AndroidUtilities.dp(AndroidUtilities.isTablet() ? 13 : 9); } else { messageLeft = AndroidUtilities.dp(16); - avatarLeft = getMeasuredWidth() - AndroidUtilities.dp(61); + avatarLeft = getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.isTablet() ? 65 : 61); } avatarImage.setImageCoords(avatarLeft, avatarTop, AndroidUtilities.dp(52), AndroidUtilities.dp(52)); if (drawError) { @@ -543,15 +556,15 @@ public class DialogCell extends BaseCell { if (LocaleController.isRTL) { if (nameLayout != null && nameLayout.getLineCount() > 0) { left = nameLayout.getLineLeft(0); + widthpx = Math.ceil(nameLayout.getLineWidth(0)); + if (dialogMuted) { + nameMuteLeft = (int) (nameLeft + (nameWidth - widthpx) - AndroidUtilities.dp(6) - muteDrawable.getIntrinsicWidth()); + } if (left == 0) { - widthpx = Math.ceil(nameLayout.getLineWidth(0)); if (widthpx < nameWidth) { nameLeft += (nameWidth - widthpx); } } - if (dialogMuted) { - nameMuteLeft = (nameLeft - AndroidUtilities.dp(6) - muteDrawable.getIntrinsicWidth()); - } } if (messageLayout != null && messageLayout.getLineCount() > 0) { left = messageLayout.getLineLeft(0); @@ -587,10 +600,42 @@ public class DialogCell extends BaseCell { } } + public void checkCurrentDialogIndex() { + TLRPC.TL_dialog dialog = null; + if (isServerOnly) { + if (index < MessagesController.getInstance().dialogsServerOnly.size()) { + dialog = MessagesController.getInstance().dialogsServerOnly.get(index); + } + } else { + if (index < MessagesController.getInstance().dialogs.size()) { + dialog = MessagesController.getInstance().dialogs.get(index); + } + } + if (dialog != null) { + if (currentDialogId != dialog.id || message != null && message.getId() != dialog.top_message || unreadCount != dialog.unread_count) { + currentDialogId = dialog.id; + update(0); + } + } + } + public void update(int mask) { + if (isDialogCell) { + TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(currentDialogId); + if (dialog != null && mask == 0) { + message = MessagesController.getInstance().dialogMessage.get(dialog.top_message); + lastUnreadState = message != null && message.isUnread(); + unreadCount = dialog.unread_count; + lastMessageDate = dialog.last_message_date; + if (message != null) { + lastSendState = message.messageOwner.send_state; + } + } + } + if (mask != 0) { boolean continueUpdate = false; - if (allowPrintStrings && (mask & MessagesController.UPDATE_MASK_USER_PRINT) != 0) { + if (isDialogCell && (mask & MessagesController.UPDATE_MASK_USER_PRINT) != 0) { CharSequence printString = MessagesController.getInstance().printingStrings.get(currentDialogId); if (lastPrintString != null && printString == null || lastPrintString == null && printString != null || lastPrintString != null && printString != null && !lastPrintString.equals(printString)) { continueUpdate = true; @@ -618,8 +663,9 @@ public class DialogCell extends BaseCell { } if (!continueUpdate && (mask & MessagesController.UPDATE_MASK_READ_DIALOG_MESSAGE) != 0) { if (message != null && lastUnreadState != message.isUnread()) { + lastUnreadState = message.isUnread(); continueUpdate = true; - } else if (allowPrintStrings) { + } else if (isDialogCell) { TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(currentDialogId); if (dialog != null && unreadCount != dialog.unread_count) { unreadCount = dialog.unread_count; @@ -627,11 +673,19 @@ public class DialogCell extends BaseCell { } } } + if (!continueUpdate && (mask & MessagesController.UPDATE_MASK_SEND_STATE) != 0) { + if (message != null && lastSendState != message.messageOwner.send_state) { + lastSendState = message.messageOwner.send_state; + continueUpdate = true; + } + } if (!continueUpdate) { return; } } + + dialogMuted = isDialogCell && MessagesController.getInstance().isDialogMuted(currentDialogId); user = null; chat = null; encryptedChat = null; @@ -748,9 +802,9 @@ public class DialogCell extends BaseCell { if (useSeparator) { if (LocaleController.isRTL) { - canvas.drawLine(0, getMeasuredHeight() - 1, getMeasuredWidth() - AndroidUtilities.dp(72), getMeasuredHeight() - 1, linePaint); + canvas.drawLine(0, getMeasuredHeight() - 1, getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline), getMeasuredHeight() - 1, linePaint); } else { - canvas.drawLine(AndroidUtilities.dp(72), getMeasuredHeight() - 1, getMeasuredWidth(), getMeasuredHeight() - 1, linePaint); + canvas.drawLine(AndroidUtilities.dp(AndroidUtilities.leftBaseline), getMeasuredHeight() - 1, getMeasuredWidth(), getMeasuredHeight() - 1, linePaint); } } 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 f1dfbb2e5..706323fd6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DrawerProfileCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DrawerProfileCell.java @@ -9,15 +9,25 @@ package org.telegram.ui.Cells; import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; import android.os.Build; import android.util.TypedValue; import android.view.Gravity; import android.widget.FrameLayout; +import android.widget.ImageView; import android.widget.TextView; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.AndroidUtilities; import org.telegram.android.ContactsController; +import org.telegram.messenger.ApplicationLoader; +import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.ui.Components.AvatarDrawable; import org.telegram.ui.Components.BackupImageView; @@ -27,15 +37,30 @@ public class DrawerProfileCell extends FrameLayout { private BackupImageView avatarImageView; private TextView nameTextView; private TextView phoneTextView; + private ImageView shadowView; + private Rect srcRect = new Rect(); + private Rect destRect = new Rect(); + private Paint paint = new Paint(); public DrawerProfileCell(Context context) { super(context); setBackgroundColor(0xff4c84b5); + shadowView = new ImageView(context); + shadowView.setVisibility(INVISIBLE); + shadowView.setScaleType(ImageView.ScaleType.FIT_XY); + shadowView.setImageResource(R.drawable.bottom_shadow); + addView(shadowView); + LayoutParams layoutParams = (FrameLayout.LayoutParams) shadowView.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = AndroidUtilities.dp(70); + layoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM; + shadowView.setLayoutParams(layoutParams); + avatarImageView = new BackupImageView(context); - avatarImageView.imageReceiver.setRoundRadius(AndroidUtilities.dp(32)); + avatarImageView.getImageReceiver().setRoundRadius(AndroidUtilities.dp(32)); addView(avatarImageView); - LayoutParams layoutParams = (LayoutParams) avatarImageView.getLayoutParams(); + layoutParams = (LayoutParams) avatarImageView.getLayoutParams(); layoutParams.width = AndroidUtilities.dp(64); layoutParams.height = AndroidUtilities.dp(64); layoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM; @@ -88,6 +113,35 @@ public class DrawerProfileCell extends FrameLayout { } } + @Override + protected void onDraw(Canvas canvas) { + Drawable backgroundDrawable = ApplicationLoader.getCachedWallpaper(); + if (ApplicationLoader.isCustomTheme() && backgroundDrawable != null) { + phoneTextView.setTextColor(0xffffffff); + shadowView.setVisibility(VISIBLE); + if (backgroundDrawable instanceof ColorDrawable) { + backgroundDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight()); + backgroundDrawable.draw(canvas); + } else if (backgroundDrawable instanceof BitmapDrawable) { + Bitmap bitmap = ((BitmapDrawable) backgroundDrawable).getBitmap(); + float scaleX = (float) getMeasuredWidth() / (float) bitmap.getWidth(); + float scaleY = (float) getMeasuredHeight() / (float) bitmap.getHeight(); + float scale = scaleX < scaleY ? scaleY : scaleX; + int width = (int) (getMeasuredWidth() / scale); + int height = (int) (getMeasuredHeight() / scale); + int x = (bitmap.getWidth() - width) / 2; + int y = (bitmap.getHeight() - height) / 2; + srcRect.set(x, y, x + width, y + height); + destRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight()); + canvas.drawBitmap(bitmap, srcRect, destRect, paint); + } + } else { + shadowView.setVisibility(INVISIBLE); + phoneTextView.setTextColor(0xffc2e5ff); + super.onDraw(canvas); + } + } + public void setUser(TLRPC.User user) { if (user == null) { return; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/GreySectionCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/GreySectionCell.java index b13f3de75..633e02c8e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/GreySectionCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/GreySectionCell.java @@ -9,7 +9,6 @@ package org.telegram.ui.Cells; import android.content.Context; -import android.util.AttributeSet; import android.util.TypedValue; import android.view.Gravity; import android.widget.FrameLayout; @@ -21,7 +20,9 @@ import org.telegram.android.LocaleController; public class GreySectionCell extends FrameLayout { private TextView textView; - private void init() { + public GreySectionCell(Context context) { + super(context); + setBackgroundColor(0xfff2f2f2); textView = new TextView(getContext()); @@ -39,26 +40,6 @@ public class GreySectionCell extends FrameLayout { textView.setLayoutParams(layoutParams); } - public GreySectionCell(Context context) { - super(context); - init(); - } - - public GreySectionCell(Context context, AttributeSet attrs) { - super(context, attrs); - init(); - } - - public GreySectionCell(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - init(); - } - - public GreySectionCell(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - init(); - } - @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(36), MeasureSpec.EXACTLY)); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/HashtagSearchCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/HashtagSearchCell.java new file mode 100644 index 000000000..ccb8dbcef --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/HashtagSearchCell.java @@ -0,0 +1,53 @@ +/* + * This is the source code of Telegram for Android v. 2.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-2015. + */ + +package org.telegram.ui.Cells; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.util.TypedValue; +import android.view.Gravity; +import android.widget.TextView; + +import org.telegram.android.AndroidUtilities; + +public class HashtagSearchCell extends TextView { + + private boolean needDivider; + private static Paint paint; + + public HashtagSearchCell(Context context) { + super(context); + setGravity(Gravity.CENTER_VERTICAL); + setPadding(AndroidUtilities.dp(16), 0, AndroidUtilities.dp(16), 0); + setTextSize(TypedValue.COMPLEX_UNIT_DIP, 17); + setTextColor(0xff000000); + if (paint == null) { + paint = new Paint(); + paint.setColor(0xffdcdcdc); + } + } + + public void setNeedDivider(boolean value) { + needDivider = value; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), AndroidUtilities.dp(48) + 1); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + if (needDivider) { + canvas.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1, paint); + } + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/MentionCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/MentionCell.java new file mode 100644 index 000000000..67111a811 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/MentionCell.java @@ -0,0 +1,107 @@ +/* + * This is the source code of Telegram for Android v. 2.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-2015. + */ + +package org.telegram.ui.Cells; + +import android.content.Context; +import android.text.TextUtils; +import android.util.TypedValue; +import android.view.Gravity; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.telegram.android.AndroidUtilities; +import org.telegram.android.ContactsController; +import org.telegram.messenger.TLRPC; +import org.telegram.ui.Components.AvatarDrawable; +import org.telegram.ui.Components.BackupImageView; + +public class MentionCell extends LinearLayout { + + private BackupImageView imageView; + private TextView nameTextView; + private TextView usernameTextView; + private AvatarDrawable avatarDrawable; + + public MentionCell(Context context) { + super(context); + + setOrientation(HORIZONTAL); + + avatarDrawable = new AvatarDrawable(); + avatarDrawable.setSmallStyle(true); + + imageView = new BackupImageView(context); + imageView.setRoundRadius(AndroidUtilities.dp(14)); + addView(imageView); + LayoutParams layoutParams = (LayoutParams) imageView.getLayoutParams(); + layoutParams.leftMargin = AndroidUtilities.dp(12); + layoutParams.topMargin = AndroidUtilities.dp(4); + layoutParams.width = AndroidUtilities.dp(28); + layoutParams.height = AndroidUtilities.dp(28); + imageView.setLayoutParams(layoutParams); + + nameTextView = new TextView(context); + nameTextView.setTextColor(0xff000000); + nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); + nameTextView.setSingleLine(true); + nameTextView.setGravity(Gravity.LEFT); + nameTextView.setEllipsize(TextUtils.TruncateAt.END); + addView(nameTextView); + layoutParams = (LayoutParams) nameTextView.getLayoutParams(); + layoutParams.leftMargin = AndroidUtilities.dp(12); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.CENTER_VERTICAL; + nameTextView.setLayoutParams(layoutParams); + + usernameTextView = new TextView(context); + usernameTextView.setTextColor(0xff999999); + usernameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); + usernameTextView.setSingleLine(true); + usernameTextView.setGravity(Gravity.LEFT); + usernameTextView.setEllipsize(TextUtils.TruncateAt.END); + addView(usernameTextView); + layoutParams = (LayoutParams) usernameTextView.getLayoutParams(); + layoutParams.leftMargin = AndroidUtilities.dp(12); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.CENTER_VERTICAL; + usernameTextView.setLayoutParams(layoutParams); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(36), MeasureSpec.EXACTLY)); + } + + public void setUser(TLRPC.User user) { + if (user == null) { + nameTextView.setText(""); + usernameTextView.setText(""); + imageView.setImageDrawable(null); + return; + } + avatarDrawable.setInfo(user); + if (user.photo != null && user.photo.photo_small != null) { + imageView.setImage(user.photo.photo_small, "50_50", avatarDrawable); + } else { + imageView.setImageDrawable(avatarDrawable); + } + nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name)); + usernameTextView.setText("@" + user.username); + imageView.setVisibility(VISIBLE); + usernameTextView.setVisibility(VISIBLE); + } + + public void setText(String text) { + imageView.setVisibility(INVISIBLE); + usernameTextView.setVisibility(INVISIBLE); + nameTextView.setText(text); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoEditToolCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoEditToolCell.java index b6be0e98c..25d67fe46 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoEditToolCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoEditToolCell.java @@ -9,6 +9,7 @@ package org.telegram.ui.Cells; import android.content.Context; +import android.text.TextUtils; import android.util.TypedValue; import android.view.Gravity; import android.widget.ImageView; @@ -32,28 +33,60 @@ public class PhotoEditToolCell extends FrameLayoutFixed { LayoutParams layoutParams = (LayoutParams) iconImage.getLayoutParams(); layoutParams.width = LayoutParams.MATCH_PARENT; layoutParams.height = LayoutParams.MATCH_PARENT; - layoutParams.bottomMargin = AndroidUtilities.dp(20); + layoutParams.bottomMargin = AndroidUtilities.dp(12); iconImage.setLayoutParams(layoutParams); nameTextView = new TextView(context); nameTextView.setGravity(Gravity.CENTER); nameTextView.setTextColor(0xffffffff); - nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12); + nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 10); + nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + nameTextView.setMaxLines(1); + nameTextView.setSingleLine(true); + nameTextView.setEllipsize(TextUtils.TruncateAt.END); addView(nameTextView); layoutParams = (LayoutParams) nameTextView.getLayoutParams(); layoutParams.width = LayoutParams.MATCH_PARENT; - layoutParams.height = AndroidUtilities.dp(20); + layoutParams.height = LayoutParams.WRAP_CONTENT; layoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM; + layoutParams.leftMargin = AndroidUtilities.dp(4); + layoutParams.rightMargin = AndroidUtilities.dp(4); nameTextView.setLayoutParams(layoutParams); + + valueTextView = new TextView(context); + valueTextView.setTextColor(0xff6cc3ff); + valueTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 11); + valueTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + addView(valueTextView); + layoutParams = (LayoutParams) valueTextView.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.LEFT | Gravity.TOP; + layoutParams.leftMargin = AndroidUtilities.dp(57); + layoutParams.topMargin = AndroidUtilities.dp(3); + valueTextView.setLayoutParams(layoutParams); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(80), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(60), MeasureSpec.EXACTLY)); + super.onMeasure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(86), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(60), MeasureSpec.EXACTLY)); } - public void setIconAndText(int resId, String text) { + public void setIconAndTextAndValue(int resId, String text, float value) { iconImage.setImageResource(resId); - nameTextView.setText(text); + nameTextView.setText(text.toUpperCase()); + if (value == 0) { + valueTextView.setText(""); + } else if (value > 0) { + valueTextView.setText("+" + (int) value); + } else { + valueTextView.setText("" + (int) value); + } + } + + public void setIconAndTextAndValue(int resId, String text, String value) { + iconImage.setImageResource(resId); + nameTextView.setText(text.toUpperCase()); + valueTextView.setText(value); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoPickerAlbumsCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoPickerAlbumsCell.java index 15a240371..16540b5da 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoPickerAlbumsCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoPickerAlbumsCell.java @@ -15,7 +15,6 @@ import android.util.TypedValue; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; -import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.TextView; @@ -23,11 +22,12 @@ import org.telegram.android.AndroidUtilities; import org.telegram.android.MediaController; import org.telegram.messenger.R; import org.telegram.ui.Components.BackupImageView; +import org.telegram.ui.Components.FrameLayoutFixed; -public class PhotoPickerAlbumsCell extends FrameLayout { +public class PhotoPickerAlbumsCell extends FrameLayoutFixed { - public static interface PhotoPickerAlbumsCellDelegate { - public abstract void didSelectAlbum(MediaController.AlbumEntry albumEntry); + public interface PhotoPickerAlbumsCellDelegate { + void didSelectAlbum(MediaController.AlbumEntry albumEntry); } private AlbumView[] albumViews; @@ -35,7 +35,7 @@ public class PhotoPickerAlbumsCell extends FrameLayout { private int albumsCount; private PhotoPickerAlbumsCellDelegate delegate; - private class AlbumView extends FrameLayout { + private class AlbumView extends FrameLayoutFixed { private BackupImageView imageView; private TextView nameTextView; @@ -117,7 +117,7 @@ public class PhotoPickerAlbumsCell extends FrameLayout { for (int a = 0; a < 4; a++) { albumViews[a] = new AlbumView(context); addView(albumViews[a]); - albumViews[a].setVisibility(GONE); + albumViews[a].setVisibility(INVISIBLE); albumViews[a].setTag(a); albumViews[a].setOnClickListener(new OnClickListener() { @Override @@ -132,7 +132,7 @@ public class PhotoPickerAlbumsCell extends FrameLayout { public void setAlbumsCount(int count) { for (int a = 0; a < albumViews.length; a++) { - albumViews[a].setVisibility(a < count ? VISIBLE : GONE); + albumViews[a].setVisibility(a < count ? VISIBLE : INVISIBLE); } albumsCount = count; } @@ -146,7 +146,9 @@ public class PhotoPickerAlbumsCell extends FrameLayout { if (albumEntry != null) { AlbumView albumView = albumViews[a]; + albumView.imageView.setOrientation(0, true); if (albumEntry.coverPhoto != null && albumEntry.coverPhoto.path != null) { + albumView.imageView.setOrientation(albumEntry.coverPhoto.orientation, true); albumView.imageView.setImage("thumb://" + albumEntry.coverPhoto.imageId + ":" + albumEntry.coverPhoto.path, null, getContext().getResources().getDrawable(R.drawable.nophotos)); } else { albumView.imageView.setImageResource(R.drawable.nophotos); @@ -154,7 +156,7 @@ public class PhotoPickerAlbumsCell extends FrameLayout { albumView.nameTextView.setText(albumEntry.bucketName); albumView.countTextView.setText(String.format("%d", albumEntry.photos.size())); } else { - albumViews[a].setVisibility(GONE); + albumViews[a].setVisibility(INVISIBLE); } } @@ -167,16 +169,16 @@ public class PhotoPickerAlbumsCell extends FrameLayout { itemWidth = (AndroidUtilities.displaySize.x - ((albumsCount + 1) * AndroidUtilities.dp(4))) / albumsCount; } - setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(4) + itemWidth, MeasureSpec.EXACTLY)); - for (int a = 0; a < albumsCount; a++) { LayoutParams layoutParams = (LayoutParams) albumViews[a].getLayoutParams(); layoutParams.topMargin = AndroidUtilities.dp(4); layoutParams.leftMargin = (itemWidth + AndroidUtilities.dp(4)) * a; layoutParams.width = itemWidth; layoutParams.height = itemWidth; + layoutParams.gravity = Gravity.LEFT | Gravity.TOP; albumViews[a].setLayoutParams(layoutParams); - albumViews[a].measure(MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY)); } + + super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(4) + itemWidth, MeasureSpec.EXACTLY)); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoPickerPhotoCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoPickerPhotoCell.java index 4879a0c09..f00434920 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoPickerPhotoCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoPickerPhotoCell.java @@ -11,7 +11,6 @@ package org.telegram.ui.Cells; import android.content.Context; import android.view.Gravity; import android.widget.FrameLayout; -import android.widget.ImageView; import org.telegram.android.AndroidUtilities; import org.telegram.messenger.R; @@ -23,7 +22,6 @@ public class PhotoPickerPhotoCell extends FrameLayout { public BackupImageView photoImage; public FrameLayout checkFrame; public CheckBox checkBox; - public ImageView editedImage; public int itemWidth; public PhotoPickerPhotoCell(Context context) { @@ -57,16 +55,6 @@ public class PhotoPickerPhotoCell extends FrameLayout { layoutParams.topMargin = AndroidUtilities.dp(6); layoutParams.rightMargin = AndroidUtilities.dp(6); checkBox.setLayoutParams(layoutParams); - - editedImage = new ImageView(context); - editedImage.setImageResource(R.drawable.photo_edit); - editedImage.setScaleType(ImageView.ScaleType.CENTER); - addView(editedImage); - layoutParams = (LayoutParams) editedImage.getLayoutParams(); - layoutParams.width = AndroidUtilities.dp(42); - layoutParams.height = AndroidUtilities.dp(42); - layoutParams.gravity = Gravity.LEFT | Gravity.TOP; - editedImage.setLayoutParams(layoutParams); } @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoPickerSearchCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoPickerSearchCell.java index ecd88357d..e24419ed1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoPickerSearchCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoPickerSearchCell.java @@ -10,6 +10,7 @@ package org.telegram.ui.Cells; import android.content.Context; import android.os.Build; +import android.text.TextUtils; import android.util.TypedValue; import android.view.Gravity; import android.view.MotionEvent; @@ -25,8 +26,8 @@ import org.telegram.messenger.R; public class PhotoPickerSearchCell extends LinearLayout { - public static interface PhotoPickerSearchCellDelegate { - public abstract void didPressedSearchButton(int index); + public interface PhotoPickerSearchCellDelegate { + void didPressedSearchButton(int index); } private class SearchButton extends FrameLayout { @@ -39,62 +40,57 @@ public class PhotoPickerSearchCell extends LinearLayout { public SearchButton(Context context) { super(context); - setBackgroundColor(0xff292929); + setBackgroundColor(0xff1a1a1a); selector = new View(context); selector.setBackgroundResource(R.drawable.list_selector); addView(selector); FrameLayout.LayoutParams layoutParams1 = (FrameLayout.LayoutParams) selector.getLayoutParams(); - layoutParams1.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams1.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams1.width = LayoutParams.MATCH_PARENT; + layoutParams1.height = LayoutParams.MATCH_PARENT; selector.setLayoutParams(layoutParams1); - LinearLayout linearLayout = new LinearLayout(context); - linearLayout.setOrientation(HORIZONTAL); - addView(linearLayout); - layoutParams1 = (FrameLayout.LayoutParams) linearLayout.getLayoutParams(); - layoutParams1.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams1.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams1.gravity = Gravity.CENTER; - linearLayout.setLayoutParams(layoutParams1); - imageView = new ImageView(context); - linearLayout.addView(imageView); - LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) imageView.getLayoutParams(); - layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; - layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT; + imageView.setScaleType(ImageView.ScaleType.CENTER); + addView(imageView); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) imageView.getLayoutParams(); + layoutParams.height = AndroidUtilities.dp(48); + layoutParams.width = AndroidUtilities.dp(48); + layoutParams1.gravity = Gravity.LEFT | Gravity.TOP; imageView.setLayoutParams(layoutParams); - FrameLayout frameLayout = new FrameLayout(context); - frameLayout.setPadding(AndroidUtilities.dp(4), 0, 0, 0); - linearLayout.addView(frameLayout); - layoutParams = (LinearLayout.LayoutParams) frameLayout.getLayoutParams(); - layoutParams.height = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT; - frameLayout.setLayoutParams(layoutParams); - textView1 = new TextView(context); textView1.setGravity(Gravity.CENTER_VERTICAL); - textView1.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13); - textView1.setPadding(0, 0, AndroidUtilities.dp(8), 0); + textView1.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); textView1.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); textView1.setTextColor(0xffffffff); - frameLayout.addView(textView1); + textView1.setSingleLine(true); + textView1.setEllipsize(TextUtils.TruncateAt.END); + addView(textView1); layoutParams1 = (FrameLayout.LayoutParams) textView1.getLayoutParams(); - layoutParams1.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams1.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams1.width = LayoutParams.MATCH_PARENT; + layoutParams1.height = LayoutParams.WRAP_CONTENT; + layoutParams1.gravity = Gravity.TOP | Gravity.LEFT; + layoutParams1.rightMargin = AndroidUtilities.dp(4); + layoutParams1.leftMargin = AndroidUtilities.dp(51); + layoutParams1.topMargin = AndroidUtilities.dp(8); textView1.setLayoutParams(layoutParams1); textView2 = new TextView(context); textView2.setGravity(Gravity.CENTER_VERTICAL); - textView2.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 9); - textView2.setPadding(0, AndroidUtilities.dp(24), AndroidUtilities.dp(8), 0); + textView2.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 10); textView2.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); - textView2.setTextColor(0xff464646); - frameLayout.addView(textView2); + textView2.setTextColor(0xff666666); + textView2.setSingleLine(true); + textView2.setEllipsize(TextUtils.TruncateAt.END); + addView(textView2); layoutParams1 = (FrameLayout.LayoutParams) textView2.getLayoutParams(); - layoutParams1.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams1.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams1.width = LayoutParams.MATCH_PARENT; + layoutParams1.height = LayoutParams.WRAP_CONTENT; + layoutParams1.gravity = Gravity.TOP | Gravity.LEFT; + layoutParams1.leftMargin = AndroidUtilities.dp(51); + layoutParams1.rightMargin = AndroidUtilities.dp(4); + layoutParams1.topMargin = AndroidUtilities.dp(26); textView2.setLayoutParams(layoutParams1); } @@ -115,7 +111,8 @@ public class PhotoPickerSearchCell extends LinearLayout { SearchButton searchButton = new SearchButton(context); searchButton.textView1.setText(LocaleController.getString("SearchImages", R.string.SearchImages)); - searchButton.imageView.setImageResource(R.drawable.web_search); + searchButton.textView2.setText(LocaleController.getString("SearchImagesInfo", R.string.SearchImagesInfo)); + searchButton.imageView.setImageResource(R.drawable.search_web); addView(searchButton); LayoutParams layoutParams = (LayoutParams) searchButton.getLayoutParams(); layoutParams.weight = 0.5f; @@ -144,7 +141,7 @@ public class PhotoPickerSearchCell extends LinearLayout { searchButton = new SearchButton(context); searchButton.textView1.setText(LocaleController.getString("SearchGifs", R.string.SearchGifs)); searchButton.textView2.setText("GIPHY"); - searchButton.imageView.setImageResource(R.drawable.gif_search); + searchButton.imageView.setImageResource(R.drawable.search_gif); addView(searchButton); layoutParams = (LayoutParams) searchButton.getLayoutParams(); layoutParams.weight = 0.5f; 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 47b4773b3..b6ce6a2f8 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java @@ -30,6 +30,7 @@ import org.telegram.messenger.UserConfig; import org.telegram.ui.Components.AvatarDrawable; public class ProfileSearchCell extends BaseCell { + private static TextPaint namePaint; private static TextPaint nameEncryptedPaint; private static TextPaint onlinePaint; @@ -149,10 +150,10 @@ public class ProfileSearchCell extends BaseCell { if (encryptedChat != null) { drawNameLock = true; if (!LocaleController.isRTL) { - nameLockLeft = AndroidUtilities.dp(72); - nameLeft = AndroidUtilities.dp(76) + lockDrawable.getIntrinsicWidth(); + nameLockLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline); + nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline + 4) + lockDrawable.getIntrinsicWidth(); } else { - nameLockLeft = getMeasuredWidth() - AndroidUtilities.dp(74) - lockDrawable.getIntrinsicWidth(); + nameLockLeft = getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline + 2) - lockDrawable.getIntrinsicWidth(); nameLeft = AndroidUtilities.dp(11); } nameLockTop = AndroidUtilities.dp(16.5f); @@ -167,15 +168,15 @@ public class ProfileSearchCell extends BaseCell { nameLockTop = AndroidUtilities.dp(30); } if (!LocaleController.isRTL) { - nameLockLeft = AndroidUtilities.dp(72); - nameLeft = AndroidUtilities.dp(76) + (drawNameGroup ? groupDrawable.getIntrinsicWidth() : broadcastDrawable.getIntrinsicWidth()); + nameLockLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline); + nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline + 4) + (drawNameGroup ? groupDrawable.getIntrinsicWidth() : broadcastDrawable.getIntrinsicWidth()); } else { - nameLockLeft = getMeasuredWidth() - AndroidUtilities.dp(74) - (drawNameGroup ? groupDrawable.getIntrinsicWidth() : broadcastDrawable.getIntrinsicWidth()); + nameLockLeft = getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline + 2) - (drawNameGroup ? groupDrawable.getIntrinsicWidth() : broadcastDrawable.getIntrinsicWidth()); nameLeft = AndroidUtilities.dp(11); } } else { if (!LocaleController.isRTL) { - nameLeft = AndroidUtilities.dp(72); + nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline); } else { nameLeft = AndroidUtilities.dp(11); } @@ -211,7 +212,7 @@ public class ProfileSearchCell extends BaseCell { if (!LocaleController.isRTL) { onlineWidth = nameWidth = getMeasuredWidth() - nameLeft - AndroidUtilities.dp(14); } else { - onlineWidth = nameWidth = getMeasuredWidth() - nameLeft - AndroidUtilities.dp(72); + onlineWidth = nameWidth = getMeasuredWidth() - nameLeft - AndroidUtilities.dp(AndroidUtilities.leftBaseline); } if (drawNameLock) { nameWidth -= AndroidUtilities.dp(6) + lockDrawable.getIntrinsicWidth(); @@ -226,7 +227,7 @@ public class ProfileSearchCell extends BaseCell { if (chat == null) { if (!LocaleController.isRTL) { - onlineLeft = AndroidUtilities.dp(72); + onlineLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline); } else { onlineLeft = AndroidUtilities.dp(11); } @@ -254,9 +255,9 @@ public class ProfileSearchCell extends BaseCell { int avatarLeft; if (!LocaleController.isRTL) { - avatarLeft = AndroidUtilities.dp(9); + avatarLeft = AndroidUtilities.dp(AndroidUtilities.isTablet() ? 13 : 9); } else { - avatarLeft = getMeasuredWidth() - AndroidUtilities.dp(61); + avatarLeft = getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.isTablet() ? 65 : 61); } avatarImage.setImageCoords(avatarLeft, AndroidUtilities.dp(10), AndroidUtilities.dp(52), AndroidUtilities.dp(52)); @@ -384,9 +385,9 @@ public class ProfileSearchCell extends BaseCell { if (useSeparator) { if (LocaleController.isRTL) { - canvas.drawLine(0, getMeasuredHeight() - 1, getMeasuredWidth() - AndroidUtilities.dp(72), getMeasuredHeight() - 1, linePaint); + canvas.drawLine(0, getMeasuredHeight() - 1, getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline), getMeasuredHeight() - 1, linePaint); } else { - canvas.drawLine(AndroidUtilities.dp(72), getMeasuredHeight() - 1, getMeasuredWidth(), getMeasuredHeight() - 1, linePaint); + canvas.drawLine(AndroidUtilities.dp(AndroidUtilities.leftBaseline), getMeasuredHeight() - 1, getMeasuredWidth(), getMeasuredHeight() - 1, linePaint); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/SessionCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SessionCell.java new file mode 100644 index 000000000..924a851f7 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SessionCell.java @@ -0,0 +1,205 @@ +/* + * This is the source code of Telegram for Android v. 2.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-2015. + */ + +package org.telegram.ui.Cells; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.text.TextUtils; +import android.util.TypedValue; +import android.view.Gravity; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.telegram.android.AndroidUtilities; +import org.telegram.android.LocaleController; +import org.telegram.messenger.R; +import org.telegram.messenger.TLRPC; + +import java.util.Locale; + +public class SessionCell extends FrameLayout { + + private TextView nameTextView; + private TextView onlineTextView; + private TextView detailTextView; + private TextView detailExTextView; + boolean needDivider; + private static Paint paint; + + public SessionCell(Context context) { + super(context); + + if (paint == null) { + paint = new Paint(); + paint.setColor(0xffd9d9d9); + paint.setStrokeWidth(1); + } + + LinearLayout linearLayout = new LinearLayout(context); + linearLayout.setOrientation(LinearLayout.HORIZONTAL); + linearLayout.setWeightSum(1); + addView(linearLayout); + LayoutParams layoutParams = (LayoutParams) linearLayout.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = AndroidUtilities.dp(30); + layoutParams.leftMargin = AndroidUtilities.dp(17); + layoutParams.rightMargin = AndroidUtilities.dp(17); + layoutParams.topMargin = AndroidUtilities.dp(11); + layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT; + linearLayout.setLayoutParams(layoutParams); + + nameTextView = new TextView(context); + nameTextView.setTextColor(0xff212121); + nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + nameTextView.setLines(1); + nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + nameTextView.setMaxLines(1); + nameTextView.setSingleLine(true); + nameTextView.setEllipsize(TextUtils.TruncateAt.END); + nameTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP); + + onlineTextView = new TextView(context); + onlineTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + onlineTextView.setGravity((LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.TOP); + + if (LocaleController.isRTL) { + linearLayout.addView(onlineTextView); + linearLayout.addView(nameTextView); + } else { + linearLayout.addView(nameTextView); + linearLayout.addView(onlineTextView); + } + + LinearLayout.LayoutParams layoutParams2 = (LinearLayout.LayoutParams) nameTextView.getLayoutParams(); + layoutParams2.width = 0; + layoutParams2.height = LayoutParams.MATCH_PARENT; + layoutParams2.weight = 1; + if (LocaleController.isRTL) { + layoutParams2.leftMargin = AndroidUtilities.dp(10); + } else { + layoutParams2.rightMargin = AndroidUtilities.dp(10); + } + layoutParams2.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT; + nameTextView.setLayoutParams(layoutParams2); + + layoutParams2 = (LinearLayout.LayoutParams) onlineTextView.getLayoutParams(); + layoutParams2.width = LayoutParams.WRAP_CONTENT; + layoutParams2.height = LayoutParams.MATCH_PARENT; + layoutParams2.topMargin = AndroidUtilities.dp(2); + layoutParams2.gravity = (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.TOP; + onlineTextView.setLayoutParams(layoutParams2); + + detailTextView = new TextView(context); + detailTextView.setTextColor(0xff212121); + detailTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + detailTextView.setLines(1); + detailTextView.setMaxLines(1); + detailTextView.setSingleLine(true); + detailTextView.setEllipsize(TextUtils.TruncateAt.END); + detailTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP); + addView(detailTextView); + layoutParams = (LayoutParams) detailTextView.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.leftMargin = AndroidUtilities.dp(17); + layoutParams.rightMargin = AndroidUtilities.dp(17); + layoutParams.topMargin = AndroidUtilities.dp(36); + layoutParams.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP; + detailTextView.setLayoutParams(layoutParams); + + detailExTextView = new TextView(context); + detailExTextView.setTextColor(0xff999999); + detailExTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + detailExTextView.setLines(1); + detailExTextView.setMaxLines(1); + detailExTextView.setSingleLine(true); + detailExTextView.setEllipsize(TextUtils.TruncateAt.END); + detailExTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP); + addView(detailExTextView); + layoutParams = (LayoutParams) detailExTextView.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.leftMargin = AndroidUtilities.dp(17); + layoutParams.rightMargin = AndroidUtilities.dp(17); + layoutParams.topMargin = AndroidUtilities.dp(59); + layoutParams.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP; + detailExTextView.setLayoutParams(layoutParams); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(90) + (needDivider ? 1 : 0), MeasureSpec.EXACTLY)); + } + + public void setSession(TLRPC.TL_authorization session, boolean divider) { + needDivider = divider; + + nameTextView.setText(String.format(Locale.US, "%s %s", session.app_name, session.app_version)); + if ((session.flags & 1) != 0) { + onlineTextView.setText(LocaleController.getString("Online", R.string.Online)); + onlineTextView.setTextColor(0xff2f8cc9); + } else { + onlineTextView.setText(LocaleController.stringForMessageListDate(session.date_active)); + onlineTextView.setTextColor(0xff999999); + } + + StringBuilder stringBuilder = new StringBuilder(); + if (session.ip.length() != 0) { + stringBuilder.append(session.ip); + } + if (session.country.length() != 0) { + if (stringBuilder.length() != 0) { + stringBuilder.append(" "); + } + stringBuilder.append("— "); + stringBuilder.append(session.country); + } + detailExTextView.setText(stringBuilder); + + stringBuilder = new StringBuilder(); + if (session.device_model.length() != 0) { + stringBuilder.append(session.device_model); + } + if (session.system_version.length() != 0 || session.platform.length() != 0) { + if (stringBuilder.length() != 0) { + stringBuilder.append(", "); + } + if (session.platform.length() != 0) { + stringBuilder.append(session.platform); + } + if (session.system_version.length() != 0) { + if (session.platform.length() != 0) { + stringBuilder.append(" "); + } + stringBuilder.append(session.system_version); + } + } + + if ((session.flags & 2) == 0) { + if (stringBuilder.length() != 0) { + stringBuilder.append(", "); + } + stringBuilder.append(LocaleController.getString("UnofficialApp", R.string.UnofficialApp)); + stringBuilder.append(" (ID: "); + stringBuilder.append(session.api_id); + stringBuilder.append(")"); + } + + detailTextView.setText(stringBuilder); + } + + @Override + protected void onDraw(Canvas canvas) { + if (needDivider) { + canvas.drawLine(getPaddingLeft(), getHeight() - 1, getWidth() - getPaddingRight(), getHeight() - 1, paint); + } + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedDocumentCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedDocumentCell.java index 2ddd7307b..a41172b06 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedDocumentCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedDocumentCell.java @@ -36,7 +36,7 @@ import org.telegram.ui.Components.LineProgressView; import java.io.File; import java.util.Date; -public class SharedDocumentCell extends FrameLayout implements MediaController.FileDownloadProgressListener { +public class SharedDocumentCell extends FrameLayout implements MediaController.FileDownloadProgressListener { private ImageView placeholderImabeView; private BackupImageView thumbImageView; @@ -106,11 +106,11 @@ public class SharedDocumentCell extends FrameLayout implements MediaController. extTextView.setLayoutParams(layoutParams); thumbImageView = new BackupImageView(context); - thumbImageView.imageReceiver.setDelegate(new ImageReceiver.ImageReceiverDelegate() { + thumbImageView.getImageReceiver().setDelegate(new ImageReceiver.ImageReceiverDelegate() { @Override public void didSetImage(ImageReceiver imageReceiver, boolean set, boolean thumb) { - extTextView.setVisibility(set ? GONE : VISIBLE); - placeholderImabeView.setVisibility(set ? GONE : VISIBLE); + extTextView.setVisibility(set ? INVISIBLE : VISIBLE); + placeholderImabeView.setVisibility(set ? INVISIBLE : VISIBLE); } }); addView(thumbImageView); @@ -143,7 +143,7 @@ public class SharedDocumentCell extends FrameLayout implements MediaController. nameTextView.setLayoutParams(layoutParams); statusImageView = new ImageView(context); - statusImageView.setVisibility(GONE); + statusImageView.setVisibility(INVISIBLE); addView(statusImageView); layoutParams = (LayoutParams) statusImageView.getLayoutParams(); layoutParams.width = LayoutParams.WRAP_CONTENT; @@ -184,7 +184,7 @@ public class SharedDocumentCell extends FrameLayout implements MediaController. progressView.setLayoutParams(layoutParams); checkBox = new CheckBox(context, R.drawable.round_check2); - checkBox.setVisibility(GONE); + checkBox.setVisibility(INVISIBLE); addView(checkBox); layoutParams = (LayoutParams) checkBox.getLayoutParams(); layoutParams.width = AndroidUtilities.dp(22); @@ -229,13 +229,13 @@ public class SharedDocumentCell extends FrameLayout implements MediaController. extTextView.setVisibility(VISIBLE); extTextView.setText(type); } else { - extTextView.setVisibility(GONE); + extTextView.setVisibility(INVISIBLE); } if (resId == 0) { placeholderImabeView.setImageResource(getThumbForNameOrMime(text, type)); placeholderImabeView.setVisibility(VISIBLE); } else { - placeholderImabeView.setVisibility(GONE); + placeholderImabeView.setVisibility(INVISIBLE); } if (thumb != null || resId != 0) { if (thumb != null) { @@ -245,10 +245,16 @@ public class SharedDocumentCell extends FrameLayout implements MediaController. } thumbImageView.setVisibility(VISIBLE); } else { - thumbImageView.setVisibility(GONE); + thumbImageView.setVisibility(INVISIBLE); } } + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + MediaController.getInstance().removeLoadingFileObserver(this); + } + public void setChecked(boolean checked, boolean animated) { if (checkBox.getVisibility() != VISIBLE) { checkBox.setVisibility(VISIBLE); @@ -262,30 +268,40 @@ public class SharedDocumentCell extends FrameLayout implements MediaController. loaded = false; loading = false; - int idx = -1; - String name = FileLoader.getDocumentFileName(document.messageOwner.media.document); - placeholderImabeView.setVisibility(VISIBLE); - extTextView.setVisibility(VISIBLE); - placeholderImabeView.setImageResource(getThumbForNameOrMime(name, document.messageOwner.media.document.mime_type)); - nameTextView.setText(name); - extTextView.setText((idx = name.lastIndexOf(".")) == -1 ? "" : name.substring(idx + 1).toLowerCase()); - if (document.messageOwner.media.document.thumb instanceof TLRPC.TL_photoSizeEmpty) { - thumbImageView.setVisibility(GONE); - thumbImageView.setImageBitmap(null); + if (document != null && document.messageOwner.media != null) { + int idx = -1; + String name = FileLoader.getDocumentFileName(document.messageOwner.media.document); + placeholderImabeView.setVisibility(VISIBLE); + extTextView.setVisibility(VISIBLE); + placeholderImabeView.setImageResource(getThumbForNameOrMime(name, document.messageOwner.media.document.mime_type)); + nameTextView.setText(name); + extTextView.setText((idx = name.lastIndexOf(".")) == -1 ? "" : name.substring(idx + 1).toLowerCase()); + if (document.messageOwner.media.document.thumb instanceof TLRPC.TL_photoSizeEmpty) { + thumbImageView.setVisibility(INVISIBLE); + thumbImageView.setImageBitmap(null); + } else { + thumbImageView.setVisibility(VISIBLE); + thumbImageView.setImage(document.messageOwner.media.document.thumb.location, "40_40", (Drawable) null); + } + long date = (long) document.messageOwner.date * 1000; + dateTextView.setText(String.format("%s, %s", Utilities.formatFileSize(document.messageOwner.media.document.size), LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, LocaleController.formatterYear.format(new Date(date)), LocaleController.formatterDay.format(new Date(date))))); } else { - thumbImageView.setVisibility(VISIBLE); - thumbImageView.setImage(document.messageOwner.media.document.thumb.location, "40_40", (Drawable) null); + nameTextView.setText(""); + extTextView.setText(""); + dateTextView.setText(""); + placeholderImabeView.setVisibility(VISIBLE); + extTextView.setVisibility(VISIBLE); + thumbImageView.setVisibility(INVISIBLE); + thumbImageView.setImageBitmap(null); } - long date = (long) document.messageOwner.date * 1000; - dateTextView.setText(String.format("%s, %s", Utilities.formatFileSize(document.messageOwner.media.document.size), LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, LocaleController.formatterYear.format(new Date(date)), LocaleController.formatterDay.format(new Date(date))))); + setWillNotDraw(!needDivider); progressView.setProgress(0, false); - updateFileExistIcon(); } public void updateFileExistIcon() { - if (message != null) { + if (message != null && message.messageOwner.media != null) { String fileName = null; File cacheFile = null; if (message.messageOwner.attachPath == null || message.messageOwner.attachPath.length() == 0 || !(new File(message.messageOwner.attachPath).exists())) { @@ -296,7 +312,7 @@ public class SharedDocumentCell extends FrameLayout implements MediaController. } loaded = false; if (fileName == null) { - statusImageView.setVisibility(GONE); + statusImageView.setVisibility(INVISIBLE); dateTextView.setPadding(0, 0, 0, 0); loading = false; loaded = true; @@ -315,15 +331,15 @@ public class SharedDocumentCell extends FrameLayout implements MediaController. } progressView.setProgress(progress, false); } else { - progressView.setVisibility(GONE); + progressView.setVisibility(INVISIBLE); } } } else { loading = false; loaded = true; - progressView.setVisibility(GONE); + progressView.setVisibility(INVISIBLE); progressView.setProgress(0, false); - statusImageView.setVisibility(GONE); + statusImageView.setVisibility(INVISIBLE); dateTextView.setPadding(0, 0, 0, 0); MediaController.getInstance().removeLoadingFileObserver(this); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedMediaSectionCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedMediaSectionCell.java new file mode 100644 index 000000000..4b7d29c58 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedMediaSectionCell.java @@ -0,0 +1,50 @@ +/* + * This is the source code of Telegram for Android v. 2.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-2015. + */ + +package org.telegram.ui.Cells; + +import android.content.Context; +import android.util.TypedValue; +import android.view.Gravity; +import android.widget.FrameLayout; +import android.widget.TextView; + +import org.telegram.android.AndroidUtilities; +import org.telegram.android.LocaleController; + +public class SharedMediaSectionCell extends FrameLayout { + + private TextView textView; + + public SharedMediaSectionCell(Context context) { + super(context); + + textView = new TextView(getContext()); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + textView.setTextColor(0xff222222); + textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL); + addView(textView); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)textView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.leftMargin = AndroidUtilities.dp(13); + layoutParams.rightMargin = AndroidUtilities.dp(13); + layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT; + textView.setLayoutParams(layoutParams); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(40), MeasureSpec.EXACTLY)); + } + + public void setText(String text) { + textView.setText(text); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedPhotoVideoCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedPhotoVideoCell.java new file mode 100644 index 000000000..7b6085d45 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedPhotoVideoCell.java @@ -0,0 +1,254 @@ +/* + * 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.Cells; + +import android.content.Context; +import android.os.Build; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.MotionEvent; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.telegram.android.AndroidUtilities; +import org.telegram.android.MessageObject; +import org.telegram.messenger.ApplicationLoader; +import org.telegram.messenger.FileLoader; +import org.telegram.messenger.R; +import org.telegram.messenger.TLRPC; +import org.telegram.ui.Components.BackupImageView; +import org.telegram.ui.Components.CheckBox; +import org.telegram.ui.Components.FrameLayoutFixed; +import org.telegram.ui.PhotoViewer; + +public class SharedPhotoVideoCell extends FrameLayoutFixed { + + private PhotoVideoView[] photoVideoViews; + private MessageObject[] messageObjects; + private int[] indeces; + private SharedPhotoVideoCellDelegate delegate; + private int itemsCount; + private boolean isFirst; + + public interface SharedPhotoVideoCellDelegate { + void didClickItem(SharedPhotoVideoCell cell, int index, MessageObject messageObject, int a); + boolean didLongClickItem(SharedPhotoVideoCell cell, int index, MessageObject messageObject, int a); + } + + private class PhotoVideoView extends FrameLayoutFixed { + + private BackupImageView imageView; + private TextView videoTextView; + private LinearLayout videoInfoContainer; + private View selector; + private CheckBox checkBox; + + public PhotoVideoView(Context context) { + super(context); + + imageView = new BackupImageView(context); + imageView.getImageReceiver().setNeedsQualityThumb(true); + imageView.getImageReceiver().setShouldGenerateQualityThumb(true); + addView(imageView); + LayoutParams layoutParams = (LayoutParams) imageView.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = LayoutParams.MATCH_PARENT; + imageView.setLayoutParams(layoutParams); + + videoInfoContainer = new LinearLayout(context); + videoInfoContainer.setOrientation(LinearLayout.HORIZONTAL); + videoInfoContainer.setBackgroundResource(R.drawable.phototime); + videoInfoContainer.setPadding(AndroidUtilities.dp(3), 0, AndroidUtilities.dp(3), 0); + videoInfoContainer.setGravity(Gravity.CENTER_VERTICAL); + addView(videoInfoContainer); + layoutParams = (LayoutParams) videoInfoContainer.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = AndroidUtilities.dp(16); + layoutParams.gravity = Gravity.BOTTOM | Gravity.LEFT; + videoInfoContainer.setLayoutParams(layoutParams); + + ImageView imageView1 = new ImageView(context); + imageView1.setImageResource(R.drawable.ic_video); + videoInfoContainer.addView(imageView1); + LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams) imageView1.getLayoutParams(); + layoutParams1.width = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams1.height = LinearLayout.LayoutParams.WRAP_CONTENT; + imageView1.setLayoutParams(layoutParams1); + + videoTextView = new TextView(context); + videoTextView.setTextColor(0xffffffff); + videoTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12); + videoTextView.setGravity(Gravity.CENTER_VERTICAL); + videoInfoContainer.addView(videoTextView); + layoutParams1 = (LinearLayout.LayoutParams) videoTextView.getLayoutParams(); + layoutParams1.width = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams1.height = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams1.leftMargin = AndroidUtilities.dp(4); + layoutParams1.gravity = Gravity.CENTER_VERTICAL; + layoutParams1.bottomMargin = AndroidUtilities.dp(1); + videoTextView.setLayoutParams(layoutParams1); + + selector = new View(context); + selector.setBackgroundResource(R.drawable.list_selector); + addView(selector); + layoutParams = (LayoutParams) selector.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = LayoutParams.MATCH_PARENT; + selector.setLayoutParams(layoutParams); + + checkBox = new CheckBox(context, R.drawable.round_check2); + checkBox.setVisibility(INVISIBLE); + addView(checkBox); + layoutParams = (LayoutParams) checkBox.getLayoutParams(); + layoutParams.width = AndroidUtilities.dp(22); + layoutParams.height = AndroidUtilities.dp(22); + layoutParams.gravity = Gravity.RIGHT | Gravity.TOP; + layoutParams.topMargin = AndroidUtilities.dp(6); + layoutParams.rightMargin = AndroidUtilities.dp(6); + checkBox.setLayoutParams(layoutParams); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (Build.VERSION.SDK_INT >= 21) { + selector.drawableHotspotChanged(event.getX(), event.getY()); + } + return super.onTouchEvent(event); + } + } + + public SharedPhotoVideoCell(Context context) { + super(context); + + messageObjects = new MessageObject[6]; + photoVideoViews = new PhotoVideoView[6]; + indeces = new int[6]; + for (int a = 0; a < 6; a++) { + photoVideoViews[a] = new PhotoVideoView(context); + addView(photoVideoViews[a]); + photoVideoViews[a].setVisibility(INVISIBLE); + photoVideoViews[a].setTag(a); + photoVideoViews[a].setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (delegate != null) { + int a = (Integer) v.getTag(); + delegate.didClickItem(SharedPhotoVideoCell.this, indeces[a], messageObjects[a], a); + } + } + }); + photoVideoViews[a].setOnLongClickListener(new OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + if (delegate != null) { + int a = (Integer) v.getTag(); + return delegate.didLongClickItem(SharedPhotoVideoCell.this, indeces[a], messageObjects[a], a); + } + return false; + } + }); + } + } + + public void setDelegate(SharedPhotoVideoCellDelegate delegate) { + this.delegate = delegate; + } + + public void setItemsCount(int count) { + for (int a = 0; a < photoVideoViews.length; a++) { + photoVideoViews[a].setVisibility(a < count ? VISIBLE : INVISIBLE); + } + itemsCount = count; + } + + public BackupImageView getImageView(int a) { + if (a >= itemsCount) { + return null; + } + return photoVideoViews[a].imageView; + } + + public MessageObject getMessageObject(int a) { + if (a >= itemsCount) { + return null; + } + return messageObjects[a]; + } + + public void setIsFirst(boolean first) { + isFirst = first; + } + + public void setChecked(int a, boolean checked, boolean animated) { + if (photoVideoViews[a].checkBox.getVisibility() != VISIBLE) { + photoVideoViews[a].checkBox.setVisibility(VISIBLE); + } + photoVideoViews[a].checkBox.setChecked(checked, animated); + } + + public void setItem(int a, int index, MessageObject messageObject) { + messageObjects[a] = messageObject; + indeces[a] = index; + + if (messageObject != null) { + photoVideoViews[a].setVisibility(VISIBLE); + + PhotoVideoView photoVideoView = photoVideoViews[a]; + photoVideoView.imageView.getImageReceiver().setParentMessageObject(messageObject); + photoVideoView.imageView.getImageReceiver().setVisible(!PhotoViewer.getInstance().isShowingImage(messageObject), false); + if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVideo && messageObject.messageOwner.media.video != null) { + photoVideoView.videoInfoContainer.setVisibility(VISIBLE); + int duration = messageObject.messageOwner.media.video.duration; + int minutes = duration / 60; + int seconds = duration - minutes * 60; + photoVideoView.videoTextView.setText(String.format("%d:%02d", minutes, seconds)); + if (messageObject.messageOwner.media.video.thumb != null) { + TLRPC.FileLocation location = messageObject.messageOwner.media.video.thumb.location; + photoVideoView.imageView.setImage(null, null, null, ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.photo_placeholder_in), null, location, "b", 0); + } else { + photoVideoView.imageView.setImageResource(R.drawable.photo_placeholder_in); + } + } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && messageObject.messageOwner.media.photo != null && !messageObject.photoThumbs.isEmpty()) { + photoVideoView.videoInfoContainer.setVisibility(INVISIBLE); + TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 80); + photoVideoView.imageView.setImage(null, null, null, ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.photo_placeholder_in), null, photoSize.location, "b", 0); + } else { + photoVideoView.videoInfoContainer.setVisibility(INVISIBLE); + photoVideoView.imageView.setImageResource(R.drawable.photo_placeholder_in); + } + } else { + photoVideoViews[a].setVisibility(INVISIBLE); + messageObjects[a] = null; + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int itemWidth; + if (AndroidUtilities.isTablet()) { + itemWidth = (AndroidUtilities.dp(490) - ((itemsCount + 1) * AndroidUtilities.dp(4))) / itemsCount; + } else { + itemWidth = (AndroidUtilities.displaySize.x - ((itemsCount + 1) * AndroidUtilities.dp(4))) / itemsCount; + } + + for (int a = 0; a < itemsCount; a++) { + LayoutParams layoutParams = (LayoutParams) photoVideoViews[a].getLayoutParams(); + layoutParams.topMargin = isFirst ? 0 : AndroidUtilities.dp(4); + layoutParams.leftMargin = (itemWidth + AndroidUtilities.dp(4)) * a + AndroidUtilities.dp(4); + layoutParams.width = itemWidth; + layoutParams.height = itemWidth; + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + photoVideoViews[a].setLayoutParams(layoutParams); + } + + super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec((isFirst ? 0 : AndroidUtilities.dp(4)) + itemWidth, MeasureSpec.EXACTLY)); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/StickerCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/StickerCell.java index 59b9c4ddf..34e04c69b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/StickerCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/StickerCell.java @@ -26,9 +26,7 @@ public class StickerCell extends FrameLayoutFixed { super(context); imageView = new BackupImageView(context); - imageView.imageReceiver.setAspectFit(true); - imageView.imageReceiver.setDisableRecycle(true); - imageView.processDetach = false; + imageView.setAspectFit(true); addView(imageView); LayoutParams layoutParams = (LayoutParams) imageView.getLayoutParams(); layoutParams.width = AndroidUtilities.dp(66); @@ -45,8 +43,8 @@ public class StickerCell extends FrameLayoutFixed { @Override public void setPressed(boolean pressed) { - if (imageView.imageReceiver.getPressed() != pressed) { - imageView.imageReceiver.setPressed(pressed); + if (imageView.getImageReceiver().getPressed() != pressed) { + imageView.getImageReceiver().setPressed(pressed); imageView.invalidate(); } super.setPressed(pressed); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextCell.java index 0c05b6e53..d86331002 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextCell.java @@ -97,32 +97,32 @@ public class TextCell extends FrameLayout { public void setText(String text) { textView.setText(text); - imageView.setVisibility(GONE); - valueTextView.setVisibility(GONE); - valueImageView.setVisibility(GONE); + imageView.setVisibility(INVISIBLE); + valueTextView.setVisibility(INVISIBLE); + valueImageView.setVisibility(INVISIBLE); } public void setTextAndIcon(String text, int resId) { textView.setText(text); imageView.setImageResource(resId); imageView.setVisibility(VISIBLE); - valueTextView.setVisibility(GONE); - valueImageView.setVisibility(GONE); + valueTextView.setVisibility(INVISIBLE); + valueImageView.setVisibility(INVISIBLE); } public void setTextAndValue(String text, String value) { textView.setText(text); valueTextView.setText(value); valueTextView.setVisibility(VISIBLE); - imageView.setVisibility(GONE); - valueImageView.setVisibility(GONE); + imageView.setVisibility(INVISIBLE); + valueImageView.setVisibility(INVISIBLE); } public void setTextAndValueDrawable(String text, Drawable drawable) { textView.setText(text); valueImageView.setVisibility(VISIBLE); valueImageView.setImageDrawable(drawable); - valueTextView.setVisibility(GONE); - imageView.setVisibility(GONE); + valueTextView.setVisibility(INVISIBLE); + imageView.setVisibility(INVISIBLE); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextDetailCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextDetailCell.java index 86afa6085..513daf871 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextDetailCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextDetailCell.java @@ -82,7 +82,7 @@ public class TextDetailCell extends FrameLayout { public void setTextAndValue(String text, String value) { textView.setText(text); valueTextView.setText(value); - imageView.setVisibility(GONE); + imageView.setVisibility(INVISIBLE); } public void setTextAndValueAndIcon(String text, String value, int resId) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextFieldCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextFieldCell.java deleted file mode 100644 index 3d8cb7cde..000000000 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextFieldCell.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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.Cells; - -import android.content.Context; -import android.graphics.Typeface; -import android.text.InputType; -import android.util.TypedValue; -import android.view.Gravity; -import android.view.KeyEvent; -import android.view.inputmethod.EditorInfo; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.TextView; - -import org.telegram.android.AndroidUtilities; -import org.telegram.android.LocaleController; - -public class TextFieldCell extends LinearLayout { - - private TextView textView; - private EditText editText; - - public TextFieldCell(Context context) { - super(context); - setOrientation(VERTICAL); - - textView = new TextView(context); - textView.setTextColor(0xff505050); - textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12); - addView(textView); - LayoutParams layoutParams = (LayoutParams) textView.getLayoutParams(); - layoutParams.topMargin = AndroidUtilities.dp(17); - layoutParams.height = LayoutParams.WRAP_CONTENT; - layoutParams.leftMargin = AndroidUtilities.dp(17); - layoutParams.rightMargin = AndroidUtilities.dp(17); - layoutParams.width = LayoutParams.MATCH_PARENT; - textView.setLayoutParams(layoutParams); - - editText = new EditText(context); - editText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); - editText.setHintTextColor(0xffbebebe); - editText.setTextColor(0xff212121); - editText.setMaxLines(1); - editText.setLines(1); - editText.setSingleLine(true); - editText.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); - editText.setImeOptions(EditorInfo.IME_ACTION_DONE); - AndroidUtilities.clearCursorDrawable(editText); - addView(editText); - layoutParams = (LayoutParams) editText.getLayoutParams(); - layoutParams.topMargin = AndroidUtilities.dp(10); - layoutParams.bottomMargin = AndroidUtilities.dp(17); - layoutParams.height = AndroidUtilities.dp(30); - layoutParams.leftMargin = AndroidUtilities.dp(17); - layoutParams.rightMargin = AndroidUtilities.dp(17); - layoutParams.width = LayoutParams.MATCH_PARENT; - editText.setLayoutParams(layoutParams); - editText.setOnEditorActionListener(new TextView.OnEditorActionListener() { - @Override - public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { - if (i == EditorInfo.IME_ACTION_DONE) { - textView.clearFocus(); - AndroidUtilities.hideKeyboard(textView); - return true; - } - return false; - } - }); - } - - public void setFieldText(String text) { - editText.setText(text); - } - - public String getFieldText() { - return editText.getText().toString(); - } - - public void setFieldTitleAndHint(String title, String hint, int bottom, boolean password) { - editText.setHint(hint); - LayoutParams layoutParams = (LayoutParams) editText.getLayoutParams(); - layoutParams.bottomMargin = bottom; - editText.setLayoutParams(layoutParams); - if (password) { - editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); - editText.setTypeface(Typeface.DEFAULT); - } else { - editText.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); - } - if (title != null) { - textView.setText(title); - textView.setVisibility(VISIBLE); - } else { - textView.setVisibility(GONE); - } - } -} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextInfoPrivacyCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextInfoPrivacyCell.java index b16c84c70..6c8bcffa6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextInfoPrivacyCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextInfoPrivacyCell.java @@ -25,10 +25,10 @@ public class TextInfoPrivacyCell extends FrameLayout { super(context); textView = new TextView(context); - textView.setTextColor(0xffa3a3a3); - textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13); + textView.setTextColor(0xff808080); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); textView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); - textView.setPadding(0, AndroidUtilities.dp(6), 0, AndroidUtilities.dp(16)); + textView.setPadding(0, AndroidUtilities.dp(10), 0, AndroidUtilities.dp(17)); addView(textView); LayoutParams layoutParams = (LayoutParams) textView.getLayoutParams(); layoutParams.width = LayoutParams.WRAP_CONTENT; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextSettingsCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextSettingsCell.java index e6c0414c2..e3c3ffb58 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextSettingsCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextSettingsCell.java @@ -74,7 +74,7 @@ public class TextSettingsCell extends FrameLayout { valueImageView = new ImageView(context); valueImageView.setScaleType(ImageView.ScaleType.CENTER); - valueImageView.setVisibility(GONE); + valueImageView.setVisibility(INVISIBLE); addView(valueImageView); layoutParams = (LayoutParams) valueImageView.getLayoutParams(); layoutParams.width = LayoutParams.WRAP_CONTENT; @@ -109,20 +109,20 @@ public class TextSettingsCell extends FrameLayout { public void setText(String text, boolean divider) { textView.setText(text); - valueTextView.setVisibility(GONE); - valueImageView.setVisibility(GONE); + valueTextView.setVisibility(INVISIBLE); + valueImageView.setVisibility(INVISIBLE); needDivider = divider; setWillNotDraw(!divider); } public void setTextAndValue(String text, String value, boolean divider) { textView.setText(text); - valueImageView.setVisibility(GONE); + valueImageView.setVisibility(INVISIBLE); if (value != null) { valueTextView.setText(value); valueTextView.setVisibility(VISIBLE); } else { - valueTextView.setVisibility(GONE); + valueTextView.setVisibility(INVISIBLE); } needDivider = divider; setWillNotDraw(!divider); @@ -130,12 +130,12 @@ public class TextSettingsCell extends FrameLayout { public void setTextAndIcon(String text, int resId, boolean divider) { textView.setText(text); - valueTextView.setVisibility(GONE); + valueTextView.setVisibility(INVISIBLE); if (resId != 0) { valueImageView.setVisibility(VISIBLE); valueImageView.setImageResource(resId); } else { - valueImageView.setVisibility(GONE); + valueImageView.setVisibility(INVISIBLE); } needDivider = divider; setWillNotDraw(!divider); 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 c5bda3824..909be3b41 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/UserCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/UserCell.java @@ -54,7 +54,7 @@ public class UserCell extends FrameLayout { super(context); avatarImageView = new BackupImageView(context); - avatarImageView.imageReceiver.setRoundRadius(AndroidUtilities.dp(24)); + avatarImageView.setRoundRadius(AndroidUtilities.dp(24)); addView(avatarImageView); LayoutParams layoutParams = (LayoutParams) avatarImageView.getLayoutParams(); layoutParams.width = AndroidUtilities.dp(48); @@ -113,7 +113,7 @@ public class UserCell extends FrameLayout { imageView.setLayoutParams(layoutParams); checkBox = new CheckBox(context, R.drawable.round_check2); - checkBox.setVisibility(GONE); + checkBox.setVisibility(INVISIBLE); addView(checkBox); layoutParams = (LayoutParams) checkBox.getLayoutParams(); layoutParams.width = AndroidUtilities.dp(22); @@ -228,7 +228,7 @@ public class UserCell extends FrameLayout { } } - imageView.setVisibility(currentDrawable == 0 ? GONE : VISIBLE); + imageView.setVisibility(currentDrawable == 0 ? INVISIBLE : VISIBLE); imageView.setImageResource(currentDrawable); avatarImageView.setImage(photo, "50_50", avatarDrawable); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChangeChatNameActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangeChatNameActivity.java index ddecb6b5a..eb94acb69 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChangeChatNameActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangeChatNameActivity.java @@ -9,6 +9,7 @@ package org.telegram.ui; import android.app.Activity; +import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; import android.text.InputType; @@ -55,85 +56,78 @@ public class ChangeChatNameActivity extends BaseFragment { } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - actionBar.setTitle(LocaleController.getString("EditName", R.string.EditName)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + actionBar.setTitle(LocaleController.getString("EditName", R.string.EditName)); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } else if (id == done_button) { + if (firstNameField.getText().length() != 0) { + saveName(); finishFragment(); - } else if (id == done_button) { - if (firstNameField.getText().length() != 0) { - saveName(); - finishFragment(); - } } } - }); + } + }); - ActionBarMenu menu = actionBar.createMenu(); - doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + ActionBarMenu menu = actionBar.createMenu(); + doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); - TLRPC.Chat currentChat = MessagesController.getInstance().getChat(chat_id); + TLRPC.Chat currentChat = MessagesController.getInstance().getChat(chat_id); - 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() { - @Override - public boolean onTouch(View v, MotionEvent event) { + fragmentView = new LinearLayout(context); + fragmentView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + ((LinearLayout) fragmentView).setOrientation(LinearLayout.VERTICAL); + fragmentView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + firstNameField = new EditText(context); + firstNameField.setText(currentChat.title); + firstNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + firstNameField.setHintTextColor(0xff979797); + firstNameField.setTextColor(0xff212121); + firstNameField.setMaxLines(3); + firstNameField.setPadding(0, 0, 0, 0); + firstNameField.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); + firstNameField.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); + firstNameField.setImeOptions(EditorInfo.IME_ACTION_DONE); + firstNameField.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); + AndroidUtilities.clearCursorDrawable(firstNameField); + firstNameField.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { + if (i == EditorInfo.IME_ACTION_DONE && doneButton != null) { + doneButton.performClick(); return true; } - }); - - firstNameField = new EditText(getParentActivity()); - firstNameField.setText(currentChat.title); - firstNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); - firstNameField.setHintTextColor(0xff979797); - firstNameField.setTextColor(0xff212121); - firstNameField.setMaxLines(3); - firstNameField.setPadding(0, 0, 0, 0); - firstNameField.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); - firstNameField.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); - firstNameField.setImeOptions(EditorInfo.IME_ACTION_DONE); - firstNameField.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); - AndroidUtilities.clearCursorDrawable(firstNameField); - firstNameField.setOnEditorActionListener(new TextView.OnEditorActionListener() { - @Override - public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { - if (i == EditorInfo.IME_ACTION_DONE && doneButton != null) { - doneButton.performClick(); - return true; - } - return false; - } - }); - - ((LinearLayout) fragmentView).addView(firstNameField); - LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams)firstNameField.getLayoutParams(); - layoutParams.topMargin = AndroidUtilities.dp(24); - layoutParams.height = AndroidUtilities.dp(36); - layoutParams.leftMargin = AndroidUtilities.dp(24); - layoutParams.rightMargin = AndroidUtilities.dp(24); - layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; - firstNameField.setLayoutParams(layoutParams); - - if (chat_id > 0) { - firstNameField.setHint(LocaleController.getString("GroupName", R.string.GroupName)); - } else { - firstNameField.setHint(LocaleController.getString("EnterListName", R.string.EnterListName)); + return false; } - firstNameField.setSelection(firstNameField.length()); + }); + + ((LinearLayout) fragmentView).addView(firstNameField); + LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) firstNameField.getLayoutParams(); + layoutParams.topMargin = AndroidUtilities.dp(24); + layoutParams.height = AndroidUtilities.dp(36); + layoutParams.leftMargin = AndroidUtilities.dp(24); + layoutParams.rightMargin = AndroidUtilities.dp(24); + layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; + firstNameField.setLayoutParams(layoutParams); + + if (chat_id > 0) { + firstNameField.setHint(LocaleController.getString("GroupName", R.string.GroupName)); } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); - } + firstNameField.setHint(LocaleController.getString("EnterListName", R.string.EnterListName)); } + firstNameField.setSelection(firstNameField.length()); + return fragmentView; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChangeNameActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangeNameActivity.java index 666525aa4..4c672106e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChangeNameActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangeNameActivity.java @@ -9,6 +9,7 @@ package org.telegram.ui; import android.app.Activity; +import android.content.Context; import android.content.SharedPreferences; import android.text.InputType; import android.util.TypedValue; @@ -48,117 +49,111 @@ public class ChangeNameActivity extends BaseFragment { private final static int done_button = 1; @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - actionBar.setTitle(LocaleController.getString("EditName", R.string.EditName)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + actionBar.setTitle(LocaleController.getString("EditName", R.string.EditName)); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } else if (id == done_button) { + if (firstNameField.getText().length() != 0) { + saveName(); finishFragment(); - } else if (id == done_button) { - if (firstNameField.getText().length() != 0) { - saveName(); - finishFragment(); - } } } - }); - - ActionBarMenu menu = actionBar.createMenu(); - doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); - - TLRPC.User user = MessagesController.getInstance().getUser(UserConfig.getClientUserId()); - if (user == null) { - user = UserConfig.getCurrentUser(); } + }); - 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() { - @Override - public boolean onTouch(View v, MotionEvent event) { + ActionBarMenu menu = actionBar.createMenu(); + doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + + TLRPC.User user = MessagesController.getInstance().getUser(UserConfig.getClientUserId()); + if (user == null) { + user = UserConfig.getCurrentUser(); + } + + fragmentView = new LinearLayout(context); + fragmentView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + ((LinearLayout) fragmentView).setOrientation(LinearLayout.VERTICAL); + fragmentView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + firstNameField = new EditText(context); + firstNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + firstNameField.setHintTextColor(0xff979797); + firstNameField.setTextColor(0xff212121); + firstNameField.setMaxLines(1); + firstNameField.setLines(1); + firstNameField.setSingleLine(true); + firstNameField.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); + firstNameField.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); + firstNameField.setImeOptions(EditorInfo.IME_ACTION_NEXT); + firstNameField.setHint(LocaleController.getString("FirstName", R.string.FirstName)); + AndroidUtilities.clearCursorDrawable(firstNameField); + ((LinearLayout) fragmentView).addView(firstNameField); + LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) firstNameField.getLayoutParams(); + layoutParams.topMargin = AndroidUtilities.dp(24); + layoutParams.height = AndroidUtilities.dp(36); + layoutParams.leftMargin = AndroidUtilities.dp(24); + layoutParams.rightMargin = AndroidUtilities.dp(24); + layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; + firstNameField.setLayoutParams(layoutParams); + firstNameField.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { + if (i == EditorInfo.IME_ACTION_NEXT) { + lastNameField.requestFocus(); + lastNameField.setSelection(lastNameField.length()); return true; } - }); - - firstNameField = new EditText(getParentActivity()); - firstNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); - firstNameField.setHintTextColor(0xff979797); - firstNameField.setTextColor(0xff212121); - firstNameField.setMaxLines(1); - firstNameField.setLines(1); - firstNameField.setSingleLine(true); - firstNameField.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); - firstNameField.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); - firstNameField.setImeOptions(EditorInfo.IME_ACTION_NEXT); - firstNameField.setHint(LocaleController.getString("FirstName", R.string.FirstName)); - AndroidUtilities.clearCursorDrawable(firstNameField); - ((LinearLayout) fragmentView).addView(firstNameField); - LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams)firstNameField.getLayoutParams(); - layoutParams.topMargin = AndroidUtilities.dp(24); - layoutParams.height = AndroidUtilities.dp(36); - layoutParams.leftMargin = AndroidUtilities.dp(24); - layoutParams.rightMargin = AndroidUtilities.dp(24); - layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; - firstNameField.setLayoutParams(layoutParams); - firstNameField.setOnEditorActionListener(new TextView.OnEditorActionListener() { - @Override - public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { - if (i == EditorInfo.IME_ACTION_NEXT) { - lastNameField.requestFocus(); - lastNameField.setSelection(lastNameField.length()); - return true; - } - return false; - } - }); - - lastNameField = new EditText(getParentActivity()); - lastNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); - lastNameField.setHintTextColor(0xff979797); - lastNameField.setTextColor(0xff212121); - lastNameField.setMaxLines(1); - lastNameField.setLines(1); - lastNameField.setSingleLine(true); - lastNameField.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); - lastNameField.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); - lastNameField.setImeOptions(EditorInfo.IME_ACTION_DONE); - lastNameField.setHint(LocaleController.getString("LastName", R.string.LastName)); - AndroidUtilities.clearCursorDrawable(lastNameField); - ((LinearLayout) fragmentView).addView(lastNameField); - layoutParams = (LinearLayout.LayoutParams)lastNameField.getLayoutParams(); - layoutParams.topMargin = AndroidUtilities.dp(16); - layoutParams.height = AndroidUtilities.dp(36); - layoutParams.leftMargin = AndroidUtilities.dp(24); - layoutParams.rightMargin = AndroidUtilities.dp(24); - layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; - lastNameField.setLayoutParams(layoutParams); - lastNameField.setOnEditorActionListener(new TextView.OnEditorActionListener() { - @Override - public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { - if (i == EditorInfo.IME_ACTION_DONE) { - doneButton.performClick(); - return true; - } - return false; - } - }); - - if (user != null) { - firstNameField.setText(user.first_name); - firstNameField.setSelection(firstNameField.length()); - lastNameField.setText(user.last_name); + return false; } - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); + }); + + lastNameField = new EditText(context); + lastNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + lastNameField.setHintTextColor(0xff979797); + lastNameField.setTextColor(0xff212121); + lastNameField.setMaxLines(1); + lastNameField.setLines(1); + lastNameField.setSingleLine(true); + lastNameField.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); + lastNameField.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); + lastNameField.setImeOptions(EditorInfo.IME_ACTION_DONE); + lastNameField.setHint(LocaleController.getString("LastName", R.string.LastName)); + AndroidUtilities.clearCursorDrawable(lastNameField); + ((LinearLayout) fragmentView).addView(lastNameField); + layoutParams = (LinearLayout.LayoutParams) lastNameField.getLayoutParams(); + layoutParams.topMargin = AndroidUtilities.dp(16); + layoutParams.height = AndroidUtilities.dp(36); + layoutParams.leftMargin = AndroidUtilities.dp(24); + layoutParams.rightMargin = AndroidUtilities.dp(24); + layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; + lastNameField.setLayoutParams(layoutParams); + lastNameField.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { + if (i == EditorInfo.IME_ACTION_DONE) { + doneButton.performClick(); + return true; + } + return false; } + }); + + if (user != null) { + firstNameField.setText(user.first_name); + firstNameField.setSelection(firstNameField.length()); + lastNameField.setText(user.last_name); } + return fragmentView; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java index d0dc19b26..01e54b550 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java @@ -25,7 +25,6 @@ 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; @@ -101,80 +100,74 @@ public class ChangePhoneActivity extends BaseFragment { } @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(); + public View createView(Context context, LayoutInflater inflater) { + 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(context); + ScrollView scrollView = (ScrollView) fragmentView; + scrollView.setFillViewport(true); + + FrameLayout frameLayout = new FrameLayout(context); + 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(context); + 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(context); + 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); } } - }); - - 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); } + } catch (Exception e) { + FileLog.e("tmessages", e); } + + actionBar.setTitle(views[0].getHeaderName()); + return fragmentView; } @@ -289,9 +282,9 @@ public class ChangePhoneActivity extends BaseFragment { private int countryState = 0; - private ArrayList countriesArray = new ArrayList(); - private HashMap countriesMap = new HashMap(); - private HashMap codesMap = new HashMap(); + private ArrayList countriesArray = new ArrayList<>(); + private HashMap countriesMap = new HashMap<>(); + private HashMap codesMap = new HashMap<>(); private boolean ignoreSelection = false; private boolean ignoreOnTextChange = false; @@ -533,7 +526,7 @@ public class ChangePhoneActivity extends BaseFragment { layoutParams.gravity = Gravity.LEFT; textView.setLayoutParams(layoutParams); - HashMap languageMap = new HashMap(); + HashMap languageMap = new HashMap<>(); try { BufferedReader reader = new BufferedReader(new InputStreamReader(getResources().getAssets().open("countries.txt"))); String line; @@ -544,6 +537,7 @@ public class ChangePhoneActivity extends BaseFragment { codesMap.put(args[0], args[2]); languageMap.put(args[1], args[2]); } + reader.close(); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -1013,7 +1007,7 @@ public class ChangePhoneActivity extends BaseFragment { destroyCodeTimer(); UserConfig.setCurrentUser(user); UserConfig.saveConfig(true); - ArrayList users = new ArrayList(); + ArrayList users = new ArrayList<>(); users.add(user); MessagesStorage.getInstance().putUsersAndChats(users, null, true, true); MessagesController.getInstance().putUser(user, false); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneHelpActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneHelpActivity.java index e2c2b2cb5..3da860185 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneHelpActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneHelpActivity.java @@ -9,13 +9,13 @@ package org.telegram.ui; import android.app.AlertDialog; +import android.content.Context; 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; @@ -35,129 +35,122 @@ 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); - } - }); + public View createView(Context context, LayoutInflater inflater) { + 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 { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); - } + 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(context); + fragmentView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + RelativeLayout relativeLayout = (RelativeLayout) fragmentView; + + ScrollView scrollView = new ScrollView(context); + 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(context); + 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(context); + 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(context); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + textView.setGravity(Gravity.CENTER_HORIZONTAL); + textView.setTextColor(0xff212121); + + try { + textView.setText(AndroidUtilities.replaceTags(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(context); + 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); + } + }); + 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 42c811344..e0169de83 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChangeUsernameActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangeUsernameActivity.java @@ -11,6 +11,7 @@ package org.telegram.ui; 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.text.Editable; @@ -61,130 +62,124 @@ public class ChangeUsernameActivity extends BaseFragment { private final static int done_button = 1; @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - actionBar.setTitle(LocaleController.getString("Username", R.string.Username)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } else if (id == done_button) { - saveName(); - } + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + actionBar.setTitle(LocaleController.getString("Username", R.string.Username)); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } else if (id == done_button) { + saveName(); } - }); - - ActionBarMenu menu = actionBar.createMenu(); - doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); - - TLRPC.User user = MessagesController.getInstance().getUser(UserConfig.getClientUserId()); - if (user == null) { - user = UserConfig.getCurrentUser(); } + }); - 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() { - @Override - public boolean onTouch(View v, MotionEvent event) { + ActionBarMenu menu = actionBar.createMenu(); + doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + + TLRPC.User user = MessagesController.getInstance().getUser(UserConfig.getClientUserId()); + if (user == null) { + user = UserConfig.getCurrentUser(); + } + + fragmentView = new LinearLayout(context); + fragmentView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + ((LinearLayout) fragmentView).setOrientation(LinearLayout.VERTICAL); + fragmentView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + firstNameField = new EditText(context); + firstNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + firstNameField.setHintTextColor(0xff979797); + firstNameField.setTextColor(0xff212121); + firstNameField.setMaxLines(1); + firstNameField.setLines(1); + firstNameField.setPadding(0, 0, 0, 0); + firstNameField.setSingleLine(true); + firstNameField.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); + firstNameField.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); + firstNameField.setImeOptions(EditorInfo.IME_ACTION_DONE); + firstNameField.setHint(LocaleController.getString("UsernamePlaceholder", R.string.UsernamePlaceholder)); + AndroidUtilities.clearCursorDrawable(firstNameField); + firstNameField.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { + if (i == EditorInfo.IME_ACTION_DONE && doneButton != null) { + doneButton.performClick(); return true; } - }); - - firstNameField = new EditText(getParentActivity()); - firstNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); - firstNameField.setHintTextColor(0xff979797); - firstNameField.setTextColor(0xff212121); - firstNameField.setMaxLines(1); - firstNameField.setLines(1); - firstNameField.setPadding(0, 0, 0, 0); - firstNameField.setSingleLine(true); - firstNameField.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); - firstNameField.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); - firstNameField.setImeOptions(EditorInfo.IME_ACTION_DONE); - firstNameField.setHint(LocaleController.getString("UsernamePlaceholder", R.string.UsernamePlaceholder)); - AndroidUtilities.clearCursorDrawable(firstNameField); - firstNameField.setOnEditorActionListener(new TextView.OnEditorActionListener() { - @Override - public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { - if (i == EditorInfo.IME_ACTION_DONE && doneButton != null) { - doneButton.performClick(); - return true; - } - return false; - } - }); - - ((LinearLayout) fragmentView).addView(firstNameField); - LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams)firstNameField.getLayoutParams(); - layoutParams.topMargin = AndroidUtilities.dp(24); - layoutParams.height = AndroidUtilities.dp(36); - layoutParams.leftMargin = AndroidUtilities.dp(24); - layoutParams.rightMargin = AndroidUtilities.dp(24); - layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; - firstNameField.setLayoutParams(layoutParams); - - if (user != null && user.username != null && user.username.length() > 0) { - firstNameField.setText(user.username); - firstNameField.setSelection(firstNameField.length()); + return false; } + }); - checkTextView = new TextView(getParentActivity()); - checkTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); - checkTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); - ((LinearLayout) fragmentView).addView(checkTextView); - layoutParams = (LinearLayout.LayoutParams)checkTextView.getLayoutParams(); - layoutParams.topMargin = AndroidUtilities.dp(12); - layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT; - layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; - layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT; - layoutParams.leftMargin = AndroidUtilities.dp(24); - layoutParams.rightMargin = AndroidUtilities.dp(24); - checkTextView.setLayoutParams(layoutParams); + ((LinearLayout) fragmentView).addView(firstNameField); + LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) firstNameField.getLayoutParams(); + layoutParams.topMargin = AndroidUtilities.dp(24); + layoutParams.height = AndroidUtilities.dp(36); + layoutParams.leftMargin = AndroidUtilities.dp(24); + layoutParams.rightMargin = AndroidUtilities.dp(24); + layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; + firstNameField.setLayoutParams(layoutParams); - TextView helpTextView = new TextView(getParentActivity()); - helpTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); - helpTextView.setTextColor(0xff6d6d72); - helpTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); - helpTextView.setText(Html.fromHtml(LocaleController.getString("UsernameHelp", R.string.UsernameHelp))); - ((LinearLayout) fragmentView).addView(helpTextView); - layoutParams = (LinearLayout.LayoutParams)helpTextView.getLayoutParams(); - layoutParams.topMargin = AndroidUtilities.dp(10); - layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT; - layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; - layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT; - layoutParams.leftMargin = AndroidUtilities.dp(24); - layoutParams.rightMargin = AndroidUtilities.dp(24); - helpTextView.setLayoutParams(layoutParams); - - firstNameField.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) { - checkUserName(firstNameField.getText().toString(), false); - } - - @Override - public void afterTextChanged(Editable editable) { - - } - }); - - checkTextView.setVisibility(View.GONE); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); - } + if (user != null && user.username != null && user.username.length() > 0) { + firstNameField.setText(user.username); + firstNameField.setSelection(firstNameField.length()); } + + checkTextView = new TextView(context); + checkTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); + checkTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); + ((LinearLayout) fragmentView).addView(checkTextView); + layoutParams = (LinearLayout.LayoutParams) checkTextView.getLayoutParams(); + layoutParams.topMargin = AndroidUtilities.dp(12); + layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT; + layoutParams.leftMargin = AndroidUtilities.dp(24); + layoutParams.rightMargin = AndroidUtilities.dp(24); + checkTextView.setLayoutParams(layoutParams); + + TextView helpTextView = new TextView(context); + helpTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); + helpTextView.setTextColor(0xff6d6d72); + helpTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); + helpTextView.setText(AndroidUtilities.replaceTags(LocaleController.getString("UsernameHelp", R.string.UsernameHelp))); + ((LinearLayout) fragmentView).addView(helpTextView); + layoutParams = (LinearLayout.LayoutParams) helpTextView.getLayoutParams(); + layoutParams.topMargin = AndroidUtilities.dp(10); + layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT; + layoutParams.leftMargin = AndroidUtilities.dp(24); + layoutParams.rightMargin = AndroidUtilities.dp(24); + helpTextView.setLayoutParams(layoutParams); + + firstNameField.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) { + checkUserName(firstNameField.getText().toString(), false); + } + + @Override + public void afterTextChanged(Editable editable) { + + } + }); + + checkTextView.setVisibility(View.GONE); + return fragmentView; } @@ -205,14 +200,19 @@ public class ChangeUsernameActivity extends BaseFragment { } AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - if (error.equals("USERNAME_INVALID")) { - builder.setMessage(LocaleController.getString("UsernameInvalid", R.string.UsernameInvalid)); - } else if (error.equals("USERNAME_OCCUPIED")) { - builder.setMessage(LocaleController.getString("UsernameInUse", R.string.UsernameInUse)); - } else if (error.equals("USERNAMES_UNAVAILABLE")) { - builder.setMessage(LocaleController.getString("FeatureUnavailable", R.string.FeatureUnavailable)); - } else { - builder.setMessage(LocaleController.getString("ErrorOccurred", R.string.ErrorOccurred)); + switch (error) { + case "USERNAME_INVALID": + builder.setMessage(LocaleController.getString("UsernameInvalid", R.string.UsernameInvalid)); + break; + case "USERNAME_OCCUPIED": + builder.setMessage(LocaleController.getString("UsernameInUse", R.string.UsernameInUse)); + break; + case "USERNAMES_UNAVAILABLE": + builder.setMessage(LocaleController.getString("FeatureUnavailable", R.string.FeatureUnavailable)); + break; + default: + builder.setMessage(LocaleController.getString("ErrorOccurred", R.string.ErrorOccurred)); + break; } builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null); showAlertDialog(builder); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index 7b4590106..801c41d59 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -10,6 +10,7 @@ package org.telegram.ui; import android.app.Activity; import android.app.AlertDialog; +import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -20,13 +21,14 @@ import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.media.ExifInterface; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.provider.MediaStore; import android.support.v7.widget.LinearLayoutManager; -import android.text.Html; import android.text.TextUtils; +import android.util.Base64; import android.util.SparseArray; import android.util.TypedValue; import android.view.Gravity; @@ -42,19 +44,28 @@ import android.widget.AdapterView; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import org.telegram.android.AndroidUtilities; import org.telegram.PhoneFormat.PhoneFormat; +import org.telegram.android.Emoji; 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.android.query.ReplyMessageQuery; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLoader; +import org.telegram.messenger.RPCRequest; +import org.telegram.messenger.SerializedData; +import org.telegram.messenger.TLClassStore; +import org.telegram.messenger.TLObject; import org.telegram.messenger.TLRPC; import org.telegram.android.ContactsController; import org.telegram.messenger.FileLog; @@ -66,6 +77,7 @@ import org.telegram.messenger.R; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; import org.telegram.ui.Adapters.BaseFragmentAdapter; +import org.telegram.ui.Adapters.MentionsAdapter; import org.telegram.ui.Adapters.StickersAdapter; import org.telegram.ui.AnimationCompat.AnimatorListenerAdapterProxy; import org.telegram.ui.AnimationCompat.AnimatorSetProxy; @@ -107,8 +119,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private TLRPC.EncryptedChat currentEncryptedChat; private boolean userBlocked = false; - private View progressView; - private View bottomOverlay; + private FrameLayout progressView; + private FrameLayout bottomOverlay; private ChatAdapter chatAdapter; private ChatActivityEnterView chatActivityEnterView; private ImageView timeItem; @@ -121,9 +133,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private LayoutListView chatListView; private BackupImageView avatarImageView; private TextView bottomOverlayChatText; - private View bottomOverlayChat; + private FrameLayout bottomOverlayChat; private TypingDotsDrawable typingDotsDrawable; - private View emptyViewContainer; + private FrameLayout emptyViewContainer; private ArrayList actionModeViews = new ArrayList<>(); private TextView nameTextView; private TextView onlineTextView; @@ -133,16 +145,32 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private TextView selectedMessagesCountTextView; private RecyclerListView stickersListView; private StickersAdapter stickersAdapter; - private View stickersPanel; + private FrameLayout stickersPanel; private TextView muteItem; + private ImageView pagedownButton; + private BackupImageView replyImageView; + private TextView replyNameTextView; + private TextView replyObjectTextView; + private ImageView replyIconImageView; + private MentionsAdapter mentionsAdapter; + private ListView mentionListView; + private AnimatorSetProxy mentionListAnimation; private boolean allowStickersPanel; private AnimatorSetProxy runningAnimation; private MessageObject selectedObject; + private ArrayList forwardingMessages; private MessageObject forwaringMessage; + private MessageObject replyingMessageObject; private boolean paused = true; private boolean readWhenResume = false; + private TLRPC.FileLocation replyImageLocation; + private long linkSearchRequestId; + private TLRPC.WebPage foundWebPage; + private String pendingLinkSearchString; + private Runnable pendingWebPageTimeoutRunnable; + private Runnable waitingForCharaterEnterRunnable; private boolean openAnimationEnded = false; @@ -150,8 +178,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private int readWithMid = 0; private boolean scrollToTopOnResume = false; private boolean scrollToTopUnReadOnResume = false; - private boolean isCustomTheme = false; - private View pagedownButton; private long dialog_id; private boolean isBroadcast = false; private HashMap selectedMessagesIds = new HashMap<>(); @@ -170,6 +196,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private int loadsCount = 0; private int startLoadFromMessageId = 0; + private boolean needSelectFromMessageId; + private int returnToMessageId = 0; private int minDate = 0; private boolean first = true; @@ -215,6 +243,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private final static int delete_chat = 12; private final static int share_contact = 13; private final static int mute = 14; + private final static int reply = 15; + + private final static int id_chat_compose_panel = 1000; AdapterView.OnItemLongClickListener onItemLongClickListener = new AdapterView.OnItemLongClickListener() { @Override @@ -355,75 +386,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not return false; } } - dialog_id = ((long)encId) << 32; + dialog_id = ((long) encId) << 32; maxMessageId = Integer.MIN_VALUE; minMessageId = Integer.MAX_VALUE; MediaController.getInstance().startMediaObserver(); } else { return false; } - chatActivityEnterView = new ChatActivityEnterView(); - chatActivityEnterView.setDialogId(dialog_id); - chatActivityEnterView.setDelegate(new ChatActivityEnterView.ChatActivityEnterViewDelegate() { - @Override - public void onMessageSend() { - chatListView.post(new Runnable() { - @Override - public void run() { - chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop()); - } - }); - } - @Override - public void onTextChanged(CharSequence text) { - if (stickersAdapter != null) { - stickersAdapter.loadStikersForEmoji(text); - } - } - - @Override - public void needSendTyping() { - MessagesController.getInstance().sendTyping(dialog_id, classGuid); - } - - @Override - public void onAttachButtonHidden() { - if (attachItem != null) { - attachItem.setVisibility(View.VISIBLE); - } - if (headerItem != null) { - headerItem.setVisibility(View.INVISIBLE); - } - } - - @Override - public void onAttachButtonShow() { - if (attachItem != null) { - attachItem.setVisibility(View.INVISIBLE); - } - if (headerItem != null) { - headerItem.setVisibility(View.VISIBLE); - } - } - - @Override - public void onWindowSizeChanged(int size) { - if (size < AndroidUtilities.dp(72) + AndroidUtilities.getCurrentActionBarHeight()) { - allowStickersPanel = false; - if (stickersPanel.getVisibility() == View.VISIBLE) { - stickersPanel.clearAnimation(); - stickersPanel.setVisibility(View.INVISIBLE); - } - } else { - allowStickersPanel = true; - if (stickersPanel.getVisibility() == View.INVISIBLE) { - stickersPanel.clearAnimation(); - stickersPanel.setVisibility(View.VISIBLE); - } - } - } - }); NotificationCenter.getInstance().addObserver(this, NotificationCenter.messagesDidLoaded); NotificationCenter.getInstance().addObserver(this, NotificationCenter.emojiDidLoaded); NotificationCenter.getInstance().addObserver(this, NotificationCenter.updateInterfaces); @@ -449,12 +419,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not NotificationCenter.getInstance().addObserver(this, NotificationCenter.updateMessageMedia); NotificationCenter.getInstance().addObserver(this, NotificationCenter.replaceMessagesObjects); NotificationCenter.getInstance().addObserver(this, NotificationCenter.notificationsSettingsUpdated); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.didLoadedReplyMessages); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.didReceivedWebpages); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.didReceivedWebpagesInUpdates); super.onFragmentCreate(); loading = true; if (startLoadFromMessageId != 0) { + needSelectFromMessageId = true; MessagesController.getInstance().loadMessages(dialog_id, AndroidUtilities.isTablet() ? 30 : 20, startLoadFromMessageId, true, 0, classGuid, 3, 0, 0, false); } else { MessagesController.getInstance().loadMessages(dialog_id, AndroidUtilities.isTablet() ? 30 : 20, 0, true, 0, classGuid, 2, 0, 0, true); @@ -509,6 +483,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not NotificationCenter.getInstance().removeObserver(this, NotificationCenter.updateMessageMedia); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.replaceMessagesObjects); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.notificationsSettingsUpdated); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.didLoadedReplyMessages); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.didReceivedWebpages); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.didReceivedWebpagesInUpdates); + if (AndroidUtilities.isTablet()) { NotificationCenter.getInstance().postNotificationName(NotificationCenter.openedChatChanged, dialog_id, true); } @@ -528,942 +506,1744 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not MediaController.getInstance().stopAudio(); } - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - lastPrintString = null; - lastStatus = null; + @Override + public View createView(Context context, LayoutInflater inflater) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(final int id) { - if (id == -1) { - finishFragment(); - } else if (id == -2) { - selectedMessagesIds.clear(); - selectedMessagesCanCopyIds.clear(); - actionBar.hideActionMode(); - updateVisibleRows(); - } else if (id == attach_photo) { - try { - Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - File image = Utilities.generatePicturePath(); - if (image != null) { - takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image)); - currentPicturePath = image.getAbsolutePath(); - } - startActivityForResult(takePictureIntent, 0); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } else if (id == attach_gallery) { - PhotoAlbumPickerActivity fragment = new PhotoAlbumPickerActivity(); - fragment.setDelegate(new PhotoAlbumPickerActivity.PhotoAlbumPickerActivityDelegate() { - @Override - public void didSelectPhotos(ArrayList photos) { - SendMessagesHelper.prepareSendingPhotos(photos, null, dialog_id); - } + lastPrintString = null; + lastStatus = null; + hasOwnBackground = true; - @Override - public void didSelectWebPhotos(ArrayList photos) { - SendMessagesHelper.prepareSendingPhotosSearch(photos, dialog_id); - } - - @Override - public void startPhotoSelectActivity() { - try { - Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); - photoPickerIntent.setType("image/*"); - startActivityForResult(photoPickerIntent, 1); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } - }); - presentFragment(fragment); - } else if (id == attach_video) { - try { - Intent pickIntent = new Intent(); - pickIntent.setType("video/*"); - pickIntent.setAction(Intent.ACTION_GET_CONTENT); - pickIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, (long) (1024 * 1024 * 1000)); - Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); - File video = Utilities.generateVideoPath(); - if (video != null) { - if (Build.VERSION.SDK_INT >= 18) { - takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(video)); - } - takeVideoIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, (long) (1024 * 1024 * 1000)); - currentPicturePath = video.getAbsolutePath(); - } - Intent chooserIntent = Intent.createChooser(pickIntent, ""); - chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{takeVideoIntent}); - - startActivityForResult(chooserIntent, 2); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } else if (id == attach_location) { - if (!isGoogleMapsInstalled()) { - return; - } - LocationActivity fragment = new LocationActivity(); - fragment.setDelegate(new LocationActivity.LocationActivityDelegate() { - @Override - public void didSelectLocation(double latitude, double longitude) { - SendMessagesHelper.getInstance().sendMessage(latitude, longitude, dialog_id); - if (chatListView != null) { - chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop()); - } - if (paused) { - scrollToTopOnResume = true; - } - } - }); - presentFragment(fragment); - } else if (id == attach_document) { - DocumentSelectActivity fragment = new DocumentSelectActivity(); - fragment.setDelegate(new DocumentSelectActivity.DocumentSelectActivityDelegate() { - @Override - public void didSelectFiles(DocumentSelectActivity activity, ArrayList files) { - activity.finishFragment(); - SendMessagesHelper.prepareSendingDocuments(files, files, null, null, dialog_id); - } - - @Override - public void startDocumentSelectActivity() { - try { - Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); - photoPickerIntent.setType("*/*"); - startActivityForResult(photoPickerIntent, 21); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } - }); - presentFragment(fragment); - } else if (id == copy) { - String str = ""; - ArrayList ids = new ArrayList<>(selectedMessagesCanCopyIds.keySet()); - if (currentEncryptedChat == null) { - Collections.sort(ids); - } else { - Collections.sort(ids, Collections.reverseOrder()); - } - for (Integer messageId : ids) { - MessageObject messageObject = selectedMessagesCanCopyIds.get(messageId); - if (str.length() != 0) { - str += "\n"; - } - if (messageObject.messageOwner.message != null) { - str += messageObject.messageOwner.message; + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(final int id) { + if (id == attach_photo || id == attach_gallery || id == attach_document || id == attach_video) { + String action = null; + if (currentChat != null) { + if (currentChat.participants_count > MessagesController.getInstance().groupBigSize) { + if (id == attach_photo || id == attach_gallery) { + action = "bigchat_upload_photo"; } else { - str += messageObject.messageText; + action = "bigchat_upload_document"; } - } - if (str.length() != 0) { - if (Build.VERSION.SDK_INT < 11) { - android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); - clipboard.setText(str); + } else { + if (id == attach_photo || id == attach_gallery) { + action = "chat_upload_photo"; } else { - android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); - android.content.ClipData clip = android.content.ClipData.newPlainText("label", str); - clipboard.setPrimaryClip(clip); + action = "chat_upload_document"; } } - selectedMessagesIds.clear(); - selectedMessagesCanCopyIds.clear(); - actionBar.hideActionMode(); - updateVisibleRows(); - } else if (id == delete) { - if (getParentActivity() == null) { - return; - } - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setMessage(LocaleController.formatString("AreYouSureDeleteMessages", R.string.AreYouSureDeleteMessages, LocaleController.formatPluralString("messages", selectedMessagesIds.size()))); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - ArrayList ids = new ArrayList<>(selectedMessagesIds.keySet()); - ArrayList random_ids = null; - if (currentEncryptedChat != null) { - random_ids = new ArrayList<>(); - for (HashMap.Entry entry : selectedMessagesIds.entrySet()) { - MessageObject msg = entry.getValue(); - if (msg.messageOwner.random_id != 0 && msg.type != 10) { - random_ids.add(msg.messageOwner.random_id); - } - } - } - MessagesController.getInstance().deleteMessages(ids, random_ids, currentEncryptedChat); - actionBar.hideActionMode(); - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } else if (id == forward) { - Bundle args = new Bundle(); - args.putBoolean("onlySelect", true); - args.putBoolean("serverOnly", true); - args.putString("selectAlertString", LocaleController.getString("ForwardMessagesTo", R.string.ForwardMessagesTo)); - args.putString("selectAlertStringGroup", LocaleController.getString("ForwardMessagesToGroup", R.string.ForwardMessagesToGroup)); - MessagesActivity fragment = new MessagesActivity(args); - fragment.setDelegate(ChatActivity.this); - presentFragment(fragment); - } else if (id == chat_enc_timer) { - if (getParentActivity() == null) { - return; - } - showAlertDialog(AndroidUtilities.buildTTLAlert(getParentActivity(), currentEncryptedChat)); - } else if (id == clear_history || id == delete_chat) { - if (getParentActivity() == null) { - return; - } - final boolean isChat = (int)dialog_id < 0 && (int)(dialog_id >> 32) != 1; - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - if (id == clear_history) { - builder.setMessage(LocaleController.getString("AreYouSureClearHistory", R.string.AreYouSureClearHistory)); - } else { - if (isChat) { - builder.setMessage(LocaleController.getString("AreYouSureDeleteAndExit", R.string.AreYouSureDeleteAndExit)); - } else { - builder.setMessage(LocaleController.getString("AreYouSureDeleteThisChat", R.string.AreYouSureDeleteThisChat)); - } - } - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - MessagesController.getInstance().deleteDialog(dialog_id, 0, id == clear_history); - if (id != clear_history) { - if (isChat) { - MessagesController.getInstance().deleteUserFromChat((int) -dialog_id, MessagesController.getInstance().getUser(UserConfig.getClientUserId()), null); - } - finishFragment(); - } - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } else if (id == share_contact) { - if (currentUser == null || getParentActivity() == null) { - return; - } - if (currentUser.phone != null && currentUser.phone.length() != 0) { - Bundle args = new Bundle(); - args.putInt("user_id", currentUser.id); - args.putBoolean("addContact", true); - presentFragment(new ContactAddActivity(args)); - } else { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setMessage(LocaleController.getString("AreYouSureShareMyContactInfo", R.string.AreYouSureShareMyContactInfo)); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - SendMessagesHelper.getInstance().sendMessage(UserConfig.getCurrentUser(), dialog_id); - chatListView.post(new Runnable() { - @Override - public void run() { - chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop()); - } - }); - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } - } else if (id == mute) { - boolean muted = MessagesController.getInstance().isDialogMuted(dialog_id); - if (!muted) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("Notifications", R.string.Notifications)); - CharSequence[] items = new CharSequence[]{ - LocaleController.formatString("MuteFor", R.string.MuteFor, LocaleController.formatPluralString("Hours", 1)), - LocaleController.formatString("MuteFor", R.string.MuteFor, LocaleController.formatPluralString("Hours", 8)), - LocaleController.formatString("MuteFor", R.string.MuteFor, LocaleController.formatPluralString("Days", 2)) - }; - builder.setItems(items, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - int untilTime = ConnectionsManager.getInstance().getCurrentTime(); - if (i == 0) { - untilTime += 60 * 60; - } else if (i == 1) { - untilTime += 60 * 60 * 8; - } else if (i == 2) { - untilTime += 60 * 60 * 48; - } - - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - editor.putInt("notify2_" + dialog_id, 3); - editor.putInt("notifyuntil_" + dialog_id, untilTime); - long flags = ((long)untilTime << 32) | 1; - MessagesStorage.getInstance().setDialogFlags(dialog_id, flags); - editor.commit(); - TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(dialog_id); - if (dialog != null) { - dialog.notify_settings = new TLRPC.TL_peerNotifySettings(); - dialog.notify_settings.mute_until = untilTime; - } - NotificationsController.updateServerNotificationsSettings(dialog_id); - } - } - ); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } else { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - editor.putInt("notify2_" + dialog_id, 0); - MessagesStorage.getInstance().setDialogFlags(dialog_id, 0); - editor.commit(); - TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(dialog_id); - if (dialog != null) { - dialog.notify_settings = new TLRPC.TL_peerNotifySettings(); - } - NotificationsController.updateServerNotificationsSettings(dialog_id); - } - } - } - }); - - avatarContainer = new FrameLayoutFixed(getParentActivity()); - avatarContainer.setBackgroundResource(R.drawable.bar_selector); - avatarContainer.setPadding(AndroidUtilities.dp(8), 0, AndroidUtilities.dp(8), 0); - actionBar.addView(avatarContainer); - FrameLayout.LayoutParams layoutParams2 = (FrameLayout.LayoutParams) avatarContainer.getLayoutParams(); - layoutParams2.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams2.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams2.rightMargin = AndroidUtilities.dp(40); - layoutParams2.leftMargin = AndroidUtilities.dp(56); - layoutParams2.gravity = Gravity.TOP | Gravity.LEFT; - avatarContainer.setLayoutParams(layoutParams2); - avatarContainer.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (currentUser != null) { - Bundle args = new Bundle(); - args.putInt("user_id", currentUser.id); - if (currentEncryptedChat != null) { - args.putLong("dialog_id", dialog_id); - } - presentFragment(new ProfileActivity(args)); - } else if (currentChat != null) { - Bundle args = new Bundle(); - args.putInt("chat_id", currentChat.id); - ProfileActivity fragment = new ProfileActivity(args); - fragment.setChatInfo(info); - presentFragment(fragment); - } - } - }); - - if (currentChat != null) { - int count = currentChat.participants_count; - if (info != null) { - count = info.participants.size(); - } - if (count == 0 || currentChat.left || currentChat instanceof TLRPC.TL_chatForbidden || info != null && info instanceof TLRPC.TL_chatParticipantsForbidden) { - avatarContainer.setEnabled(false); - } - } - - avatarImageView = new BackupImageView(getParentActivity()); - avatarImageView.imageReceiver.setRoundRadius(AndroidUtilities.dp(21)); - avatarImageView.processDetach = false; - avatarContainer.addView(avatarImageView); - layoutParams2 = (FrameLayout.LayoutParams) avatarImageView.getLayoutParams(); - layoutParams2.width = AndroidUtilities.dp(42); - layoutParams2.height = AndroidUtilities.dp(42); - layoutParams2.topMargin = AndroidUtilities.dp(3); - layoutParams2.gravity = Gravity.TOP | Gravity.LEFT; - avatarImageView.setLayoutParams(layoutParams2); - - if (currentEncryptedChat != null) { - timeItem = new ImageView(getParentActivity()); - timeItem.setPadding(AndroidUtilities.dp(10), AndroidUtilities.dp(10), AndroidUtilities.dp(5), AndroidUtilities.dp(5)); - timeItem.setScaleType(ImageView.ScaleType.CENTER); - avatarContainer.addView(timeItem); - timerDrawable = new TimerDrawable(getParentActivity()); - - layoutParams2 = (FrameLayout.LayoutParams) timeItem.getLayoutParams(); - layoutParams2.width = AndroidUtilities.dp(34); - layoutParams2.height = AndroidUtilities.dp(34); - layoutParams2.topMargin = AndroidUtilities.dp(18); - layoutParams2.leftMargin = AndroidUtilities.dp(16); - layoutParams2.gravity = Gravity.TOP | Gravity.LEFT; - timeItem.setLayoutParams(layoutParams2); - timeItem.setImageDrawable(timerDrawable); - - timeItem.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (getParentActivity() == null) { - return; - } - showAlertDialog(AndroidUtilities.buildTTLAlert(getParentActivity(), currentEncryptedChat)); - } - }); - } - - nameTextView = new TextView(getParentActivity()); - nameTextView.setTextColor(0xffffffff); - nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); - nameTextView.setLines(1); - nameTextView.setMaxLines(1); - nameTextView.setSingleLine(true); - nameTextView.setEllipsize(TextUtils.TruncateAt.END); - nameTextView.setGravity(Gravity.LEFT); - nameTextView.setCompoundDrawablePadding(AndroidUtilities.dp(4)); - nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); - avatarContainer.addView(nameTextView); - layoutParams2 = (FrameLayout.LayoutParams) nameTextView.getLayoutParams(); - layoutParams2.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams2.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams2.leftMargin = AndroidUtilities.dp(54); - layoutParams2.bottomMargin = AndroidUtilities.dp(22); - layoutParams2.gravity = Gravity.BOTTOM; - nameTextView.setLayoutParams(layoutParams2); - - onlineTextView = new TextView(getParentActivity()); - onlineTextView.setTextColor(0xffd7e8f7); - onlineTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); - onlineTextView.setLines(1); - onlineTextView.setMaxLines(1); - onlineTextView.setSingleLine(true); - onlineTextView.setEllipsize(TextUtils.TruncateAt.END); - onlineTextView.setGravity(Gravity.LEFT); - avatarContainer.addView(onlineTextView); - layoutParams2 = (FrameLayout.LayoutParams) onlineTextView.getLayoutParams(); - layoutParams2.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams2.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams2.leftMargin = AndroidUtilities.dp(54); - layoutParams2.bottomMargin = AndroidUtilities.dp(4); - layoutParams2.gravity = Gravity.BOTTOM; - onlineTextView.setLayoutParams(layoutParams2); - - ActionBarMenu menu = actionBar.createMenu(); - - headerItem = menu.addItem(0, R.drawable.ic_ab_other); - if (currentUser != null) { - addContactItem = headerItem.addSubItem(share_contact, "", 0); - } - if (currentEncryptedChat != null) { - timeItem2 = headerItem.addSubItem(chat_enc_timer, LocaleController.getString("SetTimer", R.string.SetTimer), 0); - } - headerItem.addSubItem(clear_history, LocaleController.getString("ClearHistory", R.string.ClearHistory), 0); - if (currentChat != null && !isBroadcast) { - headerItem.addSubItem(delete_chat, LocaleController.getString("DeleteAndExit", R.string.DeleteAndExit), 0); - } else { - headerItem.addSubItem(delete_chat, LocaleController.getString("DeleteChatUser", R.string.DeleteChatUser), 0); - } - muteItem = headerItem.addSubItem(mute, null, 0); - - LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) headerItem.getLayoutParams(); - layoutParams.rightMargin = AndroidUtilities.dp(-48); - headerItem.setLayoutParams(layoutParams); - - updateTitle(); - updateSubtitle(); - updateTitleIcons(); - - attachItem = menu.addItem(chat_menu_attach, R.drawable.ic_ab_other); - attachItem.addSubItem(attach_photo, LocaleController.getString("ChatTakePhoto", R.string.ChatTakePhoto), R.drawable.ic_attach_photo); - attachItem.addSubItem(attach_gallery, LocaleController.getString("ChatGallery", R.string.ChatGallery), R.drawable.ic_attach_gallery); - attachItem.addSubItem(attach_video, LocaleController.getString("ChatVideo", R.string.ChatVideo), R.drawable.ic_attach_video); - attachItem.addSubItem(attach_document, LocaleController.getString("ChatDocument", R.string.ChatDocument), R.drawable.ic_ab_doc); - attachItem.addSubItem(attach_location, LocaleController.getString("ChatLocation", R.string.ChatLocation), R.drawable.ic_attach_location); - attachItem.setVisibility(View.INVISIBLE); - - menuItem = menu.addItem(chat_menu_attach, R.drawable.ic_ab_attach); - menuItem.addSubItem(attach_photo, LocaleController.getString("ChatTakePhoto", R.string.ChatTakePhoto), R.drawable.ic_attach_photo); - menuItem.addSubItem(attach_gallery, LocaleController.getString("ChatGallery", R.string.ChatGallery), R.drawable.ic_attach_gallery); - menuItem.addSubItem(attach_video, LocaleController.getString("ChatVideo", R.string.ChatVideo), R.drawable.ic_attach_video); - menuItem.addSubItem(attach_document, LocaleController.getString("ChatDocument", R.string.ChatDocument), R.drawable.ic_ab_doc); - menuItem.addSubItem(attach_location, LocaleController.getString("ChatLocation", R.string.ChatLocation), R.drawable.ic_attach_location); - menuItem.setShowFromBottom(true); - menuItem.setBackgroundDrawable(null); - - actionModeViews.clear(); - - final ActionBarMenu actionMode = actionBar.createActionMode(); - actionModeViews.add(actionMode.addItem(-2, R.drawable.ic_ab_back_grey, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); - - selectedMessagesCountTextView = new TextView(actionMode.getContext()); - selectedMessagesCountTextView.setTextSize(18); - selectedMessagesCountTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); - selectedMessagesCountTextView.setTextColor(0xff737373); - selectedMessagesCountTextView.setSingleLine(true); - selectedMessagesCountTextView.setLines(1); - selectedMessagesCountTextView.setEllipsize(TextUtils.TruncateAt.END); - selectedMessagesCountTextView.setPadding(AndroidUtilities.dp(11), 0, 0, AndroidUtilities.dp(2)); - selectedMessagesCountTextView.setGravity(Gravity.CENTER_VERTICAL); - selectedMessagesCountTextView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return true; - } - }); - actionMode.addView(selectedMessagesCountTextView); - layoutParams = (LinearLayout.LayoutParams)selectedMessagesCountTextView.getLayoutParams(); - layoutParams.weight = 1; - layoutParams.width = 0; - layoutParams.height = LinearLayout.LayoutParams.MATCH_PARENT; - selectedMessagesCountTextView.setLayoutParams(layoutParams); - - if (currentEncryptedChat == null) { - actionModeViews.add(actionMode.addItem(copy, R.drawable.ic_ab_fwd_copy, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); - actionModeViews.add(actionMode.addItem(forward, R.drawable.ic_ab_fwd_forward, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); - actionModeViews.add(actionMode.addItem(delete, R.drawable.ic_ab_fwd_delete, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); - } else { - actionModeViews.add(actionMode.addItem(copy, R.drawable.ic_ab_fwd_copy, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); - actionModeViews.add(actionMode.addItem(delete, R.drawable.ic_ab_fwd_delete, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); - } - actionMode.getItem(copy).setVisibility(selectedMessagesCanCopyIds.size() != 0 ? View.VISIBLE : View.GONE); - checkActionBarMenu(); - - fragmentView = inflater.inflate(R.layout.chat_layout, container, false); - - View contentView = fragmentView.findViewById(R.id.chat_layout); - TextView emptyView = (TextView) fragmentView.findViewById(R.id.searchEmptyView); - emptyViewContainer = fragmentView.findViewById(R.id.empty_view); - emptyViewContainer.setVisibility(View.INVISIBLE); - emptyViewContainer.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return true; - } - }); - emptyView.setText(LocaleController.getString("NoMessages", R.string.NoMessages)); - chatListView = (LayoutListView)fragmentView.findViewById(R.id.chat_list_view); - chatListView.setAdapter(chatAdapter = new ChatAdapter(getParentActivity())); - bottomOverlay = fragmentView.findViewById(R.id.bottom_overlay); - bottomOverlayText = (TextView)fragmentView.findViewById(R.id.bottom_overlay_text); - bottomOverlayChat = fragmentView.findViewById(R.id.bottom_overlay_chat); - progressView = fragmentView.findViewById(R.id.progressLayout); - pagedownButton = fragmentView.findViewById(R.id.pagedown_button); - pagedownButton.setVisibility(View.GONE); - - View progressViewInner = progressView.findViewById(R.id.progressLayoutInner); - - updateContactStatus(); - - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); - int selectedBackground = preferences.getInt("selectedBackground", 1000001); - int selectedColor = preferences.getInt("selectedColor", 0); - if (selectedColor != 0) { - contentView.setBackgroundColor(selectedColor); - chatListView.setCacheColorHint(selectedColor); - } else { - chatListView.setCacheColorHint(0); - try { - if (ApplicationLoader.cachedWallpaper != null) { - isCustomTheme = selectedBackground != 1000001; - ((SizeNotifierRelativeLayout) contentView).setBackgroundImage(ApplicationLoader.cachedWallpaper); } else { - if (selectedBackground == 1000001) { - ((SizeNotifierRelativeLayout) contentView).setBackgroundImage(R.drawable.background_hd); - ApplicationLoader.cachedWallpaper = ((SizeNotifierRelativeLayout) contentView).getBackgroundImage(); + if (id == attach_photo || id == attach_gallery) { + action = "pm_upload_photo"; } else { - File toFile = new File(ApplicationLoader.applicationContext.getFilesDir(), "wallpaper.jpg"); - if (toFile.exists()) { - Drawable drawable = Drawable.createFromPath(toFile.getAbsolutePath()); - if (drawable != null) { - ((SizeNotifierRelativeLayout) contentView).setBackgroundImage(drawable); - ApplicationLoader.cachedWallpaper = drawable; - } else { - contentView.setBackgroundColor(-2693905); - chatListView.setCacheColorHint(-2693905); - } - isCustomTheme = true; - } else { - ((SizeNotifierRelativeLayout) contentView).setBackgroundImage(R.drawable.background_hd); - ApplicationLoader.cachedWallpaper = ((SizeNotifierRelativeLayout) contentView).getBackgroundImage(); - isCustomTheme = false; - } + action = "pm_upload_document"; } } - } catch (Throwable e) { - contentView.setBackgroundColor(-2693905); - chatListView.setCacheColorHint(-2693905); - FileLog.e("tmessages", e); - } - } - - if (isCustomTheme) { - progressViewInner.setBackgroundResource(R.drawable.system_loader2); - emptyView.setBackgroundResource(R.drawable.system_black); - } else { - progressViewInner.setBackgroundResource(R.drawable.system_loader1); - emptyView.setBackgroundResource(R.drawable.system_blue); - } - emptyView.setPadding(AndroidUtilities.dp(7), AndroidUtilities.dp(1), AndroidUtilities.dp(7), AndroidUtilities.dp(1)); - - if (currentUser != null && (currentUser.id / 1000 == 333 || currentUser.id % 1000 == 0)) { - emptyView.setText(LocaleController.getString("GotAQuestion", R.string.GotAQuestion)); - } - - chatListView.setOnItemLongClickListener(onItemLongClickListener); - chatListView.setOnItemClickListener(onItemClickListener); - - final Rect scrollRect = new Rect(); - - chatListView.setOnInterceptTouchEventListener(new LayoutListView.OnInterceptTouchEventListener() { - @Override - public boolean onInterceptTouchEvent(MotionEvent event) { - if (actionBar.isActionModeShowed()) { - return false; - } - if (event.getAction() == MotionEvent.ACTION_DOWN) { - int x = (int)event.getX(); - int y = (int)event.getY(); - int count = chatListView.getChildCount(); - Rect rect = new Rect(); - for (int a = 0; a < count; a++) { - View view = chatListView.getChildAt(a); - int top = view.getTop(); - int bottom = view.getBottom(); - view.getLocalVisibleRect(rect); - if (top > y || bottom < y) { - continue; - } - if (!(view instanceof ChatMediaCell)) { - break; - } - final ChatMediaCell cell = (ChatMediaCell)view; - final MessageObject messageObject = cell.getMessageObject(); - if (messageObject == null || !messageObject.isSecretPhoto() || !cell.getPhotoImage().isInsideImage(x, y - top)) { - break; - } - File file = FileLoader.getPathToMessage(messageObject.messageOwner); - if (!file.exists()) { - break; - } - startX = x; - startY = y; - chatListView.setOnItemClickListener(null); - openSecretPhotoRunnable = new Runnable() { - @Override - public void run() { - if (openSecretPhotoRunnable == null) { - return; - } - chatListView.requestDisallowInterceptTouchEvent(true); - chatListView.setOnItemLongClickListener(null); - chatListView.setLongClickable(false); - openSecretPhotoRunnable = null; - if (sendSecretMessageRead(messageObject)) { - cell.invalidate(); - } - SecretPhotoViewer.getInstance().setParentActivity(getParentActivity()); - SecretPhotoViewer.getInstance().openPhoto(messageObject); - } - }; - AndroidUtilities.runOnUIThread(openSecretPhotoRunnable, 100); - return true; - } - } - return false; - } - }); - - chatListView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - if (openSecretPhotoRunnable != null || SecretPhotoViewer.getInstance().isVisible()) { - if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_POINTER_UP) { - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - chatListView.setOnItemClickListener(onItemClickListener); - } - }, 150); - if (openSecretPhotoRunnable != null) { - AndroidUtilities.cancelRunOnUIThread(openSecretPhotoRunnable); - openSecretPhotoRunnable = null; - try { - Toast.makeText(v.getContext(), LocaleController.getString("PhotoTip", R.string.PhotoTip), Toast.LENGTH_SHORT).show(); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } else { - if (SecretPhotoViewer.getInstance().isVisible()) { - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - chatListView.setOnItemLongClickListener(onItemLongClickListener); - chatListView.setLongClickable(true); - } - }); - SecretPhotoViewer.getInstance().closePhoto(); - } - } - } else if (event.getAction() != MotionEvent.ACTION_DOWN) { - if (SecretPhotoViewer.getInstance().isVisible()) { - return true; - } else if (openSecretPhotoRunnable != null) { - if (event.getAction() == MotionEvent.ACTION_MOVE) { - if (Math.hypot(startX - event.getX(), startY - event.getY()) > AndroidUtilities.dp(5)) { - AndroidUtilities.cancelRunOnUIThread(openSecretPhotoRunnable); - openSecretPhotoRunnable = null; - } - } else { - AndroidUtilities.cancelRunOnUIThread(openSecretPhotoRunnable); - openSecretPhotoRunnable = null; - } - } - } - } - return false; - } - }); - - chatListView.setOnScrollListener(new AbsListView.OnScrollListener() { - @Override - public void onScrollStateChanged(AbsListView absListView, int i) { - if (i == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL || i == AbsListView.OnScrollListener.SCROLL_STATE_FLING && highlightMessageId != Integer.MAX_VALUE) { - highlightMessageId = Integer.MAX_VALUE; - updateVisibleRows(); + if (action != null && !MessagesController.isFeatureEnabled(action, ChatActivity.this)) { + return; } } + if (id == -1) { + finishFragment(); + } else if (id == -2) { + selectedMessagesIds.clear(); + selectedMessagesCanCopyIds.clear(); + actionBar.hideActionMode(); + updateVisibleRows(); + } else if (id == attach_photo) { + try { + Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + File image = Utilities.generatePicturePath(); + if (image != null) { + takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image)); + currentPicturePath = image.getAbsolutePath(); + } + startActivityForResult(takePictureIntent, 0); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } else if (id == attach_gallery) { + PhotoAlbumPickerActivity fragment = new PhotoAlbumPickerActivity(false); + fragment.setDelegate(new PhotoAlbumPickerActivity.PhotoAlbumPickerActivityDelegate() { + @Override + public void didSelectPhotos(ArrayList photos, ArrayList webPhotos) { + SendMessagesHelper.prepareSendingPhotos(photos, null, dialog_id, replyingMessageObject); + SendMessagesHelper.prepareSendingPhotosSearch(webPhotos, dialog_id, replyingMessageObject); + showReplyPanel(false, null, null, null, false, true); + } - @Override - public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - if (visibleItemCount > 0) { - if (firstVisibleItem <= 10) { - if (!endReached && !loading) { - if (messagesByDays.size() != 0) { - MessagesController.getInstance().loadMessages(dialog_id, 20, maxMessageId, !cacheEndReaced && startLoadFromMessageId == 0, minDate, classGuid, 0, 0, 0, startLoadFromMessageId == 0); - } else { - MessagesController.getInstance().loadMessages(dialog_id, 20, 0, !cacheEndReaced && startLoadFromMessageId == 0, minDate, classGuid, 0, 0, 0, startLoadFromMessageId == 0); - } - loading = true; + @Override + public void startPhotoSelectActivity() { + try { + Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); + photoPickerIntent.setType("image/*"); + startActivityForResult(photoPickerIntent, 1); + } catch (Exception e) { + FileLog.e("tmessages", e); } } - if (firstVisibleItem + visibleItemCount >= totalItemCount - 6) { - if (!forward_end_reached && !loadingForward) { - MessagesController.getInstance().loadMessages(dialog_id, 20, minMessageId, startLoadFromMessageId == 0, maxDate, classGuid, 1, 0, 0, startLoadFromMessageId == 0); - loadingForward = true; + }); + presentFragment(fragment); + } else if (id == attach_video) { + try { + Intent pickIntent = new Intent(); + pickIntent.setType("video/*"); + pickIntent.setAction(Intent.ACTION_GET_CONTENT); + pickIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, (long) (1024 * 1024 * 1536)); + Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); + File video = Utilities.generateVideoPath(); + if (video != null) { + if (Build.VERSION.SDK_INT >= 18) { + takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(video)); + } + takeVideoIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, (long) (1024 * 1024 * 1536)); + currentPicturePath = video.getAbsolutePath(); + } + Intent chooserIntent = Intent.createChooser(pickIntent, null); + chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{takeVideoIntent}); + + startActivityForResult(chooserIntent, 2); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } else if (id == attach_location) { + if (!isGoogleMapsInstalled()) { + return; + } + LocationActivity fragment = new LocationActivity(); + fragment.setDelegate(new LocationActivity.LocationActivityDelegate() { + @Override + public void didSelectLocation(double latitude, double longitude) { + SendMessagesHelper.getInstance().sendMessage(latitude, longitude, dialog_id, replyingMessageObject); + moveScrollToLastMessage(); + showReplyPanel(false, null, null, null, false, true); + if (paused) { + scrollToTopOnResume = true; } } - if (firstVisibleItem + visibleItemCount == totalItemCount && forward_end_reached) { - showPagedownButton(false, true); + }); + presentFragment(fragment); + } else if (id == attach_document) { + DocumentSelectActivity fragment = new DocumentSelectActivity(); + fragment.setDelegate(new DocumentSelectActivity.DocumentSelectActivityDelegate() { + @Override + public void didSelectFiles(DocumentSelectActivity activity, ArrayList files) { + activity.finishFragment(); + SendMessagesHelper.prepareSendingDocuments(files, files, null, null, dialog_id, replyingMessageObject); + showReplyPanel(false, null, null, null, false, true); } - } - for (int a = 0; a < visibleItemCount; a++) { - View view = absListView.getChildAt(a); - if (view instanceof ChatMessageCell) { - ChatMessageCell messageCell = (ChatMessageCell)view; - messageCell.getLocalVisibleRect(scrollRect); - messageCell.setVisiblePart(scrollRect.top, scrollRect.bottom - scrollRect.top); - } - } - } - }); - stickersListView = (RecyclerListView) fragmentView.findViewById(R.id.stickers_listview); - LinearLayoutManager layoutManager = new LinearLayoutManager(getParentActivity()); - layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); - stickersListView.setLayoutManager(layoutManager); - stickersPanel = fragmentView.findViewById(R.id.stickers_panel); - stickersPanel.setVisibility(View.GONE); - stickersListView.setClipToPadding(false); - if (Build.VERSION.SDK_INT >= 9) { - stickersListView.setOverScrollMode(RecyclerListView.OVER_SCROLL_NEVER); - } - - if (stickersAdapter != null) { - stickersAdapter.destroy(); - } - - if (currentEncryptedChat == null || currentEncryptedChat != null && AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 23) { - stickersListView.setPadding(AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18), 0); - stickersListView.setAdapter(stickersAdapter = new StickersAdapter(getParentActivity(), new StickersAdapter.StickersAdapterDelegate() { - @Override - public void needChangePanelVisibility(final boolean show) { - if (show && stickersPanel.getVisibility() == View.VISIBLE || !show && stickersPanel.getVisibility() == View.GONE) { - return; - } - if (show) { - stickersListView.scrollToPosition(0); - stickersPanel.clearAnimation(); - stickersPanel.setVisibility(allowStickersPanel ? View.VISIBLE : View.INVISIBLE); - } - if (runningAnimation != null) { - runningAnimation.cancel(); - runningAnimation = null; - } - if (stickersPanel.getVisibility() != View.INVISIBLE) { - runningAnimation = new AnimatorSetProxy(); - runningAnimation.playTogether( - ObjectAnimatorProxy.ofFloat(stickersPanel, "alpha", show ? 0.0f : 1.0f, show ? 1.0f : 0.0f) - ); - runningAnimation.setDuration(150); - runningAnimation.addListener(new AnimatorListenerAdapterProxy() { - @Override - public void onAnimationEnd(Object animation) { - if (runningAnimation != null && runningAnimation.equals(animation)) { - if (!show) { - stickersAdapter.clearStickers(); - stickersPanel.clearAnimation(); - stickersPanel.setVisibility(View.GONE); - } - runningAnimation = null; - } - } - }); - runningAnimation.start(); - } else if (!show) { - stickersPanel.setVisibility(View.GONE); - } - } - })); - stickersListView.addOnItemTouchListener(new RecyclerListView.RecyclerListViewItemClickListener(getParentActivity(), new RecyclerListView.OnItemClickListener() { - @Override - public void onItemClick(View view, int position) { - TLRPC.Document document = stickersAdapter.getItem(position); - if (document instanceof TLRPC.TL_document) { - if (currentEncryptedChat != null && document.thumb instanceof TLRPC.TL_photoSize) { - File file = FileLoader.getPathToAttach(document.thumb, true); - if (file.exists()) { - try { - int len = (int)file.length(); - byte[] arr = new byte[(int)file.length()]; - RandomAccessFile reader = new RandomAccessFile(file, "r"); - reader.readFully(arr); - TLRPC.TL_document newDocument = new TLRPC.TL_document(); - newDocument.thumb = new TLRPC.TL_photoCachedSize(); - newDocument.thumb.location = document.thumb.location; - newDocument.thumb.size = document.thumb.size; - newDocument.thumb.w = document.thumb.w; - newDocument.thumb.h = document.thumb.h; - newDocument.thumb.type = document.thumb.type; - newDocument.thumb.bytes = arr; - - newDocument.id = document.id; - newDocument.access_hash = document.access_hash; - newDocument.date = document.date; - newDocument.mime_type = document.mime_type; - newDocument.size = document.size; - newDocument.dc_id = document.dc_id; - newDocument.attributes = document.attributes; - document = newDocument; - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } + @Override + public void startDocumentSelectActivity() { + try { + Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); + photoPickerIntent.setType("*/*"); + startActivityForResult(photoPickerIntent, 21); + } catch (Exception e) { + FileLog.e("tmessages", e); } - SendMessagesHelper.getInstance().sendMessage((TLRPC.TL_document) document, null, null, dialog_id); } - chatActivityEnterView.setFieldText(""); + }); + presentFragment(fragment); + } else if (id == copy) { + String str = ""; + ArrayList ids = new ArrayList<>(selectedMessagesCanCopyIds.keySet()); + if (currentEncryptedChat == null) { + Collections.sort(ids); + } else { + Collections.sort(ids, Collections.reverseOrder()); } - })); - } - - bottomOverlayChatText = (TextView)fragmentView.findViewById(R.id.bottom_overlay_chat_text); - TextView textView = (TextView)fragmentView.findViewById(R.id.secret_title); - textView.setText(LocaleController.getString("EncryptedDescriptionTitle", R.string.EncryptedDescriptionTitle)); - textView = (TextView)fragmentView.findViewById(R.id.secret_description1); - textView.setText(LocaleController.getString("EncryptedDescription1", R.string.EncryptedDescription1)); - textView = (TextView)fragmentView.findViewById(R.id.secret_description2); - textView.setText(LocaleController.getString("EncryptedDescription2", R.string.EncryptedDescription2)); - textView = (TextView)fragmentView.findViewById(R.id.secret_description3); - textView.setText(LocaleController.getString("EncryptedDescription3", R.string.EncryptedDescription3)); - textView = (TextView)fragmentView.findViewById(R.id.secret_description4); - textView.setText(LocaleController.getString("EncryptedDescription4", R.string.EncryptedDescription4)); - - if (loading && messages.isEmpty()) { - progressView.setVisibility(View.VISIBLE); - chatListView.setEmptyView(null); - } else { - progressView.setVisibility(View.INVISIBLE); - chatListView.setEmptyView(emptyViewContainer); - } - - pagedownButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - scrollToLastMessage(); - } - }); - - bottomOverlayChat.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { + for (Integer messageId : ids) { + MessageObject messageObject = selectedMessagesCanCopyIds.get(messageId); + if (str.length() != 0) { + str += "\n"; + } + if (messageObject.messageOwner.message != null) { + str += messageObject.messageOwner.message; + } else { + str += messageObject.messageText; + } + } + if (str.length() != 0) { + if (Build.VERSION.SDK_INT < 11) { + android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); + clipboard.setText(str); + } else { + android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); + android.content.ClipData clip = android.content.ClipData.newPlainText("label", str); + clipboard.setPrimaryClip(clip); + } + } + selectedMessagesIds.clear(); + selectedMessagesCanCopyIds.clear(); + actionBar.hideActionMode(); + updateVisibleRows(); + } else if (id == delete) { if (getParentActivity() == null) { return; } AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.formatString("AreYouSureDeleteMessages", R.string.AreYouSureDeleteMessages, LocaleController.formatPluralString("messages", selectedMessagesIds.size()))); builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - if (currentUser != null && userBlocked) { - builder.setMessage(LocaleController.getString("AreYouSureUnblockContact", R.string.AreYouSureUnblockContact)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - MessagesController.getInstance().unblockUser(currentUser.id); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + ArrayList ids = new ArrayList<>(selectedMessagesIds.keySet()); + ArrayList random_ids = null; + if (currentEncryptedChat != null) { + random_ids = new ArrayList<>(); + for (HashMap.Entry entry : selectedMessagesIds.entrySet()) { + MessageObject msg = entry.getValue(); + if (msg.messageOwner.random_id != 0 && msg.type != 10) { + random_ids.add(msg.messageOwner.random_id); + } + } } - }); - } else { - builder.setMessage(LocaleController.getString("AreYouSureDeleteThisChat", R.string.AreYouSureDeleteThisChat)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - MessagesController.getInstance().deleteDialog(dialog_id, 0, false); - finishFragment(); - } - }); - } + MessagesController.getInstance().deleteMessages(ids, random_ids, currentEncryptedChat); + actionBar.hideActionMode(); + } + }); builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); showAlertDialog(builder); + } else if (id == forward) { + Bundle args = new Bundle(); + args.putBoolean("onlySelect", true); + args.putBoolean("serverOnly", true); + MessagesActivity fragment = new MessagesActivity(args); + fragment.setDelegate(ChatActivity.this); + presentFragment(fragment); + } else if (id == chat_enc_timer) { + if (getParentActivity() == null) { + return; + } + showAlertDialog(AndroidUtilities.buildTTLAlert(getParentActivity(), currentEncryptedChat)); + } else if (id == clear_history || id == delete_chat) { + if (getParentActivity() == null) { + return; + } + final boolean isChat = (int) dialog_id < 0 && (int) (dialog_id >> 32) != 1; + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + if (id == clear_history) { + builder.setMessage(LocaleController.getString("AreYouSureClearHistory", R.string.AreYouSureClearHistory)); + } else { + if (isChat) { + builder.setMessage(LocaleController.getString("AreYouSureDeleteAndExit", R.string.AreYouSureDeleteAndExit)); + } else { + builder.setMessage(LocaleController.getString("AreYouSureDeleteThisChat", R.string.AreYouSureDeleteThisChat)); + } + } + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + if (id != clear_history) { + if (isChat) { + MessagesController.getInstance().deleteUserFromChat((int) -dialog_id, MessagesController.getInstance().getUser(UserConfig.getClientUserId()), null); + } else { + MessagesController.getInstance().deleteDialog(dialog_id, 0, false); + } + finishFragment(); + } else { + MessagesController.getInstance().deleteDialog(dialog_id, 0, true); + } + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } else if (id == share_contact) { + if (currentUser == null || getParentActivity() == null) { + return; + } + if (currentUser.phone != null && currentUser.phone.length() != 0) { + Bundle args = new Bundle(); + args.putInt("user_id", currentUser.id); + args.putBoolean("addContact", true); + presentFragment(new ContactAddActivity(args)); + } else { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.getString("AreYouSureShareMyContactInfo", R.string.AreYouSureShareMyContactInfo)); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + SendMessagesHelper.getInstance().sendMessage(UserConfig.getCurrentUser(), dialog_id, replyingMessageObject); + moveScrollToLastMessage(); + showReplyPanel(false, null, null, null, false, true); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } + } else if (id == mute) { + boolean muted = MessagesController.getInstance().isDialogMuted(dialog_id); + if (!muted) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("Notifications", R.string.Notifications)); + CharSequence[] items = new CharSequence[]{ + LocaleController.formatString("MuteFor", R.string.MuteFor, LocaleController.formatPluralString("Hours", 1)), + LocaleController.formatString("MuteFor", R.string.MuteFor, LocaleController.formatPluralString("Hours", 8)), + LocaleController.formatString("MuteFor", R.string.MuteFor, LocaleController.formatPluralString("Days", 2)), + LocaleController.getString("MuteDisable", R.string.MuteDisable) + }; + builder.setItems(items, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + int untilTime = ConnectionsManager.getInstance().getCurrentTime(); + if (i == 0) { + untilTime += 60 * 60; + } else if (i == 1) { + untilTime += 60 * 60 * 8; + } else if (i == 2) { + untilTime += 60 * 60 * 48; + } else if (i == 3) { + untilTime = Integer.MAX_VALUE; + } + + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + long flags = 0; + if (i == 3) { + editor.putInt("notify2_" + dialog_id, 2); + flags = 1; + } else { + editor.putInt("notify2_" + dialog_id, 3); + editor.putInt("notifyuntil_" + dialog_id, untilTime); + flags = ((long) untilTime << 32) | 1; + } + MessagesStorage.getInstance().setDialogFlags(dialog_id, flags); + editor.commit(); + TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(dialog_id); + if (dialog != null) { + dialog.notify_settings = new TLRPC.TL_peerNotifySettings(); + dialog.notify_settings.mute_until = untilTime; + } + NotificationsController.updateServerNotificationsSettings(dialog_id); + } + } + ); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } else { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.putInt("notify2_" + dialog_id, 0); + MessagesStorage.getInstance().setDialogFlags(dialog_id, 0); + editor.commit(); + TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(dialog_id); + if (dialog != null) { + dialog.notify_settings = new TLRPC.TL_peerNotifySettings(); + } + NotificationsController.updateServerNotificationsSettings(dialog_id); + } + } else if (id == reply) { + if (selectedMessagesIds.size() == 1) { + ArrayList ids = new ArrayList<>(selectedMessagesIds.keySet()); + MessageObject messageObject = messagesDict.get(ids.get(0)); + if (messageObject != null && messageObject.messageOwner.id > 0) { + showReplyPanel(true, messageObject, null, null, false, true); + } + } + selectedMessagesIds.clear(); + selectedMessagesCanCopyIds.clear(); + actionBar.hideActionMode(); + updateVisibleRows(); + } + } + }); + + avatarContainer = new FrameLayoutFixed(context); + avatarContainer.setBackgroundResource(R.drawable.bar_selector); + avatarContainer.setPadding(AndroidUtilities.dp(8), 0, AndroidUtilities.dp(8), 0); + actionBar.addView(avatarContainer); + FrameLayout.LayoutParams layoutParams2 = (FrameLayout.LayoutParams) avatarContainer.getLayoutParams(); + layoutParams2.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams2.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.rightMargin = AndroidUtilities.dp(40); + layoutParams2.leftMargin = AndroidUtilities.dp(56); + layoutParams2.gravity = Gravity.TOP | Gravity.LEFT; + avatarContainer.setLayoutParams(layoutParams2); + avatarContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (currentUser != null) { + Bundle args = new Bundle(); + args.putInt("user_id", currentUser.id); + if (currentEncryptedChat != null) { + args.putLong("dialog_id", dialog_id); + } + presentFragment(new ProfileActivity(args)); + } else if (currentChat != null) { + Bundle args = new Bundle(); + args.putInt("chat_id", currentChat.id); + ProfileActivity fragment = new ProfileActivity(args); + fragment.setChatInfo(info); + presentFragment(fragment); + } + } + }); + + if (currentChat != null) { + int count = currentChat.participants_count; + if (info != null) { + count = info.participants.size(); + } + if (count == 0 || currentChat.left || currentChat instanceof TLRPC.TL_chatForbidden || info != null && info instanceof TLRPC.TL_chatParticipantsForbidden) { + avatarContainer.setEnabled(false); + } + } + + avatarImageView = new BackupImageView(context); + avatarImageView.setRoundRadius(AndroidUtilities.dp(21)); + avatarContainer.addView(avatarImageView); + layoutParams2 = (FrameLayout.LayoutParams) avatarImageView.getLayoutParams(); + layoutParams2.width = AndroidUtilities.dp(42); + layoutParams2.height = AndroidUtilities.dp(42); + layoutParams2.topMargin = AndroidUtilities.dp(3); + layoutParams2.gravity = Gravity.TOP | Gravity.LEFT; + avatarImageView.setLayoutParams(layoutParams2); + + if (currentEncryptedChat != null) { + timeItem = new ImageView(context); + timeItem.setPadding(AndroidUtilities.dp(10), AndroidUtilities.dp(10), AndroidUtilities.dp(5), AndroidUtilities.dp(5)); + timeItem.setScaleType(ImageView.ScaleType.CENTER); + avatarContainer.addView(timeItem); + timerDrawable = new TimerDrawable(context); + + layoutParams2 = (FrameLayout.LayoutParams) timeItem.getLayoutParams(); + layoutParams2.width = AndroidUtilities.dp(34); + layoutParams2.height = AndroidUtilities.dp(34); + layoutParams2.topMargin = AndroidUtilities.dp(18); + layoutParams2.leftMargin = AndroidUtilities.dp(16); + layoutParams2.gravity = Gravity.TOP | Gravity.LEFT; + timeItem.setLayoutParams(layoutParams2); + timeItem.setImageDrawable(timerDrawable); + + timeItem.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (getParentActivity() == null) { + return; + } + showAlertDialog(AndroidUtilities.buildTTLAlert(getParentActivity(), currentEncryptedChat)); + } + }); + } + + nameTextView = new TextView(context); + nameTextView.setTextColor(0xffffffff); + nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + nameTextView.setLines(1); + nameTextView.setMaxLines(1); + nameTextView.setSingleLine(true); + nameTextView.setEllipsize(TextUtils.TruncateAt.END); + nameTextView.setGravity(Gravity.LEFT); + nameTextView.setCompoundDrawablePadding(AndroidUtilities.dp(4)); + nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + avatarContainer.addView(nameTextView); + layoutParams2 = (FrameLayout.LayoutParams) nameTextView.getLayoutParams(); + layoutParams2.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.leftMargin = AndroidUtilities.dp(54); + layoutParams2.bottomMargin = AndroidUtilities.dp(22); + layoutParams2.gravity = Gravity.BOTTOM; + nameTextView.setLayoutParams(layoutParams2); + + onlineTextView = new TextView(context); + onlineTextView.setTextColor(0xffd7e8f7); + onlineTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + onlineTextView.setLines(1); + onlineTextView.setMaxLines(1); + onlineTextView.setSingleLine(true); + onlineTextView.setEllipsize(TextUtils.TruncateAt.END); + onlineTextView.setGravity(Gravity.LEFT); + avatarContainer.addView(onlineTextView); + layoutParams2 = (FrameLayout.LayoutParams) onlineTextView.getLayoutParams(); + layoutParams2.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.leftMargin = AndroidUtilities.dp(54); + layoutParams2.bottomMargin = AndroidUtilities.dp(4); + layoutParams2.gravity = Gravity.BOTTOM; + onlineTextView.setLayoutParams(layoutParams2); + + ActionBarMenu menu = actionBar.createMenu(); + + headerItem = menu.addItem(0, R.drawable.ic_ab_other); + if (currentUser != null) { + addContactItem = headerItem.addSubItem(share_contact, "", 0); + } + if (currentEncryptedChat != null) { + timeItem2 = headerItem.addSubItem(chat_enc_timer, LocaleController.getString("SetTimer", R.string.SetTimer), 0); + } + headerItem.addSubItem(clear_history, LocaleController.getString("ClearHistory", R.string.ClearHistory), 0); + if (currentChat != null && !isBroadcast) { + headerItem.addSubItem(delete_chat, LocaleController.getString("DeleteAndExit", R.string.DeleteAndExit), 0); + } else { + headerItem.addSubItem(delete_chat, LocaleController.getString("DeleteChatUser", R.string.DeleteChatUser), 0); + } + muteItem = headerItem.addSubItem(mute, null, 0); + + LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) headerItem.getLayoutParams(); + layoutParams.rightMargin = AndroidUtilities.dp(-48); + headerItem.setLayoutParams(layoutParams); + + updateTitle(); + updateSubtitle(); + updateTitleIcons(); + + attachItem = menu.addItem(chat_menu_attach, R.drawable.ic_ab_other); + attachItem.addSubItem(attach_photo, LocaleController.getString("ChatTakePhoto", R.string.ChatTakePhoto), R.drawable.ic_attach_photo); + attachItem.addSubItem(attach_gallery, LocaleController.getString("ChatGallery", R.string.ChatGallery), R.drawable.ic_attach_gallery); + attachItem.addSubItem(attach_video, LocaleController.getString("ChatVideo", R.string.ChatVideo), R.drawable.ic_attach_video); + attachItem.addSubItem(attach_document, LocaleController.getString("ChatDocument", R.string.ChatDocument), R.drawable.ic_ab_doc); + attachItem.addSubItem(attach_location, LocaleController.getString("ChatLocation", R.string.ChatLocation), R.drawable.ic_attach_location); + attachItem.setVisibility(View.INVISIBLE); + + menuItem = menu.addItem(chat_menu_attach, R.drawable.ic_ab_attach); + menuItem.addSubItem(attach_photo, LocaleController.getString("ChatTakePhoto", R.string.ChatTakePhoto), R.drawable.ic_attach_photo); + menuItem.addSubItem(attach_gallery, LocaleController.getString("ChatGallery", R.string.ChatGallery), R.drawable.ic_attach_gallery); + menuItem.addSubItem(attach_video, LocaleController.getString("ChatVideo", R.string.ChatVideo), R.drawable.ic_attach_video); + menuItem.addSubItem(attach_document, LocaleController.getString("ChatDocument", R.string.ChatDocument), R.drawable.ic_ab_doc); + menuItem.addSubItem(attach_location, LocaleController.getString("ChatLocation", R.string.ChatLocation), R.drawable.ic_attach_location); + menuItem.setShowFromBottom(true); + menuItem.setBackgroundDrawable(null); + + actionModeViews.clear(); + + final ActionBarMenu actionMode = actionBar.createActionMode(); + actionModeViews.add(actionMode.addItem(-2, R.drawable.ic_ab_back_grey, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); + + selectedMessagesCountTextView = new TextView(actionMode.getContext()); + selectedMessagesCountTextView.setTextSize(18); + selectedMessagesCountTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + selectedMessagesCountTextView.setTextColor(0xff737373); + selectedMessagesCountTextView.setSingleLine(true); + selectedMessagesCountTextView.setLines(1); + selectedMessagesCountTextView.setEllipsize(TextUtils.TruncateAt.END); + selectedMessagesCountTextView.setPadding(AndroidUtilities.dp(11), 0, 0, AndroidUtilities.dp(2)); + selectedMessagesCountTextView.setGravity(Gravity.CENTER_VERTICAL); + selectedMessagesCountTextView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + actionMode.addView(selectedMessagesCountTextView); + layoutParams = (LinearLayout.LayoutParams) selectedMessagesCountTextView.getLayoutParams(); + layoutParams.weight = 1; + layoutParams.width = 0; + layoutParams.height = LinearLayout.LayoutParams.MATCH_PARENT; + selectedMessagesCountTextView.setLayoutParams(layoutParams); + + if (currentEncryptedChat == null) { + actionModeViews.add(actionMode.addItem(copy, R.drawable.ic_ab_fwd_copy, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); + if (!isBroadcast) { + actionModeViews.add(actionMode.addItem(reply, R.drawable.ic_ab_reply, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); + } + actionModeViews.add(actionMode.addItem(forward, R.drawable.ic_ab_fwd_forward, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); + actionModeViews.add(actionMode.addItem(delete, R.drawable.ic_ab_fwd_delete, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); + } else { + actionModeViews.add(actionMode.addItem(copy, R.drawable.ic_ab_fwd_copy, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); + actionModeViews.add(actionMode.addItem(delete, R.drawable.ic_ab_fwd_delete, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); + } + actionMode.getItem(copy).setVisibility(selectedMessagesCanCopyIds.size() != 0 ? View.VISIBLE : View.GONE); + if (actionMode.getItem(reply) != null) { + actionMode.getItem(reply).setVisibility(selectedMessagesIds.size() == 1 ? View.VISIBLE : View.GONE); + } + checkActionBarMenu(); + + fragmentView = new SizeNotifierRelativeLayout(context); + SizeNotifierRelativeLayout contentView = (SizeNotifierRelativeLayout) fragmentView; + + contentView.setBackgroundImage(ApplicationLoader.getCachedWallpaper()); + + emptyViewContainer = new FrameLayout(context); + emptyViewContainer.setPadding(0, 0, 0, AndroidUtilities.dp(48)); + emptyViewContainer.setVisibility(View.INVISIBLE); + contentView.addView(emptyViewContainer); + RelativeLayout.LayoutParams layoutParams3 = (RelativeLayout.LayoutParams) emptyViewContainer.getLayoutParams(); + layoutParams3.width = RelativeLayout.LayoutParams.MATCH_PARENT; + layoutParams3.height = RelativeLayout.LayoutParams.MATCH_PARENT; + emptyViewContainer.setLayoutParams(layoutParams3); + emptyViewContainer.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + if (currentEncryptedChat == null) { + TextView emptyView = new TextView(context); + if (currentUser != null && currentUser.id != 777000 && (currentUser.id / 1000 == 333 || currentUser.id % 1000 == 0)) { + emptyView.setText(LocaleController.getString("GotAQuestion", R.string.GotAQuestion)); + } else { + emptyView.setText(LocaleController.getString("NoMessages", R.string.NoMessages)); + } + emptyView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + emptyView.setGravity(Gravity.CENTER); + emptyView.setTextColor(0xffffffff); + emptyView.setBackgroundResource(ApplicationLoader.isCustomTheme() ? R.drawable.system_black : R.drawable.system_blue); + emptyView.setPadding(AndroidUtilities.dp(7), AndroidUtilities.dp(1), AndroidUtilities.dp(7), AndroidUtilities.dp(1)); + emptyViewContainer.addView(emptyView); + layoutParams2 = (FrameLayout.LayoutParams) emptyView.getLayoutParams(); + layoutParams2.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.gravity = Gravity.CENTER; + emptyView.setLayoutParams(layoutParams2); + } else { + LinearLayout secretChatPlaceholder = new LinearLayout(context); + secretChatPlaceholder.setBackgroundResource(ApplicationLoader.isCustomTheme() ? R.drawable.system_black : R.drawable.system_blue); + secretChatPlaceholder.setPadding(AndroidUtilities.dp(16), AndroidUtilities.dp(12), AndroidUtilities.dp(16), AndroidUtilities.dp(12)); + secretChatPlaceholder.setOrientation(LinearLayout.VERTICAL); + emptyViewContainer.addView(secretChatPlaceholder); + layoutParams2 = (FrameLayout.LayoutParams) secretChatPlaceholder.getLayoutParams(); + layoutParams2.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.gravity = Gravity.CENTER; + secretChatPlaceholder.setLayoutParams(layoutParams2); + + secretViewStatusTextView = new TextView(context); + secretViewStatusTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); + secretViewStatusTextView.setTextColor(0xffffffff); + secretViewStatusTextView.setGravity(Gravity.CENTER_HORIZONTAL); + secretViewStatusTextView.setMaxWidth(AndroidUtilities.dp(210)); + if (currentEncryptedChat.admin_id == UserConfig.getClientUserId()) { + if (currentUser.first_name.length() > 0) { + secretViewStatusTextView.setText(LocaleController.formatString("EncryptedPlaceholderTitleOutgoing", R.string.EncryptedPlaceholderTitleOutgoing, currentUser.first_name)); + } else { + secretViewStatusTextView.setText(LocaleController.formatString("EncryptedPlaceholderTitleOutgoing", R.string.EncryptedPlaceholderTitleOutgoing, currentUser.last_name)); + } + } else { + if (currentUser.first_name.length() > 0) { + secretViewStatusTextView.setText(LocaleController.formatString("EncryptedPlaceholderTitleIncoming", R.string.EncryptedPlaceholderTitleIncoming, currentUser.first_name)); + } else { + secretViewStatusTextView.setText(LocaleController.formatString("EncryptedPlaceholderTitleIncoming", R.string.EncryptedPlaceholderTitleIncoming, currentUser.last_name)); + } + } + secretChatPlaceholder.addView(secretViewStatusTextView); + layoutParams = (LinearLayout.LayoutParams) secretViewStatusTextView.getLayoutParams(); + layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.CENTER_HORIZONTAL; + secretViewStatusTextView.setLayoutParams(layoutParams); + + TextView textView = new TextView(context); + textView.setText(LocaleController.getString("EncryptedDescriptionTitle", R.string.EncryptedDescriptionTitle)); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); + textView.setTextColor(0xffffffff); + textView.setGravity(Gravity.CENTER_HORIZONTAL); + textView.setMaxWidth(AndroidUtilities.dp(260)); + secretChatPlaceholder.addView(textView); + layoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams(); + layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams.topMargin = AndroidUtilities.dp(8); + layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT; + textView.setLayoutParams(layoutParams); + + for (int a = 0; a < 4; a++) { + LinearLayout linearLayout = new LinearLayout(context); + linearLayout.setOrientation(LinearLayout.HORIZONTAL); + secretChatPlaceholder.addView(linearLayout); + layoutParams = (LinearLayout.LayoutParams) linearLayout.getLayoutParams(); + layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams.topMargin = AndroidUtilities.dp(8); + layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT; + linearLayout.setLayoutParams(layoutParams); + + ImageView imageView = new ImageView(context); + imageView.setImageResource(R.drawable.ic_lock_white); + + textView = new TextView(context); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); + textView.setTextColor(0xffffffff); + textView.setGravity(Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)); + textView.setMaxWidth(AndroidUtilities.dp(260)); + + switch (a) { + case 0: + textView.setText(LocaleController.getString("EncryptedDescription1", R.string.EncryptedDescription1)); + break; + case 1: + textView.setText(LocaleController.getString("EncryptedDescription2", R.string.EncryptedDescription2)); + break; + case 2: + textView.setText(LocaleController.getString("EncryptedDescription3", R.string.EncryptedDescription3)); + break; + case 3: + textView.setText(LocaleController.getString("EncryptedDescription4", R.string.EncryptedDescription4)); + break; + } + + if (LocaleController.isRTL) { + linearLayout.addView(textView); + linearLayout.addView(imageView); + } else { + linearLayout.addView(imageView); + linearLayout.addView(textView); + } + layoutParams = (LinearLayout.LayoutParams) imageView.getLayoutParams(); + layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams.rightMargin = LocaleController.isRTL ? 0 : AndroidUtilities.dp(8); + layoutParams.leftMargin = LocaleController.isRTL ? AndroidUtilities.dp(8) : 0; + layoutParams.topMargin = AndroidUtilities.dp(LocaleController.isRTL ? 3 : 4); + imageView.setLayoutParams(layoutParams); + + layoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams(); + layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; + textView.setLayoutParams(layoutParams); + } + } + + chatListView = new LayoutListView(context); + chatListView.setAdapter(chatAdapter = new ChatAdapter(context)); + chatListView.setCacheColorHint(ApplicationLoader.getSelectedColor()); + chatListView.setClipToPadding(false); + chatListView.setStackFromBottom(true); + chatListView.setPadding(0, AndroidUtilities.dp(4), 0, AndroidUtilities.dp(3)); + chatListView.setDivider(null); + chatListView.setSelector(R.drawable.transparent); + chatListView.setOnItemLongClickListener(onItemLongClickListener); + chatListView.setOnItemClickListener(onItemClickListener); + contentView.addView(chatListView); + layoutParams3 = (RelativeLayout.LayoutParams) chatListView.getLayoutParams(); + layoutParams3.width = RelativeLayout.LayoutParams.MATCH_PARENT; + layoutParams3.height = RelativeLayout.LayoutParams.MATCH_PARENT; + layoutParams3.bottomMargin = -AndroidUtilities.dp(3); + layoutParams3.addRule(RelativeLayout.ABOVE, id_chat_compose_panel); + chatListView.setLayoutParams(layoutParams3); + chatListView.setOnInterceptTouchEventListener(new LayoutListView.OnInterceptTouchEventListener() { + @Override + public boolean onInterceptTouchEvent(MotionEvent event) { + if (actionBar.isActionModeShowed()) { + return false; + } + if (event.getAction() == MotionEvent.ACTION_DOWN) { + int x = (int) event.getX(); + int y = (int) event.getY(); + int count = chatListView.getChildCount(); + Rect rect = new Rect(); + for (int a = 0; a < count; a++) { + View view = chatListView.getChildAt(a); + int top = view.getTop(); + int bottom = view.getBottom(); + view.getLocalVisibleRect(rect); + if (top > y || bottom < y) { + continue; + } + if (!(view instanceof ChatMediaCell)) { + break; + } + final ChatMediaCell cell = (ChatMediaCell) view; + final MessageObject messageObject = cell.getMessageObject(); + if (messageObject == null || !messageObject.isSecretPhoto() || !cell.getPhotoImage().isInsideImage(x, y - top)) { + break; + } + File file = FileLoader.getPathToMessage(messageObject.messageOwner); + if (!file.exists()) { + break; + } + startX = x; + startY = y; + chatListView.setOnItemClickListener(null); + openSecretPhotoRunnable = new Runnable() { + @Override + public void run() { + if (openSecretPhotoRunnable == null) { + return; + } + chatListView.requestDisallowInterceptTouchEvent(true); + chatListView.setOnItemLongClickListener(null); + chatListView.setLongClickable(false); + openSecretPhotoRunnable = null; + if (sendSecretMessageRead(messageObject)) { + cell.invalidate(); + } + SecretPhotoViewer.getInstance().setParentActivity(getParentActivity()); + SecretPhotoViewer.getInstance().openPhoto(messageObject); + } + }; + AndroidUtilities.runOnUIThread(openSecretPhotoRunnable, 100); + return true; + } + } + return false; + } + }); + chatListView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + if (openSecretPhotoRunnable != null || SecretPhotoViewer.getInstance().isVisible()) { + if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_POINTER_UP) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + chatListView.setOnItemClickListener(onItemClickListener); + } + }, 150); + if (openSecretPhotoRunnable != null) { + AndroidUtilities.cancelRunOnUIThread(openSecretPhotoRunnable); + openSecretPhotoRunnable = null; + try { + Toast.makeText(v.getContext(), LocaleController.getString("PhotoTip", R.string.PhotoTip), Toast.LENGTH_SHORT).show(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } else { + if (SecretPhotoViewer.getInstance().isVisible()) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + chatListView.setOnItemLongClickListener(onItemLongClickListener); + chatListView.setLongClickable(true); + } + }); + SecretPhotoViewer.getInstance().closePhoto(); + } + } + } else if (event.getAction() != MotionEvent.ACTION_DOWN) { + if (SecretPhotoViewer.getInstance().isVisible()) { + return true; + } else if (openSecretPhotoRunnable != null) { + if (event.getAction() == MotionEvent.ACTION_MOVE) { + if (Math.hypot(startX - event.getX(), startY - event.getY()) > AndroidUtilities.dp(5)) { + AndroidUtilities.cancelRunOnUIThread(openSecretPhotoRunnable); + openSecretPhotoRunnable = null; + } + } else { + AndroidUtilities.cancelRunOnUIThread(openSecretPhotoRunnable); + openSecretPhotoRunnable = null; + } + } + } + } + return false; + } + }); + chatListView.setOnScrollListener(new AbsListView.OnScrollListener() { + Rect scrollRect = new Rect(); + + @Override + public void onScrollStateChanged(AbsListView absListView, int i) { + if (i == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL || i == AbsListView.OnScrollListener.SCROLL_STATE_FLING && highlightMessageId != Integer.MAX_VALUE) { + highlightMessageId = Integer.MAX_VALUE; + updateVisibleRows(); + } + } + + @Override + public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { + if (visibleItemCount > 0) { + if (firstVisibleItem <= 10) { + if (!endReached && !loading) { + if (messagesByDays.size() != 0) { + MessagesController.getInstance().loadMessages(dialog_id, 20, maxMessageId, !cacheEndReaced && startLoadFromMessageId == 0, minDate, classGuid, 0, 0, 0, startLoadFromMessageId == 0); + } else { + MessagesController.getInstance().loadMessages(dialog_id, 20, 0, !cacheEndReaced && startLoadFromMessageId == 0, minDate, classGuid, 0, 0, 0, startLoadFromMessageId == 0); + } + loading = true; + } + } + if (firstVisibleItem + visibleItemCount >= totalItemCount - 6) { + if (!forward_end_reached && !loadingForward) { + MessagesController.getInstance().loadMessages(dialog_id, 20, minMessageId, startLoadFromMessageId == 0, maxDate, classGuid, 1, 0, 0, startLoadFromMessageId == 0); + loadingForward = true; + } + } + if (firstVisibleItem + visibleItemCount == totalItemCount && forward_end_reached) { + showPagedownButton(false, true); + } + } + for (int a = 0; a < visibleItemCount; a++) { + View view = absListView.getChildAt(a); + if (view instanceof ChatMessageCell) { + ChatMessageCell messageCell = (ChatMessageCell) view; + messageCell.getLocalVisibleRect(scrollRect); + messageCell.setVisiblePart(scrollRect.top, scrollRect.bottom - scrollRect.top); + } + } + } + }); + + progressView = new FrameLayout(context); + progressView.setVisibility(View.INVISIBLE); + progressView.setBackgroundResource(ApplicationLoader.isCustomTheme() ? R.drawable.system_loader2 : R.drawable.system_loader1); + contentView.addView(progressView); + layoutParams3 = (RelativeLayout.LayoutParams) progressView.getLayoutParams(); + layoutParams3.width = AndroidUtilities.dp(36); + layoutParams3.height = AndroidUtilities.dp(36); + layoutParams3.bottomMargin = AndroidUtilities.dp(48); + layoutParams3.addRule(RelativeLayout.CENTER_IN_PARENT); + progressView.setLayoutParams(layoutParams3); + + ProgressBar progressBar = new ProgressBar(context); + try { + progressBar.setIndeterminateDrawable(context.getResources().getDrawable(R.drawable.loading_animation)); + } catch (Exception e) { + //don't promt + } + progressBar.setIndeterminate(true); + AndroidUtilities.setProgressBarAnimationDuration(progressBar, 1500); + progressView.addView(progressBar); + layoutParams2 = (FrameLayout.LayoutParams) progressBar.getLayoutParams(); + layoutParams2.width = AndroidUtilities.dp(32); + layoutParams2.height = AndroidUtilities.dp(32); + layoutParams2.gravity = Gravity.CENTER; + progressBar.setLayoutParams(layoutParams2); + + if (currentEncryptedChat == null && !isBroadcast) { + mentionListView = new ListView(context); + mentionListView.setBackgroundResource(R.drawable.compose_panel); + mentionListView.setVisibility(View.GONE); + mentionListView.setPadding(0, AndroidUtilities.dp(2), 0, 0); + mentionListView.setClipToPadding(true); + mentionListView.setDividerHeight(0); + mentionListView.setDivider(null); + if (Build.VERSION.SDK_INT > 8) { + mentionListView.setOverScrollMode(ListView.OVER_SCROLL_NEVER); + } + contentView.addView(mentionListView); + layoutParams3 = (RelativeLayout.LayoutParams) mentionListView.getLayoutParams(); + layoutParams3.width = RelativeLayout.LayoutParams.MATCH_PARENT; + layoutParams3.height = AndroidUtilities.dp(110); + layoutParams3.topMargin = -AndroidUtilities.dp(108); + layoutParams3.addRule(RelativeLayout.ALIGN_TOP, id_chat_compose_panel); + mentionListView.setLayoutParams(layoutParams3); + + mentionListView.setAdapter(mentionsAdapter = new MentionsAdapter(context, new MentionsAdapter.MentionsAdapterDelegate() { + @Override + public void needChangePanelVisibility(boolean show) { + if (show) { + RelativeLayout.LayoutParams layoutParams3 = (RelativeLayout.LayoutParams) mentionListView.getLayoutParams(); + int height = 36 * Math.min(3, mentionsAdapter.getCount()) + (mentionsAdapter.getCount() > 3 ? 18 : 0); + layoutParams3.height = AndroidUtilities.dp(2 + height); + layoutParams3.topMargin = -AndroidUtilities.dp(height); + mentionListView.setLayoutParams(layoutParams3); + + if (mentionListAnimation != null) { + mentionListAnimation.cancel(); + mentionListAnimation = null; + } + + if (mentionListView.getVisibility() == View.VISIBLE) { + ViewProxy.setAlpha(mentionListView, 1.0f); + return; + } + if (allowStickersPanel) { + mentionListView.setVisibility(View.VISIBLE); + mentionListAnimation = new AnimatorSetProxy(); + mentionListAnimation.playTogether( + ObjectAnimatorProxy.ofFloat(mentionListView, "alpha", 0.0f, 1.0f) + ); + mentionListAnimation.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + if (mentionListAnimation != null && mentionListAnimation.equals(animation)) { + mentionListView.clearAnimation(); + mentionListAnimation = null; + } + } + }); + mentionListAnimation.setDuration(200); + mentionListAnimation.start(); + } else { + ViewProxy.setAlpha(mentionListView, 1.0f); + mentionListView.clearAnimation(); + mentionListView.setVisibility(View.INVISIBLE); + } + } else { + if (mentionListAnimation != null) { + mentionListAnimation.cancel(); + mentionListAnimation = null; + } + + if (mentionListView.getVisibility() == View.GONE) { + return; + } + if (allowStickersPanel) { + mentionListAnimation = new AnimatorSetProxy(); + mentionListAnimation.playTogether( + ObjectAnimatorProxy.ofFloat(mentionListView, "alpha", 0.0f) + ); + mentionListAnimation.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + if (mentionListAnimation != null && mentionListAnimation.equals(animation)) { + mentionListView.clearAnimation(); + mentionListView.setVisibility(View.GONE); + mentionListAnimation = null; + } + } + }); + mentionListAnimation.setDuration(200); + mentionListAnimation.start(); + } else { + mentionListView.clearAnimation(); + mentionListView.setVisibility(View.GONE); + } + } + } + })); + mentionsAdapter.setChatInfo(info); + mentionsAdapter.setNeedUsernames(currentChat != null); + + mentionListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Object object = mentionsAdapter.getItem(position); + int start = mentionsAdapter.getResultStartPosition(); + int len = mentionsAdapter.getResultLength(); + if (object instanceof TLRPC.User) { + TLRPC.User user = (TLRPC.User) object; + if (user != null) { + chatActivityEnterView.replaceWithText(start, len, "@" + user.username + " "); + } + } else if (object instanceof String) { + chatActivityEnterView.replaceWithText(start, len, object + " "); + } } }); - updateBottomOverlay(); - - chatActivityEnterView.setContainerView(getParentActivity(), fragmentView); - chatActivityEnterView.addToAttachLayout(menuItem); - - if (currentEncryptedChat != null) { - emptyView.setVisibility(View.INVISIBLE); - View secretChatPlaceholder = contentView.findViewById(R.id.secret_placeholder); - secretChatPlaceholder.setVisibility(View.VISIBLE); - if (isCustomTheme) { - secretChatPlaceholder.setBackgroundResource(R.drawable.system_black); - } else { - secretChatPlaceholder.setBackgroundResource(R.drawable.system_blue); - } - secretViewStatusTextView = (TextView) contentView.findViewById(R.id.invite_text); - secretChatPlaceholder.setPadding(AndroidUtilities.dp(16), AndroidUtilities.dp(12), AndroidUtilities.dp(16), AndroidUtilities.dp(12)); - - View v = contentView.findViewById(R.id.secret_placeholder); - v.setVisibility(View.VISIBLE); - - if (currentEncryptedChat.admin_id == UserConfig.getClientUserId()) { - if (currentUser.first_name.length() > 0) { - secretViewStatusTextView.setText(LocaleController.formatString("EncryptedPlaceholderTitleOutgoing", R.string.EncryptedPlaceholderTitleOutgoing, currentUser.first_name)); - } else { - secretViewStatusTextView.setText(LocaleController.formatString("EncryptedPlaceholderTitleOutgoing", R.string.EncryptedPlaceholderTitleOutgoing, currentUser.last_name)); - } - } else { - if (currentUser.first_name.length() > 0) { - secretViewStatusTextView.setText(LocaleController.formatString("EncryptedPlaceholderTitleIncoming", R.string.EncryptedPlaceholderTitleIncoming, currentUser.first_name)); - } else { - secretViewStatusTextView.setText(LocaleController.formatString("EncryptedPlaceholderTitleIncoming", R.string.EncryptedPlaceholderTitleIncoming, currentUser.last_name)); + mentionListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { + Object object = mentionsAdapter.getItem(position); + if (object instanceof String) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setMessage(LocaleController.getString("ClearSearch", R.string.ClearSearch)); + builder.setPositiveButton(LocaleController.getString("ClearButton", R.string.ClearButton).toUpperCase(), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + mentionsAdapter.clearRecentHashtags(); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + return true; } + return false; } + }); + } - updateSecretStatus(); + if (chatActivityEnterView != null) { + chatActivityEnterView.onDestroy(); + } + chatActivityEnterView = new ChatActivityEnterView(getParentActivity(), contentView, this, true); + chatActivityEnterView.setDialogId(dialog_id); + chatActivityEnterView.addToAttachLayout(menuItem); + chatActivityEnterView.setId(id_chat_compose_panel); + contentView.addView(chatActivityEnterView); + layoutParams3 = (RelativeLayout.LayoutParams) chatActivityEnterView.getLayoutParams(); + layoutParams3.width = RelativeLayout.LayoutParams.MATCH_PARENT; + layoutParams3.height = RelativeLayout.LayoutParams.WRAP_CONTENT; + layoutParams3.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); + chatActivityEnterView.setLayoutParams(layoutParams3); + chatActivityEnterView.setDelegate(new ChatActivityEnterView.ChatActivityEnterViewDelegate() { + @Override + public void onMessageSend(String message) { + moveScrollToLastMessage(); + showReplyPanel(false, null, null, null, false, true); + if (mentionsAdapter != null) { + mentionsAdapter.addHashtagsFromMessage(message); + } + if (message != null) { + NotificationsController.getInstance().playOutChatSound(); + } } + + @Override + public void onTextChanged(final CharSequence text, boolean bigChange) { + if (stickersAdapter != null) { + stickersAdapter.loadStikersForEmoji(text); + } + if (mentionsAdapter != null) { + mentionsAdapter.searchUsernameOrHashtag(text.toString(), chatActivityEnterView.getCursorPosition(), messages); + } + if (waitingForCharaterEnterRunnable != null) { + AndroidUtilities.cancelRunOnUIThread(waitingForCharaterEnterRunnable); + waitingForCharaterEnterRunnable = null; + } + if (bigChange) { + searchLinks(text, true); + } else { + waitingForCharaterEnterRunnable = new Runnable() { + @Override + public void run() { + if (this == waitingForCharaterEnterRunnable) { + searchLinks(text, false); + waitingForCharaterEnterRunnable = null; + } + } + }; + AndroidUtilities.runOnUIThread(waitingForCharaterEnterRunnable, 1000); + } + } + + @Override + public void needSendTyping() { + MessagesController.getInstance().sendTyping(dialog_id, classGuid); + } + + @Override + public void onAttachButtonHidden() { + if (attachItem != null) { + attachItem.setVisibility(View.VISIBLE); + } + if (headerItem != null) { + headerItem.setVisibility(View.INVISIBLE); + } + } + + @Override + public void onAttachButtonShow() { + if (attachItem != null) { + attachItem.setVisibility(View.INVISIBLE); + } + if (headerItem != null) { + headerItem.setVisibility(View.VISIBLE); + } + } + + @Override + public void onWindowSizeChanged(int size) { + if (size < AndroidUtilities.dp(72) + AndroidUtilities.getCurrentActionBarHeight()) { + allowStickersPanel = false; + if (stickersPanel.getVisibility() == View.VISIBLE) { + stickersPanel.clearAnimation(); + stickersPanel.setVisibility(View.INVISIBLE); + } + if (mentionListView != null && mentionListView.getVisibility() == View.VISIBLE) { + mentionListView.clearAnimation(); + mentionListView.setVisibility(View.INVISIBLE); + } + } else { + allowStickersPanel = true; + if (stickersPanel.getVisibility() == View.INVISIBLE) { + stickersPanel.clearAnimation(); + stickersPanel.setVisibility(View.VISIBLE); + } + if (mentionListView != null && mentionListView.getVisibility() == View.INVISIBLE) { + mentionListView.clearAnimation(); + mentionListView.setVisibility(View.VISIBLE); + } + } + } + }); + + FrameLayout replyLayout = new FrameLayout(context); + replyLayout.setClickable(true); + chatActivityEnterView.addTopView(replyLayout, AndroidUtilities.dp(48)); + + View lineView = new View(context); + lineView.setBackgroundColor(0xffe8e8e8); + replyLayout.addView(lineView); + layoutParams2 = (FrameLayout.LayoutParams) lineView.getLayoutParams(); + layoutParams2.gravity = Gravity.BOTTOM; + layoutParams2.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams2.height = AndroidUtilities.dp(1); + lineView.setLayoutParams(layoutParams2); + + replyIconImageView = new ImageView(context); + replyIconImageView.setScaleType(ImageView.ScaleType.CENTER); + replyLayout.addView(replyIconImageView); + layoutParams2 = (FrameLayout.LayoutParams) replyIconImageView.getLayoutParams(); + layoutParams2.gravity = Gravity.TOP | Gravity.LEFT; + layoutParams2.width = AndroidUtilities.dp(52); + layoutParams2.height = AndroidUtilities.dp(46); + replyIconImageView.setLayoutParams(layoutParams2); + + ImageView imageView = new ImageView(context); + imageView.setImageResource(R.drawable.delete_reply); + imageView.setScaleType(ImageView.ScaleType.CENTER); + replyLayout.addView(imageView); + layoutParams2 = (FrameLayout.LayoutParams) imageView.getLayoutParams(); + layoutParams2.topMargin = AndroidUtilities.dp(0.5f); + layoutParams2.width = AndroidUtilities.dp(52); + layoutParams2.height = AndroidUtilities.dp(46); + layoutParams2.gravity = Gravity.RIGHT | Gravity.TOP; + imageView.setLayoutParams(layoutParams2); + imageView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (forwardingMessages != null) { + forwardingMessages.clear(); + } + showReplyPanel(false, null, null, foundWebPage, true, true); + } + }); + + replyNameTextView = new TextView(context); + replyNameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + replyNameTextView.setTextColor(0xff377aae); + replyNameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + replyNameTextView.setSingleLine(true); + replyNameTextView.setEllipsize(TextUtils.TruncateAt.END); + replyNameTextView.setMaxLines(1); + replyLayout.addView(replyNameTextView); + layoutParams2 = (FrameLayout.LayoutParams) replyNameTextView.getLayoutParams(); + layoutParams2.leftMargin = AndroidUtilities.dp(52); + layoutParams2.rightMargin = AndroidUtilities.dp(52); + layoutParams2.topMargin = AndroidUtilities.dp(4); + layoutParams2.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.gravity = Gravity.TOP | Gravity.LEFT; + replyNameTextView.setLayoutParams(layoutParams2); + + replyObjectTextView = new TextView(context); + replyObjectTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + replyObjectTextView.setTextColor(0xff999999); + replyObjectTextView.setSingleLine(true); + replyObjectTextView.setEllipsize(TextUtils.TruncateAt.END); + replyObjectTextView.setMaxLines(1); + replyLayout.addView(replyObjectTextView); + layoutParams2 = (FrameLayout.LayoutParams) replyObjectTextView.getLayoutParams(); + layoutParams2.leftMargin = AndroidUtilities.dp(52); + layoutParams2.rightMargin = AndroidUtilities.dp(52); + layoutParams2.topMargin = AndroidUtilities.dp(22); + layoutParams2.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.gravity = Gravity.TOP | Gravity.LEFT; + replyObjectTextView.setLayoutParams(layoutParams2); + + replyImageView = new BackupImageView(context); + replyLayout.addView(replyImageView); + layoutParams2 = (FrameLayout.LayoutParams) replyImageView.getLayoutParams(); + layoutParams2.leftMargin = AndroidUtilities.dp(52); + layoutParams2.topMargin = AndroidUtilities.dp(6); + layoutParams2.width = AndroidUtilities.dp(34); + layoutParams2.height = AndroidUtilities.dp(34); + layoutParams2.gravity = Gravity.TOP | Gravity.LEFT; + replyImageView.setLayoutParams(layoutParams2); + + stickersPanel = new FrameLayout(context); + stickersPanel.setVisibility(View.GONE); + contentView.addView(stickersPanel); + layoutParams3 = (RelativeLayout.LayoutParams) stickersPanel.getLayoutParams(); + layoutParams3.width = RelativeLayout.LayoutParams.WRAP_CONTENT; + layoutParams3.height = AndroidUtilities.dp(81.5f); + layoutParams3.bottomMargin = AndroidUtilities.dp(38); + layoutParams3.addRule(RelativeLayout.ALIGN_BOTTOM, id_chat_compose_panel); + stickersPanel.setLayoutParams(layoutParams3); + + stickersListView = new RecyclerListView(context); + LinearLayoutManager layoutManager = new LinearLayoutManager(context); + layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); + stickersListView.setLayoutManager(layoutManager); + stickersListView.setClipToPadding(false); + if (Build.VERSION.SDK_INT >= 9) { + stickersListView.setOverScrollMode(RecyclerListView.OVER_SCROLL_NEVER); + } + stickersPanel.addView(stickersListView); + layoutParams2 = (FrameLayout.LayoutParams) stickersListView.getLayoutParams(); + layoutParams2.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams2.height = AndroidUtilities.dp(78); + stickersListView.setLayoutParams(layoutParams2); + if (currentEncryptedChat == null || currentEncryptedChat != null && AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 23) { + if (stickersAdapter != null) { + stickersAdapter.destroy(); + } + stickersListView.setPadding(AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18), 0); + stickersListView.setAdapter(stickersAdapter = new StickersAdapter(context, new StickersAdapter.StickersAdapterDelegate() { + @Override + public void needChangePanelVisibility(final boolean show) { + if (show && stickersPanel.getVisibility() == View.VISIBLE || !show && stickersPanel.getVisibility() == View.GONE) { + return; + } + if (show) { + stickersListView.scrollToPosition(0); + stickersPanel.clearAnimation(); + stickersPanel.setVisibility(allowStickersPanel ? View.VISIBLE : View.INVISIBLE); + } + if (runningAnimation != null) { + runningAnimation.cancel(); + runningAnimation = null; + } + if (stickersPanel.getVisibility() != View.INVISIBLE) { + runningAnimation = new AnimatorSetProxy(); + runningAnimation.playTogether( + ObjectAnimatorProxy.ofFloat(stickersPanel, "alpha", show ? 0.0f : 1.0f, show ? 1.0f : 0.0f) + ); + runningAnimation.setDuration(150); + runningAnimation.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + if (runningAnimation != null && runningAnimation.equals(animation)) { + if (!show) { + stickersAdapter.clearStickers(); + stickersPanel.clearAnimation(); + stickersPanel.setVisibility(View.GONE); + } + runningAnimation = null; + } + } + }); + runningAnimation.start(); + } else if (!show) { + stickersPanel.setVisibility(View.GONE); + } + } + })); + stickersListView.addOnItemTouchListener(new RecyclerListView.RecyclerListViewItemClickListener(context, new RecyclerListView.OnItemClickListener() { + @Override + public void onItemClick(View view, int position) { + TLRPC.Document document = stickersAdapter.getItem(position); + if (document instanceof TLRPC.TL_document) { + if (currentEncryptedChat != null && document.thumb instanceof TLRPC.TL_photoSize) { + File file = FileLoader.getPathToAttach(document.thumb, true); + if (file.exists()) { + try { + int len = (int) file.length(); + byte[] arr = new byte[(int) file.length()]; + RandomAccessFile reader = new RandomAccessFile(file, "r"); + reader.readFully(arr); + TLRPC.TL_document newDocument = new TLRPC.TL_document(); + newDocument.thumb = new TLRPC.TL_photoCachedSize(); + newDocument.thumb.location = document.thumb.location; + newDocument.thumb.size = document.thumb.size; + newDocument.thumb.w = document.thumb.w; + newDocument.thumb.h = document.thumb.h; + newDocument.thumb.type = document.thumb.type; + newDocument.thumb.bytes = arr; + + newDocument.id = document.id; + newDocument.access_hash = document.access_hash; + newDocument.date = document.date; + newDocument.mime_type = document.mime_type; + newDocument.size = document.size; + newDocument.dc_id = document.dc_id; + newDocument.attributes = document.attributes; + document = newDocument; + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + } + for (int a = 0; a < document.attributes.size(); a++) { + TLRPC.DocumentAttribute attribute = document.attributes.get(a); + if (attribute instanceof TLRPC.TL_documentAttributeSticker) { + document.attributes.remove(a); + document.attributes.add(new TLRPC.TL_documentAttributeSticker_old()); + break; + } + } + SendMessagesHelper.getInstance().sendMessage((TLRPC.TL_document) document, null, null, dialog_id, replyingMessageObject); + showReplyPanel(false, null, null, null, false, true); + } + chatActivityEnterView.setFieldText(""); + } + })); + } + + imageView = new ImageView(context); + imageView.setImageResource(R.drawable.stickers_back_arrow); + stickersPanel.addView(imageView); + layoutParams2 = (FrameLayout.LayoutParams) imageView.getLayoutParams(); + layoutParams2.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.gravity = Gravity.BOTTOM; + layoutParams2.leftMargin = AndroidUtilities.dp(53); + imageView.setLayoutParams(layoutParams2); + + bottomOverlay = new FrameLayout(context); + bottomOverlay.setBackgroundColor(0xffffffff); + bottomOverlay.setVisibility(View.INVISIBLE); + bottomOverlay.setFocusable(true); + bottomOverlay.setFocusableInTouchMode(true); + bottomOverlay.setClickable(true); + contentView.addView(bottomOverlay); + layoutParams3 = (RelativeLayout.LayoutParams) bottomOverlay.getLayoutParams(); + layoutParams3.width = RelativeLayout.LayoutParams.MATCH_PARENT; + layoutParams3.height = AndroidUtilities.dp(48); + layoutParams3.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); + bottomOverlay.setLayoutParams(layoutParams3); + + bottomOverlayText = new TextView(context); + bottomOverlayText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + bottomOverlayText.setTextColor(0xff7f7f7f); + bottomOverlay.addView(bottomOverlayText); + layoutParams2 = (FrameLayout.LayoutParams) bottomOverlayText.getLayoutParams(); + layoutParams2.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.gravity = Gravity.CENTER; + bottomOverlayText.setLayoutParams(layoutParams2); + + bottomOverlayChat = new FrameLayout(context); + bottomOverlayChat.setBackgroundColor(0xfffbfcfd); + bottomOverlayChat.setVisibility(View.INVISIBLE); + contentView.addView(bottomOverlayChat); + layoutParams3 = (RelativeLayout.LayoutParams) bottomOverlayChat.getLayoutParams(); + layoutParams3.width = RelativeLayout.LayoutParams.MATCH_PARENT; + layoutParams3.height = AndroidUtilities.dp(48); + layoutParams3.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); + bottomOverlayChat.setLayoutParams(layoutParams3); + bottomOverlayChat.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (getParentActivity() == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + if (currentUser != null && userBlocked) { + builder.setMessage(LocaleController.getString("AreYouSureUnblockContact", R.string.AreYouSureUnblockContact)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + MessagesController.getInstance().unblockUser(currentUser.id); + } + }); + } else { + builder.setMessage(LocaleController.getString("AreYouSureDeleteThisChat", R.string.AreYouSureDeleteThisChat)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + MessagesController.getInstance().deleteDialog(dialog_id, 0, false); + finishFragment(); + } + }); + } + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } + }); + + bottomOverlayChatText = new TextView(context); + bottomOverlayChatText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + bottomOverlayChatText.setTextColor(0xff3e6fa1); + bottomOverlayChat.addView(bottomOverlayChatText); + layoutParams2 = (FrameLayout.LayoutParams) bottomOverlayChatText.getLayoutParams(); + layoutParams2.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.gravity = Gravity.CENTER; + bottomOverlayChatText.setLayoutParams(layoutParams2); + + pagedownButton = new ImageView(context); + pagedownButton.setVisibility(View.INVISIBLE); + pagedownButton.setImageResource(R.drawable.pagedown); + contentView.addView(pagedownButton); + layoutParams3 = (RelativeLayout.LayoutParams) pagedownButton.getLayoutParams(); + layoutParams3.width = RelativeLayout.LayoutParams.WRAP_CONTENT; + layoutParams3.height = RelativeLayout.LayoutParams.WRAP_CONTENT; + layoutParams3.rightMargin = AndroidUtilities.dp(6); + layoutParams3.bottomMargin = AndroidUtilities.dp(4); + layoutParams3.addRule(RelativeLayout.ABOVE, id_chat_compose_panel); + layoutParams3.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); + pagedownButton.setLayoutParams(layoutParams3); + pagedownButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (returnToMessageId > 0) { + scrollToMessageId(returnToMessageId, 0, true); + } else { + scrollToLastMessage(); + } + } + }); + + if (loading && messages.isEmpty()) { + progressView.setVisibility(View.VISIBLE); + chatListView.setEmptyView(null); } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); + progressView.setVisibility(View.INVISIBLE); + chatListView.setEmptyView(emptyViewContainer); + } + + updateContactStatus(); + updateBottomOverlay(); + updateSecretStatus(); + + return fragmentView; + } + + private void searchLinks(CharSequence charSequence, boolean force) { + if (currentEncryptedChat != null) { + return; + } + if (linkSearchRequestId != 0) { + ConnectionsManager.getInstance().cancelRpc(linkSearchRequestId, true); + linkSearchRequestId = 0; + } + if (force && foundWebPage != null) { + if (foundWebPage.url != null) { + int index = TextUtils.indexOf(charSequence, foundWebPage.url); + char lastChar; + boolean lenEqual; + if (index == -1) { + index = TextUtils.indexOf(charSequence, foundWebPage.display_url); + lenEqual = index != -1 && index + foundWebPage.display_url.length() == charSequence.length(); + lastChar = index != -1 && !lenEqual ? charSequence.charAt(index + foundWebPage.display_url.length()) : 0; + } else { + lenEqual = index != -1 && index + foundWebPage.url.length() == charSequence.length(); + lastChar = index != -1 && !lenEqual ? charSequence.charAt(index + foundWebPage.url.length()) : 0; + } + if (index != -1 && (lenEqual || lastChar == ' ' || lastChar == ',' || lastChar == '.' || lastChar == '!' || lastChar == '/')) { + return; + } + } + pendingLinkSearchString = null; + showReplyPanel(false, null, null, foundWebPage, false, true); + } + if (charSequence.length() == 0 || TextUtils.indexOf(charSequence, "http") == -1 && TextUtils.indexOf(charSequence, ".com/") == -1) { + return; + } + final TLRPC.TL_messages_getWebPagePreview req = new TLRPC.TL_messages_getWebPagePreview(); + if (charSequence instanceof String) { + req.message = (String) charSequence; + } else { + req.message = charSequence.toString(); + } + linkSearchRequestId = 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() { + linkSearchRequestId = 0; + if (error == null) { + if (response instanceof TLRPC.TL_messageMediaWebPage) { + foundWebPage = ((TLRPC.TL_messageMediaWebPage) response).webpage; + if (foundWebPage instanceof TLRPC.TL_webPage || foundWebPage instanceof TLRPC.TL_webPagePending) { + if (foundWebPage instanceof TLRPC.TL_webPagePending) { + pendingLinkSearchString = req.message; + } + showReplyPanel(true, null, null, foundWebPage, false, true); + } else { + if (foundWebPage != null) { + showReplyPanel(false, null, null, foundWebPage, false, true); + foundWebPage = null; + } + } + } else { + if (foundWebPage != null) { + showReplyPanel(false, null, null, foundWebPage, false, true); + foundWebPage = null; + } + } + } + } + }); + } + }); + ConnectionsManager.getInstance().bindRequestToGuid(linkSearchRequestId, classGuid); + } + + private void forwardMessages(ArrayList arrayList, boolean fromMyName) { + if (arrayList == null || arrayList.isEmpty()) { + return; + } + if (!fromMyName) { + SendMessagesHelper.getInstance().sendMessage(arrayList, dialog_id); + } else { + for (MessageObject object : arrayList) { + SendMessagesHelper.getInstance().processForwardFromMyName(object, dialog_id); } } - return fragmentView; + } + + public void showReplyPanel(boolean show, MessageObject messageObject, ArrayList messageObjects, TLRPC.WebPage webPage, boolean cancel, boolean animated) { + if (show) { + if (messageObject == null && messageObjects == null && webPage == null) { + return; + } + if (messageObject != null) { + TLRPC.User user = MessagesController.getInstance().getUser(messageObject.messageOwner.from_id); + if (user == null) { + return; + } + forwardingMessages = null; + replyingMessageObject = messageObject; + chatActivityEnterView.setReplyingMessageObject(messageObject); + + if (foundWebPage != null) { + return; + } + replyIconImageView.setImageResource(R.drawable.reply); + replyNameTextView.setText(ContactsController.formatName(user.first_name, user.last_name)); + if (messageObject.messageText != null) { + String mess = messageObject.messageText.toString(); + if (mess.length() > 150) { + mess = mess.substring(0, 150); + } + mess = mess.replace("\n", " "); + replyObjectTextView.setText(Emoji.replaceEmoji(mess, replyObjectTextView.getPaint().getFontMetricsInt(), AndroidUtilities.dp(14))); + } + } else if (messageObjects != null) { + if (messageObjects.isEmpty()) { + return; + } + replyingMessageObject = null; + chatActivityEnterView.setReplyingMessageObject(null); + forwardingMessages = messageObjects; + + if (foundWebPage != null) { + return; + } + chatActivityEnterView.setForceShowSendButton(true, animated); + ArrayList uids = new ArrayList<>(); + replyIconImageView.setImageResource(R.drawable.forward_blue); + uids.add(messageObjects.get(0).messageOwner.from_id); + int type = messageObjects.get(0).type; + for (int a = 1; a < messageObjects.size(); a++) { + Integer uid = messageObjects.get(a).messageOwner.from_id; + if (!uids.contains(uid)) { + uids.add(uid); + } + if (messageObjects.get(a).type != type) { + type = -1; + } + } + StringBuilder userNames = new StringBuilder(); + for (int a = 0; a < uids.size(); a++) { + Integer uid = uids.get(a); + TLRPC.User user = MessagesController.getInstance().getUser(uid); + if (user == null) { + continue; + } + if (uids.size() == 1) { + userNames.append(ContactsController.formatName(user.first_name, user.last_name)); + } else if (uids.size() == 2 || userNames.length() == 0) { + if (userNames.length() > 0) { + userNames.append(", "); + } + if (user.first_name != null && user.first_name.length() > 0) { + userNames.append(user.first_name); + } else if (user.last_name != null && user.last_name.length() > 0) { + userNames.append(user.last_name); + } else { + userNames.append(" "); + } + } else { + userNames.append(" "); + userNames.append(LocaleController.formatPluralString("AndOther", uids.size() - 1)); + break; + } + } + replyNameTextView.setText(userNames); + if (type == -1 || type == 0) { + if (messageObjects.size() == 1 && messageObjects.get(0).messageText != null) { + String mess = messageObjects.get(0).messageText.toString(); + if (mess.length() > 150) { + mess = mess.substring(0, 150); + } + mess = mess.replace("\n", " "); + replyObjectTextView.setText(Emoji.replaceEmoji(mess, replyObjectTextView.getPaint().getFontMetricsInt(), AndroidUtilities.dp(14))); + } else { + replyObjectTextView.setText(LocaleController.formatPluralString("ForwardedMessage", messageObjects.size())); + } + } else { + if (type == 1) { + replyObjectTextView.setText(LocaleController.formatPluralString("ForwardedPhoto", messageObjects.size())); + if (messageObjects.size() == 1) { + messageObject = messageObjects.get(0); + } + } else if (type == 4) { + replyObjectTextView.setText(LocaleController.formatPluralString("ForwardedLocation", messageObjects.size())); + } else if (type == 3) { + replyObjectTextView.setText(LocaleController.formatPluralString("ForwardedVideo", messageObjects.size())); + if (messageObjects.size() == 1) { + messageObject = messageObjects.get(0); + } + } else if (type == 12) { + replyObjectTextView.setText(LocaleController.formatPluralString("ForwardedContact", messageObjects.size())); + } else if (type == 2) { + replyObjectTextView.setText(LocaleController.formatPluralString("ForwardedAudio", messageObjects.size())); + } else if (type == 13) { + replyObjectTextView.setText(LocaleController.formatPluralString("ForwardedSticker", messageObjects.size())); + } else if (type == 8 || type == 9) { + if (messageObjects.size() == 1) { + String name = null; + if ((name = FileLoader.getDocumentFileName(messageObjects.get(0).messageOwner.media.document)).length() != 0) { + replyObjectTextView.setText(name); + } + messageObject = messageObjects.get(0); + } else { + replyObjectTextView.setText(LocaleController.formatPluralString("ForwardedFile", messageObjects.size())); + } + } + } + } else if (webPage != null) { + replyIconImageView.setImageResource(R.drawable.link); + if (webPage instanceof TLRPC.TL_webPagePending) { + replyNameTextView.setText(LocaleController.getString("GettingLinkInfo", R.string.GettingLinkInfo)); + replyObjectTextView.setText(pendingLinkSearchString); + } else { + if (webPage.site_name != null) { + replyNameTextView.setText(webPage.site_name); + } else if (webPage.title != null) { + replyNameTextView.setText(webPage.title); + } + if (webPage.description != null) { + replyObjectTextView.setText(webPage.description); + } else if (webPage.title != null && webPage.site_name != null) { + replyObjectTextView.setText(webPage.title); + } else if (webPage.author != null) { + replyObjectTextView.setText(webPage.author); + } else { + replyObjectTextView.setText(webPage.display_url); + } + chatActivityEnterView.setWebPage(webPage, true); + } + } + FrameLayout.LayoutParams layoutParams1 = (FrameLayout.LayoutParams) replyNameTextView.getLayoutParams(); + FrameLayout.LayoutParams layoutParams2 = (FrameLayout.LayoutParams) replyObjectTextView.getLayoutParams(); + TLRPC.PhotoSize photoSize = messageObject != null ? FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 80) : null; + if (photoSize == null || messageObject != null && messageObject.type == 13) { + replyImageView.setImageBitmap(null); + replyImageLocation = null; + replyImageView.setVisibility(View.INVISIBLE); + layoutParams1.leftMargin = layoutParams2.leftMargin = AndroidUtilities.dp(52); + } else { + replyImageLocation = photoSize.location; + replyImageView.setImage(replyImageLocation, "50_50", (Drawable) null); + replyImageView.setVisibility(View.VISIBLE); + layoutParams1.leftMargin = layoutParams2.leftMargin = AndroidUtilities.dp(96); + } + replyNameTextView.setLayoutParams(layoutParams1); + replyObjectTextView.setLayoutParams(layoutParams2); + chatActivityEnterView.showTopView(animated); + } else { + if (replyingMessageObject == null && forwardingMessages == null && foundWebPage == null) { + return; + } + if (foundWebPage != null) { + foundWebPage = null; + chatActivityEnterView.setWebPage(null, !cancel); + if (webPage != null && (replyingMessageObject != null || forwardingMessages != null)) { + showReplyPanel(true, replyingMessageObject, forwardingMessages, null, false, true); + return; + } + } + if (forwardingMessages != null) { + forwardMessages(forwardingMessages, false); + } + chatActivityEnterView.setForceShowSendButton(false, animated); + chatActivityEnterView.hideTopView(animated); + chatActivityEnterView.setReplyingMessageObject(null); + replyingMessageObject = null; + forwardingMessages = null; + replyImageLocation = null; + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + preferences.edit().remove("reply_" + dialog_id).commit(); + } + } + + private void moveScrollToLastMessage() { + if (chatListView != null) { + chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop()); + chatListView.setForceTop(-100000 - chatListView.getPaddingTop()); + chatListView.post(new Runnable() { + @Override + public void run() { + chatListView.setForceTop(-100000 - chatListView.getPaddingTop()); + chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop()); + } + }); + } } private boolean sendSecretMessageRead(MessageObject messageObject) { @@ -1496,17 +2276,86 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not forward_end_reached = true; loading = true; startLoadFromMessageId = 0; + needSelectFromMessageId = false; chatAdapter.notifyDataSetChanged(); MessagesController.getInstance().loadMessages(dialog_id, 30, 0, true, 0, classGuid, 0, 0, 0, true); } } + private void scrollToMessageId(int id, int fromMessageId, boolean select) { + returnToMessageId = fromMessageId; + needSelectFromMessageId = select; + + MessageObject object = messagesDict.get(id); + boolean query = false; + if (object != null) { + int index = messages.indexOf(object); + if (index != -1) { + if (needSelectFromMessageId) { + highlightMessageId = id; + } else { + highlightMessageId = Integer.MAX_VALUE; + } + final int yOffset = Math.max(0, (chatListView.getHeight() - object.getApproximateHeight()) / 2); + if (messages.get(messages.size() - 1) == object) { + chatListView.setSelectionFromTop(0, AndroidUtilities.dp(-11) + yOffset); + } else { + chatListView.setSelectionFromTop(messages.size() - messages.indexOf(object), AndroidUtilities.dp(-11) + yOffset); + } + updateVisibleRows(); + showPagedownButton(true, true); + } else { + query = true; + } + } else { + query = true; + } + + if (query) { + messagesDict.clear(); + messagesByDays.clear(); + messages.clear(); + if (currentEncryptedChat == null) { + maxMessageId = Integer.MAX_VALUE; + minMessageId = Integer.MIN_VALUE; + } else { + maxMessageId = Integer.MIN_VALUE; + minMessageId = Integer.MAX_VALUE; + } + maxDate = Integer.MIN_VALUE; + endReached = false; + loading = false; + cacheEndReaced = false; + firstLoading = true; + loadsCount = 0; + minDate = 0; + first = true; + unread_to_load = 0; + first_unread_id = 0; + last_message_id = 0; + first_message_id = 0; + forward_end_reached = true; + loadingForward = false; + unreadMessageObject = null; + scrollToMessage = null; + highlightMessageId = Integer.MAX_VALUE; + scrollToMessageMiddleScreen = false; + loading = true; + startLoadFromMessageId = id; + MessagesController.getInstance().loadMessages(dialog_id, AndroidUtilities.isTablet() ? 30 : 20, startLoadFromMessageId, true, 0, classGuid, 3, 0, 0, false); + chatAdapter.notifyDataSetChanged(); + progressView.setVisibility(View.VISIBLE); + chatListView.setEmptyView(null); + emptyViewContainer.setVisibility(View.INVISIBLE); + } + } + private void showPagedownButton(boolean show, boolean animated) { if (pagedownButton == null) { return; } if (show) { - if (pagedownButton.getVisibility() == View.GONE) { + if (pagedownButton.getVisibility() == View.INVISIBLE) { if (animated) { pagedownButton.setVisibility(View.VISIBLE); ViewProxy.setAlpha(pagedownButton, 0); @@ -1516,16 +2365,17 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } } else { + returnToMessageId = 0; if (pagedownButton.getVisibility() == View.VISIBLE) { if (animated) { ObjectAnimatorProxy.ofFloatProxy(pagedownButton, "alpha", 0.0f).setDuration(200).addListener(new AnimatorListenerAdapterProxy() { @Override public void onAnimationEnd(Object animation) { - pagedownButton.setVisibility(View.GONE); + pagedownButton.setVisibility(View.INVISIBLE); } }).start(); } else { - pagedownButton.setVisibility(View.GONE); + pagedownButton.setVisibility(View.INVISIBLE); } } } @@ -1536,7 +2386,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not return; } if (currentEncryptedChat == null || secretViewStatusTextView == null) { - bottomOverlay.setVisibility(View.GONE); + bottomOverlay.setVisibility(View.INVISIBLE); return; } boolean hideKeyboard = false; @@ -1545,7 +2395,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not bottomOverlay.setVisibility(View.VISIBLE); hideKeyboard = true; } else if (currentEncryptedChat instanceof TLRPC.TL_encryptedChatWaiting) { - bottomOverlayText.setText(Html.fromHtml(LocaleController.formatString("AwaitingEncryption", R.string.AwaitingEncryption, "" + currentUser.first_name + ""))); + bottomOverlayText.setText(AndroidUtilities.replaceTags(LocaleController.formatString("AwaitingEncryption", R.string.AwaitingEncryption, "" + currentUser.first_name + ""))); bottomOverlay.setVisibility(View.VISIBLE); hideKeyboard = true; } else if (currentEncryptedChat instanceof TLRPC.TL_encryptedChatDiscarded) { @@ -1556,11 +2406,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not preferences.edit().remove("dialog_" + dialog_id).commit(); hideKeyboard = true; } else if (currentEncryptedChat instanceof TLRPC.TL_encryptedChat) { - bottomOverlay.setVisibility(View.GONE); + bottomOverlay.setVisibility(View.INVISIBLE); } if (hideKeyboard) { chatActivityEnterView.hideEmojiPopup(); - AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); + if (getParentActivity() != null) { + AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); + } } checkActionBarMenu(); } @@ -1618,13 +2470,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not return -1; } if (currentEncryptedChat == null) { - boolean isBroadcastError = isBroadcast && messageObject.messageOwner.id <= 0 && messageObject.isSendError(); - if (!isBroadcast && messageObject.messageOwner.id <= 0 && messageObject.isOut() || isBroadcastError) { + boolean isBroadcastError = isBroadcast && messageObject.getId() <= 0 && messageObject.isSendError(); + if (!isBroadcast && messageObject.getId() <= 0 && messageObject.isOut() || isBroadcastError) { if (messageObject.isSendError()) { - if (!(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) { + if (!messageObject.isMediaEmpty()) { return 0; } else { - return 6; + return 7; } } else { return -1; @@ -1633,12 +2485,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (messageObject.type == 6) { return -1; } else if (messageObject.type == 10 || messageObject.type == 11) { - if (messageObject.messageOwner.id == 0) { + if (messageObject.getId() == 0) { return -1; } return 1; } else { - if (!(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) { + if (!messageObject.isMediaEmpty()) { if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVideo || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) { @@ -1658,8 +2510,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (canSave) { if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) { String mime = messageObject.messageOwner.media.document.mime_type; - if (mime != null && mime.endsWith("/xml")) { - return 5; + if (mime != null) { + if (mime.endsWith("/xml")) { + return 5; + } else if (mime.endsWith("/png") || mime.endsWith("/jpg") || mime.endsWith("/jpeg")) { + return 6; + } } } return 4; @@ -1678,10 +2534,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (messageObject.type == 6) { return -1; } else if (messageObject.isSendError()) { - if (!(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) { + if (!messageObject.isMediaEmpty()) { return 0; } else { - return 6; + return 7; } } else if (messageObject.type == 10 || messageObject.type == 11) { if (messageObject.isSending()) { @@ -1690,7 +2546,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not return 1; } } else { - if (!(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) { + if (!messageObject.isMediaEmpty()) { if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVideo || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) { @@ -1728,15 +2584,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } private void addToSelectedMessages(MessageObject messageObject) { - if (selectedMessagesIds.containsKey(messageObject.messageOwner.id)) { - selectedMessagesIds.remove(messageObject.messageOwner.id); + if (selectedMessagesIds.containsKey(messageObject.getId())) { + selectedMessagesIds.remove(messageObject.getId()); if (messageObject.type == 0) { - selectedMessagesCanCopyIds.remove(messageObject.messageOwner.id); + selectedMessagesCanCopyIds.remove(messageObject.getId()); } } else { - selectedMessagesIds.put(messageObject.messageOwner.id, messageObject); + selectedMessagesIds.put(messageObject.getId(), messageObject); if (messageObject.type == 0) { - selectedMessagesCanCopyIds.put(messageObject.messageOwner.id, messageObject); + selectedMessagesCanCopyIds.put(messageObject.getId(), messageObject); } } if (actionBar.isActionModeShowed()) { @@ -1744,20 +2600,23 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not actionBar.hideActionMode(); } actionBar.createActionMode().getItem(copy).setVisibility(selectedMessagesCanCopyIds.size() != 0 ? View.VISIBLE : View.GONE); + if (actionBar.createActionMode().getItem(reply) != null) { + actionBar.createActionMode().getItem(reply).setVisibility(selectedMessagesIds.size() == 1 ? View.VISIBLE : View.GONE); + } } } private void processRowSelect(View view) { MessageObject message = null; if (view instanceof ChatBaseCell) { - message = ((ChatBaseCell)view).getMessageObject(); + message = ((ChatBaseCell) view).getMessageObject(); } else if (view instanceof ChatActionCell) { - message = ((ChatActionCell)view).getMessageObject(); + message = ((ChatActionCell) view).getMessageObject(); } int type = getMessageType(message); - if (type < 2 || type == 6) { + if (type < 2 || type == 7) { return; } addToSelectedMessages(message); @@ -1795,12 +2654,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not nameTextView.setText(ContactsController.formatName(currentUser.first_name, currentUser.last_name)); } } - TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(dialog_id); - if (dialog != null && dialog.notify_settings != null) { - - } else { - nameTextView.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.mute_blue, 0); - } } private void updateTitleIcons() { @@ -1936,12 +2789,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not videoEditedInfo.resultWidth = resultWidth; videoEditedInfo.resultHeight = resultHeight; videoEditedInfo.originalPath = videoPath; - SendMessagesHelper.prepareSendingVideo(videoPath, estimatedSize, estimatedDuration, resultWidth, resultHeight, videoEditedInfo, dialog_id); + SendMessagesHelper.prepareSendingVideo(videoPath, estimatedSize, estimatedDuration, resultWidth, resultHeight, videoEditedInfo, dialog_id, replyingMessageObject); + showReplyPanel(false, null, null, null, false, true); } }); if (parentLayout == null || !fragment.onFragmentCreate()) { - SendMessagesHelper.prepareSendingVideo(videoPath, 0, 0, 0, 0, null, dialog_id); + SendMessagesHelper.prepareSendingVideo(videoPath, 0, 0, 0, 0, null, dialog_id, replyingMessageObject); + showReplyPanel(false, null, null, null, false, true); return false; } parentLayout.presentFragment(fragment, removeLast, true, true); @@ -1960,15 +2815,50 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not public void onActivityResultFragment(int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) { if (requestCode == 0) { + PhotoViewer.getInstance().setParentActivity(getParentActivity()); + final ArrayList arrayList = new ArrayList<>(); + int orientation = 0; + try { + ExifInterface ei = new ExifInterface(currentPicturePath); + int exif = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); + switch (exif) { + case ExifInterface.ORIENTATION_ROTATE_90: + orientation = 90; + break; + case ExifInterface.ORIENTATION_ROTATE_180: + orientation = 180; + break; + case ExifInterface.ORIENTATION_ROTATE_270: + orientation = 270; + break; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + arrayList.add(new MediaController.PhotoEntry(0, 0, 0, currentPicturePath, orientation)); + + PhotoViewer.getInstance().openPhotoForSelect(arrayList, 0, 2, new PhotoViewer.EmptyPhotoViewerProvider() { + @Override + public void sendButtonPressed(int index) { + MediaController.PhotoEntry photoEntry = (MediaController.PhotoEntry) arrayList.get(0); + if (photoEntry.imagePath != null) { + SendMessagesHelper.prepareSendingPhoto(photoEntry.imagePath, null, dialog_id, replyingMessageObject); + showReplyPanel(false, null, null, null, false, true); + } else if (photoEntry.path != null) { + SendMessagesHelper.prepareSendingPhoto(photoEntry.path, null, dialog_id, replyingMessageObject); + showReplyPanel(false, null, null, null, false, true); + } + } + }); Utilities.addMediaToGallery(currentPicturePath); - SendMessagesHelper.prepareSendingPhoto(currentPicturePath, null, dialog_id); currentPicturePath = null; } else if (requestCode == 1) { if (data == null || data.getData() == null) { showAttachmentError(); return; } - SendMessagesHelper.prepareSendingPhoto(null, data.getData(), dialog_id); + SendMessagesHelper.prepareSendingPhoto(null, data.getData(), dialog_id, replyingMessageObject); + showReplyPanel(false, null, null, null, false, true); } else if (requestCode == 2) { String videoPath = null; if (data != null) { @@ -2002,14 +2892,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } currentPicturePath = null; } - if(Build.VERSION.SDK_INT >= 16) { + if (Build.VERSION.SDK_INT >= 16) { if (paused) { startVideoEdit = videoPath; } else { openVideoEditor(videoPath, false); } } else { - SendMessagesHelper.prepareSendingVideo(videoPath, 0, 0, 0, 0, null, dialog_id); + SendMessagesHelper.prepareSendingVideo(videoPath, 0, 0, 0, 0, null, dialog_id, replyingMessageObject); + showReplyPanel(false, null, null, null, false, true); } } else if (requestCode == 21) { if (data == null || data.getData() == null) { @@ -2026,7 +2917,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not showAttachmentError(); return; } - SendMessagesHelper.prepareSendingDocument(tempPath, originalPath, null, null, dialog_id); + SendMessagesHelper.prepareSendingDocument(tempPath, originalPath, null, null, dialog_id, replyingMessageObject); + showReplyPanel(false, null, null, null, false, true); } } } @@ -2066,24 +2958,24 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not public void didReceivedNotification(int id, final Object... args) { if (id == NotificationCenter.messagesDidLoaded) { - long did = (Long)args[0]; + long did = (Long) args[0]; if (did == dialog_id) { loadsCount++; - int count = (Integer)args[1]; - boolean isCache = (Boolean)args[3]; - int fnid = (Integer)args[4]; - int last_unread_date = (Integer)args[8]; - int load_type = (Integer)args[9]; + int count = (Integer) args[1]; + boolean isCache = (Boolean) args[3]; + int fnid = (Integer) args[4]; + int last_unread_date = (Integer) args[8]; + int load_type = (Integer) args[9]; boolean wasUnread = false; if (fnid != 0) { first_unread_id = fnid; - last_message_id = (Integer)args[5]; - unread_to_load = (Integer)args[7]; + last_message_id = (Integer) args[5]; + unread_to_load = (Integer) args[7]; } else if (startLoadFromMessageId != 0 && load_type == 3) { - last_message_id = (Integer)args[5]; - first_message_id = (Integer)args[6]; + last_message_id = (Integer) args[5]; + first_message_id = (Integer) args[6]; } - ArrayList messArr = (ArrayList)args[2]; + ArrayList messArr = (ArrayList) args[2]; int newRowsCount = 0; @@ -2114,19 +3006,20 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (load_type == 1) { Collections.reverse(messArr); } + ReplyMessageQuery.loadReplyMessagesForMessages(messArr, dialog_id); for (int a = 0; a < messArr.size(); a++) { MessageObject obj = messArr.get(a); - if (messagesDict.containsKey(obj.messageOwner.id)) { + if (messagesDict.containsKey(obj.getId())) { continue; } - if (obj.messageOwner.id > 0) { - maxMessageId = Math.min(obj.messageOwner.id, maxMessageId); - minMessageId = Math.max(obj.messageOwner.id, minMessageId); + if (obj.getId() > 0) { + maxMessageId = Math.min(obj.getId(), maxMessageId); + minMessageId = Math.max(obj.getId(), minMessageId); } else if (currentEncryptedChat != null) { - maxMessageId = Math.max(obj.messageOwner.id, maxMessageId); - minMessageId = Math.min(obj.messageOwner.id, minMessageId); + maxMessageId = Math.max(obj.getId(), maxMessageId); + minMessageId = Math.min(obj.getId(), minMessageId); } if (obj.messageOwner.date != 0) { maxDate = Math.max(maxDate, obj.messageOwner.date); @@ -2142,7 +3035,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (!obj.isOut() && obj.isUnread()) { wasUnread = true; } - messagesDict.put(obj.messageOwner.id, obj); + messagesDict.put(obj.getId(), obj); ArrayList dayArray = messagesByDays.get(obj.dateKey); if (dayArray == null) { @@ -2171,7 +3064,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not messages.add(messages.size() - 1, obj); } - if (load_type == 2 && obj.messageOwner.id == first_unread_id) { + if (load_type == 2 && obj.getId() == first_unread_id) { TLRPC.Message dateMsg = new TLRPC.Message(); dateMsg.message = ""; dateMsg.id = 0; @@ -2187,18 +3080,22 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not scrollToMessage = unreadMessageObject; scrollToMessageMiddleScreen = false; newRowsCount++; - } else if (load_type == 3 && obj.messageOwner.id == startLoadFromMessageId) { - highlightMessageId = obj.messageOwner.id; + } else if (load_type == 3 && obj.getId() == startLoadFromMessageId) { + if (needSelectFromMessageId) { + highlightMessageId = obj.getId(); + } else { + highlightMessageId = Integer.MAX_VALUE; + } scrollToMessage = obj; if (isCache) { startLoadFromMessageId = 0; } scrollToMessageMiddleScreen = true; - } else if (load_type == 1 && startLoadFromMessageId != 0 && first_message_id != 0 && obj.messageOwner.id >= first_message_id) { + } else if (load_type == 1 && startLoadFromMessageId != 0 && first_message_id != 0 && obj.getId() >= first_message_id) { startLoadFromMessageId = 0; } - if (obj.messageOwner.id == last_message_id) { + if (obj.getId() == last_message_id) { forward_end_reached = true; } } @@ -2238,7 +3135,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (first || scrollToTopOnResume) { chatAdapter.notifyDataSetChanged(); if (scrollToMessage != null) { - final int yOffset = scrollToMessageMiddleScreen ? Math.max(0, (AndroidUtilities.displaySize.y - AndroidUtilities.statusBarHeight - scrollToMessage.textHeight - AndroidUtilities.getCurrentActionBarHeight() - AndroidUtilities.dp(48)) / 2) : 0; + final int yOffset = scrollToMessageMiddleScreen ? Math.max(0, (chatListView.getHeight() - scrollToMessage.getApproximateHeight()) / 2) : 0; if (messages.get(messages.size() - 1) == scrollToMessage) { chatListView.setSelectionFromTop(0, AndroidUtilities.dp(-11) + yOffset); } else { @@ -2262,12 +3159,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not chatListView.invalidate(); showPagedownButton(true, true); } else { - chatListView.post(new Runnable() { - @Override - public void run() { - chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop()); - } - }); + moveScrollToLastMessage(); } } else { int firstVisPos = chatListView.getLastVisiblePosition(); @@ -2300,7 +3192,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (first && messages.size() > 0) { final boolean wasUnreadFinal = wasUnread; final int last_unread_date_final = last_unread_date; - final int lastid = messages.get(0).messageOwner.id; + final int lastid = messages.get(0).getId(); AndroidUtilities.runOnUIThread(new Runnable() { @Override public void run() { @@ -2322,8 +3214,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (chatListView != null) { chatListView.invalidateViews(); } + if (replyObjectTextView != null) { + replyObjectTextView.invalidate(); + } } else if (id == NotificationCenter.updateInterfaces) { - int updateMask = (Integer)args[0]; + int updateMask = (Integer) args[0]; if ((updateMask & MessagesController.UPDATE_MASK_NAME) != 0 || (updateMask & MessagesController.UPDATE_MASK_CHAT_NAME) != 0) { updateTitle(); } @@ -2355,23 +3250,23 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not updateContactStatus(); } } else if (id == NotificationCenter.didReceivedNewMessages) { - long did = (Long)args[0]; + long did = (Long) args[0]; if (did == dialog_id) { boolean updateChat = false; boolean hasFromMe = false; - ArrayList arr = (ArrayList)args[1]; + ArrayList arr = (ArrayList) args[1]; if (currentEncryptedChat != null && arr.size() == 1) { MessageObject obj = arr.get(0); if (currentEncryptedChat != null && obj.isOut() && obj.messageOwner.action != null && obj.messageOwner.action instanceof TLRPC.TL_messageEncryptedAction && obj.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL && getParentActivity() != null) { - TLRPC.TL_decryptedMessageActionSetMessageTTL action = (TLRPC.TL_decryptedMessageActionSetMessageTTL)obj.messageOwner.action.encryptedAction; + TLRPC.TL_decryptedMessageActionSetMessageTTL action = (TLRPC.TL_decryptedMessageActionSetMessageTTL) obj.messageOwner.action.encryptedAction; if (AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) < 17 && currentEncryptedChat.ttl > 0 && currentEncryptedChat.ttl <= 60) { AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(R.string.OK, null); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null); builder.setMessage(LocaleController.formatString("CompatibilityChat", R.string.CompatibilityChat, currentUser.first_name, currentUser.first_name)); showAlertDialog(builder); } @@ -2389,23 +3284,23 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not for (MessageObject obj : arr) { if (currentEncryptedChat != null && obj.messageOwner.action != null && obj.messageOwner.action instanceof TLRPC.TL_messageEncryptedAction && obj.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL && timerDrawable != null) { - TLRPC.TL_decryptedMessageActionSetMessageTTL action = (TLRPC.TL_decryptedMessageActionSetMessageTTL)obj.messageOwner.action.encryptedAction; + TLRPC.TL_decryptedMessageActionSetMessageTTL action = (TLRPC.TL_decryptedMessageActionSetMessageTTL) obj.messageOwner.action.encryptedAction; timerDrawable.setTime(action.ttl_seconds); } if (obj.isOut() && obj.isSending()) { scrollToLastMessage(); return; } - if (messagesDict.containsKey(obj.messageOwner.id)) { + if (messagesDict.containsKey(obj.getId())) { continue; } currentMaxDate = Math.max(currentMaxDate, obj.messageOwner.date); - if (obj.messageOwner.id > 0) { - currentMinMsgId = Math.max(obj.messageOwner.id, currentMinMsgId); - last_message_id = Math.max(last_message_id, obj.messageOwner.id); + if (obj.getId() > 0) { + currentMinMsgId = Math.max(obj.getId(), currentMinMsgId); + last_message_id = Math.max(last_message_id, obj.getId()); } else if (currentEncryptedChat != null) { - currentMinMsgId = Math.min(obj.messageOwner.id, currentMinMsgId); - last_message_id = Math.min(last_message_id, obj.messageOwner.id); + currentMinMsgId = Math.min(obj.getId(), currentMinMsgId); + last_message_id = Math.min(last_message_id, obj.getId()); } if (!obj.isOut() && obj.isUnread()) { @@ -2424,21 +3319,22 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not readWithMid = currentMinMsgId; } else { if (messages.size() > 0) { - MessagesController.getInstance().markDialogAsRead(dialog_id, messages.get(0).messageOwner.id, currentMinMsgId, 0, currentMaxDate, true, false); + MessagesController.getInstance().markDialogAsRead(dialog_id, messages.get(0).getId(), currentMinMsgId, 0, currentMaxDate, true, false); } } } updateVisibleRows(); } else { + ReplyMessageQuery.loadReplyMessagesForMessages(arr, dialog_id); boolean markAsRead = false; int oldCount = messages.size(); for (MessageObject obj : arr) { if (currentEncryptedChat != null && obj.messageOwner.action != null && obj.messageOwner.action instanceof TLRPC.TL_messageEncryptedAction && obj.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL && timerDrawable != null) { - TLRPC.TL_decryptedMessageActionSetMessageTTL action = (TLRPC.TL_decryptedMessageActionSetMessageTTL)obj.messageOwner.action.encryptedAction; + TLRPC.TL_decryptedMessageActionSetMessageTTL action = (TLRPC.TL_decryptedMessageActionSetMessageTTL) obj.messageOwner.action.encryptedAction; timerDrawable.setTime(action.ttl_seconds); } - if (messagesDict.containsKey(obj.messageOwner.id)) { + if (messagesDict.containsKey(obj.getId())) { continue; } if (minDate == 0 || obj.messageOwner.date < minDate) { @@ -2454,15 +3350,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not unread_to_load++; } - if (obj.messageOwner.id > 0) { - maxMessageId = Math.min(obj.messageOwner.id, maxMessageId); - minMessageId = Math.max(obj.messageOwner.id, minMessageId); + if (obj.getId() > 0) { + maxMessageId = Math.min(obj.getId(), maxMessageId); + minMessageId = Math.max(obj.getId(), minMessageId); } else if (currentEncryptedChat != null) { - maxMessageId = Math.max(obj.messageOwner.id, maxMessageId); - minMessageId = Math.min(obj.messageOwner.id, minMessageId); + maxMessageId = Math.max(obj.getId(), maxMessageId); + minMessageId = Math.min(obj.getId(), minMessageId); } maxDate = Math.max(maxDate, obj.messageOwner.date); - messagesDict.put(obj.messageOwner.id, obj); + messagesDict.put(obj.getId(), obj); ArrayList dayArray = messagesByDays.get(obj.dateKey); if (dayArray == null) { dayArray = new ArrayList<>(); @@ -2507,12 +3403,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (paused) { scrollToTopOnResume = true; } else { - chatListView.post(new Runnable() { - @Override - public void run() { - chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop()); - } - }); + moveScrollToLastMessage(); } } } else { @@ -2528,7 +3419,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not readWithDate = maxDate; readWithMid = minMessageId; } else { - MessagesController.getInstance().markDialogAsRead(dialog_id, messages.get(0).messageOwner.id, minMessageId, 0, maxDate, true, false); + MessagesController.getInstance().markDialogAsRead(dialog_id, messages.get(0).getId(), minMessageId, 0, maxDate, true, false); } } } @@ -2539,7 +3430,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } else if (id == NotificationCenter.closeChats) { if (args != null && args.length > 0) { - long did = (Long)args[0]; + long did = (Long) args[0]; if (did == dialog_id) { finishFragment(); } @@ -2547,20 +3438,46 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not removeSelfFromStack(); } } else if (id == NotificationCenter.messagesRead) { - ArrayList markAsReadMessages = (ArrayList)args[0]; + HashMap inbox = (HashMap) args[0]; + HashMap outbox = (HashMap) args[1]; boolean updated = false; - for (Integer ids : markAsReadMessages) { - MessageObject obj = messagesDict.get(ids); - if (obj != null) { - obj.setIsRead(); - updated = true; + for (HashMap.Entry entry : inbox.entrySet()) { + if (entry.getKey() != dialog_id) { + continue; } + for (int a = 0; a < messages.size(); a++) { + MessageObject obj = messages.get(a); + if (!obj.isOut() && obj.getId() > 0 && obj.getId() <= entry.getValue()) { + if (!obj.isUnread()) { + break; + } + obj.setIsRead(); + updated = true; + } + } + break; + } + for (HashMap.Entry entry : outbox.entrySet()) { + if (entry.getKey() != dialog_id) { + continue; + } + for (int a = 0; a < messages.size(); a++) { + MessageObject obj = messages.get(a); + if (obj.isOut() && obj.getId() > 0 && obj.getId() <= entry.getValue()) { + if (!obj.isUnread()) { + break; + } + obj.setIsRead(); + updated = true; + } + } + break; } if (updated) { updateVisibleRows(); } } else if (id == NotificationCenter.messagesDeleted) { - ArrayList markAsDeletedMessages = (ArrayList)args[0]; + ArrayList markAsDeletedMessages = (ArrayList) args[0]; boolean updated = false; for (Integer ids : markAsDeletedMessages) { MessageObject obj = messagesDict.get(ids); @@ -2603,11 +3520,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not chatAdapter.notifyDataSetChanged(); } } else if (id == NotificationCenter.messageReceivedByServer) { - Integer msgId = (Integer)args[0]; + Integer msgId = (Integer) args[0]; MessageObject obj = messagesDict.get(msgId); if (obj != null) { - Integer newMsgId = (Integer)args[1]; - TLRPC.Message newMsgObj = (TLRPC.Message)args[2]; + Integer newMsgId = (Integer) args[1]; + TLRPC.Message newMsgObj = (TLRPC.Message) args[2]; + boolean mediaUpdated = (Boolean) args[3]; if (newMsgObj != null) { obj.messageOwner.media = newMsgObj.media; obj.generateThumbs(true); @@ -2617,25 +3535,31 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not obj.messageOwner.id = newMsgId; obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENT; updateVisibleRows(); + if (mediaUpdated && chatListView.getLastVisiblePosition() >= messages.size() - 1) { + moveScrollToLastMessage(); + } } } else if (id == NotificationCenter.messageReceivedByAck) { - Integer msgId = (Integer)args[0]; + Integer msgId = (Integer) args[0]; MessageObject obj = messagesDict.get(msgId); if (obj != null) { obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENT; updateVisibleRows(); } } else if (id == NotificationCenter.messageSendError) { - Integer msgId = (Integer)args[0]; + Integer msgId = (Integer) args[0]; MessageObject obj = messagesDict.get(msgId); if (obj != null) { obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR; updateVisibleRows(); } } else if (id == NotificationCenter.chatInfoDidLoaded) { - int chatId = (Integer)args[0]; + int chatId = (Integer) args[0]; if (currentChat != null && chatId == currentChat.id) { - info = (TLRPC.ChatParticipants)args[1]; + info = (TLRPC.ChatParticipants) args[1]; + if (mentionsAdapter != null) { + mentionsAdapter.setChatInfo(info); + } updateOnlineCount(); updateSubtitle(); if (isBroadcast) { @@ -2646,16 +3570,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not updateContactStatus(); updateSubtitle(); } else if (id == NotificationCenter.encryptedChatUpdated) { - TLRPC.EncryptedChat chat = (TLRPC.EncryptedChat)args[0]; + TLRPC.EncryptedChat chat = (TLRPC.EncryptedChat) args[0]; if (currentEncryptedChat != null && chat.id == currentEncryptedChat.id) { currentEncryptedChat = chat; updateContactStatus(); updateSecretStatus(); } } else if (id == NotificationCenter.messagesReadedEncrypted) { - int encId = (Integer)args[0]; + int encId = (Integer) args[0]; if (currentEncryptedChat != null && currentEncryptedChat.id == encId) { - int date = (Integer)args[1]; + int date = (Integer) args[1]; boolean started = false; for (MessageObject obj : messages) { if (!obj.isOut()) { @@ -2670,14 +3594,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not updateVisibleRows(); } } else if (id == NotificationCenter.audioDidReset) { - Integer mid = (Integer)args[0]; + Integer mid = (Integer) args[0]; if (chatListView != null) { int count = chatListView.getChildCount(); for (int a = 0; a < count; a++) { View view = chatListView.getChildAt(a); if (view instanceof ChatAudioCell) { - ChatAudioCell cell = (ChatAudioCell)view; - if (cell.getMessageObject() != null && cell.getMessageObject().messageOwner.id == mid) { + ChatAudioCell cell = (ChatAudioCell) view; + if (cell.getMessageObject() != null && cell.getMessageObject().getId() == mid) { cell.updateButtonState(); break; } @@ -2685,14 +3609,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } } else if (id == NotificationCenter.audioProgressDidChanged) { - Integer mid = (Integer)args[0]; + Integer mid = (Integer) args[0]; if (chatListView != null) { int count = chatListView.getChildCount(); for (int a = 0; a < count; a++) { View view = chatListView.getChildAt(a); if (view instanceof ChatAudioCell) { - ChatAudioCell cell = (ChatAudioCell)view; - if (cell.getMessageObject() != null && cell.getMessageObject().messageOwner.id == mid) { + ChatAudioCell cell = (ChatAudioCell) view; + if (cell.getMessageObject() != null && cell.getMessageObject().getId() == mid) { cell.updateProgress(); break; } @@ -2700,7 +3624,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } } else if (id == NotificationCenter.removeAllMessagesFromDialog) { - long did = (Long)args[0]; + long did = (Long) args[0]; if (dialog_id == did) { messages.clear(); messagesByDays.clear(); @@ -2732,19 +3656,19 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } } else if (id == NotificationCenter.FileNewChunkAvailable) { - MessageObject messageObject = (MessageObject)args[0]; - long finalSize = (Long)args[2]; + MessageObject messageObject = (MessageObject) args[0]; + long finalSize = (Long) args[2]; if (finalSize != 0 && dialog_id == messageObject.getDialogId()) { - MessageObject currentObject = messagesDict.get(messageObject.messageOwner.id); + MessageObject currentObject = messagesDict.get(messageObject.getId()); if (currentObject != null) { - currentObject.messageOwner.media.video.size = (int)finalSize; + currentObject.messageOwner.media.video.size = (int) finalSize; updateVisibleRows(); } } } else if (id == NotificationCenter.didCreatedNewDeleteTask) { - SparseArray> mids = (SparseArray>)args[0]; + SparseArray> mids = (SparseArray>) args[0]; boolean changed = false; - for(int i = 0; i < mids.size(); i++) { + for (int i = 0; i < mids.size(); i++) { int key = mids.keyAt(i); ArrayList arr = mids.get(key); for (Integer mid : arr) { @@ -2759,11 +3683,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not updateVisibleRows(); } } else if (id == NotificationCenter.audioDidStarted) { - MessageObject messageObject = (MessageObject)args[0]; + MessageObject messageObject = (MessageObject) args[0]; sendSecretMessageRead(messageObject); } else if (id == NotificationCenter.updateMessageMedia) { - MessageObject messageObject = (MessageObject)args[0]; - MessageObject existMessageObject = messagesDict.get(messageObject.messageOwner.id); + MessageObject messageObject = (MessageObject) args[0]; + MessageObject existMessageObject = messagesDict.get(messageObject.getId()); if (existMessageObject != null) { existMessageObject.messageOwner.media = messageObject.messageOwner.media; existMessageObject.messageOwner.attachPath = messageObject.messageOwner.attachPath; @@ -2773,11 +3697,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } else if (id == NotificationCenter.replaceMessagesObjects) { if (dialog_id == (long) args[0]) { boolean changed = false; + boolean mediaUpdated = false; ArrayList messageObjects = (ArrayList) args[1]; for (MessageObject messageObject : messageObjects) { - MessageObject old = messagesDict.get(messageObject.messageOwner.id); + MessageObject old = messagesDict.get(messageObject.getId()); if (old != null) { - messagesDict.put(old.messageOwner.id, messageObject); + if (!mediaUpdated && messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) { + mediaUpdated = true; + } + messagesDict.put(old.getId(), messageObject); int idx = messages.indexOf(old); if (idx >= 0) { messages.set(idx, messageObject); @@ -2787,10 +3715,45 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } if (changed) { chatAdapter.notifyDataSetChanged(); + if (mediaUpdated && chatListView.getLastVisiblePosition() >= messages.size() - 1) { + moveScrollToLastMessage(); + } } } } else if (id == NotificationCenter.notificationsSettingsUpdated) { updateTitleIcons(); + } else if (id == NotificationCenter.didLoadedReplyMessages) { + long did = (Long) args[0]; + if (did == dialog_id) { + updateVisibleRows(); + } + } else if (id == NotificationCenter.didReceivedWebpages) { + ArrayList arrayList = (ArrayList) args[0]; + boolean updated = false; + for (TLRPC.Message message : arrayList) { + MessageObject currentMessage = messagesDict.get(message.id); + if (currentMessage != null) { + currentMessage.messageOwner.media.webpage = message.media.webpage; + currentMessage.generateThumbs(true); + updated = true; + } + } + if (updated) { + updateVisibleRows(); + if (chatListView.getLastVisiblePosition() >= messages.size() - 1) { + moveScrollToLastMessage(); + } + } + } else if (id == NotificationCenter.didReceivedWebpagesInUpdates) { + if (foundWebPage != null) { + HashMap hashMap = (HashMap) args[0]; + for (TLRPC.WebPage webPage : hashMap.values()) { + if (webPage.id == foundWebPage.id) { + showReplyPanel(!(webPage instanceof TLRPC.TL_webPageEmpty), null, null, webPage, false, true); + break; + } + } + } } } @@ -2801,7 +3764,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not for (int a = 0; a < count; a++) { View view = chatListView.getChildAt(a); if (view instanceof ChatMediaCell) { - ChatMediaCell cell = (ChatMediaCell)view; + ChatMediaCell cell = (ChatMediaCell) view; cell.setAllowedToSetPhoto(true); } } @@ -2828,7 +3791,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not chatActivityEnterView.setFieldFocused(false); } else { muteItem.setVisibility(View.VISIBLE); - bottomOverlayChat.setVisibility(View.GONE); + bottomOverlayChat.setVisibility(View.INVISIBLE); } } @@ -2873,18 +3836,19 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } checkActionBarMenu(); + if (replyImageLocation != null && replyImageView != null) { + replyImageView.setImage(replyImageLocation, "50_50", (Drawable) null); + } NotificationsController.getInstance().setOpennedDialogId(dialog_id); if (scrollToTopOnResume) { if (scrollToTopUnReadOnResume && scrollToMessage != null) { if (chatListView != null) { - final int yOffset = scrollToMessageMiddleScreen ? Math.max(0, (AndroidUtilities.displaySize.y - AndroidUtilities.statusBarHeight - scrollToMessage.textHeight - AndroidUtilities.getCurrentActionBarHeight() - AndroidUtilities.dp(48)) / 2) : 0; + final int yOffset = scrollToMessageMiddleScreen ? Math.max(0, (chatListView.getHeight() - scrollToMessage.getApproximateHeight()) / 2) : 0; chatListView.setSelectionFromTop(messages.size() - messages.indexOf(scrollToMessage), -chatListView.getPaddingTop() - AndroidUtilities.dp(7) + yOffset); } } else { - if (chatListView != null) { - chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop()); - } + moveScrollToLastMessage(); } scrollToTopUnReadOnResume = false; scrollToTopOnResume = false; @@ -2893,7 +3857,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not paused = false; if (readWhenResume && !messages.isEmpty()) { for (MessageObject messageObject : messages) { - if (!messageObject.isUnread() && !messageObject.isFromMe()) { + if (!messageObject.isUnread() && !messageObject.isOut()) { break; } if (!messageObject.isOut()) { @@ -2901,7 +3865,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } readWhenResume = false; - MessagesController.getInstance().markDialogAsRead(dialog_id, messages.get(0).messageOwner.id, readWithMid, 0, readWithDate, true, false); + MessagesController.getInstance().markDialogAsRead(dialog_id, messages.get(0).getId(), readWithMid, 0, readWithDate, true, false); } fixLayout(true); @@ -2911,6 +3875,23 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not preferences.edit().remove("dialog_" + dialog_id).commit(); chatActivityEnterView.setFieldText(lastMessageText); } + String lastReplyMessage = preferences.getString("reply_" + dialog_id, null); + if (lastReplyMessage != null && lastReplyMessage.length() != 0) { + preferences.edit().remove("reply_" + dialog_id).commit(); + try { + byte[] bytes = Base64.decode(lastReplyMessage, Base64.DEFAULT); + if (bytes != null) { + SerializedData data = new SerializedData(bytes); + TLRPC.Message message = (TLRPC.Message) TLClassStore.Instance().TLdeserialize(data, data.readInt32()); + if (message != null) { + replyingMessageObject = new MessageObject(message, MessagesController.getInstance().getUsers(), false); + showReplyPanel(true, replyingMessageObject, null, null, false, false); + } + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } if (bottomOverlayChat.getVisibility() != View.VISIBLE) { chatActivityEnterView.setFieldFocused(true); } @@ -2946,19 +3927,36 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (menuItem != null) { menuItem.closeSubMenu(); } - chatActivityEnterView.hideEmojiPopup(); paused = true; NotificationsController.getInstance().setOpennedDialogId(0); - - String text = chatActivityEnterView.getFieldText(); - if (text != null) { + if (chatActivityEnterView != null) { + chatActivityEnterView.hideEmojiPopup(); + String text = chatActivityEnterView.getFieldText(); + if (text != null) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.putString("dialog_" + dialog_id, text); + editor.commit(); + } + chatActivityEnterView.setFieldFocused(false); + } + if (replyingMessageObject != null) { SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); - editor.putString("dialog_" + dialog_id, text); + try { + SerializedData data = new SerializedData(); + replyingMessageObject.messageOwner.serializeToStream(data); + String string = Base64.encodeToString(data.toByteArray(), Base64.DEFAULT); + if (string != null && string.length() != 0) { + editor.putString("reply_" + dialog_id, string); + } + } catch (Exception e) { + editor.remove("reply_" + dialog_id); + FileLog.e("tmessages", e); + } editor.commit(); } - chatActivityEnterView.setFieldFocused(false); MessagesController.getInstance().cancelTyping(dialog_id); if (currentEncryptedChat != null) { @@ -2981,7 +3979,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not ChatBaseCell cell = (ChatBaseCell) view; object = cell.getMessageObject(); } - if (object != null && object.messageOwner.id < 0 && object.messageOwner.random_id != 0) { + if (object != null && object.getId() < 0 && object.messageOwner.random_id != 0) { visibleMessages.add(object.messageOwner.random_id); } } @@ -3014,7 +4012,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } int padding = (AndroidUtilities.getCurrentActionBarHeight() - AndroidUtilities.dp(48)) / 2; avatarContainer.setPadding(avatarContainer.getPaddingLeft(), padding, avatarContainer.getPaddingRight(), padding); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)avatarContainer.getLayoutParams(); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) avatarContainer.getLayoutParams(); layoutParams.topMargin = (Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0); avatarContainer.setLayoutParams(layoutParams); return false; @@ -3031,12 +4029,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } chatListView.getViewTreeObserver().removeOnPreDrawListener(this); if (lastPos >= messages.size() - 1) { - chatListView.post(new Runnable() { - @Override - public void run() { - chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop()); - } - }); + moveScrollToLastMessage(); } return false; } @@ -3056,9 +4049,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not MessageObject message = null; if (v instanceof ChatBaseCell) { - message = ((ChatBaseCell)v).getMessageObject(); + message = ((ChatBaseCell) v).getMessageObject(); } else if (v instanceof ChatActionCell) { - message = ((ChatActionCell)v).getMessageObject(); + message = ((ChatActionCell) v).getMessageObject(); } if (message == null) { return; @@ -3071,7 +4064,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not selectedMessagesIds.clear(); actionBar.hideActionMode(); - if (single || type < 2 || type == 6) { + if (single || type < 2 || type == 7) { if (type >= 0) { selectedObject = message; if (getParentActivity() == null) { @@ -3080,122 +4073,98 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); CharSequence[] items = null; + int[] options = null; if (type == 0) { - items = new CharSequence[] {LocaleController.getString("Retry", R.string.Retry), LocaleController.getString("Delete", R.string.Delete)}; + items = new CharSequence[]{LocaleController.getString("Retry", R.string.Retry), LocaleController.getString("Delete", R.string.Delete)}; + options = new int[]{0, 1}; } else if (type == 1) { - items = new CharSequence[] {LocaleController.getString("Delete", R.string.Delete)}; - } else if (type == 6) { - items = new CharSequence[] {LocaleController.getString("Retry", R.string.Retry), LocaleController.getString("Copy", R.string.Copy), LocaleController.getString("Delete", R.string.Delete)}; + if (currentChat != null && !isBroadcast) { + items = new CharSequence[]{LocaleController.getString("Reply", R.string.Reply), LocaleController.getString("Delete", R.string.Delete)}; + options = new int[]{8, 1}; + } else { + items = new CharSequence[]{LocaleController.getString("Delete", R.string.Delete)}; + options = new int[]{1}; + } + } else if (type == 7) { + items = new CharSequence[]{LocaleController.getString("Retry", R.string.Retry), LocaleController.getString("Copy", R.string.Copy), LocaleController.getString("Delete", R.string.Delete)}; + options = new int[]{0, 3, 1}; } else { if (currentEncryptedChat == null) { - if (type == 2) { - items = new CharSequence[]{LocaleController.getString("Forward", R.string.Forward), LocaleController.getString("Delete", R.string.Delete)}; - } else if (type == 3) { - items = new CharSequence[]{LocaleController.getString("Forward", R.string.Forward), LocaleController.getString("Copy", R.string.Copy), LocaleController.getString("Delete", R.string.Delete)}; - } else if (type == 4) { - items = new CharSequence[]{LocaleController.getString(selectedObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument ? "ShareFile" : "SaveToGallery", - selectedObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument ? R.string.ShareFile : R.string.SaveToGallery), LocaleController.getString("Forward", R.string.Forward), LocaleController.getString("Delete", R.string.Delete)}; - } else if (type == 5) { - items = new CharSequence[]{LocaleController.getString("ApplyLocalizationFile", R.string.ApplyLocalizationFile), LocaleController.getString("ShareFile", R.string.ShareFile), LocaleController.getString("Forward", R.string.Forward), LocaleController.getString("Delete", R.string.Delete)}; + if (!isBroadcast && !(currentChat != null && (currentChat instanceof TLRPC.TL_chatForbidden || currentChat.left))) { + if (type == 2) { + items = new CharSequence[]{LocaleController.getString("Reply", R.string.Reply), LocaleController.getString("Forward", R.string.Forward), LocaleController.getString("Delete", R.string.Delete)}; + options = new int[]{8, 2, 1}; + } else if (type == 3) { + items = new CharSequence[]{LocaleController.getString("Reply", R.string.Reply), LocaleController.getString("Forward", R.string.Forward), LocaleController.getString("Copy", R.string.Copy), LocaleController.getString("Delete", R.string.Delete)}; + options = new int[]{8, 2, 3, 1}; + } else if (type == 4) { + if (selectedObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) { + items = new CharSequence[]{LocaleController.getString("Reply", R.string.Reply), LocaleController.getString("ShareFile", R.string.ShareFile), LocaleController.getString("Forward", R.string.Forward), LocaleController.getString("Delete", R.string.Delete)}; + } else { + items = new CharSequence[]{LocaleController.getString("Reply", R.string.Reply), LocaleController.getString("SaveToGallery", R.string.SaveToGallery), LocaleController.getString("Forward", R.string.Forward), LocaleController.getString("Delete", R.string.Delete)}; + } + options = new int[]{8, 4, 2, 1}; + } else if (type == 5) { + items = new CharSequence[]{LocaleController.getString("Reply", R.string.Reply), LocaleController.getString("ApplyLocalizationFile", R.string.ApplyLocalizationFile), LocaleController.getString("ShareFile", R.string.ShareFile), LocaleController.getString("Forward", R.string.Forward), LocaleController.getString("Delete", R.string.Delete)}; + options = new int[]{8, 5, 4, 2, 1}; + } else if (type == 6) { + items = new CharSequence[]{LocaleController.getString("Reply", R.string.Reply), LocaleController.getString("SaveToGallery", R.string.SaveToGallery), LocaleController.getString("ShareFile", R.string.ShareFile), LocaleController.getString("Forward", R.string.Forward), LocaleController.getString("Delete", R.string.Delete)}; + options = new int[]{8, 7, 6, 2, 1}; + } + } else { + if (type == 2) { + items = new CharSequence[]{LocaleController.getString("Forward", R.string.Forward), LocaleController.getString("Delete", R.string.Delete)}; + options = new int[]{2, 1}; + } else if (type == 3) { + items = new CharSequence[]{LocaleController.getString("Forward", R.string.Forward), LocaleController.getString("Copy", R.string.Copy), LocaleController.getString("Delete", R.string.Delete)}; + options = new int[]{2, 3, 1}; + } else if (type == 4) { + if (selectedObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) { + items = new CharSequence[]{LocaleController.getString("ShareFile", R.string.ShareFile), LocaleController.getString("Forward", R.string.Forward), LocaleController.getString("Delete", R.string.Delete)}; + } else { + items = new CharSequence[]{LocaleController.getString("SaveToGallery", R.string.SaveToGallery), LocaleController.getString("Forward", R.string.Forward), LocaleController.getString("Delete", R.string.Delete)}; + } + options = new int[]{4, 2, 1}; + } else if (type == 5) { + items = new CharSequence[]{LocaleController.getString("ApplyLocalizationFile", R.string.ApplyLocalizationFile), LocaleController.getString("ShareFile", R.string.ShareFile), LocaleController.getString("Forward", R.string.Forward), LocaleController.getString("Delete", R.string.Delete)}; + options = new int[]{5, 4, 2, 1}; + } else if (type == 6) { + items = new CharSequence[]{LocaleController.getString("SaveToGallery", R.string.SaveToGallery), LocaleController.getString("ShareFile", R.string.ShareFile), LocaleController.getString("Forward", R.string.Forward), LocaleController.getString("Delete", R.string.Delete)}; + options = new int[]{7, 6, 2, 1}; + } } } else { if (type == 2) { items = new CharSequence[]{LocaleController.getString("Delete", R.string.Delete)}; + options = new int[]{1}; } else if (type == 3) { items = new CharSequence[]{LocaleController.getString("Copy", R.string.Copy), LocaleController.getString("Delete", R.string.Delete)}; + options = new int[]{3, 1}; } else if (type == 4) { - items = new CharSequence[]{LocaleController.getString(selectedObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument ? "ShareFile" : "SaveToGallery", - selectedObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument ? R.string.ShareFile : R.string.SaveToGallery), LocaleController.getString("Delete", R.string.Delete)}; + if (selectedObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) { + items = new CharSequence[]{LocaleController.getString("ShareFile", R.string.ShareFile), LocaleController.getString("Delete", R.string.Delete)}; + } else { + items = new CharSequence[]{LocaleController.getString("SaveToGallery", R.string.SaveToGallery), LocaleController.getString("Delete", R.string.Delete)}; + } + options = new int[]{4, 1}; } else if (type == 5) { items = new CharSequence[]{LocaleController.getString("ApplyLocalizationFile", R.string.ApplyLocalizationFile), LocaleController.getString("Delete", R.string.Delete)}; - } + options = new int[]{5, 1}; + }/* else if (type == 6) { + options = new int[]{7, 6, 2, 1}; + }*/ } } + final int[] finalOptions = options; builder.setItems(items, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { - if (selectedObject == null) { + if (finalOptions == null || selectedObject == null || i < 0 || i >= finalOptions.length) { return; } - if (type == 0) { - if (i == 0) { - processSelectedOption(0); - } else if (i == 1) { - processSelectedOption(1); - } - } else if (type == 1) { - processSelectedOption(1); - } else if (type == 2) { - if (currentEncryptedChat == null) { - if (i == 0) { - processSelectedOption(2); - } else if (i == 1) { - processSelectedOption(1); - } - } else { - processSelectedOption(1); - } - } else if (type == 3) { - if (currentEncryptedChat == null) { - if (i == 0) { - processSelectedOption(2); - } else if (i == 1) { - processSelectedOption(3); - } else if (i == 2) { - processSelectedOption(1); - } - } else { - if (i == 0) { - processSelectedOption(3); - } else if (i == 1) { - processSelectedOption(1); - } - } - } else if (type == 4) { - if (currentEncryptedChat == null) { - if (i == 0) { - processSelectedOption(4); - } else if (i == 1) { - processSelectedOption(2); - } else if (i == 2) { - processSelectedOption(1); - } - } else { - if (i == 0) { - processSelectedOption(4); - } else if (i == 1) { - processSelectedOption(1); - } - } - } else if (type == 5) { - if (i == 0) { - processSelectedOption(5); - } else { - if (currentEncryptedChat == null) { - if (i == 1) { - processSelectedOption(4); - } else if (i == 2) { - processSelectedOption(2); - } else if (i == 3) { - processSelectedOption(1); - } - } else { - if (i == 1) { - processSelectedOption(1); - } - } - } - } else if (type == 6) { - if (i == 0) { - processSelectedOption(0); - } else if (i == 1) { - processSelectedOption(3); - } else if (i == 2) { - processSelectedOption(1); - } - } + processSelectedOption(finalOptions[i]); } }); @@ -3234,7 +4203,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } if (option == 0) { if (SendMessagesHelper.getInstance().retrySendMessage(selectedObject, false)) { - chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop()); + moveScrollToLastMessage(); } } else if (option == 1) { final MessageObject finalSelectedObject = selectedObject; @@ -3245,7 +4214,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not @Override public void onClick(DialogInterface dialogInterface, int i) { ArrayList ids = new ArrayList<>(); - ids.add(finalSelectedObject.messageOwner.id); + ids.add(finalSelectedObject.getId()); removeUnreadPlane(true); ArrayList random_ids = null; if (currentEncryptedChat != null && finalSelectedObject.messageOwner.random_id != 0 && finalSelectedObject.type != 10) { @@ -3262,17 +4231,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not Bundle args = new Bundle(); args.putBoolean("onlySelect", true); args.putBoolean("serverOnly", true); - args.putString("selectAlertString", LocaleController.getString("ForwardMessagesTo", R.string.ForwardMessagesTo)); - args.putString("selectAlertStringGroup", LocaleController.getString("ForwardMessagesToGroup", R.string.ForwardMessagesToGroup)); MessagesActivity fragment = new MessagesActivity(args); fragment.setDelegate(this); presentFragment(fragment); } else if (option == 3) { - if(Build.VERSION.SDK_INT < 11) { - android.text.ClipboardManager clipboard = (android.text.ClipboardManager)ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); + if (Build.VERSION.SDK_INT < 11) { + android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); clipboard.setText(selectedObject.messageText); } else { - android.content.ClipboardManager clipboard = (android.content.ClipboardManager)ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); + android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); android.content.ClipData clip = android.content.ClipData.newPlainText("label", selectedObject.messageText); clipboard.setPrimaryClip(clip); } @@ -3296,7 +4263,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not Intent intent = new Intent(Intent.ACTION_SEND); intent.setType(selectedObject.messageOwner.media.document.mime_type); intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(path))); - getParentActivity().startActivity(Intent.createChooser(intent, "")); + getParentActivity().startActivityForResult(Intent.createChooser(intent, LocaleController.getString("ShareFile", R.string.ShareFile)), 500); } } else if (option == 5) { File locFile = null; @@ -3326,35 +4293,91 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not showAlertDialog(builder); } } + } else if (option == 6 || option == 7) { + String fileName = selectedObject.getFileName(); + String path = selectedObject.messageOwner.attachPath; + if (path != null && path.length() > 0) { + File temp = new File(path); + if (!temp.exists()) { + path = null; + } + } + if (path == null || path.length() == 0) { + path = FileLoader.getPathToMessage(selectedObject.messageOwner).toString(); + } + if (selectedObject.type == 8 || selectedObject.type == 9) { + if (option == 6) { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType(selectedObject.messageOwner.media.document.mime_type); + intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(path))); + getParentActivity().startActivityForResult(Intent.createChooser(intent, LocaleController.getString("ShareFile", R.string.ShareFile)), 500); + } else if (option == 7) { + MediaController.saveFile(path, getParentActivity(), 0, null); + } + } + } else if (option == 8) { + showReplyPanel(true, selectedObject, null, null, false, true); } selectedObject = null; } - private void forwardSelectedMessages(long did, boolean fromMyName) { - if (forwaringMessage != null) { - if (!fromMyName) { - if (forwaringMessage.messageOwner.id > 0) { - SendMessagesHelper.getInstance().sendMessage(forwaringMessage, did); - } - } else { - SendMessagesHelper.getInstance().processForwardFromMyName(forwaringMessage, did); - } - forwaringMessage = null; + private void openProfileWithUsername(String username) { + TLRPC.User user = MessagesController.getInstance().getUser(username); + if (user != null) { + Bundle args = new Bundle(); + args.putInt("user_id", user.id); + presentFragment(new ProfileActivity(args)); } else { - ArrayList ids = new ArrayList<>(selectedMessagesIds.keySet()); - Collections.sort(ids); - for (Integer id : ids) { - if (!fromMyName) { - if (id > 0) { - SendMessagesHelper.getInstance().sendMessage(selectedMessagesIds.get(id), did); - } - } else { - SendMessagesHelper.getInstance().processForwardFromMyName(selectedMessagesIds.get(id), did); - } + if (getParentActivity() == null) { + return; } - selectedMessagesCanCopyIds.clear(); - selectedMessagesIds.clear(); - actionBar.hideActionMode(); + final ProgressDialog progressDialog = new ProgressDialog(getParentActivity()); + 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() { + try { + progressDialog.dismiss(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + visibleDialog = null; + if (error == 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); + presentFragment(new ProfileActivity(args)); + } + } + }); + } + }); + 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); + } + visibleDialog = null; + } + }); + visibleDialog = progressDialog; + progressDialog.show(); } } @@ -3364,8 +4387,27 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (isBroadcast) { param = true; } + + ArrayList fmessages = new ArrayList<>(); + if (forwaringMessage != null) { + fmessages.add(forwaringMessage); + forwaringMessage = null; + } else { + ArrayList ids = new ArrayList<>(selectedMessagesIds.keySet()); + Collections.sort(ids); + for (Integer id : ids) { + MessageObject message = selectedMessagesIds.get(id); + if (message != null && id > 0) { + fmessages.add(message); + } + } + selectedMessagesCanCopyIds.clear(); + selectedMessagesIds.clear(); + actionBar.hideActionMode(); + } + if (did != dialog_id) { - int lower_part = (int)did; + int lower_part = (int) did; if (lower_part != 0) { Bundle args = new Bundle(); args.putBoolean("scrollToTopOnResume", scrollToTopOnResume); @@ -3374,27 +4416,29 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } else if (lower_part < 0) { args.putInt("chat_id", -lower_part); } - forwardSelectedMessages(did, param); ChatActivity chatActivity = new ChatActivity(args); - presentFragment(chatActivity, true); - if (!AndroidUtilities.isTablet()) { - removeSelfFromStack(); - Activity parentActivity = getParentActivity(); - if (parentActivity == null) { - parentActivity = chatActivity.getParentActivity(); - } - if (parentActivity != null) { - parentActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + if (presentFragment(chatActivity, true)) { + chatActivity.showReplyPanel(true, null, fmessages, null, false, false); + if (!AndroidUtilities.isTablet()) { + removeSelfFromStack(); + Activity parentActivity = getParentActivity(); + if (parentActivity == null) { + parentActivity = chatActivity.getParentActivity(); + } + if (parentActivity != null) { + parentActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + } } + } else { + activity.finishFragment(); } } else { activity.finishFragment(); } } else { activity.finishFragment(); - forwardSelectedMessages(did, param); - chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop()); - scrollToTopOnResume = true; + moveScrollToLastMessage(); + showReplyPanel(true, null, fmessages, null, false, AndroidUtilities.isTablet()); if (AndroidUtilities.isTablet()) { actionBar.hideActionMode(); } @@ -3421,7 +4465,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not try { ApplicationInfo info = ApplicationLoader.applicationContext.getPackageManager().getApplicationInfo("com.google.android.apps.maps", 0); return true; - } catch(PackageManager.NameNotFoundException e) { + } catch (PackageManager.NameNotFoundException e) { if (getParentActivity() == null) { return false; } @@ -3433,13 +4477,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not public void onClick(DialogInterface dialogInterface, int i) { try { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.apps.maps")); - getParentActivity().startActivity(intent); + getParentActivity().startActivityForResult(intent, 500); } catch (Exception e) { FileLog.e("tmessages", e); } } }); - builder.setNegativeButton(R.string.Cancel, null); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); showAlertDialog(builder); return false; } @@ -3453,12 +4497,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not for (int a = 0; a < count; a++) { View view = chatListView.getChildAt(a); if (view instanceof ChatBaseCell) { - ChatBaseCell cell = (ChatBaseCell)view; + ChatBaseCell cell = (ChatBaseCell) view; boolean disableSelection = false; boolean selected = false; if (actionBar.isActionModeShowed()) { - if (selectedMessagesIds.containsKey(cell.getMessageObject().messageOwner.id)) { + if (selectedMessagesIds.containsKey(cell.getMessageObject().getId())) { view.setBackgroundColor(0x6633b5e5); selected = true; } else { @@ -3470,12 +4514,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } cell.setMessageObject(cell.getMessageObject()); - cell.setCheckPressed(!disableSelection, disableSelection && selected); - - if (highlightMessageId != Integer.MAX_VALUE && cell.getMessageObject() != null && cell.getMessageObject().messageOwner.id == highlightMessageId) { - cell.setCheckPressed(false, true); - } + cell.setHighlighted(highlightMessageId != Integer.MAX_VALUE && cell.getMessageObject() != null && cell.getMessageObject().getId() == highlightMessageId); } } } @@ -3495,6 +4535,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not showAlertDialog(builder); } + @Override + public void updatePhotoAtIndex(int index) { + + } + @Override public PhotoViewer.PlaceProviderObject getPlaceForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index) { if (messageObject == null) { @@ -3507,16 +4552,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not ImageReceiver imageReceiver = null; View view = chatListView.getChildAt(a); if (view instanceof ChatMediaCell) { - ChatMediaCell cell = (ChatMediaCell)view; + ChatMediaCell cell = (ChatMediaCell) view; MessageObject message = cell.getMessageObject(); - if (message != null && message.messageOwner.id == messageObject.messageOwner.id) { + if (message != null && message.getId() == messageObject.getId()) { messageToOpen = message; imageReceiver = cell.getPhotoImage(); } } else if (view instanceof ChatActionCell) { - ChatActionCell cell = (ChatActionCell)view; + ChatActionCell cell = (ChatActionCell) view; MessageObject message = cell.getMessageObject(); - if (message != null && message.messageOwner.id == messageObject.messageOwner.id) { + if (message != null && message.getId() == messageObject.getId()) { messageToOpen = message; imageReceiver = cell.getPhotoImage(); } @@ -3544,25 +4589,34 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } @Override - public void willSwitchFromPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index) { } + public void willSwitchFromPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index) { + } @Override - public void willHidePhotoViewer() { } + public void willHidePhotoViewer() { + } @Override - public boolean isPhotoChecked(int index) { return false; } + public boolean isPhotoChecked(int index) { + return false; + } @Override - public void setPhotoChecked(int index) { } + public void setPhotoChecked(int index) { + } @Override - public void cancelButtonPressed() { } + public void cancelButtonPressed() { + } @Override - public void sendButtonPressed(int index) { } + public void sendButtonPressed(int index) { + } @Override - public int getSelectedCount() { return 0; } + public int getSelectedCount() { + return 0; + } private class ChatAdapter extends BaseFragmentAdapter { @@ -3621,10 +4675,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (i == 0 && !endReached || !forward_end_reached && i == (messages.size() + 1 - offset)) { View progressBar = null; if (view == null) { - LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = li.inflate(R.layout.chat_loading_layout, viewGroup, false); progressBar = view.findViewById(R.id.progressLayout); - if (isCustomTheme) { + if (ApplicationLoader.isCustomTheme()) { progressBar.setBackgroundResource(R.drawable.system_loader2); } else { progressBar.setBackgroundResource(R.drawable.system_loader1); @@ -3642,21 +4696,22 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (view == null) { if (type == 0) { view = new ChatMessageCell(mContext); - } if (type == 1) { + } + if (type == 1) { view = new ChatMediaCell(mContext); } else if (type == 2) { view = new ChatAudioCell(mContext); } else if (type == 3) { view = new ChatContactCell(mContext); } else if (type == 6) { - LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = li.inflate(R.layout.chat_unread_layout, viewGroup, false); } else if (type == 4) { view = new ChatActionCell(mContext); } if (view instanceof ChatBaseCell) { - ((ChatBaseCell)view).setDelegate(new ChatBaseCell.ChatBaseCellDelegate() { + ((ChatBaseCell) view).setDelegate(new ChatBaseCell.ChatBaseCellDelegate() { @Override public void didPressedUserAvatar(ChatBaseCell cell, TLRPC.User user) { if (actionBar.isActionModeShowed()) { @@ -3687,6 +4742,22 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not public boolean canPerformActions() { return actionBar != null && !actionBar.isActionModeShowed(); } + + @Override + public void didPressUrl(String url) { + if (url.startsWith("@")) { + openProfileWithUsername(url.substring(1)); + } else if (url.startsWith("#")) { + MessagesActivity fragment = new MessagesActivity(null); + fragment.setSearchString(url); + presentFragment(fragment); + } + } + + @Override + public void didPressReplyMessage(ChatBaseCell cell, int id) { + scrollToMessageId(id, cell.getMessageObject().getId(), true); + } }); if (view instanceof ChatMediaCell) { ((ChatMediaCell) view).setAllowedToSetPhoto(openAnimationEnded); @@ -3715,7 +4786,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(f), "video/mp4"); - getParentActivity().startActivity(intent); + getParentActivity().startActivityForResult(intent, 500); } catch (Exception e) { alertUserOpenError(message); } @@ -3762,13 +4833,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } if (realMimeType != null) { try { - getParentActivity().startActivity(intent); + getParentActivity().startActivityForResult(intent, 500); } catch (Exception e) { intent.setDataAndType(Uri.fromFile(f), "text/plain"); - getParentActivity().startActivity(intent); + getParentActivity().startActivityForResult(intent, 500); } } else { - getParentActivity().startActivity(intent); + getParentActivity().startActivityForResult(intent, 500); } } catch (Exception e) { alertUserOpenError(message); @@ -3783,7 +4854,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } }); } else if (view instanceof ChatContactCell) { - ((ChatContactCell)view).setContactDelegate(new ChatContactCell.ChatContactCellDelegate() { + ((ChatContactCell) view).setContactDelegate(new ChatContactCell.ChatContactCellDelegate() { @Override public void didClickAddButton(ChatContactCell cell, TLRPC.User user) { if (actionBar.isActionModeShowed()) { @@ -3816,7 +4887,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not try { Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + messageObject.messageOwner.media.phone_number)); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - getParentActivity().startActivity(intent); + getParentActivity().startActivityForResult(intent, 500); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -3838,7 +4909,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not }); } } else if (view instanceof ChatActionCell) { - ((ChatActionCell)view).setDelegate(new ChatActionCell.ChatActionCellDelegate() { + ((ChatActionCell) view).setDelegate(new ChatActionCell.ChatActionCellDelegate() { @Override public void didClickedImage(ChatActionCell cell) { MessageObject message = cell.getMessageObject(); @@ -3866,7 +4937,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not boolean selected = false; boolean disableSelection = false; if (actionBar.isActionModeShowed()) { - if (selectedMessagesIds.containsKey(message.messageOwner.id)) { + if (selectedMessagesIds.containsKey(message.getId())) { view.setBackgroundColor(0x6633b5e5); selected = true; } else { @@ -3878,23 +4949,20 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } if (view instanceof ChatBaseCell) { - ChatBaseCell baseCell = (ChatBaseCell)view; + ChatBaseCell baseCell = (ChatBaseCell) view; baseCell.isChat = currentChat != null; baseCell.setMessageObject(message); baseCell.setCheckPressed(!disableSelection, disableSelection && selected); if (view instanceof ChatAudioCell && MediaController.getInstance().canDownloadMedia(MediaController.AUTODOWNLOAD_MASK_AUDIO)) { - ((ChatAudioCell)view).downloadAudioIfNeed(); - } - if (highlightMessageId != Integer.MAX_VALUE && message.messageOwner.id == highlightMessageId) { - baseCell.setCheckPressed(false, true); + ((ChatAudioCell) view).downloadAudioIfNeed(); } + baseCell.setHighlighted(highlightMessageId != Integer.MAX_VALUE && message.getId() == highlightMessageId); } else if (view instanceof ChatActionCell) { - ChatActionCell actionCell = (ChatActionCell)view; + ChatActionCell actionCell = (ChatActionCell) view; actionCell.setMessageObject(message); - actionCell.setUseBlackBackground(isCustomTheme); } if (type == 6) { - TextView messageTextView = (TextView)view.findViewById(R.id.chat_message_text); + TextView messageTextView = (TextView) view.findViewById(R.id.chat_message_text); messageTextView.setText(LocaleController.formatPluralString("NewMessages", unread_to_load)); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarDrawable.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarDrawable.java index ec5c9fd8d..e2a850391 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarDrawable.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarDrawable.java @@ -13,6 +13,7 @@ import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.os.Build; import android.text.Layout; import android.text.StaticLayout; import android.text.TextPaint; @@ -30,6 +31,7 @@ public class AvatarDrawable extends Drawable { private static Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); private static TextPaint namePaint; + private static TextPaint namePaintSmall; private static int[] arrColors = {0xffe56555, 0xfff28c48, 0xffeec764, 0xff76c84d, 0xff5fbed5, 0xff549cdd, 0xff8e85ee, 0xfff2749a}; private static int[] arrColorsProfiles = {0xffd86f65, 0xfff69d61, 0xfffabb3c, 0xff67b35d, 0xff56a2bb, 0xff5c98cd, 0xff8c79d2, 0xfff37fa6}; private static int[] arrColorsProfilesBack = {0xffca6056, 0xfff18944, 0xff7d6ac4, 0xff56a14c, 0xff4492ac, 0xff4c84b6, 0xff7d6ac4, 0xff4c84b6}; @@ -38,8 +40,6 @@ public class AvatarDrawable extends Drawable { private static int[] arrColorsButtons = {R.drawable.bar_selector_red, R.drawable.bar_selector_orange, R.drawable.bar_selector_violet, R.drawable.bar_selector_green, R.drawable.bar_selector_cyan, R.drawable.bar_selector_blue, R.drawable.bar_selector_violet, R.drawable.bar_selector_blue}; - - private static Drawable broadcastDrawable; private static Drawable photoDrawable; @@ -51,6 +51,7 @@ public class AvatarDrawable extends Drawable { private boolean isProfile; private boolean drawBrodcast; private boolean drawPhoto; + private boolean smallStyle; public AvatarDrawable() { super(); @@ -60,6 +61,10 @@ public class AvatarDrawable extends Drawable { namePaint.setColor(0xffffffff); namePaint.setTextSize(AndroidUtilities.dp(20)); + namePaintSmall = new TextPaint(Paint.ANTI_ALIAS_FLAG); + namePaintSmall.setColor(0xffffffff); + namePaintSmall.setTextSize(AndroidUtilities.dp(14)); + broadcastDrawable = ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.broadcast_w); } } @@ -88,6 +93,10 @@ public class AvatarDrawable extends Drawable { } } + public void setSmallStyle(boolean value) { + smallStyle = value; + } + public static int getColorIndex(int id) { if (id >= 0 && id < 8) { return id; @@ -164,6 +173,11 @@ public class AvatarDrawable extends Drawable { drawBrodcast = isBroadcast; + if (firstName == null || firstName.length() == 0) { + firstName = lastName; + lastName = null; + } + String text = ""; if (firstName != null && firstName.length() > 0) { text += firstName.substring(0, 1); @@ -176,12 +190,30 @@ public class AvatarDrawable extends Drawable { } lastch = lastName.substring(a, a + 1); } - text += lastch; + if (Build.VERSION.SDK_INT >= 16) { + text += "\u200C" + lastch; + } else { + text += lastch; + } + } else if (firstName != null && firstName.length() > 0) { + for (int a = firstName.length() - 1; a >= 0; a--) { + if (firstName.charAt(a) == ' ') { + if (a != firstName.length() - 1 && firstName.charAt(a + 1) != ' ') { + if (Build.VERSION.SDK_INT >= 16) { + text += "\u200C" + firstName.substring(a + 1, a + 2); + } else { + text += firstName.substring(a + 1, a + 2); + } + break; + } + } + } } + if (text.length() > 0) { text = text.toUpperCase(); try { - textLayout = new StaticLayout(text, namePaint, AndroidUtilities.dp(100), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); + textLayout = new StaticLayout(text, (smallStyle ? namePaintSmall : namePaint), AndroidUtilities.dp(100), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); if (textLayout.getLineCount() > 0) { textLeft = textLayout.getLineLeft(0); textWidth = textLayout.getLineWidth(0); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarUpdater.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarUpdater.java index 2b0150e50..1fa82ddd5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarUpdater.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarUpdater.java @@ -11,12 +11,14 @@ package org.telegram.ui.Components; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; +import android.media.ExifInterface; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; import org.telegram.android.AndroidUtilities; import org.telegram.android.ImageLoader; +import org.telegram.android.MediaController; import org.telegram.messenger.TLRPC; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; @@ -24,12 +26,16 @@ import org.telegram.android.NotificationCenter; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; import org.telegram.ui.LaunchActivity; +import org.telegram.ui.PhotoAlbumPickerActivity; import org.telegram.ui.PhotoCropActivity; import org.telegram.ui.ActionBar.BaseFragment; +import org.telegram.ui.PhotoViewer; import java.io.File; +import java.util.ArrayList; public class AvatarUpdater implements NotificationCenter.NotificationCenterDelegate, PhotoCropActivity.PhotoEditActivityDelegate { + public String currentPicturePath; private TLRPC.PhotoSize smallPhoto; private TLRPC.PhotoSize bigPhoto; @@ -40,8 +46,8 @@ public class AvatarUpdater implements NotificationCenter.NotificationCenterDeleg private boolean clearAfterUpdate = false; public boolean returnOnly = false; - public static abstract interface AvatarUpdaterDelegate { - public abstract void didUploadedPhoto(TLRPC.InputFile file, TLRPC.PhotoSize small, TLRPC.PhotoSize big); + public interface AvatarUpdaterDelegate { + void didUploadedPhoto(TLRPC.InputFile file, TLRPC.PhotoSize small, TLRPC.PhotoSize big); } public void clear() { @@ -68,13 +74,28 @@ public class AvatarUpdater implements NotificationCenter.NotificationCenterDeleg } public void openGallery() { - try { - Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT); - photoPickerIntent.setType("image/*"); - parentFragment.startActivityForResult(photoPickerIntent, 14); - } catch (Exception e) { - FileLog.e("tmessages", e); - } + PhotoAlbumPickerActivity fragment = new PhotoAlbumPickerActivity(true); + fragment.setDelegate(new PhotoAlbumPickerActivity.PhotoAlbumPickerActivityDelegate() { + @Override + public void didSelectPhotos(ArrayList photos, ArrayList webPhotos) { + if (!photos.isEmpty()) { + Bitmap bitmap = ImageLoader.loadBitmap(photos.get(0), null, 800, 800, true); + processBitmap(bitmap); + } + } + + @Override + public void startPhotoSelectActivity() { + try { + Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT); + photoPickerIntent.setType("image/*"); + parentFragment.startActivityForResult(photoPickerIntent, 14); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + parentFragment.presentFragment(fragment); } private void startCrop(String path, Uri uri) { @@ -102,9 +123,42 @@ public class AvatarUpdater implements NotificationCenter.NotificationCenterDeleg public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) { if (requestCode == 13) { + PhotoViewer.getInstance().setParentActivity(parentFragment.getParentActivity()); + int orientation = 0; + try { + ExifInterface ei = new ExifInterface(currentPicturePath); + int exif = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); + switch(exif) { + case ExifInterface.ORIENTATION_ROTATE_90: + orientation = 90; + break; + case ExifInterface.ORIENTATION_ROTATE_180: + orientation = 180; + break; + case ExifInterface.ORIENTATION_ROTATE_270: + orientation = 270; + break; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + final ArrayList arrayList = new ArrayList<>(); + arrayList.add(new MediaController.PhotoEntry(0, 0, 0, currentPicturePath, orientation)); + PhotoViewer.getInstance().openPhotoForSelect(arrayList, 0, 1, new PhotoViewer.EmptyPhotoViewerProvider() { + @Override + public void sendButtonPressed(int index) { + String path = null; + MediaController.PhotoEntry photoEntry = (MediaController.PhotoEntry) arrayList.get(0); + if (photoEntry.imagePath != null) { + path = photoEntry.imagePath; + } else if (photoEntry.path != null) { + path = photoEntry.path; + } + Bitmap bitmap = ImageLoader.loadBitmap(path, null, 800, 800, true); + processBitmap(bitmap); + } + }); Utilities.addMediaToGallery(currentPicturePath); - startCrop(currentPicturePath, null); - currentPicturePath = null; } else if (requestCode == 14) { if (data == null || data.getData() == null) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/BackupImageView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/BackupImageView.java index 7f30f2658..e625402ef 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/BackupImageView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/BackupImageView.java @@ -20,10 +20,9 @@ import org.telegram.android.ImageReceiver; import org.telegram.messenger.TLObject; import org.telegram.messenger.TLRPC; - public class BackupImageView extends View { - public ImageReceiver imageReceiver; - public boolean processDetach = true; + + private ImageReceiver imageReceiver; public BackupImageView(Context context) { super(context); @@ -68,6 +67,10 @@ public class BackupImageView extends View { setImage(null, path, filter, thumb, null, null, null, 0); } + public void setOrientation(int angle, boolean center) { + imageReceiver.setOrientation(angle, center); + } + public void setImage(TLObject path, String httpUrl, String filter, Drawable thumb, Bitmap thumbBitmap, TLRPC.FileLocation thumbLocation, String thumbFilter, int size) { if (thumbBitmap != null) { thumb = new BitmapDrawable(null, thumbBitmap); @@ -87,12 +90,22 @@ public class BackupImageView extends View { imageReceiver.setImageBitmap(drawable); } + public void setRoundRadius(int value) { + imageReceiver.setRoundRadius(value); + } + + public void setAspectFit(boolean value) { + imageReceiver.setAspectFit(value); + } + + public ImageReceiver getImageReceiver() { + return imageReceiver; + } + @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - if (processDetach) { - imageReceiver.clearImage(); - } + imageReceiver.clearImage(); } @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java index 556827700..de1b773b6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java @@ -11,17 +11,16 @@ package org.telegram.ui.Components; import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; -import android.graphics.Rect; import android.media.AudioManager; import android.os.Build; import android.os.PowerManager; import android.text.Editable; import android.text.TextWatcher; import android.text.style.ImageSpan; +import android.util.TypedValue; import android.view.Gravity; import android.view.KeyEvent; import android.view.MotionEvent; -import android.view.Surface; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; @@ -29,15 +28,17 @@ import android.view.animation.AccelerateDecelerateInterpolator; import android.view.inputmethod.EditorInfo; import android.widget.EditText; import android.widget.FrameLayout; -import android.widget.ImageButton; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.PopupWindow; +import android.widget.RelativeLayout; import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.android.Emoji; import org.telegram.android.LocaleController; import org.telegram.android.MediaController; +import org.telegram.android.MessageObject; import org.telegram.android.MessagesController; import org.telegram.android.SendMessagesHelper; import org.telegram.messenger.ConnectionsManager; @@ -46,6 +47,7 @@ import org.telegram.android.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; +import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.AnimationCompat.AnimatorListenerAdapterProxy; import org.telegram.ui.AnimationCompat.AnimatorSetProxy; import org.telegram.ui.AnimationCompat.ObjectAnimatorProxy; @@ -54,29 +56,32 @@ import org.telegram.messenger.ApplicationLoader; import java.lang.reflect.Field; -public class ChatActivityEnterView implements NotificationCenter.NotificationCenterDelegate, SizeNotifierRelativeLayout.SizeNotifierRelativeLayoutDelegate { +public class ChatActivityEnterView extends FrameLayoutFixed implements NotificationCenter.NotificationCenterDelegate, SizeNotifierRelativeLayout.SizeNotifierRelativeLayoutDelegate { - public static interface ChatActivityEnterViewDelegate { - public abstract void onMessageSend(); - public abstract void needSendTyping(); - public abstract void onTextChanged(CharSequence text); - public abstract void onAttachButtonHidden(); - public abstract void onAttachButtonShow(); - public abstract void onWindowSizeChanged(int size); + public interface ChatActivityEnterViewDelegate { + void onMessageSend(String message); + void needSendTyping(); + void onTextChanged(CharSequence text, boolean bigChange); + void onAttachButtonHidden(); + void onAttachButtonShow(); + void onWindowSizeChanged(int size); } - private EditText messsageEditText; - private ImageButton sendButton; + private EditText messageEditText; + private ImageView sendButton; private PopupWindow emojiPopup; private ImageView emojiButton; private EmojiView emojiView; private TextView recordTimeText; - private ImageButton audioSendButton; - private View recordPanel; - private View slideText; - private PowerManager.WakeLock mWakeLock; + private ImageView audioSendButton; + private FrameLayout recordPanel; + private LinearLayout slideText; private SizeNotifierRelativeLayout sizeNotifierRelativeLayout; private FrameLayout attachButton; + private LinearLayout textFieldContainer; + private View topView; + + private PowerManager.WakeLock mWakeLock; private AnimatorSetProxy runningAnimation; private AnimatorSetProxy runningAnimation2; private ObjectAnimatorProxy runningAnimationAudio; @@ -92,13 +97,29 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen private float startedDraggingX = -1; private float distCanMove = AndroidUtilities.dp(80); private boolean recordingAudio; + private boolean forceShowSendButton; private Activity parentActivity; + private BaseFragment parentFragment; private long dialog_id; private boolean ignoreTextChange; + private MessageObject replyingMessageObject; + private TLRPC.WebPage messageWebPage; + private boolean messageWebPageSearch; private ChatActivityEnterViewDelegate delegate; - public ChatActivityEnterView() { + private float topViewAnimation; + private boolean topViewShowed; + private boolean needShowTopView; + private boolean allowShowTopView; + private AnimatorSetProxy currentTopViewAnimation; + + public ChatActivityEnterView(Activity context, SizeNotifierRelativeLayout parent, BaseFragment fragment, boolean isChat) { + super(context); + setBackgroundResource(R.drawable.compose_panel); + setFocusable(true); + setFocusableInTouchMode(true); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.recordStarted); NotificationCenter.getInstance().addObserver(this, NotificationCenter.recordStartError); NotificationCenter.getInstance().addObserver(this, NotificationCenter.recordStopped); @@ -108,64 +129,42 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen NotificationCenter.getInstance().addObserver(this, NotificationCenter.emojiDidLoaded); NotificationCenter.getInstance().addObserver(this, NotificationCenter.hideEmojiKeyboard); NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioRouteChanged); + parentActivity = context; + parentFragment = fragment; + sizeNotifierRelativeLayout = parent; + sizeNotifierRelativeLayout.setDelegate(this); SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); sendByEnter = preferences.getBoolean("send_by_enter", false); - } - public void onDestroy() { - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.recordStarted); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.recordStartError); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.recordStopped); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.recordProgressChanged); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.closeChats); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioDidSent); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.emojiDidLoaded); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.hideEmojiKeyboard); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioRouteChanged); - if (mWakeLock != null) { - try { - mWakeLock.release(); - mWakeLock = null; - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } - if (sizeNotifierRelativeLayout != null) { - sizeNotifierRelativeLayout.delegate = null; - } - } + textFieldContainer = new LinearLayout(context); + textFieldContainer.setBackgroundColor(0xffffffff); + textFieldContainer.setOrientation(LinearLayout.HORIZONTAL); + addView(textFieldContainer); + LayoutParams layoutParams2 = (LayoutParams) textFieldContainer.getLayoutParams(); + layoutParams2.gravity = Gravity.LEFT | Gravity.TOP; + layoutParams2.width = LayoutParams.MATCH_PARENT; + layoutParams2.height = LayoutParams.WRAP_CONTENT; + layoutParams2.topMargin = AndroidUtilities.dp(2); + textFieldContainer.setLayoutParams(layoutParams2); - public void setContainerView(Activity activity, View containerView) { - parentActivity = activity; - - sizeNotifierRelativeLayout = (SizeNotifierRelativeLayout) containerView.findViewById(R.id.chat_layout); - sizeNotifierRelativeLayout.delegate = this; - - messsageEditText = (EditText) containerView.findViewById(R.id.chat_text_edit); - messsageEditText.setHint(LocaleController.getString("TypeMessage", R.string.TypeMessage)); - - attachButton = (FrameLayout) containerView.findViewById(R.id.chat_attach_button); - if (attachButton != null) { - ViewProxy.setPivotX(attachButton, AndroidUtilities.dp(48)); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) messsageEditText.getLayoutParams(); - layoutParams.rightMargin = AndroidUtilities.dp(50); - messsageEditText.setLayoutParams(layoutParams); - } - - sendButton = (ImageButton) containerView.findViewById(R.id.chat_send_button); - sendButton.setVisibility(View.INVISIBLE); - ViewProxy.setScaleX(sendButton, 0.1f); - ViewProxy.setScaleY(sendButton, 0.1f); - ViewProxy.setAlpha(sendButton, 0.0f); - sendButton.clearAnimation(); - emojiButton = (ImageView) containerView.findViewById(R.id.chat_smile_button); - audioSendButton = (ImageButton) containerView.findViewById(R.id.chat_audio_send_button); - recordPanel = containerView.findViewById(R.id.record_panel); - recordTimeText = (TextView) containerView.findViewById(R.id.recording_time_text); - slideText = containerView.findViewById(R.id.slideText); - TextView textView = (TextView) containerView.findViewById(R.id.slideToCancelTextView); - textView.setText(LocaleController.getString("SlideToCancel", R.string.SlideToCancel)); + FrameLayoutFixed frameLayout = new FrameLayoutFixed(context); + textFieldContainer.addView(frameLayout); + LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) frameLayout.getLayoutParams(); + layoutParams.width = 0; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.weight = 1; + frameLayout.setLayoutParams(layoutParams); + emojiButton = new ImageView(context); + emojiButton.setImageResource(R.drawable.ic_msg_panel_smiles); + emojiButton.setScaleType(ImageView.ScaleType.CENTER_INSIDE); + emojiButton.setPadding(AndroidUtilities.dp(4), AndroidUtilities.dp(1), 0, 0); + frameLayout.addView(emojiButton); + FrameLayout.LayoutParams layoutParams1 = (FrameLayout.LayoutParams) emojiButton.getLayoutParams(); + layoutParams1.width = AndroidUtilities.dp(48); + layoutParams1.height = AndroidUtilities.dp(48); + layoutParams1.gravity = Gravity.BOTTOM; + emojiButton.setLayoutParams(layoutParams1); emojiButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { @@ -173,7 +172,28 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen } }); - messsageEditText.setOnKeyListener(new View.OnKeyListener() { + messageEditText = new EditText(context); + messageEditText.setHint(LocaleController.getString("TypeMessage", R.string.TypeMessage)); + messageEditText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI); + messageEditText.setInputType(messageEditText.getInputType() | EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE); + messageEditText.setSingleLine(false); + messageEditText.setMaxLines(4); + messageEditText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + messageEditText.setGravity(Gravity.BOTTOM); + messageEditText.setPadding(0, AndroidUtilities.dp(11), 0, AndroidUtilities.dp(12)); + messageEditText.setBackgroundDrawable(null); + AndroidUtilities.clearCursorDrawable(messageEditText); + messageEditText.setTextColor(0xff000000); + messageEditText.setHintTextColor(0xffb2b2b2); + frameLayout.addView(messageEditText); + layoutParams1 = (FrameLayout.LayoutParams) messageEditText.getLayoutParams(); + layoutParams1.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams1.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams1.gravity = Gravity.BOTTOM; + layoutParams1.leftMargin = AndroidUtilities.dp(52); + layoutParams1.rightMargin = AndroidUtilities.dp(isChat ? 50 : 2); + messageEditText.setLayoutParams(layoutParams1); + messageEditText.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View view, int i, KeyEvent keyEvent) { if (i == 4 && !keyboardVisible && emojiPopup != null && emojiPopup.isShowing()) { @@ -188,8 +208,7 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen return false; } }); - - messsageEditText.setOnClickListener(new View.OnClickListener() { + messageEditText.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (emojiPopup != null && emojiPopup.isShowing()) { @@ -197,8 +216,7 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen } } }); - - messsageEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { + messageEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { if (i == EditorInfo.IME_ACTION_SEND) { @@ -213,20 +231,188 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen return false; } }); - - sendButton.setOnClickListener(new View.OnClickListener() { + messageEditText.addTextChangedListener(new TextWatcher() { @Override - public void onClick(View view) { - sendMessage(); + public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int start, int before, int count) { + String message = getTrimmedString(charSequence.toString()); + checkSendButton(true); + + if (delegate != null) { + if (before > count || count > 1) { + messageWebPageSearch = true; + } + delegate.onTextChanged(charSequence, before > count || count > 1); + } + + if (message.length() != 0 && lastTypingTimeSend < System.currentTimeMillis() - 5000 && !ignoreTextChange) { + int currentTime = ConnectionsManager.getInstance().getCurrentTime(); + TLRPC.User currentUser = null; + if ((int) dialog_id > 0) { + currentUser = MessagesController.getInstance().getUser((int) dialog_id); + } + if (currentUser != null && (currentUser.id == UserConfig.getClientUserId() || currentUser.status != null && currentUser.status.expires < currentTime)) { + return; + } + lastTypingTimeSend = System.currentTimeMillis(); + if (delegate != null) { + delegate.needSendTyping(); + } + } + } + + @Override + public void afterTextChanged(Editable editable) { + if (sendByEnter && editable.length() > 0 && editable.charAt(editable.length() - 1) == '\n') { + sendMessage(); + } + int i = 0; + ImageSpan[] arrayOfImageSpan = editable.getSpans(0, editable.length(), ImageSpan.class); + int j = arrayOfImageSpan.length; + while (true) { + if (i >= j) { + Emoji.replaceEmoji(editable, messageEditText.getPaint().getFontMetricsInt(), AndroidUtilities.dp(20)); + return; + } + editable.removeSpan(arrayOfImageSpan[i]); + i++; + } } }); + if (isChat) { + attachButton = new FrameLayout(context); + attachButton.setEnabled(false); + ViewProxy.setPivotX(attachButton, AndroidUtilities.dp(48)); + frameLayout.addView(attachButton); + layoutParams1 = (FrameLayout.LayoutParams) attachButton.getLayoutParams(); + layoutParams1.width = AndroidUtilities.dp(48); + layoutParams1.height = AndroidUtilities.dp(48); + layoutParams1.gravity = Gravity.BOTTOM | Gravity.RIGHT; + attachButton.setLayoutParams(layoutParams1); + } + + recordPanel = new FrameLayoutFixed(context); + recordPanel.setVisibility(GONE); + recordPanel.setBackgroundColor(0xffffffff); + frameLayout.addView(recordPanel); + layoutParams1 = (FrameLayout.LayoutParams) recordPanel.getLayoutParams(); + layoutParams1.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams1.height = AndroidUtilities.dp(48); + layoutParams1.gravity = Gravity.BOTTOM; + recordPanel.setLayoutParams(layoutParams1); + + slideText = new LinearLayout(context); + slideText.setOrientation(LinearLayout.HORIZONTAL); + recordPanel.addView(slideText); + layoutParams1 = (FrameLayout.LayoutParams) slideText.getLayoutParams(); + layoutParams1.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams1.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams1.gravity = Gravity.CENTER; + layoutParams1.leftMargin = AndroidUtilities.dp(30); + slideText.setLayoutParams(layoutParams1); + + ImageView imageView = new ImageView(context); + imageView.setImageResource(R.drawable.slidearrow); + slideText.addView(imageView); + layoutParams = (LinearLayout.LayoutParams) imageView.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.CENTER_VERTICAL; + layoutParams.topMargin = AndroidUtilities.dp(1); + imageView.setLayoutParams(layoutParams); + + TextView textView = new TextView(context); + textView.setText(LocaleController.getString("SlideToCancel", R.string.SlideToCancel)); + textView.setTextColor(0xff999999); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12); + slideText.addView(textView); + layoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.CENTER_VERTICAL; + layoutParams.leftMargin = AndroidUtilities.dp(6); + textView.setLayoutParams(layoutParams); + + LinearLayout linearLayout = new LinearLayout(context); + linearLayout.setOrientation(LinearLayout.HORIZONTAL); + linearLayout.setPadding(AndroidUtilities.dp(13), 0, 0, 0); + linearLayout.setBackgroundColor(0xffffffff); + recordPanel.addView(linearLayout); + layoutParams1 = (FrameLayout.LayoutParams) linearLayout.getLayoutParams(); + layoutParams1.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams1.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams1.gravity = Gravity.CENTER_VERTICAL; + linearLayout.setLayoutParams(layoutParams1); + + imageView = new ImageView(context); + imageView.setImageResource(R.drawable.rec); + linearLayout.addView(imageView); + layoutParams = (LinearLayout.LayoutParams) imageView.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.CENTER_VERTICAL; + layoutParams.topMargin = AndroidUtilities.dp(1); + imageView.setLayoutParams(layoutParams); + + recordTimeText = new TextView(context); + recordTimeText.setText("00:00"); + recordTimeText.setTextColor(0xff4d4c4b); + recordTimeText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + linearLayout.addView(recordTimeText); + layoutParams = (LinearLayout.LayoutParams) recordTimeText.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.CENTER_VERTICAL; + layoutParams.leftMargin = AndroidUtilities.dp(6); + recordTimeText.setLayoutParams(layoutParams); + + FrameLayout frameLayout1 = new FrameLayout(context); + textFieldContainer.addView(frameLayout1); + layoutParams = (LinearLayout.LayoutParams) frameLayout1.getLayoutParams(); + layoutParams.width = AndroidUtilities.dp(48); + layoutParams.height = AndroidUtilities.dp(48); + layoutParams.gravity = Gravity.BOTTOM; + frameLayout1.setLayoutParams(layoutParams); + + audioSendButton = new ImageView(context); + audioSendButton.setScaleType(ImageView.ScaleType.CENTER_INSIDE); + audioSendButton.setImageResource(R.drawable.mic_button_states); + audioSendButton.setBackgroundColor(0xffffffff); + audioSendButton.setSoundEffectsEnabled(false); + audioSendButton.setPadding(0, 0, AndroidUtilities.dp(4), 0); + frameLayout1.addView(audioSendButton); + layoutParams1 = (FrameLayout.LayoutParams) audioSendButton.getLayoutParams(); + layoutParams1.width = AndroidUtilities.dp(48); + layoutParams1.height = AndroidUtilities.dp(48); + audioSendButton.setLayoutParams(layoutParams1); audioSendButton.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { + if (parentFragment != null) { + String action = null; + TLRPC.Chat currentChat = null; + if ((int) dialog_id < 0) { + currentChat = MessagesController.getInstance().getChat(-(int) dialog_id); + if (currentChat != null && currentChat.participants_count > MessagesController.getInstance().groupBigSize) { + action = "bigchat_upload_audio"; + } else { + action = "chat_upload_audio"; + } + } else { + action = "pm_upload_audio"; + } + if (!MessagesController.isFeatureEnabled(action, parentFragment)) { + return false; + } + } startedDraggingX = -1; - MediaController.getInstance().startRecording(dialog_id); + MediaController.getInstance().startRecording(dialog_id, replyingMessageObject); updateAudioRecordIntefrace(); audioSendButton.getParent().requestDisallowInterceptTouchEvent(true); } else if (motionEvent.getAction() == MotionEvent.ACTION_UP || motionEvent.getAction() == MotionEvent.ACTION_CANCEL) { @@ -279,65 +465,239 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen } }); - messsageEditText.addTextChangedListener(new TextWatcher() { + sendButton = new ImageView(context); + sendButton.setVisibility(View.INVISIBLE); + sendButton.setScaleType(ImageView.ScaleType.CENTER_INSIDE); + sendButton.setImageResource(R.drawable.ic_send); + sendButton.setSoundEffectsEnabled(false); + ViewProxy.setScaleX(sendButton, 0.1f); + ViewProxy.setScaleY(sendButton, 0.1f); + ViewProxy.setAlpha(sendButton, 0.0f); + sendButton.clearAnimation(); + frameLayout1.addView(sendButton); + layoutParams1 = (FrameLayout.LayoutParams) sendButton.getLayoutParams(); + layoutParams1.width = AndroidUtilities.dp(48); + layoutParams1.height = AndroidUtilities.dp(48); + sendButton.setLayoutParams(layoutParams1); + sendButton.setOnClickListener(new View.OnClickListener() { @Override - public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { - - } - - @Override - public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { - String message = getTrimmedString(charSequence.toString()); - checkSendButton(true); - - if (delegate != null) { - delegate.onTextChanged(charSequence); - } - - if (message.length() != 0 && lastTypingTimeSend < System.currentTimeMillis() - 5000 && !ignoreTextChange) { - int currentTime = ConnectionsManager.getInstance().getCurrentTime(); - TLRPC.User currentUser = null; - if ((int) dialog_id > 0) { - currentUser = MessagesController.getInstance().getUser((int) dialog_id); - } - if (currentUser != null && (currentUser.id == UserConfig.getClientUserId() || currentUser.status != null && currentUser.status.expires < currentTime)) { - return; - } - lastTypingTimeSend = System.currentTimeMillis(); - if (delegate != null) { - delegate.needSendTyping(); - } - } - } - - @Override - public void afterTextChanged(Editable editable) { - if (sendByEnter && editable.length() > 0 && editable.charAt(editable.length() - 1) == '\n') { - sendMessage(); - } - int i = 0; - ImageSpan[] arrayOfImageSpan = editable.getSpans(0, editable.length(), ImageSpan.class); - int j = arrayOfImageSpan.length; - while (true) { - if (i >= j) { - Emoji.replaceEmoji(editable, messsageEditText.getPaint().getFontMetricsInt(), AndroidUtilities.dp(20)); - return; - } - editable.removeSpan(arrayOfImageSpan[i]); - i++; - } + public void onClick(View view) { + sendMessage(); } }); checkSendButton(false); } + public void addTopView(View view, int height) { + if (view == null) { + return; + } + addView(view, 0); + topView = view; + topView.setVisibility(GONE); + needShowTopView = false; + LayoutParams layoutParams = (LayoutParams) topView.getLayoutParams(); + layoutParams.width = RelativeLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = height; + layoutParams.topMargin = AndroidUtilities.dp(2); + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + topView.setLayoutParams(layoutParams); + } + + public void setTopViewAnimation(float progress) { + topViewAnimation = progress; + LayoutParams layoutParams2 = (LayoutParams) textFieldContainer.getLayoutParams(); + layoutParams2.topMargin = AndroidUtilities.dp(2) + (int) (topView.getLayoutParams().height * progress); + textFieldContainer.setLayoutParams(layoutParams2); + } + + public float getTopViewAnimation() { + return topViewAnimation; + } + + public void setForceShowSendButton(boolean value, boolean animated) { + forceShowSendButton = value; + checkSendButton(animated); + } + + public void showTopView(boolean animated) { + if (topView == null || topViewShowed) { + return; + } + needShowTopView = true; + topViewShowed = true; + if (allowShowTopView) { + topView.setVisibility(VISIBLE); + float resumeValue = 0.0f; + if (currentTopViewAnimation != null) { + resumeValue = topViewAnimation; + currentTopViewAnimation.cancel(); + currentTopViewAnimation = null; + } + if (animated) { + if (keyboardVisible || emojiPopup != null && emojiPopup.isShowing()) { + currentTopViewAnimation = new AnimatorSetProxy(); + currentTopViewAnimation.playTogether( + ObjectAnimatorProxy.ofFloat(ChatActivityEnterView.this, "topViewAnimation", 1.0f) + ); + currentTopViewAnimation.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + if (animation == currentTopViewAnimation) { + setTopViewAnimation(1.0f); + if (!forceShowSendButton) { + openKeyboard(); + } + currentTopViewAnimation = null; + } + } + }); + currentTopViewAnimation.setDuration(200); + currentTopViewAnimation.start(); + } else { + setTopViewAnimation(1.0f); + if (!forceShowSendButton) { + openKeyboard(); + } + } + } else { + setTopViewAnimation(1.0f); + } + } + } + + public void hideTopView(final boolean animated) { + if (topView == null || !topViewShowed) { + return; + } + + topViewShowed = false; + needShowTopView = false; + if (allowShowTopView) { + float resumeValue = 1.0f; + if (currentTopViewAnimation != null) { + resumeValue = topViewAnimation; + currentTopViewAnimation.cancel(); + currentTopViewAnimation = null; + } + if (animated) { + currentTopViewAnimation = new AnimatorSetProxy(); + currentTopViewAnimation.playTogether( + ObjectAnimatorProxy.ofFloat(ChatActivityEnterView.this, "topViewAnimation", resumeValue, 0.0f) + ); + currentTopViewAnimation.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + if (animation == currentTopViewAnimation) { + topView.setVisibility(GONE); + setTopViewAnimation(0.0f); + currentTopViewAnimation = null; + } + } + }); + currentTopViewAnimation.setDuration(200); + currentTopViewAnimation.start(); + } else { + topView.setVisibility(GONE); + setTopViewAnimation(0.0f); + } + } + } + + public boolean isTopViewVisible() { + return topView != null && topView.getVisibility() == VISIBLE; + } + + private void onWindowSizeChanged(int size) { + if (delegate != null) { + delegate.onWindowSizeChanged(size); + } + if (topView != null) { + if (size < AndroidUtilities.dp(72) + AndroidUtilities.getCurrentActionBarHeight()) { + if (allowShowTopView) { + allowShowTopView = false; + if (needShowTopView) { + topView.setVisibility(View.GONE); + setTopViewAnimation(0.0f); + } + } + } else { + if (!allowShowTopView) { + allowShowTopView = true; + if (needShowTopView) { + topView.setVisibility(View.VISIBLE); + setTopViewAnimation(1.0f); + } + } + } + } + } + + public void onDestroy() { + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.recordStarted); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.recordStartError); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.recordStopped); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.recordProgressChanged); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.closeChats); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioDidSent); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.emojiDidLoaded); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.hideEmojiKeyboard); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioRouteChanged); + if (mWakeLock != null) { + try { + mWakeLock.release(); + mWakeLock = null; + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + if (sizeNotifierRelativeLayout != null) { + sizeNotifierRelativeLayout.setDelegate(null); + } + } + + public void setDialogId(long id) { + dialog_id = id; + } + + public void setReplyingMessageObject(MessageObject messageObject) { + replyingMessageObject = messageObject; + } + + public void setWebPage(TLRPC.WebPage webPage, boolean searchWebPages) { + messageWebPage = webPage; + messageWebPageSearch = searchWebPages; + } + private void sendMessage() { - if (processSendingText(messsageEditText.getText().toString())) { - messsageEditText.setText(""); + if (parentFragment != null) { + String action = null; + TLRPC.Chat currentChat = null; + if ((int) dialog_id < 0) { + currentChat = MessagesController.getInstance().getChat(-(int) dialog_id); + if (currentChat != null && currentChat.participants_count > MessagesController.getInstance().groupBigSize) { + action = "bigchat_message"; + } else { + action = "chat_message"; + } + } else { + action = "pm_message"; + } + if (!MessagesController.isFeatureEnabled(action, parentFragment)) { + return; + } + } + String message = messageEditText.getText().toString(); + if (processSendingText(message)) { + messageEditText.setText(""); lastTypingTimeSend = 0; if (delegate != null) { - delegate.onMessageSend(); + delegate.onMessageSend(message); + } + } else if (forceShowSendButton) { + if (delegate != null) { + delegate.onMessageSend(null); } } } @@ -348,7 +708,7 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen int count = (int) Math.ceil(text.length() / 4096.0f); for (int a = 0; a < count; a++) { String mess = text.substring(a * 4096, Math.min((a + 1) * 4096, text.length())); - SendMessagesHelper.getInstance().sendMessage(mess, dialog_id); + SendMessagesHelper.getInstance().sendMessage(mess, dialog_id, replyingMessageObject, messageWebPage, messageWebPageSearch); } return true; } @@ -370,8 +730,8 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen } private void checkSendButton(final boolean animated) { - String message = getTrimmedString(messsageEditText.getText().toString()); - if (message.length() > 0) { + String message = getTrimmedString(messageEditText.getText().toString()); + if (message.length() > 0 || forceShowSendButton) { if (audioSendButton.getVisibility() == View.VISIBLE) { if (animated) { if (runningAnimationType == 1) { @@ -404,10 +764,10 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen }); runningAnimation2.start(); - if (messsageEditText != null) { - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) messsageEditText.getLayoutParams(); + if (messageEditText != null) { + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) messageEditText.getLayoutParams(); layoutParams.rightMargin = AndroidUtilities.dp(0); - messsageEditText.setLayoutParams(layoutParams); + messageEditText.setLayoutParams(layoutParams); } delegate.onAttachButtonHidden(); @@ -453,10 +813,10 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen if (attachButton != null) { attachButton.setVisibility(View.GONE); attachButton.clearAnimation(); - - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) messsageEditText.getLayoutParams(); + delegate.onAttachButtonHidden(); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) messageEditText.getLayoutParams(); layoutParams.rightMargin = AndroidUtilities.dp(0); - messsageEditText.setLayoutParams(layoutParams); + messageEditText.setLayoutParams(layoutParams); } } } @@ -485,10 +845,10 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen runningAnimation2.setDuration(100); runningAnimation2.start(); - if (messsageEditText != null) { - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) messsageEditText.getLayoutParams(); + if (messageEditText != null) { + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) messageEditText.getLayoutParams(); layoutParams.rightMargin = AndroidUtilities.dp(50); - messsageEditText.setLayoutParams(layoutParams); + messageEditText.setLayoutParams(layoutParams); } delegate.onAttachButtonShow(); @@ -532,10 +892,11 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen sendButton.clearAnimation(); audioSendButton.setVisibility(View.VISIBLE); if (attachButton != null) { + delegate.onAttachButtonShow(); attachButton.setVisibility(View.VISIBLE); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) messsageEditText.getLayoutParams(); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) messageEditText.getLayoutParams(); layoutParams.rightMargin = AndroidUtilities.dp(50); - messsageEditText.setLayoutParams(layoutParams); + messageEditText.setLayoutParams(layoutParams); } } } @@ -626,19 +987,19 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen emojiView = new EmojiView(parentActivity); emojiView.setListener(new EmojiView.Listener() { public void onBackspace() { - messsageEditText.dispatchKeyEvent(new KeyEvent(0, 67)); + messageEditText.dispatchKeyEvent(new KeyEvent(0, 67)); } public void onEmojiSelected(String symbol) { - int i = messsageEditText.getSelectionEnd(); + int i = messageEditText.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)); + CharSequence localCharSequence = Emoji.replaceEmoji(symbol, messageEditText.getPaint().getFontMetricsInt(), AndroidUtilities.dp(20)); + messageEditText.setText(messageEditText.getText().insert(i, localCharSequence)); int j = i + localCharSequence.length(); - messsageEditText.setSelection(j, j); + messageEditText.setSelection(j, j); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -647,50 +1008,75 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen emojiPopup = new PopupWindow(emojiView); if (Build.VERSION.SDK_INT >= 21) { + /*emojiPopup.setAnimationStyle(0); + emojiPopup.setClippingEnabled(true); + emojiPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); + emojiPopup.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED);*/ try { Field field = PopupWindow.class.getDeclaredField("mWindowLayoutType"); field.setAccessible(true); field.set(emojiPopup, WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); } catch (Exception e) { - /* ignored */ + //ignored } } } int currentHeight; - 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)); } if (keyboardHeightLand <= 0) { keyboardHeightLand = ApplicationLoader.applicationContext.getSharedPreferences("emoji", 0).getInt("kbd_height_land3", AndroidUtilities.dp(200)); } - if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { + if (AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y) { currentHeight = keyboardHeightLand; } else { currentHeight = keyboardHeight; } + FileLog.e("tmessages", "show emoji with height = " + currentHeight); emojiPopup.setHeight(View.MeasureSpec.makeMeasureSpec(currentHeight, View.MeasureSpec.EXACTLY)); if (sizeNotifierRelativeLayout != null) { emojiPopup.setWidth(View.MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.x, View.MeasureSpec.EXACTLY)); } - try { - emojiPopup.showAtLocation(parentActivity.getWindow().getDecorView(), Gravity.BOTTOM | Gravity.LEFT, 0, 0); - } catch (Exception e) { - FileLog.e("tmessages", e); - return; - } + emojiPopup.showAtLocation(parentActivity.getWindow().getDecorView(), Gravity.BOTTOM | Gravity.LEFT, 0, 0); + + /*if (Build.VERSION.SDK_INT < 21) { + try { + + } catch (Exception e) { + FileLog.e("tmessages", e); + return; + } + }*/ if (!keyboardVisible) { + /*if (Build.VERSION.SDK_INT >= 21) { + try { + emojiPopup.showAsDropDown(this, 0, 0); + } catch (Exception e) { + FileLog.e("tmessages", e); + return; + } + }*/ if (sizeNotifierRelativeLayout != null) { sizeNotifierRelativeLayout.setPadding(0, 0, 0, currentHeight); emojiButton.setImageResource(R.drawable.ic_msg_panel_hide); - if (delegate != null) { - delegate.onWindowSizeChanged(sizeNotifierRelativeLayout.getHeight() - sizeNotifierRelativeLayout.getPaddingBottom()); - } + onWindowSizeChanged(sizeNotifierRelativeLayout.getHeight() - sizeNotifierRelativeLayout.getPaddingBottom()); } return; + } else { + /*if (Build.VERSION.SDK_INT >= 21) { + try { + emojiPopup.showAsDropDown(this, 0, -currentHeight - getHeight()); + emojiPopup.update(this, 0, -currentHeight - getHeight(), -1, -1); + AndroidUtilities.hideKeyboard(messageEditText); + } catch (Exception e) { + FileLog.e("tmessages", e); + return; + } + }*/ } emojiButton.setImageResource(R.drawable.ic_msg_panel_kb); return; @@ -699,16 +1085,18 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen emojiButton.setImageResource(R.drawable.ic_msg_panel_smiles); } if (emojiPopup != null) { - emojiPopup.dismiss(); + try { + emojiPopup.dismiss(); + } catch (Exception e) { + //don't promt + } } if (sizeNotifierRelativeLayout != null) { sizeNotifierRelativeLayout.post(new Runnable() { public void run() { if (sizeNotifierRelativeLayout != null) { sizeNotifierRelativeLayout.setPadding(0, 0, 0, 0); - if (delegate != null) { - delegate.onWindowSizeChanged(sizeNotifierRelativeLayout.getHeight() - sizeNotifierRelativeLayout.getPaddingBottom()); - } + onWindowSizeChanged(sizeNotifierRelativeLayout.getHeight() - sizeNotifierRelativeLayout.getPaddingBottom()); } } }); @@ -721,36 +1109,57 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen } } + public void openKeyboard() { + AndroidUtilities.showKeyboard(messageEditText); + } + public void setDelegate(ChatActivityEnterViewDelegate delegate) { this.delegate = delegate; } - public void setDialogId(long id) { - dialog_id = id; - } - public void setFieldText(String text) { - if (messsageEditText == null) { + if (messageEditText == null) { return; } ignoreTextChange = true; - messsageEditText.setText(text); - messsageEditText.setSelection(messsageEditText.getText().length()); + messageEditText.setText(text); + messageEditText.setSelection(messageEditText.getText().length()); ignoreTextChange = false; + if (delegate != null) { + delegate.onTextChanged(messageEditText.getText(), true); + } + } + + public int getCursorPosition() { + if (messageEditText == null) { + return 0; + } + return messageEditText.getSelectionStart(); + } + + public void replaceWithText(int start, int len, String text) { + try { + StringBuilder builder = new StringBuilder(messageEditText.getText()); + builder.replace(start, start + len, text); + messageEditText.setText(builder); + messageEditText.setSelection(start + text.length()); + } catch (Exception e) { + FileLog.e("tmessages", e); + } } public void setFieldFocused(boolean focus) { - if (messsageEditText == null) { + if (messageEditText == null) { return; } if (focus) { - if (!messsageEditText.isFocused()) { - messsageEditText.postDelayed(new Runnable() { + if (!messageEditText.isFocused()) { + messageEditText.postDelayed(new Runnable() { @Override public void run() { - if (messsageEditText != null) { + if (messageEditText != null) { try { - messsageEditText.requestFocus(); + messageEditText.requestFocus(); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -759,19 +1168,19 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen }, 600); } } else { - if (messsageEditText.isFocused() && !keyboardVisible) { - messsageEditText.clearFocus(); + if (messageEditText.isFocused() && !keyboardVisible) { + messageEditText.clearFocus(); } } } public boolean hasText() { - return messsageEditText != null && messsageEditText.length() > 0; + return messageEditText != null && messageEditText.length() > 0; } public String getFieldText() { - if (messsageEditText != null && messsageEditText.length() > 0) { - return messsageEditText.getText().toString(); + if (messageEditText != null && messageEditText.length() > 0) { + return messageEditText.getText().toString(); } return null; } @@ -797,18 +1206,9 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen } @Override - public void onSizeChanged(int height) { - Rect localRect = new Rect(); - parentActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(localRect); - - WindowManager wm = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); - if (wm == null || wm.getDefaultDisplay() == null) { - return; - } - int rotation = wm.getDefaultDisplay().getRotation(); - + public void onSizeChanged(int height, boolean isWidthGreater) { if (height > AndroidUtilities.dp(50) && keyboardVisible) { - if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { + if (isWidthGreater) { keyboardHeightLand = height; ApplicationLoader.applicationContext.getSharedPreferences("emoji", 0).edit().putInt("kbd_height_land3", keyboardHeightLand).commit(); } else { @@ -819,29 +1219,33 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen if (emojiPopup != null && emojiPopup.isShowing()) { int newHeight = 0; - if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { + if (isWidthGreater) { newHeight = keyboardHeightLand; } else { newHeight = keyboardHeight; } final WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) emojiPopup.getContentView().getLayoutParams(); + FileLog.e("tmessages", "update emoji height to = " + newHeight); if (layoutParams.width != AndroidUtilities.displaySize.x || layoutParams.height != newHeight) { + /*if (Build.VERSION.SDK_INT >= 21) { + if (!keyboardVisible) { + emojiPopup.update(this, 0, 0, -1, -1); + } else { + emojiPopup.update(this, 0, -newHeight - getHeight(), -1, -1); + } + }*/ layoutParams.width = AndroidUtilities.displaySize.x; layoutParams.height = newHeight; - wm.updateViewLayout(emojiPopup.getContentView(), layoutParams); - if (!keyboardVisible) { - sizeNotifierRelativeLayout.post(new Runnable() { - @Override - public void run() { - if (sizeNotifierRelativeLayout != null) { - sizeNotifierRelativeLayout.setPadding(0, 0, 0, layoutParams.height); - sizeNotifierRelativeLayout.requestLayout(); - if (delegate != null) { - delegate.onWindowSizeChanged(sizeNotifierRelativeLayout.getHeight() - sizeNotifierRelativeLayout.getPaddingBottom()); - } - } + WindowManager wm = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); + if (wm != null) { + wm.updateViewLayout(emojiPopup.getContentView(), layoutParams); + if (!keyboardVisible) { + if (sizeNotifierRelativeLayout != null) { + sizeNotifierRelativeLayout.setPadding(0, 0, 0, layoutParams.height); + sizeNotifierRelativeLayout.requestLayout(); + onWindowSizeChanged(sizeNotifierRelativeLayout.getHeight() - sizeNotifierRelativeLayout.getPaddingBottom()); } - }); + } } } } @@ -853,9 +1257,7 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen } else if (!keyboardVisible && keyboardVisible != oldValue && emojiPopup != null && emojiPopup.isShowing()) { showEmojiPopup(false); } - if (delegate != null) { - delegate.onWindowSizeChanged(sizeNotifierRelativeLayout.getHeight() - sizeNotifierRelativeLayout.getPaddingBottom()); - } + onWindowSizeChanged(sizeNotifierRelativeLayout.getHeight() - sizeNotifierRelativeLayout.getPaddingBottom()); } @Override @@ -873,8 +1275,8 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen } } } else if (id == NotificationCenter.closeChats) { - if (messsageEditText != null && messsageEditText.isFocused()) { - AndroidUtilities.hideKeyboard(messsageEditText); + if (messageEditText != null && messageEditText.isFocused()) { + AndroidUtilities.hideKeyboard(messageEditText); } } else if (id == NotificationCenter.recordStartError || id == NotificationCenter.recordStopped) { if (recordingAudio) { @@ -888,7 +1290,7 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen } } else if (id == NotificationCenter.audioDidSent) { if (delegate != null) { - delegate.onMessageSend(); + delegate.onMessageSend(null); } } else if (id == NotificationCenter.hideEmojiKeyboard) { hideEmojiPopup(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ClippingImageView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ClippingImageView.java index a288647f5..3c17e47ee 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ClippingImageView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ClippingImageView.java @@ -14,7 +14,6 @@ import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; -import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Shader; import android.view.View; @@ -23,13 +22,16 @@ import org.telegram.messenger.FileLog; import org.telegram.ui.AnimationCompat.ViewProxy; public class ClippingImageView extends View { + private int clipBottom; private int clipLeft; private int clipRight; private int clipTop; - private Rect drawRect; + private int orientation; + private RectF drawRect; private Paint paint; private Bitmap bmp; + private Matrix matrix; private onDrawListener drawListener; private boolean needRadius; @@ -40,15 +42,17 @@ public class ClippingImageView extends View { private RectF bitmapRect; private Matrix shaderMatrix; - public static interface onDrawListener { - public abstract void onDraw(); + public interface onDrawListener { + void onDraw(); } public ClippingImageView(Context context) { super(context); paint = new Paint(); paint.setFilterBitmap(true); - drawRect = new Rect(); + matrix = new Matrix(); + drawRect = new RectF(); + bitmapRect = new RectF(); } public int getClipBottom() { @@ -76,7 +80,7 @@ public class ClippingImageView extends View { } public void onDraw(Canvas canvas) { - if (getVisibility() == GONE || getVisibility() == INVISIBLE) { + if (getVisibility() != VISIBLE) { return; } if (bmp != null) { @@ -85,6 +89,7 @@ public class ClippingImageView extends View { drawListener.onDraw(); } canvas.save(); + if (needRadius) { roundRect.set(0, 0, getWidth(), getHeight()); shaderMatrix.reset(); @@ -92,10 +97,24 @@ public class ClippingImageView extends View { bitmapShader.setLocalMatrix(shaderMatrix); canvas.drawRoundRect(roundRect, radius, radius, roundPaint); } else { + if (orientation == 90 || orientation == 270) { + drawRect.set(-getHeight() / 2, -getWidth() / 2, getHeight() / 2, getWidth() / 2); + matrix.setRectToRect(bitmapRect, drawRect, Matrix.ScaleToFit.FILL); + matrix.postRotate(orientation, 0, 0); + matrix.postTranslate(getWidth() / 2, getHeight() / 2); + } else if (orientation == 180) { + drawRect.set(-getWidth() / 2, -getHeight() / 2, getWidth() / 2, getHeight() / 2); + matrix.setRectToRect(bitmapRect, drawRect, Matrix.ScaleToFit.FILL); + matrix.postRotate(orientation, 0, 0); + matrix.postTranslate(getWidth() / 2, getHeight() / 2); + } else { + drawRect.set(0, 0, getWidth(), getHeight()); + matrix.setRectToRect(bitmapRect, drawRect, Matrix.ScaleToFit.FILL); + } + canvas.clipRect(clipLeft / scaleY, clipTop / scaleY, getWidth() - clipRight / scaleY, getHeight() - clipBottom / scaleY); - drawRect.set(0, 0, getWidth(), getHeight()); try { - canvas.drawBitmap(bmp, null, drawRect, paint); + canvas.drawBitmap(bmp, matrix, paint); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -136,16 +155,21 @@ public class ClippingImageView extends View { invalidate(); } + public void setOrientation(int angle) { + orientation = angle; + } + public void setImageBitmap(Bitmap bitmap) { bmp = bitmap; - if (bitmap != null && needRadius) { - roundRect = new RectF(); - shaderMatrix = new Matrix(); - bitmapRect = new RectF(); + if (bitmap != null) { bitmapRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight()); - bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); - roundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - roundPaint.setShader(bitmapShader); + if (needRadius) { + roundRect = new RectF(); + shaderMatrix = new Matrix(); + bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); + roundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + roundPaint.setShader(bitmapShader); + } } invalidate(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ColorPickerView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ColorPickerView.java index ef7319a03..35ce2c4e3 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ColorPickerView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ColorPickerView.java @@ -89,11 +89,11 @@ public class ColorPickerView extends View { } public interface OnColorChangedListener { - public void onColorChanged(int color); + void onColorChanged(int color); } public interface OnColorSelectedListener { - public void onColorSelected(int color); + void onColorSelected(int color); } public void setOnColorChangedListener(OnColorChangedListener listener) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiView.java index 708e00f0b..2f2706d4d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiView.java @@ -31,7 +31,8 @@ import org.telegram.messenger.R; import java.util.ArrayList; public class EmojiView extends LinearLayout { - private ArrayList adapters = new ArrayList(); + + private ArrayList adapters = new ArrayList<>(); private int[] icons = { R.drawable.ic_emoji_recent, R.drawable.ic_emoji_smile, @@ -42,7 +43,7 @@ public class EmojiView extends LinearLayout { private Listener listener; private ViewPager pager; private FrameLayout recentsWrap; - private ArrayList views = new ArrayList(); + private ArrayList views = new ArrayList<>(); public EmojiView(Context paramContext) { super(paramContext); @@ -63,7 +64,7 @@ public class EmojiView extends LinearLayout { if (this.pager.getCurrentItem() == 0) { return; } - ArrayList localArrayList = new ArrayList(); + ArrayList localArrayList = new ArrayList<>(); long[] currentRecent = Emoji.data[0]; boolean was = false; for (long aCurrentRecent : currentRecent) { @@ -161,7 +162,7 @@ public class EmojiView extends LinearLayout { } private void saveRecents() { - ArrayList localArrayList = new ArrayList(); + ArrayList localArrayList = new ArrayList<>(); long[] arrayOfLong = Emoji.data[0]; int i = arrayOfLong.length; for (int j = 0; ; j++) { @@ -299,8 +300,8 @@ public class EmojiView extends LinearLayout { } } - public static abstract interface Listener { - public abstract void onBackspace(); - public abstract void onEmojiSelected(String paramString); + public interface Listener { + void onBackspace(); + void onEmojiSelected(String paramString); } } \ No newline at end of file diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ForegroundDetector.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ForegroundDetector.java new file mode 100644 index 000000000..a1f4cf2f6 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ForegroundDetector.java @@ -0,0 +1,121 @@ +/* + * This is the source code of Telegram for Android v. 2.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-2015. + */ + +package org.telegram.ui.Components; + +import android.app.Activity; +import android.app.Application; +import android.os.Build; +import android.os.Bundle; + +import org.telegram.messenger.FileLog; + +import java.util.concurrent.CopyOnWriteArrayList; + +public class ForegroundDetector implements Application.ActivityLifecycleCallbacks { + + public interface Listener { + void onBecameForeground(); + void onBecameBackground(); + } + + private int refs; + private boolean wasInBackground = true; + private long enterBackgroundTime = 0; + private CopyOnWriteArrayList listeners = new CopyOnWriteArrayList<>(); + private static ForegroundDetector Instance = null; + + public static ForegroundDetector getInstance() { + return Instance; + } + + public ForegroundDetector(Application application) { + Instance = this; + application.registerActivityLifecycleCallbacks(this); + } + + public boolean isForeground() { + return refs > 0; + } + + public boolean isBackground() { + return refs == 0; + } + + public void addListener(Listener listener) { + listeners.add(listener); + } + + public void removeListener(Listener listener) { + listeners.remove(listener); + } + + @Override + public void onActivityStarted(Activity activity) { + if (++refs == 1) { + if (System.currentTimeMillis() - enterBackgroundTime < 200) { + wasInBackground = false; + } + FileLog.e("tmessages", "switch to foreground"); + for (Listener listener : listeners) { + try { + listener.onBecameForeground(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + } + } + + public boolean isWasInBackground(boolean reset) { + if (reset && Build.VERSION.SDK_INT >= 21 && (System.currentTimeMillis() - enterBackgroundTime < 200)) { + wasInBackground = false; + } + return wasInBackground; + } + + public void resetBackgroundVar() { + wasInBackground = false; + } + + @Override + public void onActivityStopped(Activity activity) { + if (--refs == 0) { + enterBackgroundTime = System.currentTimeMillis(); + wasInBackground = true; + FileLog.e("tmessages", "switch to background"); + for (Listener listener : listeners) { + try { + listener.onBecameBackground(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + } + } + + @Override + public void onActivityCreated(Activity activity, Bundle savedInstanceState) { + } + + @Override + public void onActivityResumed(Activity activity) { + } + + @Override + public void onActivityPaused(Activity activity) { + } + + @Override + public void onActivitySaveInstanceState(Activity activity, Bundle outState) { + } + + @Override + public void onActivityDestroyed(Activity activity) { + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/FrameLayoutFixed.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/FrameLayoutFixed.java index 1d30c5682..542623e9d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/FrameLayoutFixed.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/FrameLayoutFixed.java @@ -19,7 +19,8 @@ import org.telegram.messenger.FileLog; import java.util.ArrayList; public class FrameLayoutFixed extends FrameLayout { - private final ArrayList mMatchParentChildren = new ArrayList(1); + + private final ArrayList mMatchParentChildren = new ArrayList<>(1); public FrameLayoutFixed(Context context) { super(context); @@ -110,7 +111,7 @@ public class FrameLayoutFixed extends FrameLayout { } setMeasuredDimension(resolveSizeAndStateFixed(maxWidth, widthMeasureSpec, childState), - resolveSizeAndStateFixed(maxHeight, heightMeasureSpec, childState << MEASURED_HEIGHT_STATE_SHIFT)); + resolveSizeAndStateFixed(maxHeight, heightMeasureSpec, childState << 16)); count = mMatchParentChildren.size(); if (count > 1) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/HorizontalListView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/HorizontalListView.java index 4cc5b0915..38728e89b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/HorizontalListView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/HorizontalListView.java @@ -35,7 +35,7 @@ public class HorizontalListView extends AdapterView { private int mDisplayOffset = 0; protected Scroller mScroller; private GestureDetector mGesture; - private HashMap> mRemovedViewQueue = new HashMap>(); + private HashMap> mRemovedViewQueue = new HashMap<>(); private OnItemSelectedListener mOnItemSelected; private OnItemClickListener mOnItemClicked; private OnItemLongClickListener mOnItemLongClicked; @@ -251,7 +251,7 @@ public class HorizontalListView extends AdapterView { int type = (Integer) child.getTag(); LinkedList list = mRemovedViewQueue.get(type); if (list == null) { - list = new LinkedList(); + list = new LinkedList<>(); mRemovedViewQueue.put(type, list); } list.add(child); @@ -266,7 +266,7 @@ public class HorizontalListView extends AdapterView { int type = (Integer) child.getTag(); LinkedList list = mRemovedViewQueue.get(type); if (list == null) { - list = new LinkedList(); + list = new LinkedList<>(); mRemovedViewQueue.put(type, list); } list.add(child); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/LayoutListView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/LayoutListView.java index 6712cf6fb..1ed6f83b6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/LayoutListView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/LayoutListView.java @@ -8,6 +8,7 @@ package org.telegram.ui.Components; +import android.annotation.SuppressLint; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; @@ -16,12 +17,13 @@ import android.widget.ListView; public class LayoutListView extends ListView { - public static interface OnInterceptTouchEventListener { - public abstract boolean onInterceptTouchEvent(MotionEvent event); + public interface OnInterceptTouchEventListener { + boolean onInterceptTouchEvent(MotionEvent event); } private OnInterceptTouchEventListener onInterceptTouchEventListener; private int height = -1; + private int forceTop = Integer.MIN_VALUE; public LayoutListView(Context context) { super(context); @@ -39,6 +41,10 @@ public class LayoutListView extends ListView { onInterceptTouchEventListener = listener; } + public void setForceTop(int value) { + forceTop = value; + } + @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (onInterceptTouchEventListener != null) { @@ -47,25 +53,32 @@ public class LayoutListView extends ListView { return super.onInterceptTouchEvent(ev); } + @SuppressLint("DrawAllocation") @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { View v = getChildAt(getChildCount() - 1); + int scrollTo = getLastVisiblePosition(); if (v != null && height > 0 && changed && ((bottom - top) < height)) { - int b = height - v.getTop(); - final int scrollTo = getLastVisiblePosition(); + int lastTop = forceTop == Integer.MIN_VALUE ? (bottom - top) - (height - v.getTop()) - getPaddingTop() : forceTop; + forceTop = Integer.MIN_VALUE; + setSelectionFromTop(scrollTo, lastTop); super.onLayout(changed, left, top, right, bottom); - final int offset = (bottom - top) - b; - post(new Runnable() { - @Override - public void run() { - try { - setSelectionFromTop(scrollTo, offset - getPaddingTop()); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); + +// post(new Runnable() { +// @Override +// public void run() { +// try { +// setSelectionFromTop(scrollTo, lastTop); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// }); } else { + if (forceTop != Integer.MIN_VALUE) { + setSelectionFromTop(scrollTo, forceTop); + forceTop = Integer.MIN_VALUE; + } try { super.onLayout(changed, left, top, right, bottom); } catch (Exception e) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/LetterSectionsListView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/LetterSectionsListView.java new file mode 100644 index 000000000..aedc5bcd6 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/LetterSectionsListView.java @@ -0,0 +1,211 @@ +/* + * 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.content.Context; +import android.graphics.Canvas; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AbsListView; +import android.widget.ListAdapter; +import android.widget.ListView; + +import org.telegram.android.AndroidUtilities; +import org.telegram.android.LocaleController; +import org.telegram.messenger.FileLog; +import org.telegram.ui.Adapters.BaseSectionsAdapter; + +import java.util.ArrayList; + +public class LetterSectionsListView extends ListView implements AbsListView.OnScrollListener { + + private ArrayList headers = new ArrayList<>(); + private ArrayList headersCache = new ArrayList<>(); + private OnScrollListener mOnScrollListener; + private BaseSectionsAdapter mAdapter; + private int currentFirst = -1; + private int currentVisible = -1; + private int startSection; + private int sectionsCount; + + public LetterSectionsListView(Context context) { + super(context); + super.setOnScrollListener(this); + } + + public LetterSectionsListView(Context context, AttributeSet attrs) { + super(context, attrs); + super.setOnScrollListener(this); + } + + public LetterSectionsListView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + super.setOnScrollListener(this); + } + + @Override + public void setAdapter(ListAdapter adapter) { + if (mAdapter == adapter) { + return; + } + headers.clear(); + headersCache.clear(); + if (adapter instanceof BaseSectionsAdapter) { + mAdapter = (BaseSectionsAdapter) adapter; + } else { + mAdapter = null; + } + super.setAdapter(adapter); + } + + @Override + public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { + if (mOnScrollListener != null) { + mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); + } + if (mAdapter == null) { + return; + } + + headersCache.addAll(headers); + headers.clear(); + + if (mAdapter.getCount() == 0) { + return; + } + + if (currentFirst != firstVisibleItem || currentVisible != visibleItemCount) { + currentFirst = firstVisibleItem; + currentVisible = visibleItemCount; + + sectionsCount = 1; + startSection = mAdapter.getSectionForPosition(firstVisibleItem); + int itemNum = firstVisibleItem + mAdapter.getCountForSection(startSection) - mAdapter.getPositionInSectionForPosition(firstVisibleItem); + while (true) { + if (itemNum >= firstVisibleItem + visibleItemCount) { + break; + } + itemNum += mAdapter.getCountForSection(startSection + sectionsCount); + sectionsCount++; + } + } + + int itemNum = firstVisibleItem; + for (int a = startSection; a < startSection + sectionsCount; a++) { + View header = null; + if (!headersCache.isEmpty()) { + header = headersCache.get(0); + headersCache.remove(0); + } + header = getSectionHeaderView(a, header); + headers.add(header); + int count = mAdapter.getCountForSection(a); + if (a == startSection) { + int pos = mAdapter.getPositionInSectionForPosition(itemNum); + if (pos == count - 1) { + header.setTag(-header.getHeight()); + } else if (pos == count - 2) { + View child = getChildAt(itemNum - firstVisibleItem); + int headerTop = 0; + if (child != null) { + headerTop = child.getTop(); + } else { + headerTop = -AndroidUtilities.dp(100); + } + if (headerTop < 0) { + header.setTag(headerTop); + } else { + header.setTag(0); + } + } else { + header.setTag(0); + } + itemNum += count - mAdapter.getPositionInSectionForPosition(firstVisibleItem); + } else { + View child = getChildAt(itemNum - firstVisibleItem); + if (child != null) { + header.setTag(child.getTop()); + } else { + header.setTag(-AndroidUtilities.dp(100)); + } + itemNum += count; + } + } + } + + @Override + public void onScrollStateChanged(AbsListView view, int scrollState) { + if (mOnScrollListener != null) { + mOnScrollListener.onScrollStateChanged(view, scrollState); + } + } + + private View getSectionHeaderView(int section, View oldView) { + boolean shouldLayout = oldView == null; + View view = mAdapter.getSectionHeaderView(section, oldView, this); + if (shouldLayout) { + ensurePinnedHeaderLayout(view, false); + } + return view; + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + if (mAdapter == null || headers.isEmpty()) { + return; + } + for (View header : headers) { + ensurePinnedHeaderLayout(header, true); + } + } + + private void ensurePinnedHeaderLayout(View header, boolean forceLayout) { + if (header.isLayoutRequested() || forceLayout) { + ViewGroup.LayoutParams layoutParams = header.getLayoutParams(); + int heightSpec = MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY); + int widthSpec = MeasureSpec.makeMeasureSpec(layoutParams.width, MeasureSpec.EXACTLY); + try { + header.measure(widthSpec, heightSpec); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + header.layout(0, 0, header.getMeasuredWidth(), header.getMeasuredHeight()); + } + } + + @Override + protected void dispatchDraw(Canvas canvas) { + super.dispatchDraw(canvas); + if (mAdapter == null || headers.isEmpty()) { + return; + } + for (View header : headers) { + int saveCount = canvas.save(); + int top = (Integer)header.getTag(); + canvas.translate(LocaleController.isRTL ? getWidth() - header.getWidth() : 0, top); + canvas.clipRect(0, 0, getWidth(), header.getMeasuredHeight()); + if (top < 0) { + canvas.saveLayerAlpha(0, top, header.getWidth(), top + canvas.getHeight(), (int)(255 * (1.0f + (float)top / (float)header.getMeasuredHeight())), Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); + } + header.draw(canvas); + canvas.restoreToCount(saveCount); + } + } + + @Override + public void setOnScrollListener(OnScrollListener l) { + mOnScrollListener = l; + } + + public void setOnItemClickListener(LetterSectionsListView.OnItemClickListener listener) { + super.setOnItemClickListener(listener); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/NumberPicker.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/NumberPicker.java index a0c15f5f2..e87f71c0c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/NumberPicker.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/NumberPicker.java @@ -73,7 +73,7 @@ public class NumberPicker extends LinearLayout { private OnScrollListener mOnScrollListener; private Formatter mFormatter; private long mLongPressUpdateInterval = DEFAULT_LONG_PRESS_UPDATE_INTERVAL; - private final SparseArray mSelectorIndexToStringCache = new SparseArray(); + private final SparseArray mSelectorIndexToStringCache = new SparseArray<>(); private final int[] mSelectorIndices = new int[SELECTOR_WHEEL_ITEM_COUNT]; private Paint mSelectorWheelPaint; private Drawable mVirtualButtonPressedDrawable; @@ -110,15 +110,15 @@ public class NumberPicker extends LinearLayout { } public interface OnScrollListener { - public static int SCROLL_STATE_IDLE = 0; - public static int SCROLL_STATE_TOUCH_SCROLL = 1; - public static int SCROLL_STATE_FLING = 2; + int SCROLL_STATE_IDLE = 0; + int SCROLL_STATE_TOUCH_SCROLL = 1; + int SCROLL_STATE_FLING = 2; - public void onScrollStateChange(NumberPicker view, int scrollState); + void onScrollStateChange(NumberPicker view, int scrollState); } public interface Formatter { - public String format(int value); + String format(int value); } private void init() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/PagerSlidingTabStrip.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PagerSlidingTabStrip.java index c568f4a78..33b34963e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/PagerSlidingTabStrip.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PagerSlidingTabStrip.java @@ -38,7 +38,7 @@ import org.telegram.messenger.R; public class PagerSlidingTabStrip extends HorizontalScrollView { public interface IconTabProvider { - public int getPageIconResId(int position); + int getPageIconResId(int position); } private LinearLayout.LayoutParams defaultTabLayoutParams; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/PasscodeView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PasscodeView.java new file mode 100644 index 000000000..e314602c3 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PasscodeView.java @@ -0,0 +1,1049 @@ +/* + * This is the source code of Telegram for Android v. 2.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-2015. + */ + +package org.telegram.ui.Components; + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.Configuration; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.Typeface; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Vibrator; +import android.text.Editable; +import android.text.InputFilter; +import android.text.InputType; +import android.text.TextWatcher; +import android.text.method.PasswordTransformationMethod; +import android.util.TypedValue; +import android.view.ActionMode; +import android.view.ContextMenu; +import android.view.Gravity; +import android.view.HapticFeedbackConstants; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.telegram.android.AndroidUtilities; +import org.telegram.android.LocaleController; +import org.telegram.android.NotificationCenter; +import org.telegram.messenger.ApplicationLoader; +import org.telegram.messenger.FileLog; +import org.telegram.messenger.R; +import org.telegram.messenger.UserConfig; +import org.telegram.messenger.Utilities; +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 java.util.ArrayList; +import java.util.Locale; + +public class PasscodeView extends FrameLayout { + + public interface PasscodeViewDelegate { + void didAcceptedPassword(); + } + + private class AnimatingTextView extends FrameLayout { + + private ArrayList characterTextViews; + private ArrayList dotTextViews; + private StringBuilder stringBuilder; + private String DOT = "\u2022"; + private AnimatorSetProxy currentAnimation; + private Runnable dotRunnable; + + public AnimatingTextView(Context context) { + super(context); + characterTextViews = new ArrayList<>(4); + dotTextViews = new ArrayList<>(4); + stringBuilder = new StringBuilder(4); + + for (int a = 0; a < 4; a++) { + TextView textView = new TextView(context); + textView.setTextColor(0xffffffff); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 36); + textView.setGravity(Gravity.CENTER); + ViewProxy.setAlpha(textView, 0); + ViewProxy.setPivotX(textView, AndroidUtilities.dp(25)); + ViewProxy.setPivotY(textView, AndroidUtilities.dp(25)); + addView(textView); + LayoutParams layoutParams = (LayoutParams) textView.getLayoutParams(); + layoutParams.width = AndroidUtilities.dp(50); + layoutParams.height = AndroidUtilities.dp(50); + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + textView.setLayoutParams(layoutParams); + characterTextViews.add(textView); + + textView = new TextView(context); + textView.setTextColor(0xffffffff); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 36); + textView.setGravity(Gravity.CENTER); + ViewProxy.setAlpha(textView, 0); + textView.setText(DOT); + ViewProxy.setPivotX(textView, AndroidUtilities.dp(25)); + ViewProxy.setPivotY(textView, AndroidUtilities.dp(25)); + addView(textView); + layoutParams = (LayoutParams) textView.getLayoutParams(); + layoutParams.width = AndroidUtilities.dp(50); + layoutParams.height = AndroidUtilities.dp(50); + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + textView.setLayoutParams(layoutParams); + dotTextViews.add(textView); + } + } + + private int getXForTextView(int pos) { + return (getMeasuredWidth() - stringBuilder.length() * AndroidUtilities.dp(30)) / 2 + pos * AndroidUtilities.dp(30) - AndroidUtilities.dp(10); + } + + public void appendCharacter(String c) { + if (stringBuilder.length() == 4) { + return; + } + try { + performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + + + ArrayList animators = new ArrayList<>(); + final int newPos = stringBuilder.length(); + stringBuilder.append(c); + + TextView textView = characterTextViews.get(newPos); + textView.setText(c); + ViewProxy.setTranslationX(textView, getXForTextView(newPos)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleX", 0, 1)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleY", 0, 1)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "alpha", 0, 1)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "translationY", AndroidUtilities.dp(20), 0)); + textView = dotTextViews.get(newPos); + ViewProxy.setTranslationX(textView, getXForTextView(newPos)); + ViewProxy.setAlpha(textView, 0); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleX", 0, 1)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleY", 0, 1)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "translationY", AndroidUtilities.dp(20), 0)); + + for (int a = newPos + 1; a < 4; a++) { + textView = characterTextViews.get(a); + if (ViewProxy.getAlpha(textView) != 0) { + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleX", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleY", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "alpha", 0)); + } + + textView = dotTextViews.get(a); + if (ViewProxy.getAlpha(textView) != 0) { + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleX", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleY", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "alpha", 0)); + } + } + + if (dotRunnable != null) { + AndroidUtilities.cancelRunOnUIThread(dotRunnable); + } + dotRunnable = new Runnable() { + @Override + public void run() { + if (dotRunnable != this) { + return; + } + ArrayList animators = new ArrayList<>(); + + TextView textView = characterTextViews.get(newPos); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleX", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleY", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "alpha", 0)); + textView = dotTextViews.get(newPos); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleX", 1)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleY", 1)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "alpha", 1)); + + currentAnimation = new AnimatorSetProxy(); + currentAnimation.setDuration(150); + currentAnimation.playTogether(animators); + currentAnimation.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + if (animation.equals(currentAnimation)) { + currentAnimation = null; + } + } + }); + currentAnimation.start(); + } + }; + AndroidUtilities.runOnUIThread(dotRunnable, 1500); + + for (int a = 0; a < newPos; a++) { + textView = characterTextViews.get(a); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "translationX", getXForTextView(a))); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleX", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleY", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "alpha", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "translationY", 0)); + textView = dotTextViews.get(a); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "translationX", getXForTextView(a))); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleX", 1)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleY", 1)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "alpha", 1)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "translationY", 0)); + } + + if (currentAnimation != null) { + currentAnimation.cancel(); + } + currentAnimation = new AnimatorSetProxy(); + currentAnimation.setDuration(150); + currentAnimation.playTogether(animators); + currentAnimation.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + if (animation.equals(currentAnimation)) { + currentAnimation = null; + } + } + }); + currentAnimation.start(); + } + + public String getString() { + return stringBuilder.toString(); + } + + public int lenght() { + return stringBuilder.length(); + } + + public void eraseLastCharacter() { + if (stringBuilder.length() == 0) { + return; + } + try { + performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + + ArrayList animators = new ArrayList<>(); + int deletingPos = stringBuilder.length() - 1; + if (deletingPos != 0) { + stringBuilder.deleteCharAt(deletingPos); + } + + for (int a = deletingPos; a < 4; a++) { + TextView textView = characterTextViews.get(a); + if (ViewProxy.getAlpha(textView) != 0) { + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleX", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleY", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "alpha", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "translationY", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "translationX", getXForTextView(a))); + } + + textView = dotTextViews.get(a); + if (ViewProxy.getAlpha(textView) != 0) { + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleX", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleY", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "alpha", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "translationY", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "translationX", getXForTextView(a))); + } + } + + if (deletingPos == 0) { + stringBuilder.deleteCharAt(deletingPos); + } + + for (int a = 0; a < deletingPos; a++) { + TextView textView = characterTextViews.get(a); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "translationX", getXForTextView(a))); + textView = dotTextViews.get(a); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "translationX", getXForTextView(a))); + } + + if (dotRunnable != null) { + AndroidUtilities.cancelRunOnUIThread(dotRunnable); + dotRunnable = null; + } + + if (currentAnimation != null) { + currentAnimation.cancel(); + } + currentAnimation = new AnimatorSetProxy(); + currentAnimation.setDuration(150); + currentAnimation.playTogether(animators); + currentAnimation.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + if (animation.equals(currentAnimation)) { + currentAnimation = null; + } + } + }); + currentAnimation.start(); + } + + private void eraseAllCharacters(boolean animated) { + if (stringBuilder.length() == 0) { + return; + } + if (dotRunnable != null) { + AndroidUtilities.cancelRunOnUIThread(dotRunnable); + dotRunnable = null; + } + if (currentAnimation != null) { + currentAnimation.cancel(); + currentAnimation = null; + } + stringBuilder.delete(0, stringBuilder.length()); + if (animated) { + ArrayList animators = new ArrayList<>(); + + for (int a = 0; a < 4; a++) { + TextView textView = characterTextViews.get(a); + if (ViewProxy.getAlpha(textView) != 0) { + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleX", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleY", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "alpha", 0)); + } + + textView = dotTextViews.get(a); + if (ViewProxy.getAlpha(textView) != 0) { + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleX", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "scaleY", 0)); + animators.add(ObjectAnimatorProxy.ofFloat(textView, "alpha", 0)); + } + } + + currentAnimation = new AnimatorSetProxy(); + currentAnimation.setDuration(150); + currentAnimation.playTogether(animators); + currentAnimation.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + if (animation.equals(currentAnimation)) { + currentAnimation = null; + } + } + }); + currentAnimation.start(); + } else { + for (int a = 0; a < 4; a++) { + TextView textView = characterTextViews.get(a); + ViewProxy.setAlpha(textView, 0); + textView = dotTextViews.get(a); + ViewProxy.setAlpha(textView, 0); + } + } + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + if (dotRunnable != null) { + AndroidUtilities.cancelRunOnUIThread(dotRunnable); + dotRunnable = null; + } + if (currentAnimation != null) { + currentAnimation.cancel(); + currentAnimation = null; + } + + for (int a = 0; a < 4; a++) { + if (a < stringBuilder.length()) { + TextView textView = characterTextViews.get(a); + ViewProxy.setAlpha(textView, 0); + ViewProxy.setScaleX(textView, 1); + ViewProxy.setScaleY(textView, 1); + ViewProxy.setTranslationY(textView, 0); + ViewProxy.setTranslationX(textView, getXForTextView(a)); + + textView = dotTextViews.get(a); + ViewProxy.setAlpha(textView, 1); + ViewProxy.setScaleX(textView, 1); + ViewProxy.setScaleY(textView, 1); + ViewProxy.setTranslationY(textView, 0); + ViewProxy.setTranslationX(textView, getXForTextView(a)); + } else { + TextView textView = characterTextViews.get(a); + ViewProxy.setAlpha(textView, 0); + textView = dotTextViews.get(a); + ViewProxy.setAlpha(textView, 0); + } + } + super.onLayout(changed, left, top, right, bottom); + } + } + + private Drawable backgroundDrawable; + private FrameLayout numbersFrameLayout; + private ArrayList numberTextViews; + private ArrayList lettersTextViews; + private ArrayList numberFrameLayouts; + private FrameLayout passwordFrameLayout; + private ImageView eraseView; + private EditText passwordEditText; + private AnimatingTextView passwordEditText2; + private FrameLayout backgroundFrameLayout; + private TextView passcodeTextView; + private ImageView checkImage; + private int keyboardHeight = 0; + + private Rect rect = new Rect(); + + private PasscodeViewDelegate delegate; + + public PasscodeView(final Context context) { + super(context); + + setWillNotDraw(false); + setVisibility(GONE); + + backgroundFrameLayout = new FrameLayout(context); + addView(backgroundFrameLayout); + LayoutParams layoutParams = (LayoutParams) backgroundFrameLayout.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = LayoutParams.MATCH_PARENT; + backgroundFrameLayout.setLayoutParams(layoutParams); + + passwordFrameLayout = new FrameLayout(context); + addView(passwordFrameLayout); + layoutParams = (LayoutParams) passwordFrameLayout.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + passwordFrameLayout.setLayoutParams(layoutParams); + + ImageView imageView = new ImageView(context); + imageView.setScaleType(ImageView.ScaleType.FIT_XY); + imageView.setImageResource(R.drawable.passcode_logo); + passwordFrameLayout.addView(imageView); + layoutParams = (LayoutParams) imageView.getLayoutParams(); + if (AndroidUtilities.density < 1) { + layoutParams.width = AndroidUtilities.dp(30); + layoutParams.height = AndroidUtilities.dp(30); + } else { + layoutParams.width = AndroidUtilities.dp(40); + layoutParams.height = AndroidUtilities.dp(40); + } + layoutParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; + layoutParams.bottomMargin = AndroidUtilities.dp(100); + imageView.setLayoutParams(layoutParams); + + passcodeTextView = new TextView(context); + passcodeTextView.setTextColor(0xffffffff); + passcodeTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + passcodeTextView.setGravity(Gravity.CENTER_HORIZONTAL); + passwordFrameLayout.addView(passcodeTextView); + layoutParams = (LayoutParams) passcodeTextView.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.bottomMargin = AndroidUtilities.dp(62); + layoutParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; + passcodeTextView.setLayoutParams(layoutParams); + + passwordEditText2 = new AnimatingTextView(context); + passwordFrameLayout.addView(passwordEditText2); + layoutParams = (FrameLayout.LayoutParams) passwordEditText2.getLayoutParams(); + layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams.leftMargin = AndroidUtilities.dp(70); + layoutParams.rightMargin = AndroidUtilities.dp(70); + layoutParams.bottomMargin = AndroidUtilities.dp(6); + layoutParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; + passwordEditText2.setLayoutParams(layoutParams); + + passwordEditText = new EditText(context); + passwordEditText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 36); + passwordEditText.setTextColor(0xffffffff); + passwordEditText.setMaxLines(1); + passwordEditText.setLines(1); + passwordEditText.setGravity(Gravity.CENTER_HORIZONTAL); + passwordEditText.setSingleLine(true); + passwordEditText.setImeOptions(EditorInfo.IME_ACTION_DONE); + passwordEditText.setTypeface(Typeface.DEFAULT); + passwordEditText.setBackgroundDrawable(null); + AndroidUtilities.clearCursorDrawable(passwordEditText); + passwordFrameLayout.addView(passwordEditText); + layoutParams = (FrameLayout.LayoutParams) passwordEditText.getLayoutParams(); + layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams.leftMargin = AndroidUtilities.dp(70); + layoutParams.rightMargin = AndroidUtilities.dp(70); + layoutParams.bottomMargin = AndroidUtilities.dp(6); + layoutParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; + passwordEditText.setLayoutParams(layoutParams); + passwordEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { + if (i == EditorInfo.IME_ACTION_DONE) { + processDone(); + return true; + } + return false; + } + }); + passwordEditText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + public void afterTextChanged(Editable s) { + if (passwordEditText.length() == 4 && UserConfig.passcodeType == 0) { + processDone(); + } + } + }); + if (android.os.Build.VERSION.SDK_INT < 11) { + passwordEditText.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() { + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + menu.clear(); + } + }); + } else { + passwordEditText.setCustomSelectionActionModeCallback(new ActionMode.Callback() { + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + return false; + } + + public void onDestroyActionMode(ActionMode mode) { + } + + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + return false; + } + + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + return false; + } + }); + } + + checkImage = new ImageView(context); + checkImage.setImageResource(R.drawable.passcode_check); + checkImage.setScaleType(ImageView.ScaleType.CENTER); + checkImage.setBackgroundResource(R.drawable.bar_selector_lock); + passwordFrameLayout.addView(checkImage); + layoutParams = (LayoutParams) checkImage.getLayoutParams(); + layoutParams.width = AndroidUtilities.dp(60); + layoutParams.height = AndroidUtilities.dp(60); + layoutParams.bottomMargin = AndroidUtilities.dp(4); + layoutParams.rightMargin = AndroidUtilities.dp(10); + layoutParams.gravity = Gravity.BOTTOM | Gravity.RIGHT; + checkImage.setLayoutParams(layoutParams); + checkImage.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + processDone(); + } + }); + + FrameLayout lineFrameLayout = new FrameLayout(context); + lineFrameLayout.setBackgroundColor(0x26ffffff); + passwordFrameLayout.addView(lineFrameLayout); + layoutParams = (LayoutParams) lineFrameLayout.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = AndroidUtilities.dp(1); + layoutParams.gravity = Gravity.BOTTOM | Gravity.LEFT; + layoutParams.leftMargin = AndroidUtilities.dp(20); + layoutParams.rightMargin = AndroidUtilities.dp(20); + lineFrameLayout.setLayoutParams(layoutParams); + + numbersFrameLayout = new FrameLayout(context); + addView(numbersFrameLayout); + layoutParams = (LayoutParams) numbersFrameLayout.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + numbersFrameLayout.setLayoutParams(layoutParams); + + lettersTextViews = new ArrayList<>(10); + numberTextViews = new ArrayList<>(10); + numberFrameLayouts = new ArrayList<>(10); + for (int a = 0; a < 10; a++) { + TextView textView = new TextView(context); + textView.setTextColor(0xffffffff); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 36); + textView.setGravity(Gravity.CENTER); + textView.setText(String.format(Locale.US, "%d", a)); + numbersFrameLayout.addView(textView); + layoutParams = (LayoutParams) textView.getLayoutParams(); + layoutParams.width = AndroidUtilities.dp(50); + layoutParams.height = AndroidUtilities.dp(50); + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + textView.setLayoutParams(layoutParams); + numberTextViews.add(textView); + + textView = new TextView(context); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12); + textView.setTextColor(0x7fffffff); + textView.setGravity(Gravity.CENTER); + numbersFrameLayout.addView(textView); + layoutParams = (LayoutParams) textView.getLayoutParams(); + layoutParams.width = AndroidUtilities.dp(50); + layoutParams.height = AndroidUtilities.dp(20); + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + textView.setLayoutParams(layoutParams); + switch (a) { + case 0: + textView.setText("+"); + break; + case 2: + textView.setText("ABC"); + break; + case 3: + textView.setText("DEF"); + break; + case 4: + textView.setText("GHI"); + break; + case 5: + textView.setText("JKL"); + break; + case 6: + textView.setText("MNO"); + break; + case 7: + textView.setText("PRQS"); + break; + case 8: + textView.setText("TUV"); + break; + case 9: + textView.setText("WXYZ"); + break; + default: + break; + } + lettersTextViews.add(textView); + } + eraseView = new ImageView(context); + eraseView.setScaleType(ImageView.ScaleType.CENTER); + eraseView.setImageResource(R.drawable.passcode_delete); + numbersFrameLayout.addView(eraseView); + layoutParams = (LayoutParams) eraseView.getLayoutParams(); + layoutParams.width = AndroidUtilities.dp(50); + layoutParams.height = AndroidUtilities.dp(50); + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + eraseView.setLayoutParams(layoutParams); + for (int a = 0; a < 11; a++) { + FrameLayout frameLayout = new FrameLayout(context); + frameLayout.setBackgroundResource(R.drawable.bar_selector_lock); + frameLayout.setTag(a); + if (a == 10) { + frameLayout.setOnLongClickListener(new OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + passwordEditText.setText(""); + passwordEditText2.eraseAllCharacters(true); + return true; + } + }); + } + frameLayout.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + int tag = (Integer) v.getTag(); + int key = KeyEvent.KEYCODE_DEL; + switch (tag) { + case 0: + key = KeyEvent.KEYCODE_0; + passwordEditText2.appendCharacter("0"); + break; + case 1: + key = KeyEvent.KEYCODE_1; + passwordEditText2.appendCharacter("1"); + break; + case 2: + key = KeyEvent.KEYCODE_2; + passwordEditText2.appendCharacter("2"); + break; + case 3: + key = KeyEvent.KEYCODE_3; + passwordEditText2.appendCharacter("3"); + break; + case 4: + key = KeyEvent.KEYCODE_4; + passwordEditText2.appendCharacter("4"); + break; + case 5: + key = KeyEvent.KEYCODE_5; + passwordEditText2.appendCharacter("5"); + break; + case 6: + key = KeyEvent.KEYCODE_6; + passwordEditText2.appendCharacter("6"); + break; + case 7: + key = KeyEvent.KEYCODE_7; + passwordEditText2.appendCharacter("7"); + break; + case 8: + key = KeyEvent.KEYCODE_8; + passwordEditText2.appendCharacter("8"); + break; + case 9: + key = KeyEvent.KEYCODE_9; + passwordEditText2.appendCharacter("9"); + break; + case 10: + key = KeyEvent.KEYCODE_DEL; + passwordEditText2.eraseLastCharacter(); + break; + } + if (passwordEditText2.lenght() == 4) { + processDone(); + } + //passwordEditText.dispatchKeyEvent(new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, key, 0)); + //passwordEditText.dispatchKeyEvent(new KeyEvent(0, 0, KeyEvent.ACTION_UP, key, 0)); + } + }); + numberFrameLayouts.add(frameLayout); + } + for (int a = 10; a >= 0; a--) { + FrameLayout frameLayout = numberFrameLayouts.get(a); + numbersFrameLayout.addView(frameLayout); + layoutParams = (LayoutParams) frameLayout.getLayoutParams(); + layoutParams.width = AndroidUtilities.dp(100); + layoutParams.height = AndroidUtilities.dp(100); + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + frameLayout.setLayoutParams(layoutParams); + } + } + + public void setDelegate(PasscodeViewDelegate delegate) { + this.delegate = delegate; + } + + private void processDone() { + String password = ""; + if (UserConfig.passcodeType == 0) { + password = passwordEditText2.getString(); + } else if (UserConfig.passcodeType == 1) { + password = passwordEditText.getText().toString(); + } + if (password.length() == 0) { + onPasscodeError(); + return; + } + if (!Utilities.MD5(password).equals(UserConfig.passcodeHash)) { + passwordEditText.setText(""); + passwordEditText2.eraseAllCharacters(true); + onPasscodeError(); + return; + } + passwordEditText.clearFocus(); + AndroidUtilities.hideKeyboard(passwordEditText); + + if (Build.VERSION.SDK_INT >= 14) { + AnimatorSetProxy animatorSetProxy = new AnimatorSetProxy(); + animatorSetProxy.setDuration(200); + animatorSetProxy.playTogether( + ObjectAnimatorProxy.ofFloat(this, "translationY", AndroidUtilities.dp(20)), + ObjectAnimatorProxy.ofFloat(this, "alpha", AndroidUtilities.dp(0.0f))); + animatorSetProxy.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + PasscodeView.this.clearAnimation(); + setVisibility(View.GONE); + } + }); + animatorSetProxy.start(); + } else { + setVisibility(View.GONE); + } + + UserConfig.appLocked = false; + UserConfig.saveConfig(false); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.didSetPasscode); + setOnTouchListener(null); + if (delegate != null) { + delegate.didAcceptedPassword(); + } + } + + private void shakeTextView(final float x, final int num) { + if (num == 6) { + passcodeTextView.clearAnimation(); + return; + } + AnimatorSetProxy animatorSetProxy = new AnimatorSetProxy(); + animatorSetProxy.playTogether(ObjectAnimatorProxy.ofFloat(passcodeTextView, "translationX", AndroidUtilities.dp(x))); + animatorSetProxy.setDuration(50); + animatorSetProxy.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + shakeTextView(num == 5 ? 0 : -x, num + 1); + } + }); + animatorSetProxy.start(); + } + + private void onPasscodeError() { + Vibrator v = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE); + if (v != null) { + v.vibrate(200); + } + shakeTextView(2, 0); + } + + public void onResume() { + if (UserConfig.passcodeType == 1) { + if (passwordEditText != null) { + passwordEditText.requestFocus(); + AndroidUtilities.showKeyboard(passwordEditText); + } + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (passwordEditText != null) { + passwordEditText.requestFocus(); + AndroidUtilities.showKeyboard(passwordEditText); + } + } + }, 200); + } + } + + public void onShow() { + if (UserConfig.passcodeType == 1) { + if (passwordEditText != null) { + passwordEditText.requestFocus(); + AndroidUtilities.showKeyboard(passwordEditText); + } + } else { + Activity parentActivity = (Activity) getContext(); + if (parentActivity != null) { + View currentFocus = parentActivity.getCurrentFocus(); + if (currentFocus != null) { + currentFocus.clearFocus(); + AndroidUtilities.hideKeyboard(((Activity) getContext()).getCurrentFocus()); + } + } + } + if (getVisibility() == View.VISIBLE) { + return; + } + if (Build.VERSION.SDK_INT >= 14) { + ViewProxy.setAlpha(this, 1.0f); + ViewProxy.setTranslationY(this, 0); + this.clearAnimation(); + } + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + int selectedBackground = preferences.getInt("selectedBackground", 1000001); + boolean customTheme = false; + if (selectedBackground == 1000001) { + backgroundFrameLayout.setBackgroundColor(0xff517c9e); + } else { + backgroundDrawable = ApplicationLoader.getCachedWallpaper(); + if (backgroundDrawable != null) { + backgroundFrameLayout.setBackgroundColor(0xbf000000); + customTheme = true; + } else { + backgroundFrameLayout.setBackgroundColor(0xff517c9e); + } + } + + passcodeTextView.setText(LocaleController.getString("EnterYourPasscode", R.string.EnterYourPasscode)); + + if (UserConfig.passcodeType == 0) { + //InputFilter[] filterArray = new InputFilter[1]; + //filterArray[0] = new InputFilter.LengthFilter(4); + //passwordEditText.setFilters(filterArray); + //passwordEditText.setInputType(InputType.TYPE_CLASS_PHONE); + //passwordEditText.setFocusable(false); + //passwordEditText.setFocusableInTouchMode(false); + numbersFrameLayout.setVisibility(VISIBLE); + passwordEditText.setVisibility(GONE); + passwordEditText2.setVisibility(VISIBLE); + checkImage.setVisibility(GONE); + } else if (UserConfig.passcodeType == 1) { + passwordEditText.setFilters(new InputFilter[0]); + passwordEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); + numbersFrameLayout.setVisibility(GONE); + passwordEditText.setFocusable(true); + passwordEditText.setFocusableInTouchMode(true); + passwordEditText.setVisibility(VISIBLE); + passwordEditText2.setVisibility(GONE); + checkImage.setVisibility(VISIBLE); + } + setVisibility(VISIBLE); + passwordEditText.setTransformationMethod(PasswordTransformationMethod.getInstance()); + passwordEditText.setText(""); + passwordEditText2.eraseAllCharacters(false); + + setOnTouchListener(new OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int width = MeasureSpec.getSize(widthMeasureSpec); + int height = AndroidUtilities.displaySize.y - (Build.VERSION.SDK_INT >= 21 ? 0 : AndroidUtilities.statusBarHeight); + + LayoutParams layoutParams; + + if (!AndroidUtilities.isTablet() && getContext().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + layoutParams = (LayoutParams) passwordFrameLayout.getLayoutParams(); + layoutParams.width = UserConfig.passcodeType == 0 ? width / 2 : width; + layoutParams.height = AndroidUtilities.dp(140); + layoutParams.topMargin = (height - AndroidUtilities.dp(140)) / 2; + passwordFrameLayout.setLayoutParams(layoutParams); + + layoutParams = (LayoutParams) numbersFrameLayout.getLayoutParams(); + layoutParams.height = height; + layoutParams.leftMargin = width / 2; + layoutParams.topMargin = height - layoutParams.height; + layoutParams.width = width / 2; + numbersFrameLayout.setLayoutParams(layoutParams); + } else { + int top = 0; + int left = 0; + if (AndroidUtilities.isTablet()) { + if (width > AndroidUtilities.dp(498)) { + left = (width - AndroidUtilities.dp(498)) / 2; + width = AndroidUtilities.dp(498); + } + if (height > AndroidUtilities.dp(528)) { + top = (height - AndroidUtilities.dp(528)) / 2; + height = AndroidUtilities.dp(528); + } + } + layoutParams = (LayoutParams) passwordFrameLayout.getLayoutParams(); + layoutParams.height = height / 3; + layoutParams.width = width; + layoutParams.topMargin = top; + layoutParams.leftMargin = left; + passwordFrameLayout.setTag(top); + passwordFrameLayout.setLayoutParams(layoutParams); + + layoutParams = (LayoutParams) numbersFrameLayout.getLayoutParams(); + layoutParams.height = height / 3 * 2; + layoutParams.leftMargin = left; + layoutParams.topMargin = height - layoutParams.height + top; + layoutParams.width = width; + numbersFrameLayout.setLayoutParams(layoutParams); + } + + int sizeBetweenNumbersX = (layoutParams.width - AndroidUtilities.dp(50) * 3) / 4; + int sizeBetweenNumbersY = (layoutParams.height - AndroidUtilities.dp(50) * 4) / 5; + + for (int a = 0; a < 11; a++) { + LayoutParams layoutParams1; + int num; + if (a == 0) { + num = 10; + } else if (a == 10) { + num = 11; + } else { + num = a - 1; + } + int row = num / 3; + int col = num % 3; + int top; + if (a < 10) { + TextView textView = numberTextViews.get(a); + TextView textView1 = lettersTextViews.get(a); + layoutParams = (LayoutParams) textView.getLayoutParams(); + layoutParams1 = (LayoutParams) textView1.getLayoutParams(); + top = layoutParams1.topMargin = layoutParams.topMargin = sizeBetweenNumbersY + (sizeBetweenNumbersY + AndroidUtilities.dp(50)) * row; + layoutParams1.leftMargin = layoutParams.leftMargin = sizeBetweenNumbersX + (sizeBetweenNumbersX + AndroidUtilities.dp(50)) * col; + layoutParams1.topMargin += AndroidUtilities.dp(40); + textView.setLayoutParams(layoutParams); + textView1.setLayoutParams(layoutParams1); + } else { + layoutParams = (LayoutParams) eraseView.getLayoutParams(); + top = layoutParams.topMargin = sizeBetweenNumbersY + (sizeBetweenNumbersY + AndroidUtilities.dp(50)) * row + AndroidUtilities.dp(8); + layoutParams.leftMargin = sizeBetweenNumbersX + (sizeBetweenNumbersX + AndroidUtilities.dp(50)) * col; + top -= AndroidUtilities.dp(8); + eraseView.setLayoutParams(layoutParams); + } + + FrameLayout frameLayout = numberFrameLayouts.get(a); + layoutParams1 = (LayoutParams) frameLayout.getLayoutParams(); + layoutParams1.topMargin = top - AndroidUtilities.dp(17); + layoutParams1.leftMargin = layoutParams.leftMargin - AndroidUtilities.dp(25); + frameLayout.setLayoutParams(layoutParams1); + } + + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + View rootView = getRootView(); + int usableViewHeight = rootView.getHeight() - AndroidUtilities.statusBarHeight - AndroidUtilities.getViewInset(rootView); + getWindowVisibleDisplayFrame(rect); + keyboardHeight = usableViewHeight - (rect.bottom - rect.top); + + if (UserConfig.passcodeType == 1 && (AndroidUtilities.isTablet() || getContext().getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE)) { + int t = 0; + if (passwordFrameLayout.getTag() != 0) { + t = (Integer) passwordFrameLayout.getTag(); + } + LayoutParams layoutParams = (LayoutParams) passwordFrameLayout.getLayoutParams(); + layoutParams.topMargin = t + layoutParams.height - keyboardHeight / 2 - (Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0); + passwordFrameLayout.setLayoutParams(layoutParams); + } + + super.onLayout(changed, left, top, right, bottom); + } + + @Override + protected void onDraw(Canvas canvas) { + if (getVisibility() != VISIBLE) { + return; + } + if (backgroundDrawable != null) { + if (backgroundDrawable instanceof ColorDrawable) { + backgroundDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight()); + backgroundDrawable.draw(canvas); + } else { + float scaleX = (float) getMeasuredWidth() / (float) backgroundDrawable.getIntrinsicWidth(); + float scaleY = (float) (getMeasuredHeight() + keyboardHeight) / (float) backgroundDrawable.getIntrinsicHeight(); + float scale = scaleX < scaleY ? scaleY : scaleX; + int width = (int) Math.ceil(backgroundDrawable.getIntrinsicWidth() * scale); + int height = (int) Math.ceil(backgroundDrawable.getIntrinsicHeight() * scale); + int x = (getMeasuredWidth() - width) / 2; + int y = (getMeasuredHeight() - height + keyboardHeight) / 2; + backgroundDrawable.setBounds(x, y, x + width, y + height); + backgroundDrawable.draw(canvas); + } + } else { + super.onDraw(canvas); + } + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoCropView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoCropView.java new file mode 100644 index 000000000..5c19b596b --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoCropView.java @@ -0,0 +1,598 @@ +/* + * This is the source code of Telegram for Android v. 2.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-2015. + */ + +package org.telegram.ui.Components; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.RectF; +import android.view.MotionEvent; +import android.widget.FrameLayout; + +import org.telegram.android.AndroidUtilities; +import org.telegram.messenger.FileLog; + +public class PhotoCropView extends FrameLayout { + + public interface PhotoCropViewDelegate { + void needMoveImageTo(float x, float y, float s, boolean animated); + } + + private boolean freeformCrop = true; + private Paint rectPaint; + private Paint circlePaint; + private Paint halfPaint; + private Paint shadowPaint; + private float rectSizeX = 600; + private float rectSizeY = 600; + private int draggingState = 0; + private int orientation; + private float oldX = 0, oldY = 0; + private int bitmapWidth = 1, bitmapHeight = 1, bitmapX, bitmapY; + private float rectX = -1, rectY = -1; + private Bitmap bitmapToEdit; + private float bitmapGlobalScale = 1; + private float bitmapGlobalX = 0; + private float bitmapGlobalY = 0; + private PhotoCropViewDelegate delegate; + + private RectF animationStartValues; + private RectF animationEndValues; + private Runnable animationRunnable; + + public PhotoCropView(Context context) { + super(context); + + rectPaint = new Paint(); + rectPaint.setColor(0xb2ffffff); + rectPaint.setStrokeWidth(AndroidUtilities.dp(2)); + rectPaint.setStyle(Paint.Style.STROKE); + circlePaint = new Paint(); + circlePaint.setColor(0xffffffff); + halfPaint = new Paint(); + halfPaint.setColor(0x7f000000); + shadowPaint = new Paint(); + shadowPaint.setColor(0x1a000000); + setWillNotDraw(false); + } + + public void setBitmap(Bitmap bitmap, int rotation, boolean freeform) { + bitmapToEdit = bitmap; + rectSizeX = 600; + rectSizeY = 600; + draggingState = 0; + oldX = 0; + oldY = 0; + bitmapWidth = 1; + bitmapHeight = 1; + rectX = -1; + rectY = -1; + freeformCrop = freeform; + orientation = rotation; + requestLayout(); + } + + public boolean onTouch(MotionEvent motionEvent) { + if (motionEvent == null) { + draggingState = 0; + return false; + } + float x = motionEvent.getX(); + float y = motionEvent.getY(); + int cornerSide = AndroidUtilities.dp(20); + if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { + if (rectX - cornerSide < x && rectX + cornerSide > x && rectY - cornerSide < y && rectY + cornerSide > y) { + draggingState = 1; + } else if (rectX - cornerSide + rectSizeX < x && rectX + cornerSide + rectSizeX > x && rectY - cornerSide < y && rectY + cornerSide > y) { + draggingState = 2; + } else if (rectX - cornerSide < x && rectX + cornerSide > x && rectY - cornerSide + rectSizeY < y && rectY + cornerSide + rectSizeY > y) { + draggingState = 3; + } else if (rectX - cornerSide + rectSizeX < x && rectX + cornerSide + rectSizeX > x && rectY - cornerSide + rectSizeY < y && rectY + cornerSide + rectSizeY > y) { + draggingState = 4; + } else { + if (freeformCrop) { + if (rectX + cornerSide < x && rectX - cornerSide + rectSizeX > x && rectY - cornerSide < y && rectY + cornerSide > y) { + draggingState = 5; + } else if (rectY + cornerSide < y && rectY - cornerSide + rectSizeY > y && rectX - cornerSide + rectSizeX < x && rectX + cornerSide + rectSizeX > x) { + draggingState = 6; + } else if (rectY + cornerSide < y && rectY - cornerSide + rectSizeY > y && rectX - cornerSide < x && rectX + cornerSide > x) { + draggingState = 7; + } else if (rectX + cornerSide < x && rectX - cornerSide + rectSizeX > x && rectY - cornerSide + rectSizeY < y && rectY + cornerSide + rectSizeY > y) { + draggingState = 8; + } + } else { + draggingState = 0; + } + } + if (draggingState != 0) { + cancelAnimationRunnable(); + PhotoCropView.this.requestDisallowInterceptTouchEvent(true); + } + oldX = x; + oldY = y; + } else if (motionEvent.getAction() == MotionEvent.ACTION_UP) { + if (draggingState != 0) { + draggingState = 0; + startAnimationRunnable(); + return true; + } + } else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE && draggingState != 0) { + float diffX = x - oldX; + float diffY = y - oldY; + float bitmapScaledWidth = bitmapWidth * bitmapGlobalScale; + float bitmapScaledHeight = bitmapHeight * bitmapGlobalScale; + float bitmapStartX = (getWidth() - AndroidUtilities.dp(28) - bitmapScaledWidth) / 2 + bitmapGlobalX + AndroidUtilities.dp(14); + float bitmapStartY = (getHeight() - AndroidUtilities.dp(28) - bitmapScaledHeight) / 2 + bitmapGlobalY + AndroidUtilities.dp(14); + float bitmapEndX = bitmapStartX + bitmapScaledWidth; + float bitmapEndY = bitmapStartY + bitmapScaledHeight; + + float minSide = AndroidUtilities.getPixelsInCM(0.9f, true); + + if (draggingState == 1 || draggingState == 5) { + if (draggingState != 5) { + if (rectSizeX - diffX < minSide) { + diffX = rectSizeX - minSide; + } + if (rectX + diffX < bitmapX) { + diffX = bitmapX - rectX; + } + if (rectX + diffX < bitmapStartX) { + bitmapGlobalX -= bitmapStartX - rectX - diffX; + delegate.needMoveImageTo(bitmapGlobalX, bitmapGlobalY, bitmapGlobalScale, false); + } + } + if (!freeformCrop) { + if (rectY + diffX < bitmapY) { + diffX = bitmapY - rectY; + } + if (rectY + diffX < bitmapStartY) { + bitmapGlobalY -= bitmapStartY - rectY - diffX; + delegate.needMoveImageTo(bitmapGlobalX, bitmapGlobalY, bitmapGlobalScale, false); + } + rectX += diffX; + rectY += diffX; + rectSizeX -= diffX; + rectSizeY -= diffX; + } else { + if (rectSizeY - diffY < minSide) { + diffY = rectSizeY - minSide; + } + if (rectY + diffY < bitmapY) { + diffY = bitmapY - rectY; + } + if (rectY + diffY < bitmapStartY) { + bitmapGlobalY -= bitmapStartY - rectY - diffY; + delegate.needMoveImageTo(bitmapGlobalX, bitmapGlobalY, bitmapGlobalScale, false); + } + if (draggingState != 5) { + rectX += diffX; + rectSizeX -= diffX; + } + rectY += diffY; + rectSizeY -= diffY; + } + } else if (draggingState == 2 || draggingState == 6) { + if (rectSizeX + diffX < minSide) { + diffX = -(rectSizeX - minSide); + } + if (rectX + rectSizeX + diffX > bitmapX + bitmapWidth) { + diffX = bitmapX + bitmapWidth - rectX - rectSizeX; + } + if (rectX + rectSizeX + diffX > bitmapEndX) { + bitmapGlobalX -= bitmapEndX - rectX - rectSizeX - diffX; + delegate.needMoveImageTo(bitmapGlobalX, bitmapGlobalY, bitmapGlobalScale, false); + } + if (!freeformCrop) { + if (rectY - diffX < bitmapY) { + diffX = rectY - bitmapY; + } + if (rectY - diffX < bitmapStartY) { + bitmapGlobalY -= bitmapStartY - rectY + diffX; + delegate.needMoveImageTo(bitmapGlobalX, bitmapGlobalY, bitmapGlobalScale, false); + } + rectY -= diffX; + rectSizeX += diffX; + rectSizeY += diffX; + } else { + if (draggingState != 6) { + if (rectSizeY - diffY < minSide) { + diffY = rectSizeY - minSide; + } + if (rectY + diffY < bitmapY) { + diffY = bitmapY - rectY; + } + if (rectY + diffY < bitmapStartY) { + bitmapGlobalY -= bitmapStartY - rectY - diffY; + delegate.needMoveImageTo(bitmapGlobalX, bitmapGlobalY, bitmapGlobalScale, false); + } + rectY += diffY; + rectSizeY -= diffY; + } + rectSizeX += diffX; + } + } else if (draggingState == 3 || draggingState == 7) { + if (rectSizeX - diffX < minSide) { + diffX = rectSizeX - minSide; + } + if (rectX + diffX < bitmapX) { + diffX = bitmapX - rectX; + } + if (rectX + diffX < bitmapStartX) { + bitmapGlobalX -= bitmapStartX - rectX - diffX; + delegate.needMoveImageTo(bitmapGlobalX, bitmapGlobalY, bitmapGlobalScale, false); + } + if (!freeformCrop) { + if (rectY + rectSizeX - diffX > bitmapY + bitmapHeight) { + diffX = rectY + rectSizeX - bitmapY - bitmapHeight; + } + if (rectY + rectSizeX - diffX > bitmapEndY) { + bitmapGlobalY -= bitmapEndY - rectY - rectSizeX + diffX; + delegate.needMoveImageTo(bitmapGlobalX, bitmapGlobalY, bitmapGlobalScale, false); + } + rectX += diffX; + rectSizeX -= diffX; + rectSizeY -= diffX; + } else { + if (draggingState != 7) { + if (rectY + rectSizeY + diffY > bitmapY + bitmapHeight) { + diffY = bitmapY + bitmapHeight - rectY - rectSizeY; + } + if (rectY + rectSizeY + diffY > bitmapEndY) { + bitmapGlobalY -= bitmapEndY - rectY - rectSizeY - diffY; + delegate.needMoveImageTo(bitmapGlobalX, bitmapGlobalY, bitmapGlobalScale, false); + } + rectSizeY += diffY; + if (rectSizeY < minSide) { + rectSizeY = minSide; + } + } + rectX += diffX; + rectSizeX -= diffX; + } + } else if (draggingState == 4 || draggingState == 8) { + if (draggingState != 8) { + if (rectX + rectSizeX + diffX > bitmapX + bitmapWidth) { + diffX = bitmapX + bitmapWidth - rectX - rectSizeX; + } + if (rectX + rectSizeX + diffX > bitmapEndX) { + bitmapGlobalX -= bitmapEndX - rectX - rectSizeX - diffX; + delegate.needMoveImageTo(bitmapGlobalX, bitmapGlobalY, bitmapGlobalScale, false); + } + } + if (!freeformCrop) { + if (rectY + rectSizeX + diffX > bitmapY + bitmapHeight) { + diffX = bitmapY + bitmapHeight - rectY - rectSizeX; + } + if (rectY + rectSizeX + diffX > bitmapEndY) { + bitmapGlobalY -= bitmapEndY - rectY - rectSizeX - diffX; + delegate.needMoveImageTo(bitmapGlobalX, bitmapGlobalY, bitmapGlobalScale, false); + } + rectSizeX += diffX; + rectSizeY += diffX; + } else { + if (rectY + rectSizeY + diffY > bitmapY + bitmapHeight) { + diffY = bitmapY + bitmapHeight - rectY - rectSizeY; + } + if (rectY + rectSizeY + diffY > bitmapEndY) { + bitmapGlobalY -= bitmapEndY - rectY - rectSizeY - diffY; + delegate.needMoveImageTo(bitmapGlobalX, bitmapGlobalY, bitmapGlobalScale, false); + } + if (draggingState != 8) { + rectSizeX += diffX; + } + rectSizeY += diffY; + } + if (rectSizeX < minSide) { + rectSizeX = minSide; + } + if (rectSizeY < minSide) { + rectSizeY = minSide; + } + } + + oldX = x; + oldY = y; + invalidate(); + } + return draggingState != 0; + } + + public float getRectX() { + return rectX - AndroidUtilities.dp(14); + } + + public float getRectY() { + return rectY - AndroidUtilities.dp(14); + } + + public float getRectSizeX() { + return rectSizeX; + } + + public float getRectSizeY() { + return rectSizeY; + } + + public float getBitmapX() { + return bitmapX - AndroidUtilities.dp(14); + } + + public float getBitmapY() { + return bitmapY - AndroidUtilities.dp(14); + } + + public float getLimitX() { + return rectX - ((int) Math.max(0, Math.ceil((getWidth() - AndroidUtilities.dp(28) - bitmapWidth * bitmapGlobalScale) / 2)) + AndroidUtilities.dp(14)); + } + + public float getLimitY() { + return rectY - ((int) Math.max(0, Math.ceil((getHeight() - AndroidUtilities.dp(28) - bitmapHeight * bitmapGlobalScale) / 2)) + AndroidUtilities.dp(14)); + } + + public float getLimitWidth() { + return getWidth() - AndroidUtilities.dp(14) - rectX - (int) Math.max(0, Math.ceil((getWidth() - AndroidUtilities.dp(28) - bitmapWidth * bitmapGlobalScale) / 2)) - rectSizeX; + } + + public float getLimitHeight() { + return getHeight() - AndroidUtilities.dp(14) - rectY - (int) Math.max(0, Math.ceil((getHeight() - AndroidUtilities.dp(28) - bitmapHeight * bitmapGlobalScale) / 2)) - rectSizeY; + } + + private Bitmap createBitmap(int x, int y, int w, int h) { + Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + Paint paint = new Paint(); + paint.setFilterBitmap(true); + + Matrix matrix = new Matrix(); + matrix.setTranslate(-bitmapToEdit.getWidth() / 2, -bitmapToEdit.getHeight() / 2); + matrix.postRotate(orientation); + if (orientation == 90 || orientation == 270) { + matrix.postTranslate(bitmapToEdit.getHeight() / 2 - x, bitmapToEdit.getWidth() / 2 - y); + } else { + matrix.postTranslate(bitmapToEdit.getWidth() / 2 - x, bitmapToEdit.getHeight() / 2 - y); + } + canvas.drawBitmap(bitmapToEdit, matrix, paint); + try { + canvas.setBitmap(null); + } catch (Exception e) { + //don't promt, this will crash on 2.x + } + + return bitmap; + } + + public Bitmap getBitmap() { + float bitmapScaledWidth = bitmapWidth * bitmapGlobalScale; + float bitmapScaledHeight = bitmapHeight * bitmapGlobalScale; + float bitmapStartX = (getWidth() - AndroidUtilities.dp(28) - bitmapScaledWidth) / 2 + bitmapGlobalX + AndroidUtilities.dp(14); + float bitmapStartY = (getHeight() - AndroidUtilities.dp(28) - bitmapScaledHeight) / 2 + bitmapGlobalY + AndroidUtilities.dp(14); + + float percX = (rectX - bitmapStartX) / bitmapScaledWidth; + float percY = (rectY - bitmapStartY) / bitmapScaledHeight; + float percSizeX = rectSizeX / bitmapScaledWidth; + float percSizeY = rectSizeY / bitmapScaledHeight; + + int width; + int height; + if (orientation == 90 || orientation == 270) { + width = bitmapToEdit.getHeight(); + height = bitmapToEdit.getWidth(); + } else { + width = bitmapToEdit.getWidth(); + height = bitmapToEdit.getHeight(); + } + + int x = (int) (percX * width); + int y = (int) (percY * height); + int sizeX = (int) (percSizeX * width); + int sizeY = (int) (percSizeY * height); + if (x < 0) { + x = 0; + } + if (y < 0) { + y = 0; + } + if (x + sizeX > width) { + sizeX = width - x; + } + if (y + sizeY > height) { + sizeY = height - y; + } + try { + return createBitmap(x, y, sizeX, sizeY); + } catch (Throwable e) { + FileLog.e("tmessags", e); + System.gc(); + try { + return createBitmap(x, y, sizeX, sizeY); + } catch (Throwable e2) { + FileLog.e("tmessages", e2); + } + } + return null; + } + + @Override + protected void onDraw(Canvas canvas) { + canvas.drawRect(0, 0, getWidth(), rectY, halfPaint); + canvas.drawRect(0, rectY, rectX, rectY + rectSizeY, halfPaint); + canvas.drawRect(rectX + rectSizeX, rectY, getWidth(), rectY + rectSizeY, halfPaint); + canvas.drawRect(0, rectY + rectSizeY, getWidth(), getHeight(), halfPaint); + + int side = AndroidUtilities.dp(1); + canvas.drawRect(rectX - side * 2, rectY - side * 2, rectX - side * 2 + AndroidUtilities.dp(20), rectY, circlePaint); + canvas.drawRect(rectX - side * 2, rectY - side * 2, rectX, rectY - side * 2 + AndroidUtilities.dp(20), circlePaint); + + canvas.drawRect(rectX + rectSizeX + side * 2 - AndroidUtilities.dp(20), rectY - side * 2, rectX + rectSizeX + side * 2, rectY, circlePaint); + canvas.drawRect(rectX + rectSizeX, rectY - side * 2, rectX + rectSizeX + side * 2, rectY - side * 2 + AndroidUtilities.dp(20), circlePaint); + + canvas.drawRect(rectX - side * 2, rectY + rectSizeY + side * 2 - AndroidUtilities.dp(20), rectX, rectY + rectSizeY + side * 2, circlePaint); + canvas.drawRect(rectX - side * 2, rectY + rectSizeY, rectX - side * 2 + AndroidUtilities.dp(20), rectY + rectSizeY + side * 2, circlePaint); + + canvas.drawRect(rectX + rectSizeX + side * 2 - AndroidUtilities.dp(20), rectY + rectSizeY, rectX + rectSizeX + side * 2, rectY + rectSizeY + side * 2, circlePaint); + canvas.drawRect(rectX + rectSizeX, rectY + rectSizeY + side * 2 - AndroidUtilities.dp(20), rectX + rectSizeX + side * 2, rectY + rectSizeY + side * 2, circlePaint); + + for (int a = 1; a < 3; a++) { + canvas.drawRect(rectX + rectSizeX / 3 * a - side, rectY, rectX + side * 2 + rectSizeX / 3 * a, rectY + rectSizeY, shadowPaint); + canvas.drawRect(rectX, rectY + rectSizeY / 3 * a - side, rectX + rectSizeX, rectY + rectSizeY / 3 * a + side * 2, shadowPaint); + } + + for (int a = 1; a < 3; a++) { + canvas.drawRect(rectX + rectSizeX / 3 * a, rectY, rectX + side + rectSizeX / 3 * a, rectY + rectSizeY, circlePaint); + canvas.drawRect(rectX, rectY + rectSizeY / 3 * a, rectX + rectSizeX, rectY + rectSizeY / 3 * a + side, circlePaint); + } + + canvas.drawRect(rectX, rectY, rectX + rectSizeX, rectY + rectSizeY, rectPaint); + } + + public void setBitmapParams(float scale, float x, float y) { + bitmapGlobalScale = scale; + bitmapGlobalX = x; + bitmapGlobalY = y; + } + + public void startAnimationRunnable() { + if (animationRunnable != null) { + return; + } + animationRunnable = new Runnable() { + @Override + public void run() { + if (animationRunnable == this) { + animationRunnable = null; + animateToFill(); + } + } + }; + AndroidUtilities.runOnUIThread(animationRunnable, 1500); + } + + public void cancelAnimationRunnable() { + if (animationRunnable != null) { + AndroidUtilities.cancelRunOnUIThread(animationRunnable); + animationRunnable = null; + animationStartValues = null; + animationEndValues = null; + } + } + + public void setAnimationProgress(float animationProgress) { + if (animationStartValues != null) { + if (animationProgress == 1) { + rectX = animationEndValues.left; + rectY = animationEndValues.top; + rectSizeX = animationEndValues.right; + rectSizeY = animationEndValues.bottom; + animationStartValues = null; + animationEndValues = null; + } else { + rectX = animationStartValues.left + (animationEndValues.left - animationStartValues.left) * animationProgress; + rectY = animationStartValues.top + (animationEndValues.top - animationStartValues.top) * animationProgress; + rectSizeX = animationStartValues.right + (animationEndValues.right - animationStartValues.right) * animationProgress; + rectSizeY = animationStartValues.bottom + (animationEndValues.bottom - animationStartValues.bottom) * animationProgress; + } + invalidate(); + } + } + + public void animateToFill() { + float scaleToX = bitmapWidth / rectSizeX; + float scaleToY = bitmapHeight / rectSizeY; + float scaleTo = scaleToX > scaleToY ? scaleToY : scaleToX; + if (scaleTo > 1 && scaleTo * bitmapGlobalScale > 3) { + scaleTo = 3 / bitmapGlobalScale; + } else if (scaleTo < 1 && scaleTo * bitmapGlobalScale < 1) { + scaleTo = 1 / bitmapGlobalScale; + } + float newSizeX = rectSizeX * scaleTo; + float newSizeY = rectSizeY * scaleTo; + float newX = (getWidth() - AndroidUtilities.dp(28) - newSizeX) / 2 + AndroidUtilities.dp(14); + float newY = (getHeight() - AndroidUtilities.dp(28) - newSizeY) / 2 + AndroidUtilities.dp(14); + animationStartValues = new RectF(rectX, rectY, rectSizeX, rectSizeY); + animationEndValues = new RectF(newX, newY, newSizeX, newSizeY); + + float newBitmapGlobalX = newX + getWidth() / 2 * (scaleTo - 1) + (bitmapGlobalX - rectX) * scaleTo; + float newBitmapGlobalY = newY + getHeight() / 2 * (scaleTo - 1) + (bitmapGlobalY - rectY) * scaleTo; + + delegate.needMoveImageTo(newBitmapGlobalX, newBitmapGlobalY, bitmapGlobalScale * scaleTo, true); + } + + public void setDelegate(PhotoCropViewDelegate delegate) { + this.delegate = delegate; + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + + if (bitmapToEdit == null) { + return; + } + + int viewWidth = getWidth() - AndroidUtilities.dp(28); + int viewHeight = getHeight() - AndroidUtilities.dp(28); + + float bitmapW; + float bitmapH; + if (orientation == 90 || orientation == 270) { + bitmapW = bitmapToEdit.getHeight(); + bitmapH = bitmapToEdit.getWidth(); + } else { + bitmapW = bitmapToEdit.getWidth(); + bitmapH = bitmapToEdit.getHeight(); + } + float scaleX = viewWidth / bitmapW; + float scaleY = viewHeight / bitmapH; + if (scaleX > scaleY) { + bitmapH = viewHeight; + bitmapW = (int) Math.ceil(bitmapW * scaleY); + } else { + bitmapW = viewWidth; + bitmapH = (int) Math.ceil(bitmapH * scaleX); + } + + float percX = (rectX - bitmapX) / bitmapWidth; + float percY = (rectY - bitmapY) / bitmapHeight; + float percSizeX = rectSizeX / bitmapWidth; + float percSizeY = rectSizeY / bitmapHeight; + bitmapWidth = (int) bitmapW; + bitmapHeight = (int) bitmapH; + + bitmapX = (int) Math.ceil((viewWidth - bitmapWidth) / 2 + AndroidUtilities.dp(14)); + bitmapY = (int) Math.ceil((viewHeight - bitmapHeight) / 2 + AndroidUtilities.dp(14)); + + if (rectX == -1 && rectY == -1) { + if (freeformCrop) { + rectY = bitmapY; + rectX = bitmapX; + rectSizeX = bitmapWidth; + rectSizeY = bitmapHeight; + } else { + if (bitmapWidth > bitmapHeight) { + rectY = bitmapY; + rectX = (viewWidth - bitmapHeight) / 2 + AndroidUtilities.dp(14); + rectSizeX = bitmapHeight; + rectSizeY = bitmapHeight; + } else { + rectX = bitmapX; + rectY = (viewHeight - bitmapWidth) / 2 + AndroidUtilities.dp(14); + rectSizeX = bitmapWidth; + rectSizeY = bitmapWidth; + } + } + } else { + rectX = percX * bitmapWidth + bitmapX; + rectY = percY * bitmapHeight + bitmapY; + rectSizeX = percSizeX * bitmapWidth; + rectSizeY = percSizeY * bitmapHeight; + } + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoEditorSeekBar.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoEditorSeekBar.java new file mode 100644 index 000000000..bb92aa8ea --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoEditorSeekBar.java @@ -0,0 +1,132 @@ +/* + * This is the source code of Telegram for Android v. 2.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-2015. + */ + +package org.telegram.ui.Components; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.view.MotionEvent; +import android.view.View; + +import org.telegram.android.AndroidUtilities; + +public class PhotoEditorSeekBar extends View { + + private Paint innerPaint = new Paint(); + private Paint outerPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + private int thumbSize = AndroidUtilities.dp(16); + private int thumbDX = 0; + private float progress = 0; + private boolean pressed = false; + private int minValue; + private int maxValue; + private PhotoEditorSeekBarDelegate delegate; + + public interface PhotoEditorSeekBarDelegate { + void onProgressChanged(); + } + + public PhotoEditorSeekBar(Context context) { + super(context); + + innerPaint.setColor(0x99383838); + outerPaint.setColor(0xff53aeef); + } + + public void setDelegate(PhotoEditorSeekBarDelegate delegate) { + this.delegate = delegate; + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (event == null) { + return false; + } + float x = event.getX(); + float y = event.getY(); + float thumbX = (int)((getMeasuredWidth() - thumbSize) * progress); + if (event.getAction() == MotionEvent.ACTION_DOWN) { + int additionWidth = (getMeasuredHeight() - thumbSize) / 2; + if (thumbX - additionWidth <= x && x <= thumbX + thumbSize + additionWidth && y >= 0 && y <= getMeasuredHeight()) { + pressed = true; + thumbDX = (int)(x - thumbX); + getParent().requestDisallowInterceptTouchEvent(true); + invalidate(); + return true; + } + } else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) { + if (pressed) { + pressed = false; + invalidate(); + return true; + } + } else if (event.getAction() == MotionEvent.ACTION_MOVE) { + if (pressed) { + thumbX = (int)(x - thumbDX); + if (thumbX < 0) { + thumbX = 0; + } else if (thumbX > getMeasuredWidth() - thumbSize) { + thumbX = getMeasuredWidth() - thumbSize; + } + progress = thumbX / (getMeasuredWidth() - thumbSize); + if (delegate != null) { + delegate.onProgressChanged(); + } + invalidate(); + return true; + } + } + return false; + } + + public void setProgress(int progress) { + setProgress(progress, true); + } + + public void setProgress(int progress, boolean notify) { + if (progress < minValue) { + progress = minValue; + } else if (progress > maxValue) { + progress = maxValue; + } + this.progress = (progress - minValue) / (float) (maxValue - minValue); + invalidate(); + if (notify && delegate != null) { + delegate.onProgressChanged(); + } + } + + public int getProgress() { + return (int) (minValue + progress * (maxValue - minValue)); + } + + public void setMinMax(int min, int max) { + minValue = min; + maxValue = max; + } + + @Override + protected void onDraw(Canvas canvas) { + int y = (getMeasuredHeight() - thumbSize) / 2; + int thumbX = (int)((getMeasuredWidth() - thumbSize) * progress); + canvas.drawRect(thumbSize / 2, getMeasuredHeight() / 2 - AndroidUtilities.dp(1), getMeasuredWidth() - thumbSize / 2, getMeasuredHeight() / 2 + AndroidUtilities.dp(1), innerPaint); + if (minValue == 0) { + canvas.drawRect(thumbSize / 2, getMeasuredHeight() / 2 - AndroidUtilities.dp(1), thumbX, getMeasuredHeight() / 2 + AndroidUtilities.dp(1), outerPaint); + } else { + if (progress > 0.5f) { + canvas.drawRect(getMeasuredWidth() / 2 - AndroidUtilities.dp(1), (getMeasuredHeight() - thumbSize) / 2, getMeasuredWidth() / 2, (getMeasuredHeight() + thumbSize) / 2, outerPaint); + canvas.drawRect(getMeasuredWidth() / 2, getMeasuredHeight() / 2 - AndroidUtilities.dp(1), thumbX, getMeasuredHeight() / 2 + AndroidUtilities.dp(1), outerPaint); + } else { + canvas.drawRect(getMeasuredWidth() / 2, (getMeasuredHeight() - thumbSize) / 2, getMeasuredWidth() / 2 + AndroidUtilities.dp(1), (getMeasuredHeight() + thumbSize) / 2, outerPaint); + canvas.drawRect(thumbX, getMeasuredHeight() / 2 - AndroidUtilities.dp(1), getMeasuredWidth() / 2, getMeasuredHeight() / 2 + AndroidUtilities.dp(1), outerPaint); + } + } + canvas.drawCircle(thumbX + thumbSize / 2, y + thumbSize / 2, thumbSize / 2, outerPaint); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoFilterBlurControl.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoFilterBlurControl.java new file mode 100644 index 000000000..8fb291765 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoFilterBlurControl.java @@ -0,0 +1,499 @@ +/* + * This is the source code of Telegram for Android v. 2.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-2015. + */ + +package org.telegram.ui.Components; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; +import android.view.MotionEvent; +import android.widget.FrameLayout; + +import org.telegram.android.AndroidUtilities; + +public class PhotoFilterBlurControl extends FrameLayout { + + public interface PhotoFilterLinearBlurControlDelegate { + void valueChanged(Point centerPoint, float falloff, float size, float angle); + } + + private final static float BlurInsetProximity = AndroidUtilities.dp(20); + private final static float BlurMinimumFalloff = 0.1f; + private final static float BlurMinimumDifference = 0.02f; + private final static float BlurViewCenterInset = AndroidUtilities.dp(30.0f); + private final static float BlurViewRadiusInset = AndroidUtilities.dp(30.0f); + + private enum BlurViewActiveControl { + BlurViewActiveControlNone, + BlurViewActiveControlCenter, + BlurViewActiveControlInnerRadius, + BlurViewActiveControlOuterRadius, + BlurViewActiveControlWholeArea, + BlurViewActiveControlRotation + } + + private final int GestureStateBegan = 1; + private final int GestureStateChanged = 2; + private final int GestureStateEnded = 3; + private final int GestureStateCancelled = 4; + private final int GestureStateFailed = 5; + + private BlurViewActiveControl activeControl; + private Point startCenterPoint = new Point(); + private float startDistance; + private float startRadius; + private Size actualAreaSize = new Size(); + private Point centerPoint = new Point(0.5f, 0.5f); + private float falloff = 0.15f; + private float size = 0.35f; + private float angle; + private RectF arcRect = new RectF(); + + private float pointerStartX; + private float pointerStartY; + private float startPointerDistance; + private float pointerScale = 1; + private boolean isMoving; + private boolean isZooming; + private boolean checkForMoving; + private boolean checkForZooming; + + private int type; + + private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); + private Paint arcPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + + private PhotoFilterLinearBlurControlDelegate delegate; + + public PhotoFilterBlurControl(Context context) { + super(context); + setWillNotDraw(false); + paint.setColor(0xffffffff); + arcPaint.setColor(0xffffffff); + arcPaint.setStrokeWidth(AndroidUtilities.dp(2)); + arcPaint.setStyle(Paint.Style.STROKE); + } + + public void setType(int blurType) { + type = blurType; + } + + public void setDelegate(PhotoFilterLinearBlurControlDelegate delegate) { + this.delegate = delegate; + } + + private float getDistance(MotionEvent event) { + if (event.getPointerCount() != 2) { + return 0; + } + float x1 = event.getX(0); + float y1 = event.getY(0); + float x2 = event.getX(1); + float y2 = event.getY(1); + return (float) Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); + } + + private float degreesToRadians(float degrees) { + return degrees * (float) Math.PI / 180.0f; + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + int action = event.getActionMasked(); + + switch (action) { + case MotionEvent.ACTION_POINTER_DOWN: + case MotionEvent.ACTION_DOWN: { + if (event.getPointerCount() == 1) { + if (checkForMoving && !isMoving) { + float locationX = event.getX(); + float locationY = event.getY(); + Point centerPoint = getActualCenterPoint(); + Point delta = new Point(locationX - centerPoint.x, locationY - centerPoint.y); + float radialDistance = (float) Math.sqrt(delta.x * delta.x + delta.y * delta.y); + float innerRadius = getActualInnerRadius(); + float outerRadius = getActualOuterRadius(); + boolean close = Math.abs(outerRadius - innerRadius) < BlurInsetProximity; + float innerRadiusOuterInset = close ? 0 : BlurViewRadiusInset; + float outerRadiusInnerInset = close ? 0 : BlurViewRadiusInset; + + if (type == 0) { + float distance = (float) Math.abs(delta.x * Math.cos(degreesToRadians(angle) + Math.PI / 2) + delta.y * Math.sin(degreesToRadians(angle) + Math.PI / 2)); + if (radialDistance < BlurViewCenterInset) { + isMoving = true; + } else if (distance > innerRadius - BlurViewRadiusInset && distance < innerRadius + innerRadiusOuterInset) { + isMoving = true; + } else if (distance > outerRadius - outerRadiusInnerInset && distance < outerRadius + BlurViewRadiusInset) { + isMoving = true; + } else if ((distance <= innerRadius - BlurViewRadiusInset) || distance >= outerRadius + BlurViewRadiusInset) { + isMoving = true; + } + } else if (type == 1) { + if (radialDistance < BlurViewCenterInset) { + isMoving = true; + } else if (radialDistance > innerRadius - BlurViewRadiusInset && radialDistance < innerRadius + innerRadiusOuterInset) { + isMoving = true; + } else if (radialDistance > outerRadius - outerRadiusInnerInset && radialDistance < outerRadius + BlurViewRadiusInset) { + isMoving = true; + } + } + checkForMoving = false; + if (isMoving) { + handlePan(GestureStateBegan, event); + } + } + } else { + if (isMoving) { + handlePan(GestureStateEnded, event); + checkForMoving = true; + isMoving = false; + } + if (event.getPointerCount() == 2) { + if (checkForZooming && !isZooming) { + handlePinch(GestureStateBegan, event); + isZooming = true; + } + } else { + handlePinch(GestureStateEnded, event); + checkForZooming = true; + isZooming = false; + } + } + break; + } + + case MotionEvent.ACTION_POINTER_UP: + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: { + if (isMoving) { + handlePan(GestureStateEnded, event); + isMoving = false; + } else if (isZooming) { + handlePinch(GestureStateEnded, event); + isZooming = false; + } + checkForMoving = true; + checkForZooming = true; + break; + } + + case MotionEvent.ACTION_MOVE: { + if (isMoving) { + handlePan(GestureStateChanged, event); + } else if (isZooming) { + handlePinch(GestureStateChanged, event); + } + } + } + return true; + } + + private void handlePan(int state, MotionEvent event) { + float locationX = event.getX(); + float locationY = event.getY(); + Point actualCenterPoint = getActualCenterPoint(); + Point delta = new Point(locationX - actualCenterPoint.x, locationY - actualCenterPoint.y); + float radialDistance = (float) Math.sqrt(delta.x * delta.x + delta.y * delta.y); + float shorterSide = (actualAreaSize.width > actualAreaSize.height) ? actualAreaSize.height : actualAreaSize.width; + float innerRadius = shorterSide * falloff; + float outerRadius = shorterSide * size; + float distance = (float) Math.abs(delta.x * Math.cos(degreesToRadians(angle) + Math.PI / 2.0f) + delta.y * Math.sin(degreesToRadians(angle) + Math.PI / 2.0f)); + + switch (state) { + case GestureStateBegan: { + pointerStartX = event.getX(); + pointerStartY = event.getY(); + + boolean close = Math.abs(outerRadius - innerRadius) < BlurInsetProximity; + float innerRadiusOuterInset = close ? 0 : BlurViewRadiusInset; + float outerRadiusInnerInset = close ? 0 : BlurViewRadiusInset; + + if (type == 0) { + if (radialDistance < BlurViewCenterInset) { + activeControl = BlurViewActiveControl.BlurViewActiveControlCenter; + startCenterPoint = actualCenterPoint; + } else if (distance > innerRadius - BlurViewRadiusInset && distance < innerRadius + innerRadiusOuterInset) { + activeControl = BlurViewActiveControl.BlurViewActiveControlInnerRadius; + startDistance = distance; + startRadius = innerRadius; + } else if (distance > outerRadius - outerRadiusInnerInset && distance < outerRadius + BlurViewRadiusInset) { + activeControl = BlurViewActiveControl.BlurViewActiveControlOuterRadius; + startDistance = distance; + startRadius = outerRadius; + } else if (distance <= innerRadius - BlurViewRadiusInset || distance >= outerRadius + BlurViewRadiusInset) { + activeControl = BlurViewActiveControl.BlurViewActiveControlRotation; + } + } else if (type == 1) { + if (radialDistance < BlurViewCenterInset) { + activeControl = BlurViewActiveControl.BlurViewActiveControlCenter; + startCenterPoint = actualCenterPoint; + } else if (radialDistance > innerRadius - BlurViewRadiusInset && radialDistance < innerRadius + innerRadiusOuterInset) { + activeControl = BlurViewActiveControl.BlurViewActiveControlInnerRadius; + startDistance = radialDistance; + startRadius = innerRadius; + } else if (radialDistance > outerRadius - outerRadiusInnerInset && radialDistance < outerRadius + BlurViewRadiusInset) { + activeControl = BlurViewActiveControl.BlurViewActiveControlOuterRadius; + startDistance = radialDistance; + startRadius = outerRadius; + } + } + setSelected(true, true); + } + break; + + case GestureStateChanged: { + if (type == 0) { + switch (activeControl) { + case BlurViewActiveControlCenter: { + float translationX = locationX - pointerStartX; + float translationY = locationY - pointerStartY; + Rect actualArea = new Rect((getWidth() - actualAreaSize.width) / 2, (getHeight() - actualAreaSize.height) / 2, actualAreaSize.width, actualAreaSize.height); + Point newPoint = new Point(Math.max(actualArea.x, Math.min(actualArea.x + actualArea.width, startCenterPoint.x + translationX)), Math.max(actualArea.y, Math.min(actualArea.y + actualArea.height, startCenterPoint.y + translationY))); + centerPoint = new Point((newPoint.x - actualArea.x) / actualAreaSize.width, ((newPoint.y - actualArea.y) + (actualAreaSize.width - actualAreaSize.height) / 2) / actualAreaSize.width); + } + break; + + case BlurViewActiveControlInnerRadius: { + float d = distance - startDistance; + falloff = Math.min(Math.max(BlurMinimumFalloff, (startRadius + d) / shorterSide), size - BlurMinimumDifference); + } + break; + + case BlurViewActiveControlOuterRadius: { + float d = distance - startDistance; + size = Math.max(falloff + BlurMinimumDifference, (startRadius + d) / shorterSide); + } + break; + + case BlurViewActiveControlRotation: { + float translationX = locationX - pointerStartX; + float translationY = locationY - pointerStartY; + + boolean clockwise = false; + + boolean right = locationX > actualCenterPoint.x; + boolean bottom = locationY > actualCenterPoint.y; + + if (!right && !bottom) { + if (Math.abs(translationY) > Math.abs(translationX)) { + if (translationY < 0) { + clockwise = true; + } + } else { + if (translationX > 0) { + clockwise = true; + } + } + } else if (right && !bottom) { + if (Math.abs(translationY) > Math.abs(translationX)) { + if (translationY > 0) { + clockwise = true; + } + } else { + if (translationX > 0) { + clockwise = true; + } + } + } else if (right && bottom) { + if (Math.abs(translationY) > Math.abs(translationX)) { + if (translationY > 0) { + clockwise = true; + } + } else { + if (translationX < 0) { + clockwise = true; + } + } + } else { + if (Math.abs(translationY) > Math.abs(translationX)) { + if (translationY < 0) { + clockwise = true; + } + } else { + if (translationX < 0) { + clockwise = true; + } + } + } + + float d = (float) Math.sqrt(translationX * translationX + translationY * translationY); + angle += d * ((clockwise ? 1 : 0) * 2 - 1) / (float) Math.PI / 1.15f; + + pointerStartX = locationX; + pointerStartY = locationY; + } + break; + + default: + break; + } + } else if (type == 1) { + switch (activeControl) { + case BlurViewActiveControlCenter: { + float translationX = locationX - pointerStartX; + float translationY = locationY - pointerStartY; + Rect actualArea = new Rect((getWidth() - actualAreaSize.width) / 2, (getHeight() - actualAreaSize.height) / 2, actualAreaSize.width, actualAreaSize.height); + Point newPoint = new Point(Math.max(actualArea.x, Math.min(actualArea.x + actualArea.width, startCenterPoint.x + translationX)), Math.max(actualArea.y, Math.min(actualArea.y + actualArea.height, startCenterPoint.y + translationY))); + centerPoint = new Point((newPoint.x - actualArea.x) / actualAreaSize.width, ((newPoint.y - actualArea.y) + (actualAreaSize.width - actualAreaSize.height) / 2) / actualAreaSize.width); + } + break; + + case BlurViewActiveControlInnerRadius: { + float d = radialDistance - startDistance; + falloff = Math.min(Math.max(BlurMinimumFalloff, (startRadius + d) / shorterSide), size - BlurMinimumDifference); + } + break; + + case BlurViewActiveControlOuterRadius: { + float d = radialDistance - startDistance; + size = Math.max(falloff + BlurMinimumDifference, (startRadius + d) / shorterSide); + } + break; + + default: + break; + } + } + invalidate(); + + if (delegate != null) { + delegate.valueChanged(centerPoint, falloff, size, degreesToRadians(angle) + (float) Math.PI / 2.0f); + } + } + break; + + case GestureStateEnded: + case GestureStateCancelled: + case GestureStateFailed: { + activeControl = BlurViewActiveControl.BlurViewActiveControlNone; + setSelected(false, true); + } + break; + + default: + break; + } + } + + private void handlePinch(int state, MotionEvent event) { + + switch (state) { + case GestureStateBegan: { + startPointerDistance = getDistance(event); + pointerScale = 1; + activeControl = BlurViewActiveControl.BlurViewActiveControlWholeArea; + setSelected(true, true); + } + case GestureStateChanged: { + float newDistance = getDistance(event); + pointerScale += (newDistance - startPointerDistance) / AndroidUtilities.density * 0.01f; + + falloff = Math.max(BlurMinimumFalloff, falloff * pointerScale); + size = Math.max(falloff + BlurMinimumDifference, size * pointerScale); + + pointerScale = 1; + startPointerDistance = newDistance; + + invalidate(); + + if (delegate != null) { + delegate.valueChanged(centerPoint, falloff, size, degreesToRadians(angle) + (float) Math.PI / 2.0f); + } + } + break; + + case GestureStateEnded: + case GestureStateCancelled: + case GestureStateFailed: { + activeControl = BlurViewActiveControl.BlurViewActiveControlNone; + setSelected(false, true); + } + break; + + default: + break; + } + } + + private void setSelected(boolean selected, boolean animated) { + /*if (animated) { + [UIView animateWithDuration:0.16f delay:0.0f options:UIViewAnimationOptionBeginFromCurrentState animations:^ + { + self.alpha = selected ? 0.6f : 1.0f; + } completion:nil]; + } else { + self.alpha = selected ? 0.6f : 1.0f; + }*/ + } + + public void setActualAreaSize(float width, float height) { + actualAreaSize.width = width; + actualAreaSize.height = height; + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + Point centerPoint = getActualCenterPoint(); + float innerRadius = getActualInnerRadius(); + float outerRadius = getActualOuterRadius(); + canvas.translate(centerPoint.x, centerPoint.y); + + if (type == 0) { + canvas.rotate(angle); + + float space = AndroidUtilities.dp(6.0f); + float length = AndroidUtilities.dp(12.0f); + float thickness = AndroidUtilities.dp(1.5f); + for (int i = 0; i < 30; i++) { + canvas.drawRect(i * (length + space), -innerRadius, i * (length + space) + length, thickness - innerRadius, paint); + canvas.drawRect(-i * (length + space) - space - length, -innerRadius, -i * (length + space) - space, thickness - innerRadius, paint); + + canvas.drawRect(i * (length + space), innerRadius, length + i * (length + space), thickness + innerRadius, paint); + canvas.drawRect(-i * (length + space) - space - length, innerRadius, -i * (length + space) - space, thickness + innerRadius, paint); + } + + length = AndroidUtilities.dp(6.0f); + for (int i = 0; i < 64; i++) { + canvas.drawRect(i * (length + space), -outerRadius, length + i * (length + space), thickness - outerRadius, paint); + canvas.drawRect(-i * (length + space) - space - length, -outerRadius, -i * (length + space) - space, thickness - outerRadius, paint); + + canvas.drawRect(i * (length + space), outerRadius, length + i * (length + space), thickness + outerRadius, paint); + canvas.drawRect(-i * (length + space) - space - length, outerRadius, -i * (length + space) - space, thickness + outerRadius, paint); + } + } else if (type == 1) { + float radSpace = 6.15f; + float radLen = 10.2f; + arcRect.set(-innerRadius, -innerRadius, innerRadius, innerRadius); + for (int i = 0; i < 22; i++) { + canvas.drawArc(arcRect, i * (radSpace + radLen), radLen, false, arcPaint); + } + + radSpace = 2.02f; + radLen = 3.6f; + arcRect.set(-outerRadius, -outerRadius, outerRadius, outerRadius); + for (int i = 0; i < 64; i++) { + canvas.drawArc(arcRect, i * (radSpace + radLen), radLen, false, arcPaint); + } + } + canvas.drawCircle(0, 0, AndroidUtilities.dp(8), paint); + } + + private Point getActualCenterPoint() { + return new Point((getWidth() - actualAreaSize.width) / 2 + centerPoint.x * actualAreaSize.width, (getHeight() - actualAreaSize.height) / 2 - (actualAreaSize.width - actualAreaSize.height) / 2 + centerPoint.y * actualAreaSize.width); + } + + private float getActualInnerRadius() { + return (actualAreaSize.width > actualAreaSize.height ? actualAreaSize.height : actualAreaSize.width) * falloff; + } + + private float getActualOuterRadius() { + return (actualAreaSize.width > actualAreaSize.height ? actualAreaSize.height : actualAreaSize.width) * size; + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoFilterView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoFilterView.java new file mode 100644 index 000000000..da9ac0662 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoFilterView.java @@ -0,0 +1,2128 @@ +/* + * This is the source code of Telegram for Android v. 2.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-2015. + */ + +package org.telegram.ui.Components; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.SurfaceTexture; +import android.opengl.GLES20; +import android.opengl.GLUtils; +import android.os.Build; +import android.os.Looper; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.MotionEvent; +import android.view.TextureView; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.TextView; + +import org.telegram.android.AndroidUtilities; +import org.telegram.android.LocaleController; +import org.telegram.messenger.DispatchQueue; +import org.telegram.messenger.FileLog; +import org.telegram.messenger.R; +import org.telegram.messenger.Utilities; +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.Cells.PhotoEditToolCell; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.util.concurrent.Semaphore; + +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLContext; +import javax.microedition.khronos.egl.EGLDisplay; +import javax.microedition.khronos.egl.EGLSurface; +import javax.microedition.khronos.opengles.GL; +import javax.microedition.khronos.opengles.GL10; + +public class PhotoFilterView extends FrameLayout { + + private boolean showOriginal; + + private float previousValue; + + private int selectedTool = -1; + private int enhanceTool = 0; + private int exposureTool = 1; + private int contrastTool = 2; + private int warmthTool = 3; + private int saturationTool = 4; + private int highlightsTool = 5; + private int shadowsTool = 6; + private int vignetteTool = 7; + private int grainTool = 8; + private int blurTool = 9; + private int sharpenTool = 10; + + private float highlightsValue = 0; //0 100 + private float contrastValue = 0; //-100 100 + private float shadowsValue = 0; //0 100 + private float exposureValue = 0; //-100 100 + private float enhanceValue = 0; //0 100 + private float saturationValue = 0; //-100 100 + private float warmthValue = 0; //-100 100 + private float vignetteValue = 0; //0 100 + private float grainValue = 0; //0 100 + private float sharpenValue = 0; //0 100 + private int blurType = 0; //0 none, 1 radial, 2 linear + private float blurExcludeSize = 0.35f; + private Point blurExcludePoint = new Point(0.5f, 0.5f); + private float blurExcludeBlurSize = 0.15f; + private float blurAngle = (float) Math.PI / 2.0f; + + private ToolsAdapter toolsAdapter; + private PhotoEditorSeekBar valueSeekBar; + private FrameLayout toolsView; + private FrameLayout editView; + private TextView paramTextView; + private TextView blurTextView; + private TextView valueTextView; + private TextView doneTextView; + private TextView cancelTextView; + private TextureView textureView; + private EGLThread eglThread; + private RecyclerListView recyclerListView; + private FrameLayout blurLayout; + private PhotoFilterBlurControl blurControl; + private TextView blurOffButton; + private TextView blurRadialButton; + private TextView blurLinearButton; + + private Bitmap bitmapToEdit; + private int orientation; + + public class EGLThread extends DispatchQueue { + + private final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; + private final int EGL_OPENGL_ES2_BIT = 4; + private SurfaceTexture surfaceTexture; + private EGL10 egl10; + private EGLDisplay eglDisplay; + private EGLConfig eglConfig; + private EGLContext eglContext; + private EGLSurface eglSurface; + private GL gl; + private boolean initied; + private boolean needUpdateBlurTexture = true; + + private Bitmap currentBitmap; + + private int rgbToHsvShaderProgram; + private int rgbToHsvPositionHandle; + private int rgbToHsvInputTexCoordHandle; + private int rgbToHsvSourceImageHandle; + + private int enhanceShaderProgram; + private int enhancePositionHandle; + private int enhanceInputTexCoordHandle; + private int enhanceSourceImageHandle; + private int enhanceIntensityHandle; + private int enhanceInputImageTexture2Handle; + + private int toolsShaderProgram; + private int positionHandle; + private int inputTexCoordHandle; + private int sourceImageHandle; + private int shadowsHandle; + private int highlightsHandle; + private int exposureHandle; + private int contrastHandle; + private int saturationHandle; + private int warmthHandle; + private int vignetteHandle; + private int grainHandle; + private int widthHandle; + private int heightHandle; + + private int blurShaderProgram; + private int blurPositionHandle; + private int blurInputTexCoordHandle; + private int blurSourceImageHandle; + private int blurWidthHandle; + private int blurHeightHandle; + + private int linearBlurShaderProgram; + private int linearBlurPositionHandle; + private int linearBlurInputTexCoordHandle; + private int linearBlurSourceImageHandle; + private int linearBlurSourceImage2Handle; + private int linearBlurExcludeSizeHandle; + private int linearBlurExcludePointHandle; + private int linearBlurExcludeBlurSizeHandle; + private int linearBlurAngleHandle; + private int linearBlurAspectRatioHandle; + + private int radialBlurShaderProgram; + private int radialBlurPositionHandle; + private int radialBlurInputTexCoordHandle; + private int radialBlurSourceImageHandle; + private int radialBlurSourceImage2Handle; + private int radialBlurExcludeSizeHandle; + private int radialBlurExcludePointHandle; + private int radialBlurExcludeBlurSizeHandle; + private int radialBlurAspectRatioHandle; + + private int sharpenShaderProgram; + private int sharpenHandle; + private int sharpenWidthHandle; + private int sharpenHeightHandle; + private int sharpenPositionHandle; + private int sharpenInputTexCoordHandle; + private int sharpenSourceImageHandle; + + private int simpleShaderProgram; + private int simplePositionHandle; + private int simpleInputTexCoordHandle; + private int simpleSourceImageHandle; + + private int[] enhanceTextures = new int[2]; + private int[] renderTexture = new int[3]; + private int[] renderFrameBuffer = new int[3]; + private boolean hsvGenerated; + private int renderBufferWidth; + private int renderBufferHeight; + private volatile int surfaceWidth; + private volatile int surfaceHeight; + + private FloatBuffer vertexBuffer; + private FloatBuffer textureBuffer; + private FloatBuffer vertexInvertBuffer; + + private boolean blured; + + private final static int PGPhotoEnhanceHistogramBins = 256; + private final static int PGPhotoEnhanceSegments = 4; + + private static final String radialBlurFragmentShaderCode = + "varying highp vec2 texCoord;" + + "uniform sampler2D sourceImage;" + + "uniform sampler2D inputImageTexture2;" + + "uniform lowp float excludeSize;" + + "uniform lowp vec2 excludePoint;" + + "uniform lowp float excludeBlurSize;" + + "uniform highp float aspectRatio;" + + "void main() {" + + "lowp vec4 sharpImageColor = texture2D(sourceImage, texCoord);" + + "lowp vec4 blurredImageColor = texture2D(inputImageTexture2, texCoord);" + + "highp vec2 texCoordToUse = vec2(texCoord.x, (texCoord.y * aspectRatio + 0.5 - 0.5 * aspectRatio));" + + "highp float distanceFromCenter = distance(excludePoint, texCoordToUse);" + + "gl_FragColor = mix(sharpImageColor, blurredImageColor, smoothstep(excludeSize - excludeBlurSize, excludeSize, distanceFromCenter));" + + "}"; + + private static final String linearBlurFragmentShaderCode = + "varying highp vec2 texCoord;" + + "uniform sampler2D sourceImage;" + + "uniform sampler2D inputImageTexture2;" + + "uniform lowp float excludeSize;" + + "uniform lowp vec2 excludePoint;" + + "uniform lowp float excludeBlurSize;" + + "uniform highp float angle;" + + "uniform highp float aspectRatio;" + + "void main() {" + + "lowp vec4 sharpImageColor = texture2D(sourceImage, texCoord);" + + "lowp vec4 blurredImageColor = texture2D(inputImageTexture2, texCoord);" + + "highp vec2 texCoordToUse = vec2(texCoord.x, (texCoord.y * aspectRatio + 0.5 - 0.5 * aspectRatio));" + + "highp float distanceFromCenter = abs((texCoordToUse.x - excludePoint.x) * aspectRatio * cos(angle) + (texCoordToUse.y - excludePoint.y) * sin(angle));" + + "gl_FragColor = mix(sharpImageColor, blurredImageColor, smoothstep(excludeSize - excludeBlurSize, excludeSize, distanceFromCenter));" + + "}"; + + private static final String blurVertexShaderCode = + "attribute vec4 position;" + + "attribute vec4 inputTexCoord;" + + "uniform highp float texelWidthOffset;" + + "uniform highp float texelHeightOffset;" + + "varying vec2 blurCoordinates[9];" + + "void main() {" + + "gl_Position = position;" + + "vec2 singleStepOffset = vec2(texelWidthOffset, texelHeightOffset);" + + "blurCoordinates[0] = inputTexCoord.xy;" + + "blurCoordinates[1] = inputTexCoord.xy + singleStepOffset * 1.458430;" + + "blurCoordinates[2] = inputTexCoord.xy - singleStepOffset * 1.458430;" + + "blurCoordinates[3] = inputTexCoord.xy + singleStepOffset * 3.403985;" + + "blurCoordinates[4] = inputTexCoord.xy - singleStepOffset * 3.403985;" + + "blurCoordinates[5] = inputTexCoord.xy + singleStepOffset * 5.351806;" + + "blurCoordinates[6] = inputTexCoord.xy - singleStepOffset * 5.351806;" + + "blurCoordinates[7] = inputTexCoord.xy + singleStepOffset * 7.302940;" + + "blurCoordinates[8] = inputTexCoord.xy - singleStepOffset * 7.302940;" + + "}"; + + private static final String blurFragmentShaderCode = + "uniform sampler2D sourceImage;" + + "varying highp vec2 blurCoordinates[9];" + + "void main() {" + + "lowp vec4 sum = vec4(0.0);" + + "sum += texture2D(sourceImage, blurCoordinates[0]) * 0.133571;" + + "sum += texture2D(sourceImage, blurCoordinates[1]) * 0.233308;" + + "sum += texture2D(sourceImage, blurCoordinates[2]) * 0.233308;" + + "sum += texture2D(sourceImage, blurCoordinates[3]) * 0.135928;" + + "sum += texture2D(sourceImage, blurCoordinates[4]) * 0.135928;" + + "sum += texture2D(sourceImage, blurCoordinates[5]) * 0.051383;" + + "sum += texture2D(sourceImage, blurCoordinates[6]) * 0.051383;" + + "sum += texture2D(sourceImage, blurCoordinates[7]) * 0.012595;" + + "sum += texture2D(sourceImage, blurCoordinates[8]) * 0.012595;" + + "gl_FragColor = sum;" + + "}"; + + private static final String rgbToHsvFragmentShaderCode = + "precision highp float;" + + "varying vec2 texCoord;" + + "uniform sampler2D sourceImage;" + + "vec3 rgb_to_hsv(vec3 c) {" + + "vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);" + + "vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy);" + + "vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx);" + + "float d = q.x - min(q.w, q.y);" + + "float e = 1.0e-10;" + + "return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);" + + "}" + + "void main() {" + + "vec4 texel = texture2D(sourceImage, texCoord);" + + "gl_FragColor = vec4(rgb_to_hsv(texel.rgb), texel.a);" + + "}"; + + private static final String enhanceFragmentShaderCode = + "precision highp float;" + + "varying vec2 texCoord;" + + "uniform sampler2D sourceImage;" + + "uniform sampler2D inputImageTexture2;" + + "uniform float intensity;" + + "float enhance(float value) {" + + "const vec2 offset = vec2(0.001953125, 0.03125);" + + "value = value + offset.x;" + + "vec2 coord = (clamp(texCoord, 0.125, 1.0 - 0.125001) - 0.125) * 4.0;" + + "vec2 frac = fract(coord);" + + "coord = floor(coord);" + + "float p00 = float(coord.y * 4.0 + coord.x) * 0.0625 + offset.y;" + + "float p01 = float(coord.y * 4.0 + coord.x + 1.0) * 0.0625 + offset.y;" + + "float p10 = float((coord.y + 1.0) * 4.0 + coord.x) * 0.0625 + offset.y;" + + "float p11 = float((coord.y + 1.0) * 4.0 + coord.x + 1.0) * 0.0625 + offset.y;" + + "vec3 c00 = texture2D(inputImageTexture2, vec2(value, p00)).rgb;" + + "vec3 c01 = texture2D(inputImageTexture2, vec2(value, p01)).rgb;" + + "vec3 c10 = texture2D(inputImageTexture2, vec2(value, p10)).rgb;" + + "vec3 c11 = texture2D(inputImageTexture2, vec2(value, p11)).rgb;" + + "float c1 = ((c00.r - c00.g) / (c00.b - c00.g));" + + "float c2 = ((c01.r - c01.g) / (c01.b - c01.g));" + + "float c3 = ((c10.r - c10.g) / (c10.b - c10.g));" + + "float c4 = ((c11.r - c11.g) / (c11.b - c11.g));" + + "float c1_2 = mix(c1, c2, frac.x);" + + "float c3_4 = mix(c3, c4, frac.x);" + + "return mix(c1_2, c3_4, frac.y);" + + "}" + + "vec3 hsv_to_rgb(vec3 c) {" + + "vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);" + + "vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);" + + "return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);" + + "}" + + "void main() {" + + "vec4 texel = texture2D(sourceImage, texCoord);" + + "vec4 hsv = texel;" + + "hsv.y = min(1.0, hsv.y * 1.2);" + + "hsv.z = min(1.0, enhance(hsv.z) * 1.1);" + + "gl_FragColor = vec4(hsv_to_rgb(mix(texel.xyz, hsv.xyz, intensity)), texel.w);" + + "}"; + + private static final String simpleVertexShaderCode = + "attribute vec4 position;" + + "attribute vec2 inputTexCoord;" + + "varying vec2 texCoord;" + + "void main() {" + + "gl_Position = position;" + + "texCoord = inputTexCoord;" + + "}"; + + private static final String simpleFragmentShaderCode = + "varying highp vec2 texCoord;" + + "uniform sampler2D sourceImage;" + + "void main() {" + + "gl_FragColor = texture2D(sourceImage, texCoord);" + + "}"; + + private static final String sharpenVertexShaderCode = + "attribute vec4 position;" + + "attribute vec2 inputTexCoord;" + + "varying vec2 texCoord;" + + + "uniform highp float inputWidth;" + + "uniform highp float inputHeight;" + + "varying vec2 leftTexCoord;" + + "varying vec2 rightTexCoord;" + + "varying vec2 topTexCoord;" + + "varying vec2 bottomTexCoord;" + + + "void main() {" + + "gl_Position = position;" + + "texCoord = inputTexCoord;" + + "highp vec2 widthStep = vec2(1.0 / inputWidth, 0.0);" + + "highp vec2 heightStep = vec2(0.0, 1.0 / inputHeight);" + + "leftTexCoord = inputTexCoord - widthStep;" + + "rightTexCoord = inputTexCoord + widthStep;" + + "topTexCoord = inputTexCoord + heightStep;" + + "bottomTexCoord = inputTexCoord - heightStep;" + + "}"; + + private static final String sharpenFragmentShaderCode = + "precision highp float;" + + "varying vec2 texCoord;" + + "varying vec2 leftTexCoord;" + + "varying vec2 rightTexCoord;" + + "varying vec2 topTexCoord;" + + "varying vec2 bottomTexCoord;" + + "uniform sampler2D sourceImage;" + + "uniform float sharpen;" + + + "void main() {" + + "vec4 result = texture2D(sourceImage, texCoord);" + + + "vec3 leftTextureColor = texture2D(sourceImage, leftTexCoord).rgb;" + + "vec3 rightTextureColor = texture2D(sourceImage, rightTexCoord).rgb;" + + "vec3 topTextureColor = texture2D(sourceImage, topTexCoord).rgb;" + + "vec3 bottomTextureColor = texture2D(sourceImage, bottomTexCoord).rgb;" + + "result.rgb = result.rgb * (1.0 + 4.0 * sharpen) - (leftTextureColor + rightTextureColor + topTextureColor + bottomTextureColor) * sharpen;" + + + "gl_FragColor = result;" + + "}"; + + private static final String toolsFragmentShaderCode = + "precision highp float;" + + "varying vec2 texCoord;" + + "uniform float inputWidth;" + + "uniform float inputHeight;" + + "uniform sampler2D sourceImage;" + + "uniform float shadows;" + + "uniform float width;" + + "uniform float height;" + + "const vec3 hsLuminanceWeighting = vec3(0.3, 0.3, 0.3);" + + "uniform float highlights;" + + "uniform float exposure;" + + "uniform float contrast;" + + "const vec3 satLuminanceWeighting = vec3(0.2126, 0.7152, 0.0722);" + + "uniform float saturation;" + + "uniform float warmth;" + + "uniform float grain;" + + "const float permTexUnit = 1.0 / 256.0;" + + "const float permTexUnitHalf = 0.5 / 256.0;" + + "const float grainsize = 2.3;" + + "uniform float vignette;" + + "float getLuma(vec3 rgbP) { " + + "return (0.299 * rgbP.r) + (0.587 * rgbP.g) + (0.114 * rgbP.b); " + + "}" + + "vec3 rgbToYuv(vec3 inP) {" + + "vec3 outP;" + + "outP.r = getLuma(inP);" + + "outP.g = (1.0 / 1.772) * (inP.b - outP.r);" + + "outP.b = (1.0 / 1.402) * (inP.r - outP.r);" + + "return outP; " + + "}" + + "vec3 yuvToRgb(vec3 inP) {" + + "return vec3(1.402 * inP.b + inP.r, (inP.r - (0.299 * 1.402 / 0.587) * inP.b - (0.114 * 1.772 / 0.587) * inP.g), 1.772 * inP.g + inP.r);" + + "}" + + "float easeInOutSigmoid(float value, float strength) {" + + "float t = 1.0 / (1.0 - strength);" + + "if (value > 0.5) {" + + "return 1.0 - pow(2.0 - 2.0 * value, t) * 0.5;" + + "} else {" + + "return pow(2.0 * value, t) * 0.5; " + + "}" + + "}" + + "vec4 rnm(in vec2 tc) {" + + "float noise = sin(dot(tc,vec2(12.9898,78.233))) * 43758.5453;" + + "float noiseR = fract(noise)*2.0-1.0;" + + "float noiseG = fract(noise*1.2154)*2.0-1.0;" + + "float noiseB = fract(noise*1.3453)*2.0-1.0;" + + "float noiseA = fract(noise*1.3647)*2.0-1.0;" + + "return vec4(noiseR,noiseG,noiseB,noiseA);" + + "}" + + "float fade(in float t) {" + + "return t*t*t*(t*(t*6.0-15.0)+10.0);" + + "}" + + "float pnoise3D(in vec3 p) {" + + "vec3 pi = permTexUnit*floor(p)+permTexUnitHalf;" + + "vec3 pf = fract(p);" + + "float perm00 = rnm(pi.xy).a;" + + "vec3 grad000 = rnm(vec2(perm00, pi.z)).rgb * 4.0 - 1.0;" + + "float n000 = dot(grad000, pf);" + + "vec3 grad001 = rnm(vec2(perm00, pi.z + permTexUnit)).rgb * 4.0 - 1.0;" + + "float n001 = dot(grad001, pf - vec3(0.0, 0.0, 1.0));" + + "float perm01 = rnm(pi.xy + vec2(0.0, permTexUnit)).a;" + + "vec3 grad010 = rnm(vec2(perm01, pi.z)).rgb * 4.0 - 1.0;" + + "float n010 = dot(grad010, pf - vec3(0.0, 1.0, 0.0));" + + "vec3 grad011 = rnm(vec2(perm01, pi.z + permTexUnit)).rgb * 4.0 - 1.0;" + + "float n011 = dot(grad011, pf - vec3(0.0, 1.0, 1.0));" + + "float perm10 = rnm(pi.xy + vec2(permTexUnit, 0.0)).a;" + + "vec3 grad100 = rnm(vec2(perm10, pi.z)).rgb * 4.0 - 1.0;" + + "float n100 = dot(grad100, pf - vec3(1.0, 0.0, 0.0));" + + "vec3 grad101 = rnm(vec2(perm10, pi.z + permTexUnit)).rgb * 4.0 - 1.0;" + + "float n101 = dot(grad101, pf - vec3(1.0, 0.0, 1.0));" + + "float perm11 = rnm(pi.xy + vec2(permTexUnit, permTexUnit)).a;" + + "vec3 grad110 = rnm(vec2(perm11, pi.z)).rgb * 4.0 - 1.0;" + + "float n110 = dot(grad110, pf - vec3(1.0, 1.0, 0.0));" + + "vec3 grad111 = rnm(vec2(perm11, pi.z + permTexUnit)).rgb * 4.0 - 1.0;" + + "float n111 = dot(grad111, pf - vec3(1.0, 1.0, 1.0));" + + "vec4 n_x = mix(vec4(n000, n001, n010, n011), vec4(n100, n101, n110, n111), fade(pf.x));" + + "vec2 n_xy = mix(n_x.xy, n_x.zw, fade(pf.y));" + + "float n_xyz = mix(n_xy.x, n_xy.y, fade(pf.z));" + + "return n_xyz;" + + "}" + + "vec2 coordRot(in vec2 tc, in float angle) {" + + "float rotX = ((tc.x * 2.0 - 1.0) * cos(angle)) - ((tc.y * 2.0 - 1.0) * sin(angle));" + + "float rotY = ((tc.y * 2.0 - 1.0) * cos(angle)) + ((tc.x * 2.0 - 1.0) * sin(angle));" + + "return vec2(rotX * 0.5 + 0.5, rotY * 0.5 + 0.5);" + + "}" + + "void main() {" + + "vec4 result = texture2D(sourceImage, texCoord);" + + "const float toolEpsilon = 0.005;" + + + "float hsLuminance = dot(result.rgb, hsLuminanceWeighting);" + + "float shadow = clamp((pow(hsLuminance, 1.0 / (shadows + 1.0)) + (-0.76) * pow(hsLuminance, 2.0 / (shadows + 1.0))) - hsLuminance, 0.0, 1.0);" + + "float highlight = clamp((1.0 - (pow(1.0 - hsLuminance, 1.0 / (2.0 - highlights)) + (-0.8) * pow(1.0 - hsLuminance, 2.0 / (2.0 - highlights)))) - hsLuminance, -1.0, 0.0);" + + "vec3 shresult = (hsLuminance + shadow + highlight) * (result.rgb / hsLuminance);" + + "result = vec4(shresult.rgb, result.a);" + + + "if (abs(exposure) > toolEpsilon) {" + + "float mag = exposure * 1.045;" + + "float exppower = 1.0 + abs(mag);" + + "if (mag < 0.0) {" + + "exppower = 1.0 / exppower;" + + "}" + + "result.r = 1.0 - pow((1.0 - result.r), exppower);" + + "result.g = 1.0 - pow((1.0 - result.g), exppower);" + + "result.b = 1.0 - pow((1.0 - result.b), exppower);" + + "}" + + "result = vec4(((result.rgb - vec3(0.5)) * contrast + vec3(0.5)), result.a);" + + "float satLuminance = dot(result.rgb, satLuminanceWeighting);" + + "vec3 greyScaleColor = vec3(satLuminance);" + + "result = vec4(mix(greyScaleColor, result.rgb, saturation), result.a);" + + "if (abs(warmth) > toolEpsilon) {" + + "vec3 yuvVec; if (warmth > 0.0 ) {" + + "yuvVec = vec3(0.1765, -0.1255, 0.0902);" + + "} else {" + + "yuvVec = -vec3(0.0588, 0.1569, -0.1255);" + + "}" + + "vec3 yuvColor = rgbToYuv(result.rgb);" + + "float luma = yuvColor.r;" + + "float curveScale = sin(luma * 3.14159);" + + "yuvColor += 0.375 * warmth * curveScale * yuvVec;" + + "result.rgb = yuvToRgb(yuvColor);" + + "}" + + "if (abs(grain) > toolEpsilon) {" + + "vec3 rotOffset = vec3(1.425, 3.892, 5.835);" + + "vec2 rotCoordsR = coordRot(texCoord, rotOffset.x);" + + "vec3 noise = vec3(pnoise3D(vec3(rotCoordsR * vec2(width / grainsize, height / grainsize),0.0)));" + + "vec3 lumcoeff = vec3(0.299,0.587,0.114);" + + "float luminance = dot(result.rgb, lumcoeff);" + + "float lum = smoothstep(0.2, 0.0, luminance);" + + "lum += luminance;" + + "noise = mix(noise,vec3(0.0),pow(lum,4.0));" + + "result.rgb = result.rgb + noise * grain;" + + "}" + + "if (abs(vignette) > toolEpsilon) {" + + "const float midpoint = 0.7;" + + "const float fuzziness = 0.62;" + + "float radDist = length(texCoord - 0.5) / sqrt(0.5);" + + "float mag = easeInOutSigmoid(radDist * midpoint, fuzziness) * vignette * 0.645;" + + "result.rgb = mix(pow(result.rgb, vec3(1.0 / (1.0 - mag))), vec3(0.0), mag * mag);" + + "}" + + + "gl_FragColor = result;" + + "}"; + + public EGLThread(SurfaceTexture surface, Bitmap bitmap) { + super("EGLThread"); + surfaceTexture = surface; + currentBitmap = bitmap; + } + + private int loadShader(int type, String shaderCode) { + int shader = GLES20.glCreateShader(type); + GLES20.glShaderSource(shader, shaderCode); + GLES20.glCompileShader(shader); + int[] compileStatus = new int[1]; + GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compileStatus, 0); + if (compileStatus[0] == 0) { + GLES20.glDeleteShader(shader); + shader = 0; + } + return shader; + } + + private boolean initGL() { + egl10 = (EGL10) EGLContext.getEGL(); + + eglDisplay = egl10.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); + if (eglDisplay == EGL10.EGL_NO_DISPLAY) { + FileLog.e("tmessages", "eglGetDisplay failed " + GLUtils.getEGLErrorString(egl10.eglGetError())); + finish(); + return false; + } + + int[] version = new int[2]; + if (!egl10.eglInitialize(eglDisplay, version)) { + FileLog.e("tmessages", "eglInitialize failed " + GLUtils.getEGLErrorString(egl10.eglGetError())); + finish(); + return false; + } + + int[] configsCount = new int[1]; + EGLConfig[] configs = new EGLConfig[1]; + int[] configSpec = new int[] { + EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL10.EGL_RED_SIZE, 8, + EGL10.EGL_GREEN_SIZE, 8, + EGL10.EGL_BLUE_SIZE, 8, + EGL10.EGL_ALPHA_SIZE, 8, + EGL10.EGL_DEPTH_SIZE, 0, + EGL10.EGL_STENCIL_SIZE, 0, + EGL10.EGL_NONE + }; + if (!egl10.eglChooseConfig(eglDisplay, configSpec, configs, 1, configsCount)) { + FileLog.e("tmessages", "eglChooseConfig failed " + GLUtils.getEGLErrorString(egl10.eglGetError())); + finish(); + return false; + } else if (configsCount[0] > 0) { + eglConfig = configs[0]; + } else { + FileLog.e("tmessages", "eglConfig not initialized"); + finish(); + return false; + } + + int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; + eglContext = egl10.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list); + if (eglContext == null) { + FileLog.e("tmessages", "eglCreateContext failed " + GLUtils.getEGLErrorString(egl10.eglGetError())); + finish(); + return false; + } + + if (surfaceTexture instanceof SurfaceTexture) { + eglSurface = egl10.eglCreateWindowSurface(eglDisplay, eglConfig, surfaceTexture, null); + } else { + finish(); + return false; + } + + if (eglSurface == null || eglSurface == EGL10.EGL_NO_SURFACE) { + FileLog.e("tmessages", "createWindowSurface failed " + GLUtils.getEGLErrorString(egl10.eglGetError())); + finish(); + return false; + } + if (!egl10.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) { + FileLog.e("tmessages", "eglMakeCurrent failed " + GLUtils.getEGLErrorString(egl10.eglGetError())); + finish(); + return false; + } + gl = eglContext.getGL(); + + + float squareCoordinates[] = { + -1.0f, 1.0f, + 1.0f, 1.0f, + -1.0f, -1.0f, + 1.0f, -1.0f}; + + ByteBuffer bb = ByteBuffer.allocateDirect(squareCoordinates.length * 4); + bb.order(ByteOrder.nativeOrder()); + vertexBuffer = bb.asFloatBuffer(); + vertexBuffer.put(squareCoordinates); + vertexBuffer.position(0); + + float squareCoordinates2[] = { + -1.0f, -1.0f, + 1.0f, -1.0f, + -1.0f, 1.0f, + 1.0f, 1.0f}; + + bb = ByteBuffer.allocateDirect(squareCoordinates2.length * 4); + bb.order(ByteOrder.nativeOrder()); + vertexInvertBuffer = bb.asFloatBuffer(); + vertexInvertBuffer.put(squareCoordinates2); + vertexInvertBuffer.position(0); + + float textureCoordinates[] = { + 0.0f, 0.0f, + 1.0f, 0.0f, + 0.0f, 1.0f, + 1.0f, 1.0f, + }; + + bb = ByteBuffer.allocateDirect(textureCoordinates.length * 4); + bb.order(ByteOrder.nativeOrder()); + textureBuffer = bb.asFloatBuffer(); + textureBuffer.put(textureCoordinates); + textureBuffer.position(0); + + GLES20.glGenTextures(2, enhanceTextures, 0); + + int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, simpleVertexShaderCode); + int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, toolsFragmentShaderCode); + + if (vertexShader != 0 && fragmentShader != 0) { + toolsShaderProgram = GLES20.glCreateProgram(); + GLES20.glAttachShader(toolsShaderProgram, vertexShader); + GLES20.glAttachShader(toolsShaderProgram, fragmentShader); + GLES20.glBindAttribLocation(toolsShaderProgram, 0, "position"); + GLES20.glBindAttribLocation(toolsShaderProgram, 1, "inputTexCoord"); + + GLES20.glLinkProgram(toolsShaderProgram); + int[] linkStatus = new int[1]; + GLES20.glGetProgramiv(toolsShaderProgram, GLES20.GL_LINK_STATUS, linkStatus, 0); + if (linkStatus[0] == 0) { + /*String infoLog = GLES20.glGetProgramInfoLog(toolsShaderProgram); + FileLog.e("tmessages", "link error = " + infoLog);*/ + GLES20.glDeleteProgram(toolsShaderProgram); + toolsShaderProgram = 0; + } else { + positionHandle = GLES20.glGetAttribLocation(toolsShaderProgram, "position"); + inputTexCoordHandle = GLES20.glGetAttribLocation(toolsShaderProgram, "inputTexCoord"); + sourceImageHandle = GLES20.glGetUniformLocation(toolsShaderProgram, "sourceImage"); + shadowsHandle = GLES20.glGetUniformLocation(toolsShaderProgram, "shadows"); + highlightsHandle = GLES20.glGetUniformLocation(toolsShaderProgram, "highlights"); + exposureHandle = GLES20.glGetUniformLocation(toolsShaderProgram, "exposure"); + contrastHandle = GLES20.glGetUniformLocation(toolsShaderProgram, "contrast"); + saturationHandle = GLES20.glGetUniformLocation(toolsShaderProgram, "saturation"); + warmthHandle = GLES20.glGetUniformLocation(toolsShaderProgram, "warmth"); + vignetteHandle = GLES20.glGetUniformLocation(toolsShaderProgram, "vignette"); + grainHandle = GLES20.glGetUniformLocation(toolsShaderProgram, "grain"); + widthHandle = GLES20.glGetUniformLocation(toolsShaderProgram, "width"); + heightHandle = GLES20.glGetUniformLocation(toolsShaderProgram, "height"); + } + } else { + finish(); + return false; + } + + vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, sharpenVertexShaderCode); + fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, sharpenFragmentShaderCode); + + if (vertexShader != 0 && fragmentShader != 0) { + sharpenShaderProgram = GLES20.glCreateProgram(); + GLES20.glAttachShader(sharpenShaderProgram, vertexShader); + GLES20.glAttachShader(sharpenShaderProgram, fragmentShader); + GLES20.glBindAttribLocation(sharpenShaderProgram, 0, "position"); + GLES20.glBindAttribLocation(sharpenShaderProgram, 1, "inputTexCoord"); + + GLES20.glLinkProgram(sharpenShaderProgram); + int[] linkStatus = new int[1]; + GLES20.glGetProgramiv(sharpenShaderProgram, GLES20.GL_LINK_STATUS, linkStatus, 0); + if (linkStatus[0] == 0) { + GLES20.glDeleteProgram(sharpenShaderProgram); + sharpenShaderProgram = 0; + } else { + sharpenPositionHandle = GLES20.glGetAttribLocation(sharpenShaderProgram, "position"); + sharpenInputTexCoordHandle = GLES20.glGetAttribLocation(sharpenShaderProgram, "inputTexCoord"); + sharpenSourceImageHandle = GLES20.glGetUniformLocation(sharpenShaderProgram, "sourceImage"); + sharpenWidthHandle = GLES20.glGetUniformLocation(sharpenShaderProgram, "inputWidth"); + sharpenHeightHandle = GLES20.glGetUniformLocation(sharpenShaderProgram, "inputHeight"); + sharpenHandle = GLES20.glGetUniformLocation(sharpenShaderProgram, "sharpen"); + } + } else { + finish(); + return false; + } + + vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, blurVertexShaderCode); + fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, blurFragmentShaderCode); + + if (vertexShader != 0 && fragmentShader != 0) { + blurShaderProgram = GLES20.glCreateProgram(); + GLES20.glAttachShader(blurShaderProgram, vertexShader); + GLES20.glAttachShader(blurShaderProgram, fragmentShader); + GLES20.glBindAttribLocation(blurShaderProgram, 0, "position"); + GLES20.glBindAttribLocation(blurShaderProgram, 1, "inputTexCoord"); + + GLES20.glLinkProgram(blurShaderProgram); + int[] linkStatus = new int[1]; + GLES20.glGetProgramiv(blurShaderProgram, GLES20.GL_LINK_STATUS, linkStatus, 0); + if (linkStatus[0] == 0) { + GLES20.glDeleteProgram(blurShaderProgram); + blurShaderProgram = 0; + } else { + blurPositionHandle = GLES20.glGetAttribLocation(blurShaderProgram, "position"); + blurInputTexCoordHandle = GLES20.glGetAttribLocation(blurShaderProgram, "inputTexCoord"); + blurSourceImageHandle = GLES20.glGetUniformLocation(blurShaderProgram, "sourceImage"); + blurWidthHandle = GLES20.glGetUniformLocation(blurShaderProgram, "texelWidthOffset"); + blurHeightHandle = GLES20.glGetUniformLocation(blurShaderProgram, "texelHeightOffset"); + } + } else { + finish(); + return false; + } + + vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, simpleVertexShaderCode); + fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, linearBlurFragmentShaderCode); + + if (vertexShader != 0 && fragmentShader != 0) { + linearBlurShaderProgram = GLES20.glCreateProgram(); + GLES20.glAttachShader(linearBlurShaderProgram, vertexShader); + GLES20.glAttachShader(linearBlurShaderProgram, fragmentShader); + GLES20.glBindAttribLocation(linearBlurShaderProgram, 0, "position"); + GLES20.glBindAttribLocation(linearBlurShaderProgram, 1, "inputTexCoord"); + + GLES20.glLinkProgram(linearBlurShaderProgram); + int[] linkStatus = new int[1]; + GLES20.glGetProgramiv(linearBlurShaderProgram, GLES20.GL_LINK_STATUS, linkStatus, 0); + if (linkStatus[0] == 0) { + GLES20.glDeleteProgram(linearBlurShaderProgram); + linearBlurShaderProgram = 0; + } else { + linearBlurPositionHandle = GLES20.glGetAttribLocation(linearBlurShaderProgram, "position"); + linearBlurInputTexCoordHandle = GLES20.glGetAttribLocation(linearBlurShaderProgram, "inputTexCoord"); + linearBlurSourceImageHandle = GLES20.glGetUniformLocation(linearBlurShaderProgram, "sourceImage"); + linearBlurSourceImage2Handle = GLES20.glGetUniformLocation(linearBlurShaderProgram, "inputImageTexture2"); + linearBlurExcludeSizeHandle = GLES20.glGetUniformLocation(linearBlurShaderProgram, "excludeSize"); + linearBlurExcludePointHandle = GLES20.glGetUniformLocation(linearBlurShaderProgram, "excludePoint"); + linearBlurExcludeBlurSizeHandle = GLES20.glGetUniformLocation(linearBlurShaderProgram, "excludeBlurSize"); + linearBlurAngleHandle = GLES20.glGetUniformLocation(linearBlurShaderProgram, "angle"); + linearBlurAspectRatioHandle = GLES20.glGetUniformLocation(linearBlurShaderProgram, "aspectRatio"); + } + } else { + finish(); + return false; + } + + vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, simpleVertexShaderCode); + fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, radialBlurFragmentShaderCode); + + if (vertexShader != 0 && fragmentShader != 0) { + radialBlurShaderProgram = GLES20.glCreateProgram(); + GLES20.glAttachShader(radialBlurShaderProgram, vertexShader); + GLES20.glAttachShader(radialBlurShaderProgram, fragmentShader); + GLES20.glBindAttribLocation(radialBlurShaderProgram, 0, "position"); + GLES20.glBindAttribLocation(radialBlurShaderProgram, 1, "inputTexCoord"); + + GLES20.glLinkProgram(radialBlurShaderProgram); + int[] linkStatus = new int[1]; + GLES20.glGetProgramiv(radialBlurShaderProgram, GLES20.GL_LINK_STATUS, linkStatus, 0); + if (linkStatus[0] == 0) { + GLES20.glDeleteProgram(radialBlurShaderProgram); + radialBlurShaderProgram = 0; + } else { + radialBlurPositionHandle = GLES20.glGetAttribLocation(radialBlurShaderProgram, "position"); + radialBlurInputTexCoordHandle = GLES20.glGetAttribLocation(radialBlurShaderProgram, "inputTexCoord"); + radialBlurSourceImageHandle = GLES20.glGetUniformLocation(radialBlurShaderProgram, "sourceImage"); + radialBlurSourceImage2Handle = GLES20.glGetUniformLocation(radialBlurShaderProgram, "inputImageTexture2"); + radialBlurExcludeSizeHandle = GLES20.glGetUniformLocation(radialBlurShaderProgram, "excludeSize"); + radialBlurExcludePointHandle = GLES20.glGetUniformLocation(radialBlurShaderProgram, "excludePoint"); + radialBlurExcludeBlurSizeHandle = GLES20.glGetUniformLocation(radialBlurShaderProgram, "excludeBlurSize"); + radialBlurAspectRatioHandle = GLES20.glGetUniformLocation(radialBlurShaderProgram, "aspectRatio"); + } + } else { + finish(); + return false; + } + + vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, simpleVertexShaderCode); + fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, rgbToHsvFragmentShaderCode); + if (vertexShader != 0 && fragmentShader != 0) { + rgbToHsvShaderProgram = GLES20.glCreateProgram(); + GLES20.glAttachShader(rgbToHsvShaderProgram, vertexShader); + GLES20.glAttachShader(rgbToHsvShaderProgram, fragmentShader); + GLES20.glBindAttribLocation(rgbToHsvShaderProgram, 0, "position"); + GLES20.glBindAttribLocation(rgbToHsvShaderProgram, 1, "inputTexCoord"); + + GLES20.glLinkProgram(rgbToHsvShaderProgram); + int[] linkStatus = new int[1]; + GLES20.glGetProgramiv(rgbToHsvShaderProgram, GLES20.GL_LINK_STATUS, linkStatus, 0); + if (linkStatus[0] == 0) { + GLES20.glDeleteProgram(rgbToHsvShaderProgram); + rgbToHsvShaderProgram = 0; + } else { + rgbToHsvPositionHandle = GLES20.glGetAttribLocation(rgbToHsvShaderProgram, "position"); + rgbToHsvInputTexCoordHandle = GLES20.glGetAttribLocation(rgbToHsvShaderProgram, "inputTexCoord"); + rgbToHsvSourceImageHandle = GLES20.glGetUniformLocation(rgbToHsvShaderProgram, "sourceImage"); + } + } else { + finish(); + return false; + } + + vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, simpleVertexShaderCode); + fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, enhanceFragmentShaderCode); + if (vertexShader != 0 && fragmentShader != 0) { + enhanceShaderProgram = GLES20.glCreateProgram(); + GLES20.glAttachShader(enhanceShaderProgram, vertexShader); + GLES20.glAttachShader(enhanceShaderProgram, fragmentShader); + GLES20.glBindAttribLocation(enhanceShaderProgram, 0, "position"); + GLES20.glBindAttribLocation(enhanceShaderProgram, 1, "inputTexCoord"); + + GLES20.glLinkProgram(enhanceShaderProgram); + int[] linkStatus = new int[1]; + GLES20.glGetProgramiv(enhanceShaderProgram, GLES20.GL_LINK_STATUS, linkStatus, 0); + if (linkStatus[0] == 0) { + GLES20.glDeleteProgram(enhanceShaderProgram); + enhanceShaderProgram = 0; + } else { + enhancePositionHandle = GLES20.glGetAttribLocation(enhanceShaderProgram, "position"); + enhanceInputTexCoordHandle = GLES20.glGetAttribLocation(enhanceShaderProgram, "inputTexCoord"); + enhanceSourceImageHandle = GLES20.glGetUniformLocation(enhanceShaderProgram, "sourceImage"); + enhanceIntensityHandle = GLES20.glGetUniformLocation(enhanceShaderProgram, "intensity"); + enhanceInputImageTexture2Handle = GLES20.glGetUniformLocation(enhanceShaderProgram, "inputImageTexture2"); + } + } else { + finish(); + return false; + } + + vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, simpleVertexShaderCode); + fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, simpleFragmentShaderCode); + if (vertexShader != 0 && fragmentShader != 0) { + simpleShaderProgram = GLES20.glCreateProgram(); + GLES20.glAttachShader(simpleShaderProgram, vertexShader); + GLES20.glAttachShader(simpleShaderProgram, fragmentShader); + GLES20.glBindAttribLocation(simpleShaderProgram, 0, "position"); + GLES20.glBindAttribLocation(simpleShaderProgram, 1, "inputTexCoord"); + + GLES20.glLinkProgram(simpleShaderProgram); + int[] linkStatus = new int[1]; + GLES20.glGetProgramiv(simpleShaderProgram, GLES20.GL_LINK_STATUS, linkStatus, 0); + if (linkStatus[0] == 0) { + GLES20.glDeleteProgram(simpleShaderProgram); + simpleShaderProgram = 0; + } else { + simplePositionHandle = GLES20.glGetAttribLocation(simpleShaderProgram, "position"); + simpleInputTexCoordHandle = GLES20.glGetAttribLocation(simpleShaderProgram, "inputTexCoord"); + simpleSourceImageHandle = GLES20.glGetUniformLocation(simpleShaderProgram, "sourceImage"); + } + } else { + finish(); + return false; + } + + if (currentBitmap != null) { + loadTexture(currentBitmap); + } + + return true; + } + + public void finish() { + if (eglSurface != null) { + egl10.eglMakeCurrent(eglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); + egl10.eglDestroySurface(eglDisplay, eglSurface); + eglSurface = null; + } + if (eglContext != null) { + egl10.eglDestroyContext(eglDisplay, eglContext); + eglContext = null; + } + if (eglDisplay != null) { + egl10.eglTerminate(eglDisplay); + eglDisplay = null; + } + } + + private void drawEnhancePass() { + if (!hsvGenerated) { + GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, renderFrameBuffer[0]); + GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, renderTexture[0], 0); + GLES20.glClear(0); + + GLES20.glUseProgram(rgbToHsvShaderProgram); + GLES20.glActiveTexture(GLES20.GL_TEXTURE0); + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTexture[1]); + GLES20.glUniform1i(rgbToHsvSourceImageHandle, 0); + GLES20.glEnableVertexAttribArray(rgbToHsvInputTexCoordHandle); + GLES20.glVertexAttribPointer(rgbToHsvInputTexCoordHandle, 2, GLES20.GL_FLOAT, false, 8, textureBuffer); + GLES20.glEnableVertexAttribArray(rgbToHsvPositionHandle); + GLES20.glVertexAttribPointer(rgbToHsvPositionHandle, 2, GLES20.GL_FLOAT, false, 8, vertexBuffer); + GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); + + ByteBuffer hsvBuffer = ByteBuffer.allocateDirect(renderBufferWidth * renderBufferHeight * 4); + GLES20.glReadPixels(0, 0, renderBufferWidth, renderBufferHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, hsvBuffer); + + GLES20.glBindTexture(GL10.GL_TEXTURE_2D, enhanceTextures[0]); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); + GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, renderBufferWidth, renderBufferHeight, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, hsvBuffer); + + ByteBuffer buffer = null; + try { + buffer = ByteBuffer.allocateDirect(PGPhotoEnhanceSegments * PGPhotoEnhanceSegments * PGPhotoEnhanceHistogramBins * 4); + Utilities.calcCDT(hsvBuffer, renderBufferWidth, renderBufferHeight, buffer); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + + GLES20.glBindTexture(GL10.GL_TEXTURE_2D, enhanceTextures[1]); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); + GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 16, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buffer); + + hsvGenerated = true; + } + + GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, renderFrameBuffer[1]); + GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, renderTexture[1], 0); + GLES20.glClear(0); + + GLES20.glUseProgram(enhanceShaderProgram); + GLES20.glActiveTexture(GLES20.GL_TEXTURE0); + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, enhanceTextures[0]); + GLES20.glUniform1i(enhanceSourceImageHandle, 0); + GLES20.glActiveTexture(GLES20.GL_TEXTURE1); + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, enhanceTextures[1]); + GLES20.glUniform1i(enhanceInputImageTexture2Handle, 1); + if (showOriginal) { + GLES20.glUniform1f(enhanceIntensityHandle, 0); + } else { + GLES20.glUniform1f(enhanceIntensityHandle, getEnhanceValue()); + } + + GLES20.glEnableVertexAttribArray(enhanceInputTexCoordHandle); + GLES20.glVertexAttribPointer(enhanceInputTexCoordHandle, 2, GLES20.GL_FLOAT, false, 8, textureBuffer); + GLES20.glEnableVertexAttribArray(enhancePositionHandle); + GLES20.glVertexAttribPointer(enhancePositionHandle, 2, GLES20.GL_FLOAT, false, 8, vertexBuffer); + GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); + } + + private void drawSharpenPass() { + GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, renderFrameBuffer[0]); + GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, renderTexture[0], 0); + GLES20.glClear(0); + + GLES20.glUseProgram(sharpenShaderProgram); + GLES20.glActiveTexture(GLES20.GL_TEXTURE0); + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTexture[1]); + GLES20.glUniform1i(sharpenSourceImageHandle, 0); + if (showOriginal) { + GLES20.glUniform1f(sharpenHandle, 0); + } else { + GLES20.glUniform1f(sharpenHandle, getSharpenValue()); + } + GLES20.glUniform1f(sharpenWidthHandle, renderBufferWidth); + GLES20.glUniform1f(sharpenHeightHandle, renderBufferHeight); + GLES20.glEnableVertexAttribArray(sharpenInputTexCoordHandle); + GLES20.glVertexAttribPointer(sharpenInputTexCoordHandle, 2, GLES20.GL_FLOAT, false, 8, textureBuffer); + GLES20.glEnableVertexAttribArray(sharpenPositionHandle); + GLES20.glVertexAttribPointer(sharpenPositionHandle, 2, GLES20.GL_FLOAT, false, 8, vertexInvertBuffer); + GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); + } + + private void drawCustomParamsPass() { + GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, renderFrameBuffer[1]); + GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, renderTexture[1], 0); + GLES20.glClear(0); + + GLES20.glUseProgram(toolsShaderProgram); + GLES20.glActiveTexture(GLES20.GL_TEXTURE0); + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTexture[0]); + GLES20.glUniform1i(sourceImageHandle, 0); + if (showOriginal) { + GLES20.glUniform1f(shadowsHandle, 0); + GLES20.glUniform1f(highlightsHandle, 1); + GLES20.glUniform1f(exposureHandle, 0); + GLES20.glUniform1f(contrastHandle, 1); + GLES20.glUniform1f(saturationHandle, 1); + GLES20.glUniform1f(warmthHandle, 0); + GLES20.glUniform1f(vignetteHandle, 0); + GLES20.glUniform1f(grainHandle, 0); + } else { + GLES20.glUniform1f(shadowsHandle, getShadowsValue()); + GLES20.glUniform1f(highlightsHandle, getHighlightsValue()); + GLES20.glUniform1f(exposureHandle, getExposureValue()); + GLES20.glUniform1f(contrastHandle, getContrastValue()); + GLES20.glUniform1f(saturationHandle, getSaturationValue()); + GLES20.glUniform1f(warmthHandle, getWarmthValue()); + GLES20.glUniform1f(vignetteHandle, getVignetteValue()); + GLES20.glUniform1f(grainHandle, getGrainValue()); + } + GLES20.glUniform1f(widthHandle, renderBufferWidth); + GLES20.glUniform1f(heightHandle, renderBufferHeight); + GLES20.glEnableVertexAttribArray(inputTexCoordHandle); + GLES20.glVertexAttribPointer(inputTexCoordHandle, 2, GLES20.GL_FLOAT, false, 8, textureBuffer); + GLES20.glEnableVertexAttribArray(positionHandle); + GLES20.glVertexAttribPointer(positionHandle, 2, GLES20.GL_FLOAT, false, 8, vertexInvertBuffer); + GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); + } + + private boolean drawBlurPass() { + if (showOriginal || blurType == 0) { + return false; + } + if (needUpdateBlurTexture) { + GLES20.glUseProgram(blurShaderProgram); + GLES20.glUniform1i(blurSourceImageHandle, 0); + GLES20.glEnableVertexAttribArray(blurInputTexCoordHandle); + GLES20.glVertexAttribPointer(blurInputTexCoordHandle, 2, GLES20.GL_FLOAT, false, 8, textureBuffer); + GLES20.glEnableVertexAttribArray(blurPositionHandle); + GLES20.glVertexAttribPointer(blurPositionHandle, 2, GLES20.GL_FLOAT, false, 8, vertexInvertBuffer); + + GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, renderFrameBuffer[0]); + GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, renderTexture[0], 0); + GLES20.glClear(0); + GLES20.glActiveTexture(GLES20.GL_TEXTURE0); + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTexture[1]); + GLES20.glUniform1f(blurWidthHandle, 0.0f); + GLES20.glUniform1f(blurHeightHandle, 1.0f / renderBufferHeight); + GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); + + GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, renderFrameBuffer[2]); + GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, renderTexture[2], 0); + GLES20.glClear(0); + GLES20.glActiveTexture(GLES20.GL_TEXTURE0); + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTexture[0]); + GLES20.glUniform1f(blurWidthHandle, 1.0f / renderBufferWidth); + GLES20.glUniform1f(blurHeightHandle, 0.0f); + GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); + needUpdateBlurTexture = false; + } + + GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, renderFrameBuffer[0]); + GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, renderTexture[0], 0); + GLES20.glClear(0); + if (blurType == 1) { + GLES20.glUseProgram(radialBlurShaderProgram); + GLES20.glUniform1i(radialBlurSourceImageHandle, 0); + GLES20.glUniform1i(radialBlurSourceImage2Handle, 1); + GLES20.glUniform1f(radialBlurExcludeSizeHandle, blurExcludeSize); + GLES20.glUniform1f(radialBlurExcludeBlurSizeHandle, blurExcludeBlurSize); + GLES20.glUniform2f(radialBlurExcludePointHandle, blurExcludePoint.x, blurExcludePoint.y); + GLES20.glUniform1f(radialBlurAspectRatioHandle, (float) renderBufferHeight / (float) renderBufferWidth); + GLES20.glEnableVertexAttribArray(radialBlurInputTexCoordHandle); + GLES20.glVertexAttribPointer(radialBlurInputTexCoordHandle, 2, GLES20.GL_FLOAT, false, 8, textureBuffer); + GLES20.glEnableVertexAttribArray(radialBlurPositionHandle); + GLES20.glVertexAttribPointer(radialBlurPositionHandle, 2, GLES20.GL_FLOAT, false, 8, vertexInvertBuffer); + } else if (blurType == 2) { + GLES20.glUseProgram(linearBlurShaderProgram); + GLES20.glUniform1i(linearBlurSourceImageHandle, 0); + GLES20.glUniform1i(linearBlurSourceImage2Handle, 1); + GLES20.glUniform1f(linearBlurExcludeSizeHandle, blurExcludeSize); + GLES20.glUniform1f(linearBlurExcludeBlurSizeHandle, blurExcludeBlurSize); + GLES20.glUniform1f(linearBlurAngleHandle, blurAngle); + GLES20.glUniform2f(linearBlurExcludePointHandle, blurExcludePoint.x, blurExcludePoint.y); + GLES20.glUniform1f(linearBlurAspectRatioHandle, (float) renderBufferHeight / (float) renderBufferWidth); + GLES20.glEnableVertexAttribArray(linearBlurInputTexCoordHandle); + GLES20.glVertexAttribPointer(linearBlurInputTexCoordHandle, 2, GLES20.GL_FLOAT, false, 8, textureBuffer); + GLES20.glEnableVertexAttribArray(linearBlurPositionHandle); + GLES20.glVertexAttribPointer(linearBlurPositionHandle, 2, GLES20.GL_FLOAT, false, 8, vertexInvertBuffer); + } + + GLES20.glActiveTexture(GLES20.GL_TEXTURE0); + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTexture[1]); + GLES20.glActiveTexture(GLES20.GL_TEXTURE1); + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTexture[2]); + GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); + + return true; + } + + private Runnable drawRunnable = new Runnable() { + @Override + public void run() { + if (!initied) { + return; + } + + if (!eglContext.equals(egl10.eglGetCurrentContext()) || !eglSurface.equals(egl10.eglGetCurrentSurface(EGL10.EGL_DRAW))) { + if (!egl10.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) { + FileLog.e("tmessages", "eglMakeCurrent failed " + GLUtils.getEGLErrorString(egl10.eglGetError())); + return; + } + } + + GLES20.glViewport(0, 0, renderBufferWidth, renderBufferHeight); + drawEnhancePass(); + drawSharpenPass(); + drawCustomParamsPass(); + blured = drawBlurPass(); + + //onscreen draw + GLES20.glViewport(0, 0, surfaceWidth, surfaceHeight); + GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); + GLES20.glClear(0); + + GLES20.glUseProgram(simpleShaderProgram); + GLES20.glActiveTexture(GLES20.GL_TEXTURE0); + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTexture[blured ? 0 : 1]); + GLES20.glUniform1i(simpleSourceImageHandle, 0); + GLES20.glEnableVertexAttribArray(simpleInputTexCoordHandle); + GLES20.glVertexAttribPointer(simpleInputTexCoordHandle, 2, GLES20.GL_FLOAT, false, 8, textureBuffer); + GLES20.glEnableVertexAttribArray(simplePositionHandle); + GLES20.glVertexAttribPointer(simplePositionHandle, 2, GLES20.GL_FLOAT, false, 8, vertexBuffer); + GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); + egl10.eglSwapBuffers(eglDisplay, eglSurface); + } + }; + + private Bitmap getRenderBufferBitmap() { + ByteBuffer buffer = ByteBuffer.allocateDirect(renderBufferWidth * renderBufferHeight * 4); + GLES20.glReadPixels(0, 0, renderBufferWidth, renderBufferHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buffer); + Bitmap bitmap = Bitmap.createBitmap(renderBufferWidth, renderBufferHeight, Bitmap.Config.ARGB_8888); + bitmap.copyPixelsFromBuffer(buffer); + return bitmap; + } + + public Bitmap getTexture() { + if (!initied) { + return null; + } + final Semaphore semaphore = new Semaphore(0); + final Bitmap object[] = new Bitmap[1]; + try { + postRunnable(new Runnable() { + @Override + public void run() { + GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, renderFrameBuffer[1]); + GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, renderTexture[blured ? 0 : 1], 0); + GLES20.glClear(0); + object[0] = getRenderBufferBitmap(); + semaphore.release(); + GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); + GLES20.glClear(0); + } + }); + semaphore.acquire(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + return object[0]; + } + + private Bitmap createBitmap(Bitmap bitmap, int w, int h, float scale) { + Bitmap result = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(result); + Paint paint = new Paint(); + paint.setFilterBitmap(true); + + Matrix matrix = new Matrix(); + matrix.setScale(scale, scale); + matrix.postTranslate(-bitmap.getWidth() / 2, -bitmap.getHeight() / 2); + matrix.postRotate(orientation); + if (orientation == 90 || orientation == 270) { + matrix.postTranslate(bitmap.getHeight() / 2, bitmap.getWidth() / 2); + } else { + matrix.postTranslate(bitmap.getWidth() / 2, bitmap.getHeight() / 2); + } + canvas.drawBitmap(bitmap, matrix, paint); + try { + canvas.setBitmap(null); + } catch (Exception e) { + //don't promt, this will crash on 2.x + } + + return result; + } + + private void loadTexture(Bitmap bitmap) { + renderBufferWidth = bitmap.getWidth(); + renderBufferHeight = bitmap.getHeight(); + float maxSize = AndroidUtilities.getPhotoSize(); + if (renderBufferWidth > maxSize || renderBufferHeight > maxSize || orientation != 0) { + float scale = 1; + if (renderBufferWidth > maxSize || renderBufferHeight > maxSize) { + float scaleX = maxSize / bitmap.getWidth(); + float scaleY = maxSize / bitmap.getHeight(); + if (scaleX < scaleY) { + renderBufferWidth = (int) maxSize; + renderBufferHeight = (int) (bitmap.getHeight() * scaleX); + scale = scaleX; + } else { + renderBufferHeight = (int) maxSize; + renderBufferWidth = (int) (bitmap.getWidth() * scaleY); + scale = scaleY; + } + } + + if (orientation == 90 || orientation == 270) { + int temp = renderBufferWidth; + renderBufferWidth = renderBufferHeight; + renderBufferHeight = temp; + } + + currentBitmap = createBitmap(bitmap, renderBufferWidth, renderBufferHeight, scale); + } + GLES20.glGenFramebuffers(3, renderFrameBuffer, 0); + GLES20.glGenTextures(3, renderTexture, 0); + + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTexture[0]); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); + GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, renderBufferWidth, renderBufferHeight, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null); + + GLES20.glBindTexture(GL10.GL_TEXTURE_2D, renderTexture[1]); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); + GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, currentBitmap, 0); + + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTexture[2]); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); + GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); + GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, renderBufferWidth, renderBufferHeight, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null); + } + + public void shutdown() { + postRunnable(new Runnable() { + @Override + public void run() { + finish(); + currentBitmap = null; + Looper looper = Looper.myLooper(); + if (looper != null) { + looper.quit(); + } + } + }); + } + + public void setSurfaceTextureSize(int width, int height) { + surfaceWidth = width; + surfaceHeight = height; + } + + @Override + public void run() { + initied = initGL(); + super.run(); + } + + public void requestRender(final boolean updateBlur) { + postRunnable(new Runnable() { + @Override + public void run() { + if (!needUpdateBlurTexture) { + needUpdateBlurTexture = updateBlur; + } + cancelRunnable(drawRunnable); + postRunnable(drawRunnable); + } + }); + } + } + + public PhotoFilterView(Context context, Bitmap bitmap, int rotation) { + super(context); + + bitmapToEdit = bitmap; + orientation = rotation; + + textureView = new TextureView(context); + if (Build.VERSION.SDK_INT == 14 || Build.VERSION.SDK_INT == 15) { + //setLayerType(LAYER_TYPE_HARDWARE, null); + //textureView.setLayerType(LAYER_TYPE_HARDWARE, null); + } + addView(textureView); + textureView.setVisibility(INVISIBLE); + LayoutParams layoutParams = (LayoutParams) textureView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + textureView.setLayoutParams(layoutParams); + textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() { + @Override + public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { + if (eglThread == null && surface != null) { + eglThread = new EGLThread(surface, bitmapToEdit); + eglThread.setSurfaceTextureSize(width, height); + eglThread.requestRender(true); + } + } + + @Override + public void onSurfaceTextureSizeChanged(SurfaceTexture surface, final int width, final int height) { + if (eglThread != null) { + eglThread.setSurfaceTextureSize(width, height); + eglThread.requestRender(false); + eglThread.postRunnable(new Runnable() { + @Override + public void run() { + eglThread.requestRender(false); + } + }); + } + } + + @Override + public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { + if (eglThread != null) { + eglThread.shutdown(); + eglThread = null; + } + return true; + } + + @Override + public void onSurfaceTextureUpdated(SurfaceTexture surface) { + + } + }); + + blurControl = new PhotoFilterBlurControl(context); + blurControl.setVisibility(INVISIBLE); + addView(blurControl); + layoutParams = (LayoutParams) blurControl.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.LEFT | Gravity.TOP; + blurControl.setLayoutParams(layoutParams); + blurControl.setDelegate(new PhotoFilterBlurControl.PhotoFilterLinearBlurControlDelegate() { + @Override + public void valueChanged(Point centerPoint, float falloff, float size, float angle) { + blurExcludeSize = size; + blurExcludePoint = centerPoint; + blurExcludeBlurSize = falloff; + blurAngle = angle; + if (eglThread != null) { + eglThread.requestRender(false); + } + } + }); + + toolsView = new FrameLayout(context); + addView(toolsView); + layoutParams = (LayoutParams) toolsView.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = AndroidUtilities.dp(126); + layoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM; + toolsView.setLayoutParams(layoutParams); + + FrameLayout frameLayout = new FrameLayout(context); + frameLayout.setBackgroundColor(0xff1a1a1a); + toolsView.addView(frameLayout); + layoutParams = (LayoutParams) frameLayout.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = AndroidUtilities.dp(48); + layoutParams.gravity = Gravity.BOTTOM | Gravity.LEFT; + frameLayout.setLayoutParams(layoutParams); + + cancelTextView = new TextView(context); + cancelTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + cancelTextView.setTextColor(0xffffffff); + cancelTextView.setGravity(Gravity.CENTER); + cancelTextView.setBackgroundResource(R.drawable.bar_selector_picker); + cancelTextView.setPadding(AndroidUtilities.dp(29), 0, AndroidUtilities.dp(29), 0); + cancelTextView.setText(LocaleController.getString("Cancel", R.string.Cancel).toUpperCase()); + cancelTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + frameLayout.addView(cancelTextView); + layoutParams = (LayoutParams) cancelTextView.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + cancelTextView.setLayoutParams(layoutParams); + + doneTextView = new TextView(context); + doneTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + doneTextView.setTextColor(0xff51bdf3); + doneTextView.setGravity(Gravity.CENTER); + doneTextView.setBackgroundResource(R.drawable.bar_selector_picker); + doneTextView.setPadding(AndroidUtilities.dp(29), 0, AndroidUtilities.dp(29), 0); + doneTextView.setText(LocaleController.getString("Done", R.string.Done).toUpperCase()); + doneTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + frameLayout.addView(doneTextView); + layoutParams = (LayoutParams) doneTextView.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP | Gravity.RIGHT; + doneTextView.setLayoutParams(layoutParams); + + recyclerListView = new RecyclerListView(context); + LinearLayoutManager layoutManager = new LinearLayoutManager(context); + layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); + recyclerListView.setLayoutManager(layoutManager); + recyclerListView.setClipToPadding(false); + if (Build.VERSION.SDK_INT >= 9) { + recyclerListView.setOverScrollMode(RecyclerListView.OVER_SCROLL_NEVER); + } + recyclerListView.setAdapter(toolsAdapter = new ToolsAdapter(context)); + toolsView.addView(recyclerListView); + layoutParams = (FrameLayout.LayoutParams) recyclerListView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = AndroidUtilities.dp(60); + layoutParams.gravity = Gravity.LEFT | Gravity.TOP; + recyclerListView.setLayoutParams(layoutParams); + recyclerListView.addOnItemTouchListener(new RecyclerListView.RecyclerListViewItemClickListener(context, new RecyclerListView.OnItemClickListener() { + @Override + public void onItemClick(View view, int i) { + selectedTool = i; + if (i == enhanceTool) { + previousValue = enhanceValue; + valueSeekBar.setMinMax(0, 100); + paramTextView.setText(LocaleController.getString("Enhance", R.string.Enhance)); + } else if (i == highlightsTool) { + previousValue = highlightsValue; + valueSeekBar.setMinMax(0, 100); + paramTextView.setText(LocaleController.getString("Highlights", R.string.Highlights)); + } else if (i == contrastTool) { + previousValue = contrastValue; + valueSeekBar.setMinMax(-100, 100); + paramTextView.setText(LocaleController.getString("Contrast", R.string.Contrast)); + } else if (i == exposureTool) { + previousValue = exposureValue; + valueSeekBar.setMinMax(-100, 100); + paramTextView.setText(LocaleController.getString("Exposure", R.string.Exposure)); + } else if (i == warmthTool) { + previousValue = warmthValue; + valueSeekBar.setMinMax(-100, 100); + paramTextView.setText(LocaleController.getString("Warmth", R.string.Warmth)); + } else if (i == saturationTool) { + previousValue = saturationValue; + valueSeekBar.setMinMax(-100, 100); + paramTextView.setText(LocaleController.getString("Saturation", R.string.Saturation)); + } else if (i == vignetteTool) { + previousValue = vignetteValue; + valueSeekBar.setMinMax(0, 100); + paramTextView.setText(LocaleController.getString("Vignette", R.string.Vignette)); + } else if (i == shadowsTool) { + previousValue = shadowsValue; + valueSeekBar.setMinMax(0, 100); + paramTextView.setText(LocaleController.getString("Shadows", R.string.Shadows)); + } else if (i == grainTool) { + previousValue = grainValue; + valueSeekBar.setMinMax(0, 100); + paramTextView.setText(LocaleController.getString("Grain", R.string.Grain)); + } else if (i == sharpenTool) { + previousValue = sharpenValue; + valueSeekBar.setMinMax(0, 100); + paramTextView.setText(LocaleController.getString("Sharpen", R.string.Sharpen)); + } else if (i == blurTool) { + previousValue = blurType; + } + valueSeekBar.setProgress((int) previousValue, false); + updateValueTextView(); + switchToOrFromEditMode(); + } + })); + + editView = new FrameLayout(context); + editView.setVisibility(GONE); + addView(editView); + layoutParams = (LayoutParams) editView.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = AndroidUtilities.dp(126); + layoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM; + editView.setLayoutParams(layoutParams); + + frameLayout = new FrameLayout(context); + frameLayout.setBackgroundColor(0xff1a1a1a); + editView.addView(frameLayout); + layoutParams = (LayoutParams) frameLayout.getLayoutParams(); + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = AndroidUtilities.dp(48); + layoutParams.gravity = Gravity.BOTTOM | Gravity.LEFT; + frameLayout.setLayoutParams(layoutParams); + + ImageView imageView = new ImageView(context); + imageView.setImageResource(R.drawable.edit_cancel); + imageView.setBackgroundResource(R.drawable.bar_selector_picker); + imageView.setPadding(AndroidUtilities.dp(22), 0, AndroidUtilities.dp(22), 0); + frameLayout.addView(imageView); + layoutParams = (LayoutParams) imageView.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + imageView.setLayoutParams(layoutParams); + imageView.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (selectedTool == enhanceTool) { + enhanceValue = previousValue; + } else if (selectedTool == highlightsTool) { + highlightsValue = previousValue; + } else if (selectedTool == contrastTool) { + contrastValue = previousValue; + } else if (selectedTool == exposureTool) { + exposureValue = previousValue; + } else if (selectedTool == warmthTool) { + warmthValue = previousValue; + } else if (selectedTool == saturationTool) { + saturationValue = previousValue; + } else if (selectedTool == vignetteTool) { + vignetteValue = previousValue; + } else if (selectedTool == shadowsTool) { + shadowsValue = previousValue; + } else if (selectedTool == grainTool) { + grainValue = previousValue; + } else if (selectedTool == sharpenTool) { + sharpenValue = previousValue; + } else if (selectedTool == blurTool) { + blurType = (int) previousValue; + } + if (eglThread != null) { + eglThread.requestRender(selectedTool != blurTool); + } + switchToOrFromEditMode(); + } + }); + + imageView = new ImageView(context); + imageView.setImageResource(R.drawable.edit_doneblue); + imageView.setBackgroundResource(R.drawable.bar_selector_picker); + imageView.setPadding(AndroidUtilities.dp(22), AndroidUtilities.dp(1), AndroidUtilities.dp(22), 0); + frameLayout.addView(imageView); + layoutParams = (LayoutParams) imageView.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP | Gravity.RIGHT; + imageView.setLayoutParams(layoutParams); + imageView.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + toolsAdapter.notifyDataSetChanged(); + switchToOrFromEditMode(); + } + }); + + blurTextView = new TextView(context); + blurTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); + blurTextView.setTextColor(0xffffffff); + blurTextView.setText(LocaleController.getString("Blur", R.string.Blur)); + frameLayout.addView(blurTextView); + layoutParams = (LayoutParams) blurTextView.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.CENTER_HORIZONTAL; + layoutParams.topMargin = AndroidUtilities.dp(9); + blurTextView.setLayoutParams(layoutParams); + + paramTextView = new TextView(context); + paramTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12); + paramTextView.setTextColor(0xff808080); + frameLayout.addView(paramTextView); + layoutParams = (LayoutParams) paramTextView.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.CENTER_HORIZONTAL; + layoutParams.topMargin = AndroidUtilities.dp(26); + paramTextView.setLayoutParams(layoutParams); + + valueTextView = new TextView(context); + valueTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); + valueTextView.setTextColor(0xffffffff); + frameLayout.addView(valueTextView); + layoutParams = (LayoutParams) valueTextView.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.CENTER_HORIZONTAL; + layoutParams.topMargin = AndroidUtilities.dp(3); + valueTextView.setLayoutParams(layoutParams); + + valueSeekBar = new PhotoEditorSeekBar(context); + valueSeekBar.setDelegate(new PhotoEditorSeekBar.PhotoEditorSeekBarDelegate() { + @Override + public void onProgressChanged() { + int progress = valueSeekBar.getProgress(); + if (selectedTool == enhanceTool) { + enhanceValue = progress; + } else if (selectedTool == highlightsTool) { + highlightsValue = progress; + } else if (selectedTool == contrastTool) { + contrastValue = progress; + } else if (selectedTool == exposureTool) { + exposureValue = progress; + } else if (selectedTool == warmthTool) { + warmthValue = progress; + } else if (selectedTool == saturationTool) { + saturationValue = progress; + } else if (selectedTool == vignetteTool) { + vignetteValue = progress; + } else if (selectedTool == shadowsTool) { + shadowsValue = progress; + } else if (selectedTool == grainTool) { + grainValue = progress; + } else if (selectedTool == sharpenTool) { + sharpenValue = progress; + } + updateValueTextView(); + if (eglThread != null) { + eglThread.requestRender(true); + } + } + }); + editView.addView(valueSeekBar); + layoutParams = (LayoutParams) valueSeekBar.getLayoutParams(); + layoutParams.height = AndroidUtilities.dp(60); + layoutParams.leftMargin = AndroidUtilities.dp(14); + layoutParams.rightMargin = AndroidUtilities.dp(14); + layoutParams.topMargin = AndroidUtilities.dp(10); + if (AndroidUtilities.isTablet()) { + layoutParams.width = AndroidUtilities.dp(498); + layoutParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP; + } else { + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.LEFT | Gravity.TOP; + } + valueSeekBar.setLayoutParams(layoutParams); + + blurLayout = new FrameLayout(context); + editView.addView(blurLayout); + layoutParams = (LayoutParams) blurLayout.getLayoutParams(); + layoutParams.width = AndroidUtilities.dp(280); + layoutParams.height = AndroidUtilities.dp(60); + layoutParams.topMargin = AndroidUtilities.dp(10); + layoutParams.gravity = Gravity.CENTER_HORIZONTAL; + blurLayout.setLayoutParams(layoutParams); + + blurOffButton = new TextView(context); + blurOffButton.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.blur_off_active, 0, 0); + blurOffButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13); + blurOffButton.setTextColor(0xff51bdf3); + blurOffButton.setGravity(Gravity.CENTER_HORIZONTAL); + blurOffButton.setText(LocaleController.getString("BlurOff", R.string.BlurOff)); + blurLayout.addView(blurOffButton); + layoutParams = (LayoutParams) blurOffButton.getLayoutParams(); + layoutParams.width = AndroidUtilities.dp(80); + layoutParams.height = AndroidUtilities.dp(60); + blurOffButton.setLayoutParams(layoutParams); + blurOffButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + blurType = 0; + updateSelectedBlurType(); + blurControl.setVisibility(INVISIBLE); + if (eglThread != null) { + eglThread.requestRender(false); + } + } + }); + + blurRadialButton = new TextView(context); + blurRadialButton.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.blur_radial, 0, 0); + blurRadialButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13); + blurRadialButton.setTextColor(0xffffffff); + blurRadialButton.setGravity(Gravity.CENTER_HORIZONTAL); + blurRadialButton.setText(LocaleController.getString("BlurRadial", R.string.BlurRadial)); + blurLayout.addView(blurRadialButton); + layoutParams = (LayoutParams) blurRadialButton.getLayoutParams(); + layoutParams.width = AndroidUtilities.dp(80); + layoutParams.height = AndroidUtilities.dp(60); + layoutParams.leftMargin = AndroidUtilities.dp(100); + blurRadialButton.setLayoutParams(layoutParams); + blurRadialButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + blurType = 1; + updateSelectedBlurType(); + blurControl.setVisibility(VISIBLE); + blurControl.setType(1); + if (eglThread != null) { + eglThread.requestRender(false); + } + } + }); + + blurLinearButton = new TextView(context); + blurLinearButton.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.blur_linear, 0, 0); + blurLinearButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13); + blurLinearButton.setTextColor(0xffffffff); + blurLinearButton.setGravity(Gravity.CENTER_HORIZONTAL); + blurLinearButton.setText(LocaleController.getString("BlurLinear", R.string.BlurLinear)); + blurLayout.addView(blurLinearButton); + layoutParams = (LayoutParams) blurLinearButton.getLayoutParams(); + layoutParams.width = AndroidUtilities.dp(80); + layoutParams.height = AndroidUtilities.dp(60); + layoutParams.leftMargin = AndroidUtilities.dp(200); + blurLinearButton.setLayoutParams(layoutParams); + blurLinearButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + blurType = 2; + updateSelectedBlurType(); + blurControl.setVisibility(VISIBLE); + blurControl.setType(0); + if (eglThread != null) { + eglThread.requestRender(false); + } + } + }); + } + + private void updateSelectedBlurType() { + if (blurType == 0) { + blurOffButton.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.blur_off_active, 0, 0); + blurOffButton.setTextColor(0xff51bdf3); + blurRadialButton.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.blur_radial, 0, 0); + blurRadialButton.setTextColor(0xffffffff); + blurLinearButton.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.blur_linear, 0, 0); + blurLinearButton.setTextColor(0xffffffff); + } else if (blurType == 1) { + blurOffButton.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.blur_off, 0, 0); + blurOffButton.setTextColor(0xffffffff); + blurRadialButton.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.blur_radial_active, 0, 0); + blurRadialButton.setTextColor(0xff51bdf3); + blurLinearButton.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.blur_linear, 0, 0); + blurLinearButton.setTextColor(0xffffffff); + } else if (blurType == 2) { + blurOffButton.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.blur_off, 0, 0); + blurOffButton.setTextColor(0xffffffff); + blurRadialButton.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.blur_radial, 0, 0); + blurRadialButton.setTextColor(0xffffffff); + blurLinearButton.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.blur_linear_active, 0, 0); + blurLinearButton.setTextColor(0xff51bdf3); + } + } + + private void updateValueTextView() { + int value = 0; + if (selectedTool == enhanceTool) { + value = (int) enhanceValue; + } else if (selectedTool == highlightsTool) { + value = (int) highlightsValue; + } else if (selectedTool == contrastTool) { + value = (int) contrastValue; + } else if (selectedTool == exposureTool) { + value = (int) exposureValue; + } else if (selectedTool == warmthTool) { + value = (int) warmthValue; + } else if (selectedTool == saturationTool) { + value = (int) saturationValue; + } else if (selectedTool == vignetteTool) { + value = (int) vignetteValue; + } else if (selectedTool == shadowsTool) { + value = (int) shadowsValue; + } else if (selectedTool == grainTool) { + value = (int) grainValue; + } else if (selectedTool == sharpenTool) { + value = (int) sharpenValue; + } + if (value > 0) { + valueTextView.setText("+" + value); + } else { + valueTextView.setText("" + value); + } + } + + public boolean hasChanges() { + return enhanceValue != 0 || contrastValue != 0 || highlightsValue != 0 || exposureValue != 0 || warmthValue != 0 || saturationValue != 0 || vignetteValue != 0 || + shadowsValue != 0 || grainValue != 0 || sharpenValue != 0; + } + + public void onTouch(MotionEvent event) { + if (event.getActionMasked() == MotionEvent.ACTION_DOWN || event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) { + LayoutParams layoutParams = (LayoutParams) textureView.getLayoutParams(); + if (layoutParams != null && event.getX() >= layoutParams.leftMargin && event.getY() >= layoutParams.topMargin && event.getX() <= layoutParams.leftMargin + layoutParams.width && event.getY() <= layoutParams.topMargin + layoutParams.height) { + setShowOriginal(true); + } + } else if (event.getActionMasked() == MotionEvent.ACTION_UP || event.getActionMasked() == MotionEvent.ACTION_POINTER_UP) { + setShowOriginal(false); + } + } + + private void setShowOriginal(boolean value) { + if (showOriginal == value) { + return; + } + showOriginal = value; + if (eglThread != null) { + eglThread.requestRender(false); + } + } + + public void switchToOrFromEditMode() { + final View viewFrom; + final View viewTo; + if (editView.getVisibility() == GONE) { + viewFrom = toolsView; + viewTo = editView; + + if (selectedTool == blurTool) { + blurLayout.setVisibility(VISIBLE); + valueSeekBar.setVisibility(INVISIBLE); + blurTextView.setVisibility(VISIBLE); + paramTextView.setVisibility(INVISIBLE); + valueTextView.setVisibility(INVISIBLE); + if (blurType != 0) { + blurControl.setVisibility(VISIBLE); + } + updateSelectedBlurType(); + } else { + blurLayout.setVisibility(INVISIBLE); + valueSeekBar.setVisibility(VISIBLE); + blurTextView.setVisibility(INVISIBLE); + paramTextView.setVisibility(VISIBLE); + valueTextView.setVisibility(VISIBLE); + blurControl.setVisibility(INVISIBLE); + } + } else { + selectedTool = -1; + viewFrom = editView; + viewTo = toolsView; + blurControl.setVisibility(INVISIBLE); + } + + AnimatorSetProxy animatorSet = new AnimatorSetProxy(); + animatorSet.playTogether( + ObjectAnimatorProxy.ofFloat(viewFrom, "translationY", 0, AndroidUtilities.dp(126)) + ); + animatorSet.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + viewFrom.clearAnimation(); + viewFrom.setVisibility(GONE); + viewTo.setVisibility(VISIBLE); + ViewProxy.setTranslationY(viewTo, AndroidUtilities.dp(126)); + + AnimatorSetProxy animatorSet = new AnimatorSetProxy(); + animatorSet.playTogether( + ObjectAnimatorProxy.ofFloat(viewTo, "translationY", 0) + ); + animatorSet.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + viewTo.clearAnimation(); + if (selectedTool == enhanceTool) { + checkEnhance(); + } + } + }); + animatorSet.setDuration(200); + animatorSet.start(); + } + }); + animatorSet.setDuration(200); + animatorSet.start(); + } + + public void shutdown() { + if (eglThread != null) { + eglThread.shutdown(); + eglThread = null; + } + textureView.setVisibility(GONE); + } + + public void init() { + textureView.setVisibility(VISIBLE); + } + + public Bitmap getBitmap() { + return eglThread != null ? eglThread.getTexture() : null; + } + + private void fixLayout(int viewWidth, int viewHeight) { + if (bitmapToEdit == null) { + return; + } + + viewWidth -= AndroidUtilities.dp(28); + viewHeight -= AndroidUtilities.dp(14 + 140); + + float bitmapW = bitmapToEdit.getWidth(); + float bitmapH = bitmapToEdit.getHeight(); + if (orientation == 90 || orientation == 270) { + bitmapW = bitmapToEdit.getHeight(); + bitmapH = bitmapToEdit.getWidth(); + } else { + bitmapW = bitmapToEdit.getWidth(); + bitmapH = bitmapToEdit.getHeight(); + } + float scaleX = viewWidth / bitmapW; + float scaleY = viewHeight / bitmapH; + if (scaleX > scaleY) { + bitmapH = viewHeight; + bitmapW = (int) Math.ceil(bitmapW * scaleY); + } else { + bitmapW = viewWidth; + bitmapH = (int) Math.ceil(bitmapH * scaleX); + } + + int bitmapX = (int) Math.ceil((viewWidth - bitmapW) / 2 + AndroidUtilities.dp(14)); + int bitmapY = (int) Math.ceil((viewHeight - bitmapH) / 2 + AndroidUtilities.dp(14)); + + LayoutParams layoutParams = (LayoutParams) textureView.getLayoutParams(); + layoutParams.leftMargin = bitmapX; + layoutParams.topMargin = bitmapY; + layoutParams.width = (int) bitmapW; + layoutParams.height = (int) bitmapH; + textureView.setLayoutParams(layoutParams); + + blurControl.setActualAreaSize(layoutParams.width, layoutParams.height); + layoutParams = (LayoutParams) blurControl.getLayoutParams(); + layoutParams.height = viewHeight + AndroidUtilities.dp(28); + blurControl.setLayoutParams(layoutParams); + + if (AndroidUtilities.isTablet()) { + int total = AndroidUtilities.dp(86) * 10; + layoutParams = (FrameLayout.LayoutParams) recyclerListView.getLayoutParams(); + if (total < viewWidth) { + layoutParams.width = total; + layoutParams.leftMargin = (viewWidth - total) / 2; + } else { + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.leftMargin = 0; + } + recyclerListView.setLayoutParams(layoutParams); + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + fixLayout(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec)); + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + private float getShadowsValue() { + return (shadowsValue / 100.0f) * 0.65f; + } + + private float getHighlightsValue() { + return 1 - (highlightsValue / 100.0f); + } + + private float getEnhanceValue() { + return (enhanceValue / 100.0f); + } + + private float getExposureValue() { + return (exposureValue / 100.0f); + } + + private float getContrastValue() { + return (contrastValue / 100.0f) * 0.3f + 1; + } + + private float getWarmthValue() { + return warmthValue / 100.0f; + } + + private float getVignetteValue() { + return vignetteValue / 100.0f; + } + + private float getSharpenValue() { + return 0.11f + sharpenValue / 100.0f * 0.6f; + } + + private float getGrainValue() { + return grainValue / 100.0f * 0.04f; + } + + private float getSaturationValue() { + float parameterValue = (saturationValue / 100.0f); + if (parameterValue > 0) { + parameterValue *= 1.05f; + } + return parameterValue += 1; + } + + public FrameLayout getToolsView() { + return toolsView; + } + + public FrameLayout getEditView() { + return editView; + } + + public TextView getDoneTextView() { + return doneTextView; + } + + public TextView getCancelTextView() { + return cancelTextView; + } + + public void setEditViewFirst() { + selectedTool = 0; + previousValue = enhanceValue; + enhanceValue = 50; + valueSeekBar.setMinMax(0, 100); + paramTextView.setText(LocaleController.getString("Enhance", R.string.Enhance)); + editView.setVisibility(VISIBLE); + toolsView.setVisibility(GONE); + valueSeekBar.setProgress(50, false); + updateValueTextView(); + } + + private void checkEnhance() { + if (enhanceValue == 0) { + AnimatorSetProxy animatorSetProxy = new AnimatorSetProxy(); + animatorSetProxy.setDuration(200); + animatorSetProxy.playTogether(ObjectAnimatorProxy.ofInt(valueSeekBar, "progress", 50)); + animatorSetProxy.start(); + } + } + + public class ToolsAdapter extends RecyclerView.Adapter { + + private Context mContext; + + private class Holder extends RecyclerView.ViewHolder { + + public Holder(View itemView) { + super(itemView); + } + } + + public ToolsAdapter(Context context) { + mContext = context; + } + + @Override + public int getItemCount() { + return 11; + } + + @Override + public long getItemId(int i) { + return i; + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { + PhotoEditToolCell view = new PhotoEditToolCell(mContext); + return new Holder(view); + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) { + Holder holder = (Holder) viewHolder; + if (i == enhanceTool) { + ((PhotoEditToolCell) holder.itemView).setIconAndTextAndValue(R.drawable.tool_enhance, LocaleController.getString("Enhance", R.string.Enhance), enhanceValue); + } else if (i == highlightsTool) { + ((PhotoEditToolCell) holder.itemView).setIconAndTextAndValue(R.drawable.tool_highlights, LocaleController.getString("Highlights", R.string.Highlights), highlightsValue); + } else if (i == contrastTool) { + ((PhotoEditToolCell) holder.itemView).setIconAndTextAndValue(R.drawable.tool_contrast, LocaleController.getString("Contrast", R.string.Contrast), contrastValue); + } else if (i == exposureTool) { + ((PhotoEditToolCell) holder.itemView).setIconAndTextAndValue(R.drawable.tool_brightness, LocaleController.getString("Exposure", R.string.Exposure), exposureValue); + } else if (i == warmthTool) { + ((PhotoEditToolCell) holder.itemView).setIconAndTextAndValue(R.drawable.tool_warmth, LocaleController.getString("Warmth", R.string.Warmth), warmthValue); + } else if (i == saturationTool) { + ((PhotoEditToolCell) holder.itemView).setIconAndTextAndValue(R.drawable.tool_saturation, LocaleController.getString("Saturation", R.string.Saturation), saturationValue); + } else if (i == vignetteTool) { + ((PhotoEditToolCell) holder.itemView).setIconAndTextAndValue(R.drawable.tool_vignette, LocaleController.getString("Vignette", R.string.Vignette), vignetteValue); + } else if (i == shadowsTool) { + ((PhotoEditToolCell) holder.itemView).setIconAndTextAndValue(R.drawable.tool_shadows, LocaleController.getString("Shadows", R.string.Shadows), shadowsValue); + } else if (i == grainTool) { + ((PhotoEditToolCell) holder.itemView).setIconAndTextAndValue(R.drawable.tool_grain, LocaleController.getString("Grain", R.string.Grain), grainValue); + } else if (i == sharpenTool) { + ((PhotoEditToolCell) holder.itemView).setIconAndTextAndValue(R.drawable.tool_details, LocaleController.getString("Sharpen", R.string.Sharpen), sharpenValue); + } else if (i == blurTool) { + String value = ""; + if (blurType == 1) { + value = "R"; + } else if (blurType == 2) { + value = "L"; + } + ((PhotoEditToolCell) holder.itemView).setIconAndTextAndValue(R.drawable.tool_blur, LocaleController.getString("Blur", R.string.Blur), value); + } + } + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoPickerBottomLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoPickerBottomLayout.java index 97fc7e756..fb6db0a09 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoPickerBottomLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoPickerBottomLayout.java @@ -20,52 +20,43 @@ import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; import org.telegram.messenger.R; -public class PhotoPickerBottomLayout extends LinearLayout { +public class PhotoPickerBottomLayout extends FrameLayout { - public FrameLayout doneButton; + public LinearLayout doneButton; public TextView cancelButton; public TextView doneButtonTextView; public TextView doneButtonBadgeTextView; public PhotoPickerBottomLayout(Context context) { super(context); - setBackgroundColor(0xff333333); - setOrientation(HORIZONTAL); + setBackgroundColor(0xff1a1a1a); cancelButton = new TextView(context); cancelButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); cancelButton.setTextColor(0xffffffff); cancelButton.setGravity(Gravity.CENTER); cancelButton.setBackgroundResource(R.drawable.bar_selector_picker); - cancelButton.setPadding(AndroidUtilities.dp(3), 0, 0, 0); + cancelButton.setPadding(AndroidUtilities.dp(29), 0, AndroidUtilities.dp(29), 0); cancelButton.setText(LocaleController.getString("Cancel", R.string.Cancel).toUpperCase()); cancelButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); addView(cancelButton); LayoutParams layoutParams = (LayoutParams) cancelButton.getLayoutParams(); - layoutParams.width = 0; + layoutParams.width = LayoutParams.WRAP_CONTENT; layoutParams.height = LayoutParams.MATCH_PARENT; - layoutParams.weight = 1; + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; cancelButton.setLayoutParams(layoutParams); - doneButton = new FrameLayout(context); + doneButton = new LinearLayout(context); + doneButton.setOrientation(LinearLayout.HORIZONTAL); doneButton.setBackgroundResource(R.drawable.bar_selector_picker); - doneButton.setPadding(0, 0, AndroidUtilities.dp(3), 0); + doneButton.setPadding(AndroidUtilities.dp(29), 0, AndroidUtilities.dp(29), 0); addView(doneButton); layoutParams = (LayoutParams) doneButton.getLayoutParams(); - layoutParams.width = 0; + layoutParams.width = LayoutParams.WRAP_CONTENT; layoutParams.height = LayoutParams.MATCH_PARENT; - layoutParams.weight = 1; + layoutParams.gravity = Gravity.TOP | Gravity.RIGHT; doneButton.setLayoutParams(layoutParams); - LinearLayout linearLayout = new LinearLayout(context); - linearLayout.setOrientation(HORIZONTAL); - doneButton.addView(linearLayout); - FrameLayout.LayoutParams layoutParams1 = (FrameLayout.LayoutParams) linearLayout.getLayoutParams(); - layoutParams1.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams1.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams1.gravity = Gravity.CENTER; - linearLayout.setLayoutParams(layoutParams1); - doneButtonBadgeTextView = new TextView(context); doneButtonBadgeTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); doneButtonBadgeTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13); @@ -74,28 +65,27 @@ public class PhotoPickerBottomLayout extends LinearLayout { doneButtonBadgeTextView.setBackgroundResource(R.drawable.photobadge); doneButtonBadgeTextView.setMinWidth(AndroidUtilities.dp(23)); doneButtonBadgeTextView.setPadding(AndroidUtilities.dp(8), 0, AndroidUtilities.dp(8), AndroidUtilities.dp(1)); - linearLayout.addView(doneButtonBadgeTextView); - layoutParams = (LayoutParams) doneButtonBadgeTextView.getLayoutParams(); - layoutParams.width = LayoutParams.WRAP_CONTENT; - layoutParams.height = AndroidUtilities.dp(23); - layoutParams.rightMargin = AndroidUtilities.dp(10); - doneButtonBadgeTextView.setLayoutParams(layoutParams); + doneButton.addView(doneButtonBadgeTextView); + LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams) doneButtonBadgeTextView.getLayoutParams(); + layoutParams1.width = LayoutParams.WRAP_CONTENT; + layoutParams1.height = AndroidUtilities.dp(23); + layoutParams1.rightMargin = AndroidUtilities.dp(10); + layoutParams1.gravity = Gravity.CENTER_VERTICAL; + doneButtonBadgeTextView.setLayoutParams(layoutParams1); doneButtonTextView = new TextView(context); doneButtonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); doneButtonTextView.setTextColor(0xffffffff); doneButtonTextView.setGravity(Gravity.CENTER); doneButtonTextView.setCompoundDrawablePadding(AndroidUtilities.dp(8)); - doneButtonTextView.setBackgroundResource(R.drawable.bar_selector_picker); - doneButtonTextView.setPadding(AndroidUtilities.dp(3), 0, 0, 0); doneButtonTextView.setText(LocaleController.getString("Send", R.string.Send).toUpperCase()); doneButtonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); - linearLayout.addView(doneButtonTextView); - layoutParams = (LayoutParams) doneButtonTextView.getLayoutParams(); - layoutParams.width = LayoutParams.WRAP_CONTENT; - layoutParams.gravity = Gravity.CENTER_VERTICAL; - layoutParams.height = LayoutParams.WRAP_CONTENT; - doneButtonTextView.setLayoutParams(layoutParams); + doneButton.addView(doneButtonTextView); + layoutParams1 = (LinearLayout.LayoutParams) doneButtonTextView.getLayoutParams(); + layoutParams1.width = LayoutParams.WRAP_CONTENT; + layoutParams1.gravity = Gravity.CENTER_VERTICAL; + layoutParams1.height = LayoutParams.WRAP_CONTENT; + doneButtonTextView.setLayoutParams(layoutParams1); } public void updateSelectedCount(int count, boolean disable) { @@ -103,12 +93,10 @@ public class PhotoPickerBottomLayout extends LinearLayout { doneButtonBadgeTextView.setVisibility(View.GONE); if (disable) { - doneButtonTextView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.selectphoto_small_grey, 0, 0, 0); doneButtonTextView.setTextColor(0xff999999); doneButton.setEnabled(false); } else { doneButtonTextView.setTextColor(0xffffffff); - doneButtonTextView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.selectphoto_small_active, 0, 0, 0); } } else { doneButtonTextView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Point.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Point.java new file mode 100644 index 000000000..f22dde478 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Point.java @@ -0,0 +1,23 @@ +/* + * This is the source code of Telegram for Android v. 2.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-2015. + */ + +package org.telegram.ui.Components; + +public class Point { + public float x; + public float y; + + public Point() { + + } + + public Point(float x, float y) { + this.x = x; + this.y = y; + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ProgressView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ProgressView.java index adaa786e2..b6f2561b6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ProgressView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ProgressView.java @@ -14,6 +14,7 @@ import android.graphics.Paint; import org.telegram.android.AndroidUtilities; public class ProgressView { + private Paint innerPaint; private Paint outerPaint; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Rect.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Rect.java new file mode 100644 index 000000000..9dde354b9 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Rect.java @@ -0,0 +1,23 @@ +/* + * This is the source code of Telegram for Android v. 2.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-2015. + */ + +package org.telegram.ui.Components; + +public class Rect { + public float x; + public float y; + public float width; + public float height; + + public Rect(float x, float y, float width, float height) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/RecyclerListView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/RecyclerListView.java index 9ef873436..08eea19d4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/RecyclerListView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/RecyclerListView.java @@ -18,7 +18,7 @@ import android.view.View; public class RecyclerListView extends RecyclerView { public interface OnItemClickListener { - public void onItemClick(View view, int position); + void onItemClick(View view, int position); } public static class RecyclerListViewItemClickListener implements RecyclerView.OnItemTouchListener { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/SectionsListView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SectionsListView.java index 0d833ee41..a9d4daf79 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/SectionsListView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SectionsListView.java @@ -1,9 +1,9 @@ /* - * This is the source code of Telegram for Android v. 1.7.x. + * This is the source code of Telegram for Android v. 2.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. + * Copyright Nikolai Kudashov, 2013-2015. */ package org.telegram.ui.Components; @@ -12,7 +12,6 @@ import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.view.View; -import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.ListAdapter; import android.widget.ListView; @@ -22,18 +21,12 @@ import org.telegram.android.LocaleController; import org.telegram.messenger.FileLog; import org.telegram.ui.Adapters.BaseSectionsAdapter; -import java.util.ArrayList; - public class SectionsListView extends ListView implements AbsListView.OnScrollListener { - private ArrayList headers = new ArrayList(); - private ArrayList headersCache = new ArrayList(); + private View pinnedHeader; private OnScrollListener mOnScrollListener; private BaseSectionsAdapter mAdapter; - private int currentFirst = -1; - private int currentVisible = -1; - private int startSection; - private int sectionsCount; + private int currentStartSection = -1; public SectionsListView(Context context) { super(context); @@ -55,8 +48,7 @@ public class SectionsListView extends ListView implements AbsListView.OnScrollLi if (mAdapter == adapter) { return; } - headers.clear(); - headersCache.clear(); + pinnedHeader = null; if (adapter instanceof BaseSectionsAdapter) { mAdapter = (BaseSectionsAdapter) adapter; } else { @@ -74,69 +66,38 @@ public class SectionsListView extends ListView implements AbsListView.OnScrollLi return; } - headersCache.addAll(headers); - headers.clear(); - if (mAdapter.getCount() == 0) { return; } - if (currentFirst != firstVisibleItem || currentVisible != visibleItemCount) { - currentFirst = firstVisibleItem; - currentVisible = visibleItemCount; - - sectionsCount = 1; - startSection = mAdapter.getSectionForPosition(firstVisibleItem); - int itemNum = firstVisibleItem + mAdapter.getCountForSection(startSection) - mAdapter.getPositionInSectionForPosition(firstVisibleItem); - while (true) { - if (itemNum >= firstVisibleItem + visibleItemCount) { - break; - } - itemNum += mAdapter.getCountForSection(startSection + sectionsCount); - sectionsCount++; - } + int startSection = mAdapter.getSectionForPosition(firstVisibleItem); + if (currentStartSection != startSection || pinnedHeader == null) { + pinnedHeader = getSectionHeaderView(startSection, pinnedHeader); + currentStartSection = startSection; } - int itemNum = firstVisibleItem; - for (int a = startSection; a < startSection + sectionsCount; a++) { - View header = null; - if (!headersCache.isEmpty()) { - header = headersCache.get(0); - headersCache.remove(0); - } - header = getSectionHeaderView(a, header); - headers.add(header); - int count = mAdapter.getCountForSection(a); - if (a == startSection) { - int pos = mAdapter.getPositionInSectionForPosition(itemNum); - if (pos == count - 1) { - header.setTag(-header.getHeight()); - } else if (pos == count - 2) { - View child = getChildAt(itemNum - firstVisibleItem); - int headerTop = 0; - if (child != null) { - headerTop = child.getTop(); - } else { - headerTop = -AndroidUtilities.dp(100); - } - if (headerTop < 0) { - header.setTag(headerTop); - } else { - header.setTag(0); - } - } else { - header.setTag(0); + int count = mAdapter.getCountForSection(startSection); + + int pos = mAdapter.getPositionInSectionForPosition(firstVisibleItem); + if (pos == count - 1) { + View child = getChildAt(0); + int headerHeight = pinnedHeader.getHeight(); + int headerTop = 0; + if (child != null) { + int available = child.getTop() + child.getHeight(); + if (available < headerHeight) { + headerTop = available - headerHeight; } - itemNum += count - mAdapter.getPositionInSectionForPosition(firstVisibleItem); } else { - View child = getChildAt(itemNum - firstVisibleItem); - if (child != null) { - header.setTag(child.getTop()); - } else { - header.setTag(-AndroidUtilities.dp(100)); - } - itemNum += count; + headerTop = -AndroidUtilities.dp(100); } + if (headerTop < 0) { + pinnedHeader.setTag(headerTop); + } else { + pinnedHeader.setTag(0); + } + } else { + pinnedHeader.setTag(0); } invalidate(); @@ -161,19 +122,16 @@ public class SectionsListView extends ListView implements AbsListView.OnScrollLi @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); - if (mAdapter == null || headers.isEmpty()) { + if (mAdapter == null || pinnedHeader == null) { return; } - for (View header : headers) { - ensurePinnedHeaderLayout(header, true); - } + ensurePinnedHeaderLayout(pinnedHeader, true); } private void ensurePinnedHeaderLayout(View header, boolean forceLayout) { if (header.isLayoutRequested() || forceLayout) { - ViewGroup.LayoutParams layoutParams = header.getLayoutParams(); - int heightSpec = MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY); - int widthSpec = MeasureSpec.makeMeasureSpec(layoutParams.width, MeasureSpec.EXACTLY); + int widthSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY); + int heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); try { header.measure(widthSpec, heightSpec); } catch (Exception e) { @@ -186,20 +144,15 @@ public class SectionsListView extends ListView implements AbsListView.OnScrollLi @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); - if (mAdapter == null || headers.isEmpty()) { + if (mAdapter == null || pinnedHeader == null) { return; } - for (View header : headers) { - int saveCount = canvas.save(); - int top = (Integer)header.getTag(); - canvas.translate(LocaleController.isRTL ? getWidth() - header.getWidth() : 0, top); - canvas.clipRect(0, 0, getWidth(), header.getMeasuredHeight()); - if (top < 0) { - canvas.saveLayerAlpha(0, top, header.getWidth(), top + canvas.getHeight(), (int)(255 * (1.0f + (float)top / (float)header.getMeasuredHeight())), Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); - } - header.draw(canvas); - canvas.restoreToCount(saveCount); - } + int saveCount = canvas.save(); + int top = (Integer)pinnedHeader.getTag(); + canvas.translate(LocaleController.isRTL ? getWidth() - pinnedHeader.getWidth() : 0, top); + canvas.clipRect(0, 0, getWidth(), pinnedHeader.getMeasuredHeight()); + pinnedHeader.draw(canvas); + canvas.restoreToCount(saveCount); } @Override @@ -207,7 +160,7 @@ public class SectionsListView extends ListView implements AbsListView.OnScrollLi mOnScrollListener = l; } - public void setOnItemClickListener(SectionsListView.OnItemClickListener listener) { + public void setOnItemClickListener(OnItemClickListener listener) { super.setOnItemClickListener(listener); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/SeekBar.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SeekBar.java index 8efc59c26..bc15136a0 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/SeekBar.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SeekBar.java @@ -19,8 +19,8 @@ import org.telegram.messenger.R; public class SeekBar { - public abstract interface SeekBarDelegate { - public void onSeekBarDrag(float progress); + public interface SeekBarDelegate { + void onSeekBarDrag(float progress); } private static Drawable thumbDrawable1; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/Size.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Size.java new file mode 100644 index 000000000..986c40703 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Size.java @@ -0,0 +1,23 @@ +/* + * This is the source code of Telegram for Android v. 2.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-2015. + */ + +package org.telegram.ui.Components; + +public class Size { + public float width; + public float height; + + public Size() { + + } + + public Size(float width, float height) { + this.width = width; + this.height = height; + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayout.java index 214f320f8..54ec83b9a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayout.java @@ -8,9 +8,11 @@ package org.telegram.ui.Components; +import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.view.View; import android.widget.RelativeLayout; @@ -22,22 +24,26 @@ public class SizeNotifierRelativeLayout extends RelativeLayout { private Rect rect = new Rect(); private Drawable backgroundDrawable; - public SizeNotifierRelativeLayoutDelegate delegate; + private int keyboardHeight; + private SizeNotifierRelativeLayoutDelegate delegate; - public abstract interface SizeNotifierRelativeLayoutDelegate { - public abstract void onSizeChanged(int keyboardHeight); + public interface SizeNotifierRelativeLayoutDelegate { + void onSizeChanged(int keyboardHeight, boolean isWidthGreater); } public SizeNotifierRelativeLayout(Context context) { super(context); + setWillNotDraw(false); } public SizeNotifierRelativeLayout(android.content.Context context, android.util.AttributeSet attrs) { super(context, attrs); + setWillNotDraw(false); } public SizeNotifierRelativeLayout(android.content.Context context, android.util.AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); + setWillNotDraw(false); } public void setBackgroundImage(int resourceId) { @@ -56,30 +62,50 @@ public class SizeNotifierRelativeLayout extends RelativeLayout { return backgroundDrawable; } + public void setDelegate(SizeNotifierRelativeLayoutDelegate delegate) { + this.delegate = delegate; + } + + @SuppressLint("DrawAllocation") @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); + if (delegate != null) { View rootView = this.getRootView(); int usableViewHeight = rootView.getHeight() - AndroidUtilities.statusBarHeight - AndroidUtilities.getViewInset(rootView); this.getWindowVisibleDisplayFrame(rect); - int keyboardHeight = usableViewHeight - (rect.bottom - rect.top); - delegate.onSizeChanged(keyboardHeight); + keyboardHeight = usableViewHeight - (rect.bottom - rect.top); + final boolean isWidthGreater = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y; + FileLog.e("tmessages", "isWidthGreater = " + isWidthGreater + " height = " + keyboardHeight); + post(new Runnable() { + @Override + public void run() { + if (delegate != null) { + delegate.onSizeChanged(keyboardHeight, isWidthGreater); + } + } + }); } } @Override protected void onDraw(Canvas canvas) { if (backgroundDrawable != null) { - float scaleX = (float)getMeasuredWidth() / (float)backgroundDrawable.getIntrinsicWidth(); - float scaleY = (float)getMeasuredHeight() / (float)backgroundDrawable.getIntrinsicHeight(); - float scale = scaleX < scaleY ? scaleY : scaleX; - int width = (int)Math.ceil(backgroundDrawable.getIntrinsicWidth() * scale); - int height = (int)Math.ceil(backgroundDrawable.getIntrinsicHeight() * scale); - int x = (getMeasuredWidth() - width) / 2; - int y = (getMeasuredHeight() - height) / 2; - backgroundDrawable.setBounds(x, y, x + width, y + height); - backgroundDrawable.draw(canvas); + if (backgroundDrawable instanceof ColorDrawable) { + backgroundDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight()); + backgroundDrawable.draw(canvas); + } else { + float scaleX = (float) getMeasuredWidth() / (float) backgroundDrawable.getIntrinsicWidth(); + float scaleY = (float) (getMeasuredHeight() + keyboardHeight) / (float) backgroundDrawable.getIntrinsicHeight(); + float scale = scaleX < scaleY ? scaleY : scaleX; + int width = (int) Math.ceil(backgroundDrawable.getIntrinsicWidth() * scale); + int height = (int) Math.ceil(backgroundDrawable.getIntrinsicHeight() * scale); + int x = (getMeasuredWidth() - width) / 2; + int y = (getMeasuredHeight() - height + keyboardHeight) / 2; + backgroundDrawable.setBounds(x, y, x + width, y + height); + backgroundDrawable.draw(canvas); + } } else { super.onDraw(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 index 6464ce5f9..a1ae84c65 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/SlideView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SlideView.java @@ -49,4 +49,8 @@ public class SlideView extends LinearLayout { public void restoreStateParams(Bundle bundle) { } + + public boolean needBackButton() { + return false; + } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/SlidingTabView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SlidingTabView.java index 52c56e803..4c01ff275 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/SlidingTabView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SlidingTabView.java @@ -25,8 +25,8 @@ import org.telegram.messenger.R; public class SlidingTabView extends LinearLayout { - public static interface SlidingTabViewDelegate { - public abstract void didSelectTab(int tab); + public interface SlidingTabViewDelegate { + void didSelectTab(int tab); } private SlidingTabViewDelegate delegate; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/StaticLayoutEx.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/StaticLayoutEx.java new file mode 100644 index 000000000..4700a15e6 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/StaticLayoutEx.java @@ -0,0 +1,119 @@ +/* + * This is the source code of Telegram for Android v. 2.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-2015. + */ + +package org.telegram.ui.Components; + +import android.os.Build; +import android.text.Layout; +import android.text.StaticLayout; +import android.text.TextDirectionHeuristic; +import android.text.TextDirectionHeuristics; +import android.text.TextPaint; +import android.text.TextUtils; + +import org.telegram.messenger.FileLog; + +import java.lang.reflect.Constructor; + +public class StaticLayoutEx { + + private static final String TEXT_DIR_CLASS = "android.text.TextDirectionHeuristic"; + private static final String TEXT_DIRS_CLASS = "android.text.TextDirectionHeuristics"; + private static final String TEXT_DIR_FIRSTSTRONG_LTR = "FIRSTSTRONG_LTR"; + private static boolean initialized; + + private static Constructor sConstructor; + private static Object[] sConstructorArgs; + private static Object sTextDirection; + + public static void init() { + if (initialized) { + return; + } + + try { + final Class textDirClass; + if (Build.VERSION.SDK_INT >= 18) { + textDirClass = TextDirectionHeuristic.class; + sTextDirection = TextDirectionHeuristics.FIRSTSTRONG_LTR; + } else { + ClassLoader loader = StaticLayoutEx.class.getClassLoader(); + textDirClass = loader.loadClass(TEXT_DIR_CLASS); + Class textDirsClass = loader.loadClass(TEXT_DIRS_CLASS); + sTextDirection = textDirsClass.getField(TEXT_DIR_FIRSTSTRONG_LTR).get(textDirsClass); + } + + final Class[] signature = new Class[]{ + CharSequence.class, + int.class, + int.class, + TextPaint.class, + int.class, + Layout.Alignment.class, + textDirClass, + float.class, + float.class, + boolean.class, + TextUtils.TruncateAt.class, + int.class, + int.class + }; + + sConstructor = StaticLayout.class.getDeclaredConstructor(signature); + sConstructor.setAccessible(true); + sConstructorArgs = new Object[signature.length]; + initialized = true; + } catch (Throwable e) { + FileLog.e("tmessages", e); + } + } + + public static StaticLayout createStaticLayout(CharSequence source, TextPaint paint, int width, Layout.Alignment align, float spacingmult, float spacingadd, boolean includepad, TextUtils.TruncateAt ellipsize, int ellipsisWidth, int maxLines) { + return createStaticLayout(source, 0, source.length(), paint, width, align, spacingmult, spacingadd, includepad, ellipsize, ellipsisWidth, maxLines); + } + + public static StaticLayout createStaticLayout(CharSequence source, int bufstart, int bufend, TextPaint paint, int outerWidth, Layout.Alignment align, float spacingMult, float spacingAdd, boolean includePad, TextUtils.TruncateAt ellipsize, int ellipsisWidth, int maxLines) { + if (Build.VERSION.SDK_INT >= 14) { + init(); + try { + sConstructorArgs[0] = source; + sConstructorArgs[1] = bufstart; + sConstructorArgs[2] = bufend; + sConstructorArgs[3] = paint; + sConstructorArgs[4] = outerWidth; + sConstructorArgs[5] = align; + sConstructorArgs[6] = sTextDirection; + sConstructorArgs[7] = spacingMult; + sConstructorArgs[8] = spacingAdd; + sConstructorArgs[9] = includePad; + sConstructorArgs[10] = ellipsize; + sConstructorArgs[11] = ellipsisWidth; + sConstructorArgs[12] = maxLines; + return sConstructor.newInstance(sConstructorArgs); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + try { + if (maxLines == 1) { + return new StaticLayout(source, bufstart, bufend, paint, outerWidth, align, spacingMult, spacingAdd, includePad, ellipsize, ellipsisWidth); + } else { + StaticLayout layout = new StaticLayout(source, paint, outerWidth, align, spacingMult, spacingAdd, includePad); + if (layout.getLineCount() <= maxLines) { + return layout; + } else { + int off = layout.getOffsetForHorizontal(maxLines - 1, layout.getLineWidth(maxLines - 1)); + return new StaticLayout(source.subSequence(0, off), paint, outerWidth, align, spacingMult, spacingAdd, includePad); + } + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + return null; + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/VideoSeekBarView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/VideoSeekBarView.java index c62ed5062..e97168ed5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/VideoSeekBarView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/VideoSeekBarView.java @@ -30,8 +30,8 @@ public class VideoSeekBarView extends View { private boolean pressed = false; public SeekBarDelegate delegate; - public abstract interface SeekBarDelegate { - public void onSeekBarDrag(float progress); + public interface SeekBarDelegate { + void onSeekBarDrag(float progress); } private void init(Context context) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/VideoTimelineView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/VideoTimelineView.java index 33740781a..d562cc6bb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/VideoTimelineView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/VideoTimelineView.java @@ -29,6 +29,7 @@ import java.util.ArrayList; @TargetApi(10) public class VideoTimelineView extends View { + private long videoLength = 0; private float progressLeft = 0; private float progressRight = 1; @@ -39,7 +40,7 @@ public class VideoTimelineView extends View { private float pressDx = 0; private MediaMetadataRetriever mediaMetadataRetriever = null; private VideoTimelineViewDelegate delegate = null; - private ArrayList frames = new ArrayList(); + private ArrayList frames = new ArrayList<>(); private AsyncTask currentTask = null; private static final Object sync = new Object(); private long frameTimeOffset = 0; @@ -48,9 +49,9 @@ public class VideoTimelineView extends View { private int framesToLoad = 0; private Drawable pickDrawable = null; - public abstract interface VideoTimelineViewDelegate { - public void onLeftProgressChanged(float progress); - public void onRifhtProgressChanged(float progress); + public interface VideoTimelineViewDelegate { + void onLeftProgressChanged(float progress); + void onRifhtProgressChanged(float progress); } private void init(Context context) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java index 19e7c29d6..cf56dd75b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java @@ -9,6 +9,7 @@ package org.telegram.ui; import android.app.Activity; +import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; import android.text.InputType; @@ -19,7 +20,6 @@ import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; -import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.widget.EditText; import android.widget.FrameLayout; @@ -78,191 +78,182 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - if (addContact) { - actionBar.setTitle(LocaleController.getString("AddContactTitle", R.string.AddContactTitle)); - } else { - actionBar.setTitle(LocaleController.getString("EditName", R.string.EditName)); - } - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + if (addContact) { + actionBar.setTitle(LocaleController.getString("AddContactTitle", R.string.AddContactTitle)); + } else { + actionBar.setTitle(LocaleController.getString("EditName", R.string.EditName)); + } + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } else if (id == done_button) { + if (firstNameField.getText().length() != 0) { + TLRPC.User user = MessagesController.getInstance().getUser(user_id); + user.first_name = firstNameField.getText().toString(); + user.last_name = lastNameField.getText().toString(); + ContactsController.getInstance().addContact(user); finishFragment(); - } else if (id == done_button) { - if (firstNameField.getText().length() != 0) { - TLRPC.User user = MessagesController.getInstance().getUser(user_id); - user.first_name = firstNameField.getText().toString(); - user.last_name = lastNameField.getText().toString(); - ContactsController.getInstance().addContact(user); - finishFragment(); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, MessagesController.UPDATE_MASK_NAME); - } + NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, MessagesController.UPDATE_MASK_NAME); } } - }); + } + }); - ActionBarMenu menu = actionBar.createMenu(); - doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + ActionBarMenu menu = actionBar.createMenu(); + doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); - fragmentView = new ScrollView(getParentActivity()); + fragmentView = new ScrollView(context); - LinearLayout linearLayout = new LinearLayout(getParentActivity()); - linearLayout.setOrientation(LinearLayout.VERTICAL); - ((ScrollView) fragmentView).addView(linearLayout); - ScrollView.LayoutParams layoutParams2 = (ScrollView.LayoutParams) linearLayout.getLayoutParams(); - layoutParams2.width = ScrollView.LayoutParams.MATCH_PARENT; - layoutParams2.height = ScrollView.LayoutParams.WRAP_CONTENT; - linearLayout.setLayoutParams(layoutParams2); - linearLayout.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { + LinearLayout linearLayout = new LinearLayout(context); + linearLayout.setOrientation(LinearLayout.VERTICAL); + ((ScrollView) fragmentView).addView(linearLayout); + ScrollView.LayoutParams layoutParams2 = (ScrollView.LayoutParams) linearLayout.getLayoutParams(); + layoutParams2.width = ScrollView.LayoutParams.MATCH_PARENT; + layoutParams2.height = ScrollView.LayoutParams.WRAP_CONTENT; + linearLayout.setLayoutParams(layoutParams2); + linearLayout.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + FrameLayout frameLayout = new FrameLayout(context); + linearLayout.addView(frameLayout); + LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) frameLayout.getLayoutParams(); + layoutParams.topMargin = AndroidUtilities.dp(24); + layoutParams.leftMargin = AndroidUtilities.dp(24); + layoutParams.rightMargin = AndroidUtilities.dp(24); + layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; + frameLayout.setLayoutParams(layoutParams); + + avatarImage = new BackupImageView(context); + avatarImage.setRoundRadius(AndroidUtilities.dp(30)); + frameLayout.addView(avatarImage); + FrameLayout.LayoutParams layoutParams3 = (FrameLayout.LayoutParams) avatarImage.getLayoutParams(); + layoutParams3.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP; + layoutParams3.width = AndroidUtilities.dp(60); + layoutParams3.height = AndroidUtilities.dp(60); + avatarImage.setLayoutParams(layoutParams3); + + nameTextView = new TextView(context); + nameTextView.setTextColor(0xff212121); + nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); + nameTextView.setLines(1); + nameTextView.setMaxLines(1); + nameTextView.setSingleLine(true); + nameTextView.setEllipsize(TextUtils.TruncateAt.END); + nameTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)); + nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + frameLayout.addView(nameTextView); + layoutParams3 = (FrameLayout.LayoutParams) nameTextView.getLayoutParams(); + layoutParams3.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams3.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams3.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? 0 : 80); + layoutParams3.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? 80 : 0); + layoutParams3.topMargin = AndroidUtilities.dp(3); + layoutParams3.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP; + nameTextView.setLayoutParams(layoutParams3); + + onlineTextView = new TextView(context); + onlineTextView.setTextColor(0xff999999); + onlineTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + onlineTextView.setLines(1); + onlineTextView.setMaxLines(1); + onlineTextView.setSingleLine(true); + onlineTextView.setEllipsize(TextUtils.TruncateAt.END); + onlineTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)); + frameLayout.addView(onlineTextView); + layoutParams3 = (FrameLayout.LayoutParams) onlineTextView.getLayoutParams(); + layoutParams3.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams3.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams3.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? 0 : 80); + layoutParams3.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? 80 : 0); + layoutParams3.topMargin = AndroidUtilities.dp(32); + layoutParams3.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP; + onlineTextView.setLayoutParams(layoutParams3); + + firstNameField = new EditText(context); + firstNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + firstNameField.setHintTextColor(0xff979797); + firstNameField.setTextColor(0xff212121); + firstNameField.setMaxLines(1); + firstNameField.setLines(1); + firstNameField.setSingleLine(true); + firstNameField.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); + firstNameField.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); + firstNameField.setImeOptions(EditorInfo.IME_ACTION_NEXT); + firstNameField.setHint(LocaleController.getString("FirstName", R.string.FirstName)); + AndroidUtilities.clearCursorDrawable(firstNameField); + linearLayout.addView(firstNameField); + layoutParams = (LinearLayout.LayoutParams) firstNameField.getLayoutParams(); + layoutParams.topMargin = AndroidUtilities.dp(24); + layoutParams.height = AndroidUtilities.dp(36); + layoutParams.leftMargin = AndroidUtilities.dp(24); + layoutParams.rightMargin = AndroidUtilities.dp(24); + layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; + firstNameField.setLayoutParams(layoutParams); + firstNameField.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { + if (i == EditorInfo.IME_ACTION_NEXT) { + lastNameField.requestFocus(); + lastNameField.setSelection(lastNameField.length()); return true; } - }); - - FrameLayout frameLayout = new FrameLayout(getParentActivity()); - linearLayout.addView(frameLayout); - LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) frameLayout.getLayoutParams(); - layoutParams.topMargin = AndroidUtilities.dp(24); - layoutParams.leftMargin = AndroidUtilities.dp(24); - layoutParams.rightMargin = AndroidUtilities.dp(24); - layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; - frameLayout.setLayoutParams(layoutParams); - - avatarImage = new BackupImageView(getParentActivity()); - avatarImage.imageReceiver.setRoundRadius(AndroidUtilities.dp(30)); - avatarImage.processDetach = false; - frameLayout.addView(avatarImage); - FrameLayout.LayoutParams layoutParams3 = (FrameLayout.LayoutParams) avatarImage.getLayoutParams(); - layoutParams3.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP; - layoutParams3.width = AndroidUtilities.dp(60); - layoutParams3.height = AndroidUtilities.dp(60); - avatarImage.setLayoutParams(layoutParams3); - - nameTextView = new TextView(getParentActivity()); - nameTextView.setTextColor(0xff212121); - nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); - nameTextView.setLines(1); - nameTextView.setMaxLines(1); - nameTextView.setSingleLine(true); - nameTextView.setEllipsize(TextUtils.TruncateAt.END); - nameTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)); - nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); - frameLayout.addView(nameTextView); - layoutParams3 = (FrameLayout.LayoutParams) nameTextView.getLayoutParams(); - layoutParams3.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams3.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams3.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? 0 : 80); - layoutParams3.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? 80 : 0); - layoutParams3.topMargin = AndroidUtilities.dp(3); - layoutParams3.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP; - nameTextView.setLayoutParams(layoutParams3); - - onlineTextView = new TextView(getParentActivity()); - onlineTextView.setTextColor(0xff999999); - onlineTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); - onlineTextView.setLines(1); - onlineTextView.setMaxLines(1); - onlineTextView.setSingleLine(true); - onlineTextView.setEllipsize(TextUtils.TruncateAt.END); - onlineTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)); - frameLayout.addView(onlineTextView); - layoutParams3 = (FrameLayout.LayoutParams) onlineTextView.getLayoutParams(); - layoutParams3.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams3.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams3.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? 0 : 80); - layoutParams3.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? 80 : 0); - layoutParams3.topMargin = AndroidUtilities.dp(32); - layoutParams3.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP; - onlineTextView.setLayoutParams(layoutParams3); - - firstNameField = new EditText(getParentActivity()); - firstNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); - firstNameField.setHintTextColor(0xff979797); - firstNameField.setTextColor(0xff212121); - firstNameField.setMaxLines(1); - firstNameField.setLines(1); - firstNameField.setSingleLine(true); - firstNameField.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); - firstNameField.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); - firstNameField.setImeOptions(EditorInfo.IME_ACTION_NEXT); - firstNameField.setHint(LocaleController.getString("FirstName", R.string.FirstName)); - AndroidUtilities.clearCursorDrawable(firstNameField); - linearLayout.addView(firstNameField); - layoutParams = (LinearLayout.LayoutParams) firstNameField.getLayoutParams(); - layoutParams.topMargin = AndroidUtilities.dp(24); - layoutParams.height = AndroidUtilities.dp(36); - layoutParams.leftMargin = AndroidUtilities.dp(24); - layoutParams.rightMargin = AndroidUtilities.dp(24); - layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; - firstNameField.setLayoutParams(layoutParams); - firstNameField.setOnEditorActionListener(new TextView.OnEditorActionListener() { - @Override - public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { - if (i == EditorInfo.IME_ACTION_NEXT) { - lastNameField.requestFocus(); - lastNameField.setSelection(lastNameField.length()); - return true; - } - return false; - } - }); - - lastNameField = new EditText(getParentActivity()); - lastNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); - lastNameField.setHintTextColor(0xff979797); - lastNameField.setTextColor(0xff212121); - lastNameField.setMaxLines(1); - lastNameField.setLines(1); - lastNameField.setSingleLine(true); - lastNameField.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); - lastNameField.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); - lastNameField.setImeOptions(EditorInfo.IME_ACTION_DONE); - lastNameField.setHint(LocaleController.getString("LastName", R.string.LastName)); - AndroidUtilities.clearCursorDrawable(lastNameField); - linearLayout.addView(lastNameField); - layoutParams = (LinearLayout.LayoutParams) lastNameField.getLayoutParams(); - layoutParams.topMargin = AndroidUtilities.dp(16); - layoutParams.height = AndroidUtilities.dp(36); - layoutParams.leftMargin = AndroidUtilities.dp(24); - layoutParams.rightMargin = AndroidUtilities.dp(24); - layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; - lastNameField.setLayoutParams(layoutParams); - lastNameField.setOnEditorActionListener(new TextView.OnEditorActionListener() { - @Override - public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { - if (i == EditorInfo.IME_ACTION_DONE) { - doneButton.performClick(); - return true; - } - return false; - } - }); - - TLRPC.User user = MessagesController.getInstance().getUser(user_id); - if (user != null) { - if (user.phone == null) { - if (phone != null) { - user.phone = PhoneFormat.stripExceptNumbers(phone); - } - } - firstNameField.setText(user.first_name); - firstNameField.setSelection(firstNameField.length()); - lastNameField.setText(user.last_name); + return false; } + }); - updateAvatarLayout(); - } else { - ViewGroup parent = (ViewGroup) fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); + lastNameField = new EditText(context); + lastNameField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + lastNameField.setHintTextColor(0xff979797); + lastNameField.setTextColor(0xff212121); + lastNameField.setMaxLines(1); + lastNameField.setLines(1); + lastNameField.setSingleLine(true); + lastNameField.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); + lastNameField.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); + lastNameField.setImeOptions(EditorInfo.IME_ACTION_DONE); + lastNameField.setHint(LocaleController.getString("LastName", R.string.LastName)); + AndroidUtilities.clearCursorDrawable(lastNameField); + linearLayout.addView(lastNameField); + layoutParams = (LinearLayout.LayoutParams) lastNameField.getLayoutParams(); + layoutParams.topMargin = AndroidUtilities.dp(16); + layoutParams.height = AndroidUtilities.dp(36); + layoutParams.leftMargin = AndroidUtilities.dp(24); + layoutParams.rightMargin = AndroidUtilities.dp(24); + layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; + lastNameField.setLayoutParams(layoutParams); + lastNameField.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { + if (i == EditorInfo.IME_ACTION_DONE) { + doneButton.performClick(); + return true; + } + return false; } + }); + + TLRPC.User user = MessagesController.getInstance().getUser(user_id); + if (user != null) { + if (user.phone == null) { + if (phone != null) { + user.phone = PhoneFormat.stripExceptNumbers(phone); + } + } + firstNameField.setText(user.first_name); + firstNameField.setSelection(firstNameField.length()); + lastNameField.setText(user.last_name); } + return fragmentView; } @@ -296,6 +287,7 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent @Override public void onResume() { super.onResume(); + updateAvatarLayout(); SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); boolean animations = preferences.getBoolean("view_animations", true); if (!animations) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java index 97dbea03b..39b4310bc 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java @@ -9,12 +9,14 @@ package org.telegram.ui; import android.app.AlertDialog; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.text.InputType; +import android.util.TypedValue; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -41,13 +43,13 @@ import org.telegram.android.NotificationCenter; import org.telegram.messenger.R; import org.telegram.ui.Adapters.BaseSectionsAdapter; import org.telegram.ui.Adapters.ContactsAdapter; -import org.telegram.ui.Adapters.ContactsSearchAdapter; +import org.telegram.ui.Adapters.SearchAdapter; 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.ActionBar.BaseFragment; -import org.telegram.ui.Components.SectionsListView; +import org.telegram.ui.Components.LetterSectionsListView; import java.util.ArrayList; import java.util.HashMap; @@ -56,8 +58,8 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter private BaseSectionsAdapter listViewAdapter; private TextView emptyTextView; - private SectionsListView listView; - private ContactsSearchAdapter searchListViewAdapter; + private LetterSectionsListView listView; + private SearchAdapter searchListViewAdapter; private boolean searchWas; private boolean searching; @@ -72,8 +74,8 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter private boolean allowUsernameSearch = true; private ContactsActivityDelegate delegate; - public static interface ContactsActivityDelegate { - public abstract void didSelectContact(TLRPC.User user, String param); + public interface ContactsActivityDelegate { + void didSelectContact(TLRPC.User user, String param); } public ContactsActivity(Bundle args) { @@ -87,6 +89,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter NotificationCenter.getInstance().addObserver(this, NotificationCenter.contactsDidLoaded); NotificationCenter.getInstance().addObserver(this, NotificationCenter.updateInterfaces); NotificationCenter.getInstance().addObserver(this, NotificationCenter.encryptedChatCreated); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.closeChats); if (arguments != null) { onlyUsers = getArguments().getBoolean("onlyUsers", false); destroyAfterSelect = arguments.getBoolean("destroyAfterSelect", false); @@ -109,280 +112,286 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter NotificationCenter.getInstance().removeObserver(this, NotificationCenter.contactsDidLoaded); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.updateInterfaces); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.encryptedChatCreated); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.closeChats); delegate = null; } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - searching = false; - searchWas = false; + public View createView(Context context, LayoutInflater inflater) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - if (destroyAfterSelect) { - if (returnAsResult) { - actionBar.setTitle(LocaleController.getString("SelectContact", R.string.SelectContact)); + searching = false; + searchWas = false; + + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + if (destroyAfterSelect) { + if (returnAsResult) { + actionBar.setTitle(LocaleController.getString("SelectContact", R.string.SelectContact)); + } else { + if (createSecretChat) { + actionBar.setTitle(LocaleController.getString("NewSecretChat", R.string.NewSecretChat)); } else { actionBar.setTitle(LocaleController.getString("NewMessageTitle", R.string.NewMessageTitle)); } - } else { - actionBar.setTitle(LocaleController.getString("Contacts", R.string.Contacts)); + } + } else { + actionBar.setTitle(LocaleController.getString("Contacts", R.string.Contacts)); + } + + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } + } + }); + + ActionBarMenu menu = actionBar.createMenu(); + ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true).setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() { + @Override + public void onSearchExpand() { + searching = true; } - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); + @Override + public boolean onSearchCollapse() { + searchListViewAdapter.searchDialogs(null); + searching = false; + searchWas = false; + listView.setAdapter(listViewAdapter); + listViewAdapter.notifyDataSetChanged(); + if (android.os.Build.VERSION.SDK_INT >= 11) { + listView.setFastScrollAlwaysVisible(true); + } + listView.setFastScrollEnabled(true); + listView.setVerticalScrollBarEnabled(false); + emptyTextView.setText(LocaleController.getString("NoContacts", R.string.NoContacts)); + return true; + } + + @Override + public void onTextChanged(EditText editText) { + if (searchListViewAdapter == null) { + return; + } + String text = editText.getText().toString(); + if (text.length() != 0) { + searchWas = true; + if (listView != null) { + listView.setAdapter(searchListViewAdapter); + searchListViewAdapter.notifyDataSetChanged(); + if (android.os.Build.VERSION.SDK_INT >= 11) { + listView.setFastScrollAlwaysVisible(false); + } + listView.setFastScrollEnabled(false); + listView.setVerticalScrollBarEnabled(true); + } + if (emptyTextView != null) { + emptyTextView.setText(LocaleController.getString("NoResult", R.string.NoResult)); } } - }); + searchListViewAdapter.searchDialogs(text); + } + }); + item.getSearchField().setHint(LocaleController.getString("Search", R.string.Search)); - ActionBarMenu menu = actionBar.createMenu(); - ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true).setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() { - @Override - public void onSearchExpand() { - searching = true; - } + searchListViewAdapter = new SearchAdapter(context, ignoreUsers, allowUsernameSearch); + listViewAdapter = new ContactsAdapter(context, onlyUsers, needPhonebook, ignoreUsers); - @Override - public void onSearchCollapse() { - searchListViewAdapter.searchDialogs(null); - searching = false; - searchWas = false; - ViewGroup group = (ViewGroup) listView.getParent(); - listView.setAdapter(listViewAdapter); - listViewAdapter.notifyDataSetChanged(); - if (android.os.Build.VERSION.SDK_INT >= 11) { - listView.setFastScrollAlwaysVisible(true); - } - listView.setFastScrollEnabled(true); - listView.setVerticalScrollBarEnabled(false); - emptyTextView.setText(LocaleController.getString("NoContacts", R.string.NoContacts)); - } + fragmentView = new FrameLayout(context); - @Override - public void onTextChanged(EditText editText) { - if (searchListViewAdapter == null) { + LinearLayout emptyTextLayout = new LinearLayout(context); + emptyTextLayout.setVisibility(View.INVISIBLE); + emptyTextLayout.setOrientation(LinearLayout.VERTICAL); + ((FrameLayout) fragmentView).addView(emptyTextLayout); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) emptyTextLayout.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP; + emptyTextLayout.setLayoutParams(layoutParams); + emptyTextLayout.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + emptyTextView = new TextView(context); + emptyTextView.setTextColor(0xff808080); + emptyTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); + emptyTextView.setGravity(Gravity.CENTER); + emptyTextView.setText(LocaleController.getString("NoContacts", R.string.NoContacts)); + emptyTextLayout.addView(emptyTextView); + LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams) emptyTextView.getLayoutParams(); + layoutParams1.width = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams1.height = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams1.weight = 0.5f; + emptyTextView.setLayoutParams(layoutParams1); + + FrameLayout frameLayout = new FrameLayout(context); + emptyTextLayout.addView(frameLayout); + layoutParams1 = (LinearLayout.LayoutParams) frameLayout.getLayoutParams(); + layoutParams1.width = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams1.height = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams1.weight = 0.5f; + frameLayout.setLayoutParams(layoutParams1); + + listView = new LetterSectionsListView(context); + listView.setEmptyView(emptyTextLayout); + listView.setVerticalScrollBarEnabled(false); + listView.setDivider(null); + listView.setDividerHeight(0); + listView.setFastScrollEnabled(true); + listView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY); + listView.setAdapter(listViewAdapter); + if (Build.VERSION.SDK_INT >= 11) { + listView.setFastScrollAlwaysVisible(true); + listView.setVerticalScrollbarPosition(LocaleController.isRTL ? ListView.SCROLLBAR_POSITION_LEFT : ListView.SCROLLBAR_POSITION_RIGHT); + } + ((FrameLayout) fragmentView).addView(listView); + layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + listView.setLayoutParams(layoutParams); + + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, int i, long l) { + if (searching && searchWas) { + TLRPC.User user = searchListViewAdapter.getItem(i); + if (user == null) { return; } - String text = editText.getText().toString(); - if (text.length() != 0) { - searchWas = true; - if (listView != null) { - listView.setAdapter(searchListViewAdapter); - searchListViewAdapter.notifyDataSetChanged(); - if(android.os.Build.VERSION.SDK_INT >= 11) { - listView.setFastScrollAlwaysVisible(false); - } - listView.setFastScrollEnabled(false); - listView.setVerticalScrollBarEnabled(true); - } - if (emptyTextView != null) { - emptyTextView.setText(LocaleController.getString("NoResult", R.string.NoResult)); - } + if (searchListViewAdapter.isGlobalSearch(i)) { + ArrayList users = new ArrayList<>(); + users.add(user); + MessagesController.getInstance().putUsers(users, false); + MessagesStorage.getInstance().putUsersAndChats(users, null, false, true); } - searchListViewAdapter.searchDialogs(text); - } - }); - item.getSearchField().setHint(LocaleController.getString("Search", R.string.Search)); - - searchListViewAdapter = new ContactsSearchAdapter(getParentActivity(), ignoreUsers, allowUsernameSearch); - listViewAdapter = new ContactsAdapter(getParentActivity(), onlyUsers, needPhonebook, ignoreUsers); - - fragmentView = new FrameLayout(getParentActivity()); - - LinearLayout emptyTextLayout = new LinearLayout(getParentActivity()); - emptyTextLayout.setVisibility(View.INVISIBLE); - emptyTextLayout.setOrientation(LinearLayout.VERTICAL); - ((FrameLayout) fragmentView).addView(emptyTextLayout); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) emptyTextLayout.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.gravity = Gravity.TOP; - emptyTextLayout.setLayoutParams(layoutParams); - emptyTextLayout.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return true; - } - }); - - emptyTextView = new TextView(getParentActivity()); - emptyTextView.setTextColor(0xff808080); - emptyTextView.setTextSize(20); - emptyTextView.setGravity(Gravity.CENTER); - emptyTextView.setText(LocaleController.getString("NoContacts", R.string.NoContacts)); - emptyTextLayout.addView(emptyTextView); - LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams) emptyTextView.getLayoutParams(); - layoutParams1.width = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams1.height = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams1.weight = 0.5f; - emptyTextView.setLayoutParams(layoutParams1); - - FrameLayout frameLayout = new FrameLayout(getParentActivity()); - emptyTextLayout.addView(frameLayout); - layoutParams1 = (LinearLayout.LayoutParams) frameLayout.getLayoutParams(); - layoutParams1.width = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams1.height = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams1.weight = 0.5f; - frameLayout.setLayoutParams(layoutParams1); - - listView = new SectionsListView(getParentActivity()); - listView.setEmptyView(emptyTextLayout); - listView.setVerticalScrollBarEnabled(false); - listView.setDivider(null); - listView.setDividerHeight(0); - listView.setFastScrollEnabled(true); - listView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY); - listView.setAdapter(listViewAdapter); - if (Build.VERSION.SDK_INT >= 11) { - listView.setFastScrollAlwaysVisible(true); - listView.setVerticalScrollbarPosition(LocaleController.isRTL ? ListView.SCROLLBAR_POSITION_LEFT : ListView.SCROLLBAR_POSITION_RIGHT); - } - ((FrameLayout) fragmentView).addView(listView); - layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - listView.setLayoutParams(layoutParams); - - listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, int i, long l) { - if (searching && searchWas) { - TLRPC.User user = searchListViewAdapter.getItem(i); - if (user == null) { + if (returnAsResult) { + if (ignoreUsers != null && ignoreUsers.containsKey(user.id)) { return; } - if (searchListViewAdapter.isGlobalSearch(i)) { - ArrayList users = new ArrayList<>(); - users.add(user); - MessagesController.getInstance().putUsers(users, false); - MessagesStorage.getInstance().putUsersAndChats(users, null, false, true); - } - if (returnAsResult) { - if (ignoreUsers != null && ignoreUsers.containsKey(user.id)) { - return; - } - didSelectResult(user, true, null); + didSelectResult(user, true, null); + } else { + if (createSecretChat) { + creatingChat = true; + SecretChatHelper.getInstance().startSecretChat(getParentActivity(), user); } else { - if (createSecretChat) { - creatingChat = true; - SecretChatHelper.getInstance().startSecretChat(getParentActivity(), user); - } else { + Bundle args = new Bundle(); + args.putInt("user_id", user.id); + presentFragment(new ChatActivity(args), true); + } + } + } else { + int section = listViewAdapter.getSectionForPosition(i); + int row = listViewAdapter.getPositionInSectionForPosition(i); + if (row < 0 || section < 0) { + return; + } + if (!onlyUsers && section == 0) { + if (needPhonebook) { + if (row == 0) { + try { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + intent.putExtra(Intent.EXTRA_TEXT, ContactsController.getInstance().getInviteText()); + getParentActivity().startActivityForResult(Intent.createChooser(intent, LocaleController.getString("InviteFriends", R.string.InviteFriends)), 500); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + } else { + if (row == 0) { + if (!MessagesController.isFeatureEnabled("chat_create", ContactsActivity.this)) { + return; + } + presentFragment(new GroupCreateActivity(), false); + } else if (row == 1) { Bundle args = new Bundle(); - args.putInt("user_id", user.id); - presentFragment(new ChatActivity(args), true); + args.putBoolean("onlyUsers", true); + args.putBoolean("destroyAfterSelect", true); + args.putBoolean("createSecretChat", true); + presentFragment(new ContactsActivity(args), false); + } else if (row == 2) { + if (!MessagesController.isFeatureEnabled("broadcast_create", ContactsActivity.this)) { + return; + } + Bundle args = new Bundle(); + args.putBoolean("broadcast", true); + presentFragment(new GroupCreateActivity(args), false); } } } else { - int section = listViewAdapter.getSectionForPosition(i); - int row = listViewAdapter.getPositionInSectionForPosition(i); - if (row < 0 || section < 0) { - return; - } - if (!onlyUsers && section == 0) { - if (needPhonebook) { - if (row == 0) { + Object item = listViewAdapter.getItem(section, row); + + if (item instanceof TLRPC.User) { + TLRPC.User user = (TLRPC.User) item; + if (returnAsResult) { + if (ignoreUsers != null && ignoreUsers.containsKey(user.id)) { + return; + } + didSelectResult(user, true, null); + } else { + if (createSecretChat) { + creatingChat = true; + SecretChatHelper.getInstance().startSecretChat(getParentActivity(), user); + } else { + Bundle args = new Bundle(); + args.putInt("user_id", user.id); + presentFragment(new ChatActivity(args), true); + } + } + } else if (item instanceof ContactsController.Contact) { + ContactsController.Contact contact = (ContactsController.Contact) item; + String usePhone = null; + if (!contact.phones.isEmpty()) { + usePhone = contact.phones.get(0); + } + if (usePhone == null || getParentActivity() == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.getString("InviteUser", R.string.InviteUser)); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + final String arg1 = usePhone; + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { try { - Intent intent = new Intent(Intent.ACTION_SEND); - intent.setType("text/plain"); - intent.putExtra(Intent.EXTRA_TEXT, ContactsController.getInstance().getInviteText()); - getParentActivity().startActivity(Intent.createChooser(intent, "")); + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.fromParts("sms", arg1, null)); + intent.putExtra("sms_body", LocaleController.getString("InviteText", R.string.InviteText)); + getParentActivity().startActivityForResult(intent, 500); } catch (Exception e) { FileLog.e("tmessages", e); } } - } else { - if (row == 0) { - presentFragment(new GroupCreateActivity(), true); - } else if (row == 1) { - Bundle args = new Bundle(); - args.putBoolean("onlyUsers", true); - args.putBoolean("destroyAfterSelect", true); - args.putBoolean("createSecretChat", true); - presentFragment(new ContactsActivity(args), true); - } else if (row == 2) { - Bundle args = new Bundle(); - args.putBoolean("broadcast", true); - presentFragment(new GroupCreateActivity(args), true); - } - } - } else { - Object item = listViewAdapter.getItem(section, row); - - if (item instanceof TLRPC.User) { - TLRPC.User user = (TLRPC.User) item; - if (returnAsResult) { - if (ignoreUsers != null && ignoreUsers.containsKey(user.id)) { - return; - } - didSelectResult(user, true, null); - } else { - if (createSecretChat) { - creatingChat = true; - SecretChatHelper.getInstance().startSecretChat(getParentActivity(), user); - } else { - Bundle args = new Bundle(); - args.putInt("user_id", user.id); - presentFragment(new ChatActivity(args), true); - } - } - } else if (item instanceof ContactsController.Contact) { - ContactsController.Contact contact = (ContactsController.Contact) item; - String usePhone = null; - if (!contact.phones.isEmpty()) { - usePhone = contact.phones.get(0); - } - if (usePhone == null || getParentActivity() == null) { - return; - } - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setMessage(LocaleController.getString("InviteUser", R.string.InviteUser)); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - final String arg1 = usePhone; - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - try { - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.fromParts("sms", arg1, null)); - intent.putExtra("sms_body", LocaleController.getString("InviteText", R.string.InviteText)); - getParentActivity().startActivity(intent); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); } } } - }); - - listView.setOnScrollListener(new AbsListView.OnScrollListener() { - @Override - public void onScrollStateChanged(AbsListView absListView, int i) { - if (i == SCROLL_STATE_TOUCH_SCROLL && searching && searchWas) { - AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); - } - } - - @Override - public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - if (absListView.isFastScrollEnabled()) { - AndroidUtilities.clearDrawableAnimation(absListView); - } - } - }); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); } - } + }); + + listView.setOnScrollListener(new AbsListView.OnScrollListener() { + @Override + public void onScrollStateChanged(AbsListView absListView, int i) { + if (i == SCROLL_STATE_TOUCH_SCROLL && searching && searchWas) { + AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); + } + } + + @Override + public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { + if (absListView.isFastScrollEnabled()) { + AndroidUtilities.clearDrawableAnimation(absListView); + } + } + }); + return fragmentView; } @@ -404,13 +413,13 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter editText.setInputType(InputType.TYPE_CLASS_NUMBER); editText.setImeOptions(EditorInfo.IME_ACTION_DONE); builder.setView(editText); - builder.setPositiveButton(R.string.OK, new DialogInterface.OnClickListener() { + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { didSelectResult(user, false, editText.getText().toString()); } }); - builder.setNegativeButton(R.string.Cancel, null); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); showAlertDialog(builder); ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams)editText.getLayoutParams(); if (layoutParams != null) { @@ -462,8 +471,13 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter TLRPC.EncryptedChat encryptedChat = (TLRPC.EncryptedChat)args[0]; Bundle args2 = new Bundle(); args2.putInt("enc_id", encryptedChat.id); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); presentFragment(new ChatActivity(args2), true); } + } else if (id == NotificationCenter.closeChats) { + if (!creatingChat) { + removeSelfFromStack(); + } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java index e1607f583..2eb56da69 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java @@ -8,12 +8,12 @@ package org.telegram.ui; +import android.content.Context; import android.os.Build; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; -import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.EditText; @@ -32,15 +32,15 @@ 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.Components.SectionsListView; +import org.telegram.ui.Components.LetterSectionsListView; public class CountrySelectActivity extends BaseFragment { - public static interface CountrySelectActivityDelegate { - public abstract void didSelectCountry(String name); + public interface CountrySelectActivityDelegate { + void didSelectCountry(String name); } - private SectionsListView listView; + private LetterSectionsListView listView; private TextView emptyTextView; private CountryAdapter listViewAdapter; private CountrySearchAdapter searchListViewAdapter; @@ -61,173 +61,168 @@ public class CountrySelectActivity extends BaseFragment { } @Override - public View createView(LayoutInflater inflater, final ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - actionBar.setTitle(LocaleController.getString("ChooseCountry", R.string.ChooseCountry)); + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + actionBar.setTitle(LocaleController.getString("ChooseCountry", R.string.ChooseCountry)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } - } - }); - - ActionBarMenu menu = actionBar.createMenu(); - ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true).setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() { - @Override - public void onSearchExpand() { - searching = true; - } - - @Override - public void onSearchCollapse() { - searchListViewAdapter.search(null); - searching = false; - searchWas = false; - ViewGroup group = (ViewGroup) listView.getParent(); - listView.setAdapter(listViewAdapter); - if (android.os.Build.VERSION.SDK_INT >= 11) { - listView.setFastScrollAlwaysVisible(true); - } - listView.setFastScrollEnabled(true); - listView.setVerticalScrollBarEnabled(false); - - emptyTextView.setText(LocaleController.getString("ChooseCountry", R.string.ChooseCountry)); - } - - @Override - public void onTextChanged(EditText editText) { - String text = editText.getText().toString(); - searchListViewAdapter.search(text); - if (text.length() != 0) { - searchWas = true; - if (listView != null) { - listView.setAdapter(searchListViewAdapter); - if(android.os.Build.VERSION.SDK_INT >= 11) { - listView.setFastScrollAlwaysVisible(false); - } - listView.setFastScrollEnabled(false); - listView.setVerticalScrollBarEnabled(true); - } - if (emptyTextView != null) { - - } - } - } - }); - item.getSearchField().setHint(LocaleController.getString("Search", R.string.Search)); - - searching = false; - searchWas = false; - - listViewAdapter = new CountryAdapter(getParentActivity()); - searchListViewAdapter = new CountrySearchAdapter(getParentActivity(), listViewAdapter.getCountries()); - - fragmentView = new FrameLayout(getParentActivity()); - - LinearLayout emptyTextLayout = new LinearLayout(getParentActivity()); - emptyTextLayout.setVisibility(View.INVISIBLE); - emptyTextLayout.setOrientation(LinearLayout.VERTICAL); - ((FrameLayout) fragmentView).addView(emptyTextLayout); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) emptyTextLayout.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.gravity = Gravity.TOP; - emptyTextLayout.setLayoutParams(layoutParams); - emptyTextLayout.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return true; - } - }); - - emptyTextView = new TextView(getParentActivity()); - emptyTextView.setTextColor(0xff808080); - emptyTextView.setTextSize(20); - emptyTextView.setGravity(Gravity.CENTER); - emptyTextView.setText(LocaleController.getString("NoResult", R.string.NoResult)); - emptyTextLayout.addView(emptyTextView); - LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams) emptyTextView.getLayoutParams(); - layoutParams1.width = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams1.height = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams1.weight = 0.5f; - emptyTextView.setLayoutParams(layoutParams1); - - FrameLayout frameLayout = new FrameLayout(getParentActivity()); - emptyTextLayout.addView(frameLayout); - layoutParams1 = (LinearLayout.LayoutParams) frameLayout.getLayoutParams(); - layoutParams1.width = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams1.height = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams1.weight = 0.5f; - frameLayout.setLayoutParams(layoutParams1); - - listView = new SectionsListView(getParentActivity()); - listView.setEmptyView(emptyTextLayout); - listView.setVerticalScrollBarEnabled(false); - listView.setDivider(null); - listView.setDividerHeight(0); - listView.setFastScrollEnabled(true); - listView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY); - listView.setAdapter(listViewAdapter); - if (Build.VERSION.SDK_INT >= 11) { - listView.setFastScrollAlwaysVisible(true); - listView.setVerticalScrollbarPosition(LocaleController.isRTL ? ListView.SCROLLBAR_POSITION_LEFT : ListView.SCROLLBAR_POSITION_RIGHT); - } - ((FrameLayout) fragmentView).addView(listView); - layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - listView.setLayoutParams(layoutParams); - - listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, int i, long l) { - Country country = null; - if (searching && searchWas) { - country = searchListViewAdapter.getItem(i); - } else { - int section = listViewAdapter.getSectionForPosition(i); - int row = listViewAdapter.getPositionInSectionForPosition(i); - if (row < 0 || section < 0) { - return; - } - country = listViewAdapter.getItem(section, row); - } - if (i < 0) { - return; - } - if (country != null && delegate != null) { - delegate.didSelectCountry(country.name); - } + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { finishFragment(); } - }); - - listView.setOnScrollListener(new AbsListView.OnScrollListener() { - @Override - public void onScrollStateChanged(AbsListView absListView, int i) { - if (i == SCROLL_STATE_TOUCH_SCROLL && searching && searchWas) { - AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); - } - } - - @Override - public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - if (absListView.isFastScrollEnabled()) { - AndroidUtilities.clearDrawableAnimation(absListView); - } - } - }); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); } + }); + + ActionBarMenu menu = actionBar.createMenu(); + ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true).setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() { + @Override + public void onSearchExpand() { + searching = true; + } + + @Override + public boolean onSearchCollapse() { + searchListViewAdapter.search(null); + searching = false; + searchWas = false; + listView.setAdapter(listViewAdapter); + if (android.os.Build.VERSION.SDK_INT >= 11) { + listView.setFastScrollAlwaysVisible(true); + } + listView.setFastScrollEnabled(true); + listView.setVerticalScrollBarEnabled(false); + + emptyTextView.setText(LocaleController.getString("ChooseCountry", R.string.ChooseCountry)); + + return true; + } + + @Override + public void onTextChanged(EditText editText) { + String text = editText.getText().toString(); + searchListViewAdapter.search(text); + if (text.length() != 0) { + searchWas = true; + if (listView != null) { + listView.setAdapter(searchListViewAdapter); + if (android.os.Build.VERSION.SDK_INT >= 11) { + listView.setFastScrollAlwaysVisible(false); + } + listView.setFastScrollEnabled(false); + listView.setVerticalScrollBarEnabled(true); + } + if (emptyTextView != null) { + + } + } + } + }); + item.getSearchField().setHint(LocaleController.getString("Search", R.string.Search)); + + searching = false; + searchWas = false; + + listViewAdapter = new CountryAdapter(context); + searchListViewAdapter = new CountrySearchAdapter(context, listViewAdapter.getCountries()); + + fragmentView = new FrameLayout(context); + + LinearLayout emptyTextLayout = new LinearLayout(context); + emptyTextLayout.setVisibility(View.INVISIBLE); + emptyTextLayout.setOrientation(LinearLayout.VERTICAL); + ((FrameLayout) fragmentView).addView(emptyTextLayout); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) emptyTextLayout.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP; + emptyTextLayout.setLayoutParams(layoutParams); + emptyTextLayout.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + emptyTextView = new TextView(context); + emptyTextView.setTextColor(0xff808080); + emptyTextView.setTextSize(20); + emptyTextView.setGravity(Gravity.CENTER); + emptyTextView.setText(LocaleController.getString("NoResult", R.string.NoResult)); + emptyTextLayout.addView(emptyTextView); + LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams) emptyTextView.getLayoutParams(); + layoutParams1.width = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams1.height = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams1.weight = 0.5f; + emptyTextView.setLayoutParams(layoutParams1); + + FrameLayout frameLayout = new FrameLayout(context); + emptyTextLayout.addView(frameLayout); + layoutParams1 = (LinearLayout.LayoutParams) frameLayout.getLayoutParams(); + layoutParams1.width = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams1.height = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams1.weight = 0.5f; + frameLayout.setLayoutParams(layoutParams1); + + listView = new LetterSectionsListView(context); + listView.setEmptyView(emptyTextLayout); + listView.setVerticalScrollBarEnabled(false); + listView.setDivider(null); + listView.setDividerHeight(0); + listView.setFastScrollEnabled(true); + listView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY); + listView.setAdapter(listViewAdapter); + if (Build.VERSION.SDK_INT >= 11) { + listView.setFastScrollAlwaysVisible(true); + listView.setVerticalScrollbarPosition(LocaleController.isRTL ? ListView.SCROLLBAR_POSITION_LEFT : ListView.SCROLLBAR_POSITION_RIGHT); } + ((FrameLayout) fragmentView).addView(listView); + layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + listView.setLayoutParams(layoutParams); + + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, int i, long l) { + Country country = null; + if (searching && searchWas) { + country = searchListViewAdapter.getItem(i); + } else { + int section = listViewAdapter.getSectionForPosition(i); + int row = listViewAdapter.getPositionInSectionForPosition(i); + if (row < 0 || section < 0) { + return; + } + country = listViewAdapter.getItem(section, row); + } + if (i < 0) { + return; + } + if (country != null && delegate != null) { + delegate.didSelectCountry(country.name); + } + finishFragment(); + } + }); + + listView.setOnScrollListener(new AbsListView.OnScrollListener() { + @Override + public void onScrollStateChanged(AbsListView absListView, int i) { + if (i == SCROLL_STATE_TOUCH_SCROLL && searching && searchWas) { + AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); + } + } + + @Override + public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { + if (absListView.isFastScrollEnabled()) { + AndroidUtilities.clearDrawableAnimation(absListView); + } + } + }); + return fragmentView; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java index 177c9ae0b..1daa1499b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java @@ -51,9 +51,9 @@ import java.util.HashMap; public class DocumentSelectActivity extends BaseFragment { - public static abstract interface DocumentSelectActivityDelegate { - public void didSelectFiles(DocumentSelectActivity activity, ArrayList files); - public void startDocumentSelectActivity(); + public interface DocumentSelectActivityDelegate { + void didSelectFiles(DocumentSelectActivity activity, ArrayList files); + void startDocumentSelectActivity(); } private ListView listView; @@ -65,7 +65,7 @@ public class DocumentSelectActivity extends BaseFragment { private ArrayList items = new ArrayList<>(); private boolean receiverRegistered = false; private ArrayList history = new ArrayList<>(); - private long sizeLimit = 1024 * 1024 * 1024; + private long sizeLimit = 1024 * 1024 * 1536; private DocumentSelectActivityDelegate delegate; private HashMap selectedFiles = new HashMap<>(); private ArrayList actionModeViews = new ArrayList<>(); @@ -125,7 +125,7 @@ public class DocumentSelectActivity extends BaseFragment { } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(Context context, LayoutInflater inflater) { if (!receiverRegistered) { receiverRegistered = true; IntentFilter filter = new IntentFilter(); @@ -142,217 +142,211 @@ public class DocumentSelectActivity extends BaseFragment { getParentActivity().registerReceiver(receiver, filter); } - if (fragmentView == null) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - actionBar.setTitle(LocaleController.getString("SelectFile", R.string.SelectFile)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } else if (id == -2) { - selectedFiles.clear(); - actionBar.hideActionMode(); - listView.invalidateViews(); - } else if (id == done) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + actionBar.setTitle(LocaleController.getString("SelectFile", R.string.SelectFile)); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } else if (id == -2) { + selectedFiles.clear(); + actionBar.hideActionMode(); + listView.invalidateViews(); + } else if (id == done) { + if (delegate != null) { + ArrayList files = new ArrayList<>(); + files.addAll(selectedFiles.keySet()); + delegate.didSelectFiles(DocumentSelectActivity.this, files); + } + } + } + }); + selectedFiles.clear(); + actionModeViews.clear(); + + final ActionBarMenu actionMode = actionBar.createActionMode(); + actionModeViews.add(actionMode.addItem(-2, R.drawable.ic_ab_back_grey, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); + + selectedMessagesCountTextView = new TextView(actionMode.getContext()); + selectedMessagesCountTextView.setTextSize(18); + selectedMessagesCountTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + selectedMessagesCountTextView.setTextColor(0xff737373); + selectedMessagesCountTextView.setSingleLine(true); + selectedMessagesCountTextView.setLines(1); + selectedMessagesCountTextView.setEllipsize(TextUtils.TruncateAt.END); + selectedMessagesCountTextView.setPadding(AndroidUtilities.dp(11), 0, 0, AndroidUtilities.dp(2)); + selectedMessagesCountTextView.setGravity(Gravity.CENTER_VERTICAL); + selectedMessagesCountTextView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + actionMode.addView(selectedMessagesCountTextView); + LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) selectedMessagesCountTextView.getLayoutParams(); + layoutParams.weight = 1; + layoutParams.width = 0; + layoutParams.height = LinearLayout.LayoutParams.MATCH_PARENT; + selectedMessagesCountTextView.setLayoutParams(layoutParams); + + actionModeViews.add(actionMode.addItem(done, R.drawable.ic_ab_done_gray, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); + + fragmentView = inflater.inflate(R.layout.document_select_layout, null, false); + listAdapter = new ListAdapter(context); + emptyView = (TextView) fragmentView.findViewById(R.id.searchEmptyView); + emptyView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + listView = (ListView) fragmentView.findViewById(R.id.listView); + listView.setEmptyView(emptyView); + listView.setAdapter(listAdapter); + + listView.setOnScrollListener(new AbsListView.OnScrollListener() { + @Override + public void onScrollStateChanged(AbsListView view, int scrollState) { + scrolling = scrollState != SCROLL_STATE_IDLE; + } + + @Override + public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { + + } + }); + + listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, int i, long id) { + if (actionBar.isActionModeShowed() || i < 0 || i >= items.size()) { + return false; + } + ListItem item = items.get(i); + File file = item.file; + if (file != null && !file.isDirectory()) { + if (!file.canRead()) { + showErrorBox(LocaleController.getString("AccessError", R.string.AccessError)); + return false; + } + if (sizeLimit != 0) { + if (file.length() > sizeLimit) { + showErrorBox(LocaleController.formatString("FileUploadLimit", R.string.FileUploadLimit, Utilities.formatFileSize(sizeLimit))); + return false; + } + } + if (file.length() == 0) { + return false; + } + selectedFiles.put(file.toString(), item); + selectedMessagesCountTextView.setText(String.format("%d", selectedFiles.size())); + if (Build.VERSION.SDK_INT >= 11) { + AnimatorSetProxy animatorSet = new AnimatorSetProxy(); + ArrayList animators = new ArrayList<>(); + for (int a = 0; a < actionModeViews.size(); a++) { + View view2 = actionModeViews.get(a); + AndroidUtilities.clearDrawableAnimation(view2); + if (a < 1) { + animators.add(ObjectAnimatorProxy.ofFloat(view2, "translationX", -AndroidUtilities.dp(56), 0)); + } else { + animators.add(ObjectAnimatorProxy.ofFloat(view2, "scaleY", 0.1f, 1.0f)); + } + } + animatorSet.playTogether(animators); + animatorSet.setDuration(250); + animatorSet.start(); + } + scrolling = false; + if (view instanceof SharedDocumentCell) { + ((SharedDocumentCell) view).setChecked(true, true); + } + actionBar.showActionMode(); + } + return true; + } + }); + + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, int i, long l) { + if (i < 0 || i >= items.size()) { + return; + } + ListItem item = items.get(i); + File file = item.file; + if (file == null) { + if (item.icon == R.drawable.ic_storage_gallery) { + if (delegate != null) { + delegate.startDocumentSelectActivity(); + } + finishFragment(false); + } else { + HistoryEntry he = history.remove(history.size() - 1); + actionBar.setTitle(he.title); + if (he.dir != null) { + listFiles(he.dir); + } else { + listRoots(); + } + listView.setSelectionFromTop(he.scrollItem, he.scrollOffset); + } + } else if (file.isDirectory()) { + HistoryEntry he = new HistoryEntry(); + he.scrollItem = listView.getFirstVisiblePosition(); + he.scrollOffset = listView.getChildAt(0).getTop(); + he.dir = currentDir; + he.title = actionBar.getTitle().toString(); + history.add(he); + if (!listFiles(file)) { + history.remove(he); + return; + } + actionBar.setTitle(item.title); + listView.setSelection(0); + } else { + if (!file.canRead()) { + showErrorBox(LocaleController.getString("AccessError", R.string.AccessError)); + return; + } + if (sizeLimit != 0) { + if (file.length() > sizeLimit) { + showErrorBox(LocaleController.formatString("FileUploadLimit", R.string.FileUploadLimit, Utilities.formatFileSize(sizeLimit))); + return; + } + } + if (file.length() == 0) { + return; + } + if (actionBar.isActionModeShowed()) { + if (selectedFiles.containsKey(file.toString())) { + selectedFiles.remove(file.toString()); + } else { + selectedFiles.put(file.toString(), item); + } + if (selectedFiles.isEmpty()) { + actionBar.hideActionMode(); + } else { + selectedMessagesCountTextView.setText(String.format("%d", selectedFiles.size())); + } + scrolling = false; + if (view instanceof SharedDocumentCell) { + ((SharedDocumentCell) view).setChecked(selectedFiles.containsKey(item.file.toString()), true); + } + } else { if (delegate != null) { ArrayList files = new ArrayList<>(); - files.addAll(selectedFiles.keySet()); + files.add(file.getAbsolutePath()); delegate.didSelectFiles(DocumentSelectActivity.this, files); } } } - }); - selectedFiles.clear(); - actionModeViews.clear(); - - final ActionBarMenu actionMode = actionBar.createActionMode(); - actionModeViews.add(actionMode.addItem(-2, R.drawable.ic_ab_back_grey, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); - - selectedMessagesCountTextView = new TextView(actionMode.getContext()); - selectedMessagesCountTextView.setTextSize(18); - selectedMessagesCountTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); - selectedMessagesCountTextView.setTextColor(0xff737373); - selectedMessagesCountTextView.setSingleLine(true); - selectedMessagesCountTextView.setLines(1); - selectedMessagesCountTextView.setEllipsize(TextUtils.TruncateAt.END); - selectedMessagesCountTextView.setPadding(AndroidUtilities.dp(11), 0, 0, AndroidUtilities.dp(2)); - selectedMessagesCountTextView.setGravity(Gravity.CENTER_VERTICAL); - selectedMessagesCountTextView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return true; - } - }); - actionMode.addView(selectedMessagesCountTextView); - LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams)selectedMessagesCountTextView.getLayoutParams(); - layoutParams.weight = 1; - layoutParams.width = 0; - layoutParams.height = LinearLayout.LayoutParams.MATCH_PARENT; - selectedMessagesCountTextView.setLayoutParams(layoutParams); - - actionModeViews.add(actionMode.addItem(done, R.drawable.ic_ab_done_gray, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); - - fragmentView = inflater.inflate(R.layout.document_select_layout, container, false); - listAdapter = new ListAdapter(getParentActivity()); - emptyView = (TextView)fragmentView.findViewById(R.id.searchEmptyView); - emptyView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return true; - } - }); - listView = (ListView)fragmentView.findViewById(R.id.listView); - listView.setEmptyView(emptyView); - listView.setAdapter(listAdapter); - - listView.setOnScrollListener(new AbsListView.OnScrollListener() { - @Override - public void onScrollStateChanged(AbsListView view, int scrollState) { - scrolling = scrollState != SCROLL_STATE_IDLE; - } - - @Override - public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - - } - }); - - listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { - @Override - public boolean onItemLongClick(AdapterView parent, View view, int i, long id) { - if (actionBar.isActionModeShowed() || i < 0 || i >= items.size()) { - return false; - } - ListItem item = items.get(i); - File file = item.file; - if (file != null && !file.isDirectory()) { - if (!file.canRead()) { - showErrorBox(LocaleController.getString("AccessError", R.string.AccessError)); - return false; - } - if (sizeLimit != 0) { - if (file.length() > sizeLimit) { - showErrorBox(LocaleController.formatString("FileUploadLimit", R.string.FileUploadLimit, Utilities.formatFileSize(sizeLimit))); - return false; - } - } - if (file.length() == 0) { - return false; - } - selectedFiles.put(file.toString(), item); - selectedMessagesCountTextView.setText(String.format("%d", selectedFiles.size())); - if (Build.VERSION.SDK_INT >= 11) { - AnimatorSetProxy animatorSet = new AnimatorSetProxy(); - ArrayList animators = new ArrayList<>(); - for (int a = 0; a < actionModeViews.size(); a++) { - View view2 = actionModeViews.get(a); - AndroidUtilities.clearDrawableAnimation(view2); - if (a < 1) { - animators.add(ObjectAnimatorProxy.ofFloat(view2, "translationX", -AndroidUtilities.dp(56), 0)); - } else { - animators.add(ObjectAnimatorProxy.ofFloat(view2, "scaleY", 0.1f, 1.0f)); - } - } - animatorSet.playTogether(animators); - animatorSet.setDuration(250); - animatorSet.start(); - } - scrolling = false; - if (view instanceof SharedDocumentCell) { - ((SharedDocumentCell) view).setChecked(true, true); - } - actionBar.showActionMode(); - } - return true; - } - }); - - listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, int i, long l) { - if (i < 0 || i >= items.size()) { - return; - } - ListItem item = items.get(i); - File file = item.file; - if (file == null) { - if (item.icon == R.drawable.ic_storage_gallery) { - if (delegate != null) { - delegate.startDocumentSelectActivity(); - } - finishFragment(false); - } else { - HistoryEntry he = history.remove(history.size() - 1); - actionBar.setTitle(he.title); - if (he.dir != null) { - listFiles(he.dir); - } else { - listRoots(); - } - listView.setSelectionFromTop(he.scrollItem, he.scrollOffset); - } - } else if (file.isDirectory()) { - HistoryEntry he = new HistoryEntry(); - he.scrollItem = listView.getFirstVisiblePosition(); - he.scrollOffset = listView.getChildAt(0).getTop(); - he.dir = currentDir; - he.title = actionBar.getTitle().toString(); - history.add(he); - if (!listFiles(file)) { - history.remove(he); - return; - } - actionBar.setTitle(item.title); - listView.setSelection(0); - } else { - if (!file.canRead()) { - showErrorBox(LocaleController.getString("AccessError", R.string.AccessError)); - return; - } - if (sizeLimit != 0) { - if (file.length() > sizeLimit) { - showErrorBox(LocaleController.formatString("FileUploadLimit", R.string.FileUploadLimit, Utilities.formatFileSize(sizeLimit))); - return; - } - } - if (file.length() == 0) { - return; - } - if (actionBar.isActionModeShowed()) { - if (selectedFiles.containsKey(file.toString())) { - selectedFiles.remove(file.toString()); - } else { - selectedFiles.put(file.toString(), item); - } - if (selectedFiles.isEmpty()) { - actionBar.hideActionMode(); - } else { - selectedMessagesCountTextView.setText(String.format("%d", selectedFiles.size())); - } - scrolling = false; - if (view instanceof SharedDocumentCell) { - ((SharedDocumentCell) view).setChecked(selectedFiles.containsKey(item.file.toString()), true); - } - } else { - if (delegate != null) { - ArrayList files = new ArrayList<>(); - files.add(file.getAbsolutePath()); - delegate.didSelectFiles(DocumentSelectActivity.this, files); - } - } - } - } - }); - - listRoots(); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); } - } + }); + + listRoots(); + return fragmentView; } @@ -487,7 +481,7 @@ public class DocumentSelectActivity extends BaseFragment { if (getParentActivity() == null) { return; } - new AlertDialog.Builder(getParentActivity()).setTitle(LocaleController.getString("AppName", R.string.AppName)).setMessage(error).setPositiveButton(R.string.OK, null).show(); + new AlertDialog.Builder(getParentActivity()).setTitle(LocaleController.getString("AppName", R.string.AppName)).setMessage(error).setPositiveButton(LocaleController.getString("OK", R.string.OK), null).show(); } private void listRoots() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java index 07dc0a608..5f18cf414 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java @@ -9,6 +9,7 @@ package org.telegram.ui; import android.app.Activity; +import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; @@ -28,7 +29,6 @@ import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; -import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.widget.AbsListView; import android.widget.AdapterView; @@ -49,20 +49,20 @@ import org.telegram.android.MessagesController; import org.telegram.android.NotificationCenter; import org.telegram.messenger.R; import org.telegram.ui.Adapters.ContactsAdapter; -import org.telegram.ui.Adapters.ContactsSearchAdapter; +import org.telegram.ui.Adapters.SearchAdapter; 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.Components.SectionsListView; +import org.telegram.ui.Components.LetterSectionsListView; import java.util.ArrayList; import java.util.HashMap; public class GroupCreateActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate { - public static interface GroupCreateActivityDelegate { - public abstract void didSelectUsers(ArrayList ids); + public interface GroupCreateActivityDelegate { + void didSelectUsers(ArrayList ids); } private class XImageSpan extends ImageSpan { @@ -93,8 +93,8 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen private ContactsAdapter listViewAdapter; private TextView emptyTextView; private EditText userSelectEditText; - private SectionsListView listView; - private ContactsSearchAdapter searchListViewAdapter; + private LetterSectionsListView listView; + private SearchAdapter searchListViewAdapter; private GroupCreateActivityDelegate delegate; @@ -141,339 +141,331 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - searching = false; - searchWas = false; + public View createView(Context context, LayoutInflater inflater) { + searching = false; + searchWas = false; - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - if (isAlwaysShare) { - actionBar.setTitle(LocaleController.getString("AlwaysShareWithTitle", R.string.AlwaysShareWithTitle)); - } else if (isNeverShare) { - actionBar.setTitle(LocaleController.getString("NeverShareWithTitle", R.string.NeverShareWithTitle)); - } else { - actionBar.setTitle(isBroadcast ? LocaleController.getString("NewBroadcastList", R.string.NewBroadcastList) : LocaleController.getString("NewGroup", R.string.NewGroup)); - actionBar.setSubtitle(LocaleController.formatString("MembersCount", R.string.MembersCount, selectedContacts.size(), maxCount)); - } + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + if (isAlwaysShare) { + actionBar.setTitle(LocaleController.getString("AlwaysShareWithTitle", R.string.AlwaysShareWithTitle)); + } else if (isNeverShare) { + actionBar.setTitle(LocaleController.getString("NeverShareWithTitle", R.string.NeverShareWithTitle)); + } else { + actionBar.setTitle(isBroadcast ? LocaleController.getString("NewBroadcastList", R.string.NewBroadcastList) : LocaleController.getString("NewGroup", R.string.NewGroup)); + actionBar.setSubtitle(LocaleController.formatString("MembersCount", R.string.MembersCount, selectedContacts.size(), maxCount)); + } - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } else if (id == done_button) { - if (selectedContacts.isEmpty()) { - return; - } - ArrayList result = new ArrayList<>(); - result.addAll(selectedContacts.keySet()); - if (isAlwaysShare || isNeverShare) { - if (delegate != null) { - delegate.didSelectUsers(result); - } - finishFragment(); - } else { - Bundle args = new Bundle(); - args.putIntegerArrayList("result", result); - args.putBoolean("broadcast", isBroadcast); - presentFragment(new GroupCreateFinalActivity(args)); - } - } - } - }); - ActionBarMenu menu = actionBar.createMenu(); - menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); - - searchListViewAdapter = new ContactsSearchAdapter(getParentActivity(), null, false); - searchListViewAdapter.setCheckedMap(selectedContacts); - searchListViewAdapter.setUseUserCell(true); - listViewAdapter = new ContactsAdapter(getParentActivity(), true, false, null); - listViewAdapter.setCheckedMap(selectedContacts); - - fragmentView = new LinearLayout(getParentActivity()); - LinearLayout linearLayout = (LinearLayout) fragmentView; - linearLayout.setOrientation(LinearLayout.VERTICAL); - - FrameLayout frameLayout = new FrameLayout(getParentActivity()); - linearLayout.addView(frameLayout); - LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) frameLayout.getLayoutParams(); - layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; - layoutParams.gravity = Gravity.TOP; - frameLayout.setLayoutParams(layoutParams); - - userSelectEditText = new EditText(getParentActivity()); - userSelectEditText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); - userSelectEditText.setHintTextColor(0xff979797); - userSelectEditText.setTextColor(0xff212121); - userSelectEditText.setInputType(InputType.TYPE_TEXT_VARIATION_FILTER | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_FLAG_MULTI_LINE); - userSelectEditText.setMinimumHeight(AndroidUtilities.dp(54)); - userSelectEditText.setSingleLine(false); - userSelectEditText.setLines(2); - userSelectEditText.setMaxLines(2); - userSelectEditText.setVerticalScrollBarEnabled(true); - userSelectEditText.setHorizontalScrollBarEnabled(false); - userSelectEditText.setPadding(0, 0, 0, 0); - userSelectEditText.setImeOptions(EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_EXTRACT_UI); - userSelectEditText.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL); - AndroidUtilities.clearCursorDrawable(userSelectEditText); - frameLayout.addView(userSelectEditText); - FrameLayout.LayoutParams layoutParams1 = (FrameLayout.LayoutParams) userSelectEditText.getLayoutParams(); - layoutParams1.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams1.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams1.leftMargin = AndroidUtilities.dp(10); - layoutParams1.rightMargin = AndroidUtilities.dp(10); - layoutParams1.gravity = Gravity.TOP; - userSelectEditText.setLayoutParams(layoutParams1); - - if (isAlwaysShare) { - userSelectEditText.setHint(LocaleController.getString("AlwaysShareWithPlaceholder", R.string.AlwaysShareWithPlaceholder)); - } else if (isNeverShare) { - userSelectEditText.setHint(LocaleController.getString("NeverShareWithPlaceholder", R.string.NeverShareWithPlaceholder)); - } else { - userSelectEditText.setHint(LocaleController.getString("SendMessageTo", R.string.SendMessageTo)); - } - if (Build.VERSION.SDK_INT >= 11) { - userSelectEditText.setTextIsSelectable(false); - } - userSelectEditText.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) { - if (!ignoreChange) { - beforeChangeIndex = userSelectEditText.getSelectionStart(); - changeString = new SpannableString(charSequence); - } - } - - @Override - public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { - - } - - @Override - public void afterTextChanged(Editable editable) { - if (!ignoreChange) { - boolean search = false; - int afterChangeIndex = userSelectEditText.getSelectionEnd(); - if (editable.toString().length() < changeString.toString().length()) { - String deletedString = ""; - try { - deletedString = changeString.toString().substring(afterChangeIndex, beforeChangeIndex); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - if (deletedString.length() > 0) { - if (searching && searchWas) { - search = true; - } - Spannable span = userSelectEditText.getText(); - for (int a = 0; a < allSpans.size(); a++) { - XImageSpan sp = allSpans.get(a); - if (span.getSpanStart(sp) == -1) { - allSpans.remove(sp); - selectedContacts.remove(sp.uid); - } - } - if (!isAlwaysShare && !isNeverShare) { - actionBar.setSubtitle(LocaleController.formatString("MembersCount", R.string.MembersCount, selectedContacts.size(), maxCount)); - } - listView.invalidateViews(); - } else { - search = true; - } - } else { - search = true; - } - if (search) { - String text = userSelectEditText.getText().toString().replace("<", ""); - if (text.length() != 0) { - searching = true; - searchWas = true; - if (listView != null) { - listView.setAdapter(searchListViewAdapter); - searchListViewAdapter.notifyDataSetChanged(); - if(android.os.Build.VERSION.SDK_INT >= 11) { - listView.setFastScrollAlwaysVisible(false); - } - listView.setFastScrollEnabled(false); - listView.setVerticalScrollBarEnabled(true); - } - if (emptyTextView != null) { - emptyTextView.setText(LocaleController.getString("NoResult", R.string.NoResult)); - } - searchListViewAdapter.searchDialogs(text); - } else { - searchListViewAdapter.searchDialogs(null); - searching = false; - searchWas = false; - ViewGroup group = (ViewGroup) listView.getParent(); - listView.setAdapter(listViewAdapter); - listViewAdapter.notifyDataSetChanged(); - if (android.os.Build.VERSION.SDK_INT >= 11) { - listView.setFastScrollAlwaysVisible(true); - } - listView.setFastScrollEnabled(true); - listView.setVerticalScrollBarEnabled(false); - emptyTextView.setText(LocaleController.getString("NoContacts", R.string.NoContacts)); - } - } - } - } - }); - - LinearLayout emptyTextLayout = new LinearLayout(getParentActivity()); - emptyTextLayout.setVisibility(View.INVISIBLE); - emptyTextLayout.setOrientation(LinearLayout.VERTICAL); - linearLayout.addView(emptyTextLayout); - layoutParams = (LinearLayout.LayoutParams) emptyTextLayout.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - emptyTextLayout.setLayoutParams(layoutParams); - emptyTextLayout.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return true; - } - }); - - emptyTextView = new TextView(getParentActivity()); - emptyTextView.setTextColor(0xff808080); - emptyTextView.setTextSize(20); - emptyTextView.setGravity(Gravity.CENTER); - emptyTextView.setText(LocaleController.getString("NoContacts", R.string.NoContacts)); - emptyTextLayout.addView(emptyTextView); - layoutParams = (LinearLayout.LayoutParams) emptyTextView.getLayoutParams(); - layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams.weight = 0.5f; - emptyTextView.setLayoutParams(layoutParams); - - FrameLayout frameLayout2 = new FrameLayout(getParentActivity()); - emptyTextLayout.addView(frameLayout2); - layoutParams = (LinearLayout.LayoutParams) frameLayout2.getLayoutParams(); - layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams.weight = 0.5f; - frameLayout2.setLayoutParams(layoutParams); - - listView = new SectionsListView(getParentActivity()); - listView.setEmptyView(emptyTextLayout); - listView.setVerticalScrollBarEnabled(false); - listView.setDivider(null); - listView.setDividerHeight(0); - listView.setFastScrollEnabled(true); - listView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY); - listView.setAdapter(listViewAdapter); - if (Build.VERSION.SDK_INT >= 11) { - listView.setFastScrollAlwaysVisible(true); - listView.setVerticalScrollbarPosition(LocaleController.isRTL ? ListView.SCROLLBAR_POSITION_LEFT : ListView.SCROLLBAR_POSITION_RIGHT); - } - linearLayout.addView(listView); - layoutParams = (LinearLayout.LayoutParams) listView.getLayoutParams(); - layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = LinearLayout.LayoutParams.MATCH_PARENT; - listView.setLayoutParams(layoutParams); - listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, int i, long l) { - TLRPC.User user = null; - if (searching && searchWas) { - user = searchListViewAdapter.getItem(i); - } else { - int section = listViewAdapter.getSectionForPosition(i); - int row = listViewAdapter.getPositionInSectionForPosition(i); - if (row < 0 || section < 0) { - return; - } - user = (TLRPC.User) listViewAdapter.getItem(section, row); - } - if (user == null) { + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } else if (id == done_button) { + if (selectedContacts.isEmpty()) { return; } + ArrayList result = new ArrayList<>(); + result.addAll(selectedContacts.keySet()); + if (isAlwaysShare || isNeverShare) { + if (delegate != null) { + delegate.didSelectUsers(result); + } + finishFragment(); + } else { + Bundle args = new Bundle(); + args.putIntegerArrayList("result", result); + args.putBoolean("broadcast", isBroadcast); + presentFragment(new GroupCreateFinalActivity(args)); + } + } + } + }); + ActionBarMenu menu = actionBar.createMenu(); + menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); - boolean check = true; - if (selectedContacts.containsKey(user.id)) { - check = false; + searchListViewAdapter = new SearchAdapter(context, null, false); + searchListViewAdapter.setCheckedMap(selectedContacts); + searchListViewAdapter.setUseUserCell(true); + listViewAdapter = new ContactsAdapter(context, true, false, null); + listViewAdapter.setCheckedMap(selectedContacts); + + fragmentView = new LinearLayout(context); + LinearLayout linearLayout = (LinearLayout) fragmentView; + linearLayout.setOrientation(LinearLayout.VERTICAL); + + FrameLayout frameLayout = new FrameLayout(context); + linearLayout.addView(frameLayout); + LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) frameLayout.getLayoutParams(); + layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.TOP; + frameLayout.setLayoutParams(layoutParams); + + userSelectEditText = new EditText(context); + userSelectEditText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + userSelectEditText.setHintTextColor(0xff979797); + userSelectEditText.setTextColor(0xff212121); + userSelectEditText.setInputType(InputType.TYPE_TEXT_VARIATION_FILTER | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_FLAG_MULTI_LINE); + userSelectEditText.setMinimumHeight(AndroidUtilities.dp(54)); + userSelectEditText.setSingleLine(false); + userSelectEditText.setLines(2); + userSelectEditText.setMaxLines(2); + userSelectEditText.setVerticalScrollBarEnabled(true); + userSelectEditText.setHorizontalScrollBarEnabled(false); + userSelectEditText.setPadding(0, 0, 0, 0); + userSelectEditText.setImeOptions(EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_EXTRACT_UI); + userSelectEditText.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL); + AndroidUtilities.clearCursorDrawable(userSelectEditText); + frameLayout.addView(userSelectEditText); + FrameLayout.LayoutParams layoutParams1 = (FrameLayout.LayoutParams) userSelectEditText.getLayoutParams(); + layoutParams1.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams1.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams1.leftMargin = AndroidUtilities.dp(10); + layoutParams1.rightMargin = AndroidUtilities.dp(10); + layoutParams1.gravity = Gravity.TOP; + userSelectEditText.setLayoutParams(layoutParams1); + + if (isAlwaysShare) { + userSelectEditText.setHint(LocaleController.getString("AlwaysShareWithPlaceholder", R.string.AlwaysShareWithPlaceholder)); + } else if (isNeverShare) { + userSelectEditText.setHint(LocaleController.getString("NeverShareWithPlaceholder", R.string.NeverShareWithPlaceholder)); + } else { + userSelectEditText.setHint(LocaleController.getString("SendMessageTo", R.string.SendMessageTo)); + } + if (Build.VERSION.SDK_INT >= 11) { + userSelectEditText.setTextIsSelectable(false); + } + userSelectEditText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) { + if (!ignoreChange) { + beforeChangeIndex = userSelectEditText.getSelectionStart(); + changeString = new SpannableString(charSequence); + } + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { + + } + + @Override + public void afterTextChanged(Editable editable) { + if (!ignoreChange) { + boolean search = false; + int afterChangeIndex = userSelectEditText.getSelectionEnd(); + if (editable.toString().length() < changeString.toString().length()) { + String deletedString = ""; try { - XImageSpan span = selectedContacts.get(user.id); - selectedContacts.remove(user.id); - SpannableStringBuilder text = new SpannableStringBuilder(userSelectEditText.getText()); - text.delete(text.getSpanStart(span), text.getSpanEnd(span)); - allSpans.remove(span); - ignoreChange = true; - userSelectEditText.setText(text); - userSelectEditText.setSelection(text.length()); - ignoreChange = false; + deletedString = changeString.toString().substring(afterChangeIndex, beforeChangeIndex); } catch (Exception e) { FileLog.e("tmessages", e); } + if (deletedString.length() > 0) { + if (searching && searchWas) { + search = true; + } + Spannable span = userSelectEditText.getText(); + for (int a = 0; a < allSpans.size(); a++) { + XImageSpan sp = allSpans.get(a); + if (span.getSpanStart(sp) == -1) { + allSpans.remove(sp); + selectedContacts.remove(sp.uid); + } + } + if (!isAlwaysShare && !isNeverShare) { + actionBar.setSubtitle(LocaleController.formatString("MembersCount", R.string.MembersCount, selectedContacts.size(), maxCount)); + } + listView.invalidateViews(); + } else { + search = true; + } } else { - if (selectedContacts.size() == maxCount) { - return; - } - ignoreChange = true; - XImageSpan span = createAndPutChipForUser(user); - span.uid = user.id; - ignoreChange = false; + search = true; } - if (!isAlwaysShare && !isNeverShare) { - actionBar.setSubtitle(LocaleController.formatString("MembersCount", R.string.MembersCount, selectedContacts.size(), maxCount)); - } - if (searching || searchWas) { - ignoreChange = true; - SpannableStringBuilder ssb = new SpannableStringBuilder(""); - for (ImageSpan sp : allSpans) { - ssb.append("<<"); - ssb.setSpan(sp, ssb.length() - 2, ssb.length(), SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE); - } - userSelectEditText.setText(ssb); - userSelectEditText.setSelection(ssb.length()); - ignoreChange = false; - - searchListViewAdapter.searchDialogs(null); - searching = false; - searchWas = false; - ViewGroup group = (ViewGroup) listView.getParent(); - listView.setAdapter(listViewAdapter); - listViewAdapter.notifyDataSetChanged(); - if (android.os.Build.VERSION.SDK_INT >= 11) { - listView.setFastScrollAlwaysVisible(true); - } - listView.setFastScrollEnabled(true); - listView.setVerticalScrollBarEnabled(false); - emptyTextView.setText(LocaleController.getString("NoContacts", R.string.NoContacts)); - } else { - if (view instanceof UserCell) { - ((UserCell) view).setChecked(check, true); + if (search) { + String text = userSelectEditText.getText().toString().replace("<", ""); + if (text.length() != 0) { + searching = true; + searchWas = true; + if (listView != null) { + listView.setAdapter(searchListViewAdapter); + searchListViewAdapter.notifyDataSetChanged(); + if (android.os.Build.VERSION.SDK_INT >= 11) { + listView.setFastScrollAlwaysVisible(false); + } + listView.setFastScrollEnabled(false); + listView.setVerticalScrollBarEnabled(true); + } + if (emptyTextView != null) { + emptyTextView.setText(LocaleController.getString("NoResult", R.string.NoResult)); + } + searchListViewAdapter.searchDialogs(text); + } else { + searchListViewAdapter.searchDialogs(null); + searching = false; + searchWas = false; + listView.setAdapter(listViewAdapter); + listViewAdapter.notifyDataSetChanged(); + if (android.os.Build.VERSION.SDK_INT >= 11) { + listView.setFastScrollAlwaysVisible(true); + } + listView.setFastScrollEnabled(true); + listView.setVerticalScrollBarEnabled(false); + emptyTextView.setText(LocaleController.getString("NoContacts", R.string.NoContacts)); } } } - }); - listView.setOnScrollListener(new AbsListView.OnScrollListener() { - @Override - public void onScrollStateChanged(AbsListView absListView, int i) { - if (i == SCROLL_STATE_TOUCH_SCROLL) { - AndroidUtilities.hideKeyboard(userSelectEditText); - } - if (listViewAdapter != null) { - listViewAdapter.setIsScrolling(i != SCROLL_STATE_IDLE); - } - } - - @Override - public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - if (absListView.isFastScrollEnabled()) { - AndroidUtilities.clearDrawableAnimation(absListView); - } - } - }); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); } + }); + + LinearLayout emptyTextLayout = new LinearLayout(context); + emptyTextLayout.setVisibility(View.INVISIBLE); + emptyTextLayout.setOrientation(LinearLayout.VERTICAL); + linearLayout.addView(emptyTextLayout); + layoutParams = (LinearLayout.LayoutParams) emptyTextLayout.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + emptyTextLayout.setLayoutParams(layoutParams); + emptyTextLayout.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + emptyTextView = new TextView(context); + emptyTextView.setTextColor(0xff808080); + emptyTextView.setTextSize(20); + emptyTextView.setGravity(Gravity.CENTER); + emptyTextView.setText(LocaleController.getString("NoContacts", R.string.NoContacts)); + emptyTextLayout.addView(emptyTextView); + layoutParams = (LinearLayout.LayoutParams) emptyTextView.getLayoutParams(); + layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams.weight = 0.5f; + emptyTextView.setLayoutParams(layoutParams); + + FrameLayout frameLayout2 = new FrameLayout(context); + emptyTextLayout.addView(frameLayout2); + layoutParams = (LinearLayout.LayoutParams) frameLayout2.getLayoutParams(); + layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams.weight = 0.5f; + frameLayout2.setLayoutParams(layoutParams); + + listView = new LetterSectionsListView(context); + listView.setEmptyView(emptyTextLayout); + listView.setVerticalScrollBarEnabled(false); + listView.setDivider(null); + listView.setDividerHeight(0); + listView.setFastScrollEnabled(true); + listView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY); + listView.setAdapter(listViewAdapter); + if (Build.VERSION.SDK_INT >= 11) { + listView.setFastScrollAlwaysVisible(true); + listView.setVerticalScrollbarPosition(LocaleController.isRTL ? ListView.SCROLLBAR_POSITION_LEFT : ListView.SCROLLBAR_POSITION_RIGHT); } + linearLayout.addView(listView); + layoutParams = (LinearLayout.LayoutParams) listView.getLayoutParams(); + layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = LinearLayout.LayoutParams.MATCH_PARENT; + listView.setLayoutParams(layoutParams); + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, int i, long l) { + TLRPC.User user = null; + if (searching && searchWas) { + user = searchListViewAdapter.getItem(i); + } else { + int section = listViewAdapter.getSectionForPosition(i); + int row = listViewAdapter.getPositionInSectionForPosition(i); + if (row < 0 || section < 0) { + return; + } + user = (TLRPC.User) listViewAdapter.getItem(section, row); + } + if (user == null) { + return; + } + + boolean check = true; + if (selectedContacts.containsKey(user.id)) { + check = false; + try { + XImageSpan span = selectedContacts.get(user.id); + selectedContacts.remove(user.id); + SpannableStringBuilder text = new SpannableStringBuilder(userSelectEditText.getText()); + text.delete(text.getSpanStart(span), text.getSpanEnd(span)); + allSpans.remove(span); + ignoreChange = true; + userSelectEditText.setText(text); + userSelectEditText.setSelection(text.length()); + ignoreChange = false; + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } else { + if (selectedContacts.size() == maxCount) { + return; + } + ignoreChange = true; + XImageSpan span = createAndPutChipForUser(user); + span.uid = user.id; + ignoreChange = false; + } + if (!isAlwaysShare && !isNeverShare) { + actionBar.setSubtitle(LocaleController.formatString("MembersCount", R.string.MembersCount, selectedContacts.size(), maxCount)); + } + if (searching || searchWas) { + ignoreChange = true; + SpannableStringBuilder ssb = new SpannableStringBuilder(""); + for (ImageSpan sp : allSpans) { + ssb.append("<<"); + ssb.setSpan(sp, ssb.length() - 2, ssb.length(), SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE); + } + userSelectEditText.setText(ssb); + userSelectEditText.setSelection(ssb.length()); + ignoreChange = false; + + searchListViewAdapter.searchDialogs(null); + searching = false; + searchWas = false; + listView.setAdapter(listViewAdapter); + listViewAdapter.notifyDataSetChanged(); + if (android.os.Build.VERSION.SDK_INT >= 11) { + listView.setFastScrollAlwaysVisible(true); + } + listView.setFastScrollEnabled(true); + listView.setVerticalScrollBarEnabled(false); + emptyTextView.setText(LocaleController.getString("NoContacts", R.string.NoContacts)); + } else { + if (view instanceof UserCell) { + ((UserCell) view).setChecked(check, true); + } + } + } + }); + listView.setOnScrollListener(new AbsListView.OnScrollListener() { + @Override + public void onScrollStateChanged(AbsListView absListView, int i) { + if (i == SCROLL_STATE_TOUCH_SCROLL) { + AndroidUtilities.hideKeyboard(userSelectEditText); + } + if (listViewAdapter != null) { + listViewAdapter.setIsScrolling(i != SCROLL_STATE_IDLE); + } + } + + @Override + public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { + if (absListView.isFastScrollEnabled()) { + AndroidUtilities.clearDrawableAnimation(absListView); + } + } + }); + return fragmentView; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java index ab3fd663f..6436ef0ce 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java @@ -85,7 +85,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati avatarUpdater.parentFragment = this; avatarUpdater.delegate = this; selectedContacts = getArguments().getIntegerArrayList("result"); - final ArrayList usersToLoad = new ArrayList(); + final ArrayList usersToLoad = new ArrayList<>(); for (Integer uid : selectedContacts) { if (MessagesController.getInstance().getUser(uid) == null) { usersToLoad.add(uid); @@ -93,7 +93,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati } if (!usersToLoad.isEmpty()) { final Semaphore semaphore = new Semaphore(0); - final ArrayList users = new ArrayList(); + final ArrayList users = new ArrayList<>(); MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { @@ -138,191 +138,185 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - if (isBroadcast) { - actionBar.setTitle(LocaleController.getString("NewBroadcastList", R.string.NewBroadcastList)); - } else { - actionBar.setTitle(LocaleController.getString("NewGroup", R.string.NewGroup)); - } + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + if (isBroadcast) { + actionBar.setTitle(LocaleController.getString("NewBroadcastList", R.string.NewBroadcastList)); + } else { + actionBar.setTitle(LocaleController.getString("NewGroup", R.string.NewGroup)); + } - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } else if (id == done_button) { - if (donePressed) { - return; - } - if (nameTextView.getText().length() == 0) { - return; - } - donePressed = true; + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } else if (id == done_button) { + if (donePressed) { + return; + } + if (nameTextView.getText().length() == 0) { + return; + } + donePressed = true; - if (isBroadcast) { - MessagesController.getInstance().createChat(nameTextView.getText().toString(), selectedContacts, uploadedAvatar, isBroadcast); + if (isBroadcast) { + MessagesController.getInstance().createChat(nameTextView.getText().toString(), selectedContacts, isBroadcast); + } else { + if (avatarUpdater.uploadingAvatar != null) { + createAfterUpload = true; } else { - if (avatarUpdater.uploadingAvatar != null) { - createAfterUpload = true; - } else { - progressDialog = new ProgressDialog(getParentActivity()); - progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading)); - progressDialog.setCanceledOnTouchOutside(false); - progressDialog.setCancelable(false); + progressDialog = new ProgressDialog(getParentActivity()); + progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.setCancelable(false); - final long reqId = MessagesController.getInstance().createChat(nameTextView.getText().toString(), selectedContacts, uploadedAvatar, isBroadcast); + final long reqId = MessagesController.getInstance().createChat(nameTextView.getText().toString(), selectedContacts, isBroadcast); - 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); - donePressed = false; - try { - dialog.dismiss(); - } catch (Exception e) { - FileLog.e("tmessages", e); - } + 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); + donePressed = false; + try { + dialog.dismiss(); + } catch (Exception e) { + FileLog.e("tmessages", e); } - }); - progressDialog.show(); - } + } + }); + progressDialog.show(); } } } - }); + } + }); - ActionBarMenu menu = actionBar.createMenu(); - menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + ActionBarMenu menu = actionBar.createMenu(); + menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); - fragmentView = new LinearLayout(getParentActivity()); - LinearLayout linearLayout = (LinearLayout) fragmentView; - linearLayout.setOrientation(LinearLayout.VERTICAL); + fragmentView = new LinearLayout(context); + LinearLayout linearLayout = (LinearLayout) fragmentView; + linearLayout.setOrientation(LinearLayout.VERTICAL); - FrameLayout frameLayout = new FrameLayoutFixed(getParentActivity()); - linearLayout.addView(frameLayout); - LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) frameLayout.getLayoutParams(); - layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; - layoutParams.gravity = Gravity.TOP | Gravity.LEFT; - frameLayout.setLayoutParams(layoutParams); + FrameLayout frameLayout = new FrameLayoutFixed(context); + linearLayout.addView(frameLayout); + LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) frameLayout.getLayoutParams(); + layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + frameLayout.setLayoutParams(layoutParams); - avatarImage = new BackupImageView(getParentActivity()); - avatarImage.imageReceiver.setRoundRadius(AndroidUtilities.dp(32)); - avatarDrawable.setInfo(5, null, null, isBroadcast); - avatarImage.setImageDrawable(avatarDrawable); - frameLayout.addView(avatarImage); - FrameLayout.LayoutParams layoutParams1 = (FrameLayout.LayoutParams) avatarImage.getLayoutParams(); - layoutParams1.width = AndroidUtilities.dp(64); - layoutParams1.height = AndroidUtilities.dp(64); - layoutParams1.topMargin = AndroidUtilities.dp(12); - layoutParams1.bottomMargin = AndroidUtilities.dp(12); - layoutParams1.leftMargin = LocaleController.isRTL ? 0 : AndroidUtilities.dp(16); - layoutParams1.rightMargin = LocaleController.isRTL ? AndroidUtilities.dp(16) : 0; - layoutParams1.gravity = Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); - avatarImage.setLayoutParams(layoutParams1); - if (!isBroadcast) { - avatarDrawable.setDrawPhoto(true); - avatarImage.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - if (getParentActivity() == null) { - return; - } - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + avatarImage = new BackupImageView(context); + avatarImage.setRoundRadius(AndroidUtilities.dp(32)); + avatarDrawable.setInfo(5, null, null, isBroadcast); + avatarImage.setImageDrawable(avatarDrawable); + frameLayout.addView(avatarImage); + FrameLayout.LayoutParams layoutParams1 = (FrameLayout.LayoutParams) avatarImage.getLayoutParams(); + layoutParams1.width = AndroidUtilities.dp(64); + layoutParams1.height = AndroidUtilities.dp(64); + layoutParams1.topMargin = AndroidUtilities.dp(12); + layoutParams1.bottomMargin = AndroidUtilities.dp(12); + layoutParams1.leftMargin = LocaleController.isRTL ? 0 : AndroidUtilities.dp(16); + layoutParams1.rightMargin = LocaleController.isRTL ? AndroidUtilities.dp(16) : 0; + layoutParams1.gravity = Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); + avatarImage.setLayoutParams(layoutParams1); + if (!isBroadcast) { + avatarDrawable.setDrawPhoto(true); + avatarImage.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (getParentActivity() == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - CharSequence[] items; + CharSequence[] items; - if (avatar != null) { - items = new CharSequence[]{LocaleController.getString("FromCamera", R.string.FromCamera), LocaleController.getString("FromGalley", R.string.FromGalley), LocaleController.getString("DeletePhoto", R.string.DeletePhoto)}; - } else { - items = new CharSequence[]{LocaleController.getString("FromCamera", R.string.FromCamera), LocaleController.getString("FromGalley", R.string.FromGalley)}; - } + if (avatar != null) { + items = new CharSequence[]{LocaleController.getString("FromCamera", R.string.FromCamera), LocaleController.getString("FromGalley", R.string.FromGalley), LocaleController.getString("DeletePhoto", R.string.DeletePhoto)}; + } else { + items = new CharSequence[]{LocaleController.getString("FromCamera", R.string.FromCamera), LocaleController.getString("FromGalley", R.string.FromGalley)}; + } - builder.setItems(items, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - if (i == 0) { - avatarUpdater.openCamera(); - } else if (i == 1) { - avatarUpdater.openGallery(); - } else if (i == 2) { - avatar = null; - uploadedAvatar = null; - avatarImage.setImage(avatar, "50_50", avatarDrawable); - } + builder.setItems(items, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + if (i == 0) { + avatarUpdater.openCamera(); + } else if (i == 1) { + avatarUpdater.openGallery(); + } else if (i == 2) { + avatar = null; + uploadedAvatar = null; + avatarImage.setImage(avatar, "50_50", avatarDrawable); } - }); - showAlertDialog(builder); - } - }); - } - - nameTextView = new EditText(getParentActivity()); - nameTextView.setHint(isBroadcast ? LocaleController.getString("EnterListName", R.string.EnterListName) : LocaleController.getString("EnterGroupNamePlaceholder", R.string.EnterGroupNamePlaceholder)); - if (nameToSet != null) { - nameTextView.setText(nameToSet); - nameToSet = null; - } - nameTextView.setMaxLines(4); - nameTextView.setGravity(Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)); - nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); - nameTextView.setHintTextColor(0xff979797); - nameTextView.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI); - nameTextView.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES); - nameTextView.setPadding(0, 0, 0, AndroidUtilities.dp(8)); - AndroidUtilities.clearCursorDrawable(nameTextView); - nameTextView.setTextColor(0xff212121); - frameLayout.addView(nameTextView); - layoutParams1 = (FrameLayout.LayoutParams) nameTextView.getLayoutParams(); - layoutParams1.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams1.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams1.leftMargin = LocaleController.isRTL ? AndroidUtilities.dp(16) : AndroidUtilities.dp(96); - layoutParams1.rightMargin = LocaleController.isRTL ? AndroidUtilities.dp(96) : AndroidUtilities.dp(16); - layoutParams1.gravity = Gravity.CENTER_VERTICAL; - nameTextView.setLayoutParams(layoutParams1); - if (!isBroadcast) { - nameTextView.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - - } - - @Override - public void afterTextChanged(Editable s) { - avatarDrawable.setInfo(5, nameTextView.length() > 0 ? nameTextView.getText().toString() : null, null, isBroadcast); - avatarImage.invalidate(); - } - }); - } - - GreySectionCell sectionCell = new GreySectionCell(getParentActivity()); - sectionCell.setText(LocaleController.formatPluralString("Members", selectedContacts.size())); - linearLayout.addView(sectionCell); - - listView = new ListView(getParentActivity()); - listView.setDivider(null); - listView.setDividerHeight(0); - listView.setVerticalScrollBarEnabled(false); - listView.setAdapter(listAdapter = new ListAdapter(getParentActivity())); - linearLayout.addView(listView); - layoutParams = (LinearLayout.LayoutParams) listView.getLayoutParams(); - layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = LinearLayout.LayoutParams.MATCH_PARENT; - listView.setLayoutParams(layoutParams); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); - } + } + }); + showAlertDialog(builder); + } + }); } + + nameTextView = new EditText(context); + nameTextView.setHint(isBroadcast ? LocaleController.getString("EnterListName", R.string.EnterListName) : LocaleController.getString("EnterGroupNamePlaceholder", R.string.EnterGroupNamePlaceholder)); + if (nameToSet != null) { + nameTextView.setText(nameToSet); + nameToSet = null; + } + nameTextView.setMaxLines(4); + nameTextView.setGravity(Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)); + nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + nameTextView.setHintTextColor(0xff979797); + nameTextView.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI); + nameTextView.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES); + nameTextView.setPadding(0, 0, 0, AndroidUtilities.dp(8)); + AndroidUtilities.clearCursorDrawable(nameTextView); + nameTextView.setTextColor(0xff212121); + frameLayout.addView(nameTextView); + layoutParams1 = (FrameLayout.LayoutParams) nameTextView.getLayoutParams(); + layoutParams1.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams1.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams1.leftMargin = LocaleController.isRTL ? AndroidUtilities.dp(16) : AndroidUtilities.dp(96); + layoutParams1.rightMargin = LocaleController.isRTL ? AndroidUtilities.dp(96) : AndroidUtilities.dp(16); + layoutParams1.gravity = Gravity.CENTER_VERTICAL; + nameTextView.setLayoutParams(layoutParams1); + if (!isBroadcast) { + nameTextView.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + public void afterTextChanged(Editable s) { + avatarDrawable.setInfo(5, nameTextView.length() > 0 ? nameTextView.getText().toString() : null, null, isBroadcast); + avatarImage.invalidate(); + } + }); + } + + GreySectionCell sectionCell = new GreySectionCell(context); + sectionCell.setText(LocaleController.formatPluralString("Members", selectedContacts.size())); + linearLayout.addView(sectionCell); + + listView = new ListView(context); + listView.setDivider(null); + listView.setDividerHeight(0); + listView.setVerticalScrollBarEnabled(false); + listView.setAdapter(listAdapter = new ListAdapter(context)); + linearLayout.addView(listView); + layoutParams = (LinearLayout.LayoutParams) listView.getLayoutParams(); + layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = LinearLayout.LayoutParams.MATCH_PARENT; + listView.setLayoutParams(layoutParams); + return fragmentView; } @@ -336,7 +330,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati avatarImage.setImage(avatar, "50_50", avatarDrawable); if (createAfterUpload) { FileLog.e("tmessages", "avatar did uploaded"); - MessagesController.getInstance().createChat(nameTextView.getText().toString(), selectedContacts, uploadedAvatar, false); + MessagesController.getInstance().createChat(nameTextView.getText().toString(), selectedContacts, false); } } }); @@ -402,9 +396,14 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati FileLog.e("tmessages", e); } } + int chat_id = (Integer)args[0]; + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); Bundle args2 = new Bundle(); - args2.putInt("chat_id", (Integer)args[0]); + args2.putInt("chat_id", chat_id); presentFragment(new ChatActivity(args2), true); + if (uploadedAvatar != null) { + MessagesController.getInstance().changeChatAvatar(chat_id, uploadedAvatar); + } } }); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/IdenticonActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/IdenticonActivity.java index a4a591998..10181960b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/IdenticonActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/IdenticonActivity.java @@ -10,18 +10,17 @@ package org.telegram.ui; import android.content.Context; import android.os.Bundle; -import android.text.Html; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.Surface; import android.view.View; -import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.WindowManager; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; +import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.TLRPC; @@ -45,45 +44,39 @@ public class IdenticonActivity extends BaseFragment { } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - actionBar.setTitle(LocaleController.getString("EncryptionKey", R.string.EncryptionKey)); + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + actionBar.setTitle(LocaleController.getString("EncryptionKey", R.string.EncryptionKey)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); } - }); - - fragmentView = inflater.inflate(R.layout.identicon_layout, container, false); - ImageView identiconView = (ImageView) fragmentView.findViewById(R.id.identicon_view); - TextView textView = (TextView)fragmentView.findViewById(R.id.identicon_text); - TLRPC.EncryptedChat encryptedChat = MessagesController.getInstance().getEncryptedChat(chat_id); - if (encryptedChat != null) { - IdenticonDrawable drawable = new IdenticonDrawable(); - identiconView.setImageDrawable(drawable); - 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))); } + }); - fragmentView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return true; - } - }); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); - } + fragmentView = inflater.inflate(R.layout.identicon_layout, null, false); + ImageView identiconView = (ImageView) fragmentView.findViewById(R.id.identicon_view); + TextView textView = (TextView) fragmentView.findViewById(R.id.identicon_text); + TLRPC.EncryptedChat encryptedChat = MessagesController.getInstance().getEncryptedChat(chat_id); + if (encryptedChat != null) { + IdenticonDrawable drawable = new IdenticonDrawable(); + identiconView.setImageDrawable(drawable); + drawable.setEncryptedChat(encryptedChat); + TLRPC.User user = MessagesController.getInstance().getUser(encryptedChat.user_id); + textView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("EncryptionKeyDescription", R.string.EncryptionKeyDescription, user.first_name, user.first_name))); } + + fragmentView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + return fragmentView; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/IntroActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/IntroActivity.java index 983d43cd9..2d3599521 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/IntroActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/IntroActivity.java @@ -19,7 +19,6 @@ import android.os.Bundle; import android.os.Parcelable; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; -import android.text.Html; import android.view.View; import android.view.ViewGroup; import android.view.Window; @@ -255,7 +254,7 @@ public class IntroActivity extends Activity { container.addView(view, 0); headerTextView.setText(getString(titles[position])); - messageTextView.setText(Html.fromHtml(getString(messages[position]))); + messageTextView.setText(AndroidUtilities.replaceTags(getString(messages[position]))); return view; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java index 0744b1ab3..a6efe56be 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java @@ -52,190 +52,186 @@ public class LanguageSelectActivity extends BaseFragment { public ArrayList searchResult; @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - searching = false; - searchWas = false; + public View createView(Context context, LayoutInflater inflater) { + searching = false; + searchWas = false; - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - actionBar.setTitle(LocaleController.getString("Language", R.string.Language)); + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + actionBar.setTitle(LocaleController.getString("Language", R.string.Language)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } - } - }); - - ActionBarMenu menu = actionBar.createMenu(); - ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true).setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() { - @Override - public void onSearchExpand() { - searching = true; - } - - @Override - public void onSearchCollapse() { - search(null); - searching = false; - searchWas = false; - if (listView != null) { - emptyTextView.setVisibility(View.GONE); - listView.setAdapter(listAdapter); - } - } - - @Override - public void onTextChanged(EditText editText) { - String text = editText.getText().toString(); - search(text); - if (text.length() != 0) { - searchWas = true; - if (listView != null) { - listView.setAdapter(searchListViewAdapter); - } - } - } - }); - item.getSearchField().setHint(LocaleController.getString("Search", R.string.Search)); - - listAdapter = new ListAdapter(getParentActivity()); - searchListViewAdapter = new SearchAdapter(getParentActivity()); - - fragmentView = new FrameLayout(getParentActivity()); - - LinearLayout emptyTextLayout = new LinearLayout(getParentActivity()); - emptyTextLayout.setVisibility(View.INVISIBLE); - emptyTextLayout.setOrientation(LinearLayout.VERTICAL); - ((FrameLayout) fragmentView).addView(emptyTextLayout); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) emptyTextLayout.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.gravity = Gravity.TOP; - emptyTextLayout.setLayoutParams(layoutParams); - emptyTextLayout.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return true; - } - }); - - emptyTextView = new TextView(getParentActivity()); - emptyTextView.setTextColor(0xff808080); - emptyTextView.setTextSize(20); - emptyTextView.setGravity(Gravity.CENTER); - emptyTextView.setText(LocaleController.getString("NoResult", R.string.NoResult)); - emptyTextLayout.addView(emptyTextView); - LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams) emptyTextView.getLayoutParams(); - layoutParams1.width = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams1.height = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams1.weight = 0.5f; - emptyTextView.setLayoutParams(layoutParams1); - - FrameLayout frameLayout = new FrameLayout(getParentActivity()); - emptyTextLayout.addView(frameLayout); - layoutParams1 = (LinearLayout.LayoutParams) frameLayout.getLayoutParams(); - layoutParams1.width = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams1.height = LinearLayout.LayoutParams.MATCH_PARENT; - layoutParams1.weight = 0.5f; - frameLayout.setLayoutParams(layoutParams1); - - listView = new ListView(getParentActivity()); - listView.setEmptyView(emptyTextLayout); - listView.setVerticalScrollBarEnabled(false); - listView.setDivider(null); - listView.setDividerHeight(0); - listView.setAdapter(listAdapter); - ((FrameLayout) fragmentView).addView(listView); - layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - listView.setLayoutParams(layoutParams); - - listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, int i, long l) { - LocaleController.LocaleInfo localeInfo = null; - if (searching && searchWas) { - if (i >= 0 && i < searchResult.size()) { - localeInfo = searchResult.get(i); - } - } else { - if (i >= 0 && i < LocaleController.getInstance().sortedLanguages.size()) { - localeInfo = LocaleController.getInstance().sortedLanguages.get(i); - } - } - if (localeInfo != null) { - LocaleController.getInstance().applyLanguage(localeInfo, true); - parentLayout.rebuildAllFragmentViews(false); - } + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { finishFragment(); } - }); + } + }); - listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { - @Override - public boolean onItemLongClick(AdapterView adapterView, View view, int i, long l) { - LocaleController.LocaleInfo localeInfo = null; - if (searching && searchWas) { - if (i >= 0 && i < searchResult.size()) { - localeInfo = searchResult.get(i); - } - } else { - if (i >= 0 && i < LocaleController.getInstance().sortedLanguages.size()) { - localeInfo = LocaleController.getInstance().sortedLanguages.get(i); - } + ActionBarMenu menu = actionBar.createMenu(); + ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true).setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() { + @Override + public void onSearchExpand() { + searching = true; + } + + @Override + public boolean onSearchCollapse() { + search(null); + searching = false; + searchWas = false; + if (listView != null) { + emptyTextView.setVisibility(View.GONE); + listView.setAdapter(listAdapter); + } + + return true; + } + + @Override + public void onTextChanged(EditText editText) { + String text = editText.getText().toString(); + search(text); + if (text.length() != 0) { + searchWas = true; + if (listView != null) { + listView.setAdapter(searchListViewAdapter); } - if (localeInfo == null || localeInfo.pathToFile == null || getParentActivity() == null) { - return false; + } + } + }); + item.getSearchField().setHint(LocaleController.getString("Search", R.string.Search)); + + listAdapter = new ListAdapter(context); + searchListViewAdapter = new SearchAdapter(context); + + fragmentView = new FrameLayout(context); + + LinearLayout emptyTextLayout = new LinearLayout(context); + emptyTextLayout.setVisibility(View.INVISIBLE); + emptyTextLayout.setOrientation(LinearLayout.VERTICAL); + ((FrameLayout) fragmentView).addView(emptyTextLayout); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) emptyTextLayout.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP; + emptyTextLayout.setLayoutParams(layoutParams); + emptyTextLayout.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + emptyTextView = new TextView(context); + emptyTextView.setTextColor(0xff808080); + emptyTextView.setTextSize(20); + emptyTextView.setGravity(Gravity.CENTER); + emptyTextView.setText(LocaleController.getString("NoResult", R.string.NoResult)); + emptyTextLayout.addView(emptyTextView); + LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams) emptyTextView.getLayoutParams(); + layoutParams1.width = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams1.height = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams1.weight = 0.5f; + emptyTextView.setLayoutParams(layoutParams1); + + FrameLayout frameLayout = new FrameLayout(context); + emptyTextLayout.addView(frameLayout); + layoutParams1 = (LinearLayout.LayoutParams) frameLayout.getLayoutParams(); + layoutParams1.width = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams1.height = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams1.weight = 0.5f; + frameLayout.setLayoutParams(layoutParams1); + + listView = new ListView(context); + listView.setEmptyView(emptyTextLayout); + listView.setVerticalScrollBarEnabled(false); + listView.setDivider(null); + listView.setDividerHeight(0); + listView.setAdapter(listAdapter); + ((FrameLayout) fragmentView).addView(listView); + layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + listView.setLayoutParams(layoutParams); + + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, int i, long l) { + LocaleController.LocaleInfo localeInfo = null; + if (searching && searchWas) { + if (i >= 0 && i < searchResult.size()) { + localeInfo = searchResult.get(i); } - final LocaleController.LocaleInfo finalLocaleInfo = localeInfo; - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setMessage(LocaleController.getString("DeleteLocalization", R.string.DeleteLocalization)); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(LocaleController.getString("Delete", R.string.Delete), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - if (LocaleController.getInstance().deleteLanguage(finalLocaleInfo)) { - if (searchResult != null) { - searchResult.remove(finalLocaleInfo); - } - if (listAdapter != null) { - listAdapter.notifyDataSetChanged(); - } - if (searchListViewAdapter != null) { - searchListViewAdapter.notifyDataSetChanged(); - } + } else { + if (i >= 0 && i < LocaleController.getInstance().sortedLanguages.size()) { + localeInfo = LocaleController.getInstance().sortedLanguages.get(i); + } + } + if (localeInfo != null) { + LocaleController.getInstance().applyLanguage(localeInfo, true); + parentLayout.rebuildAllFragmentViews(false); + } + finishFragment(); + } + }); + + listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView adapterView, View view, int i, long l) { + LocaleController.LocaleInfo localeInfo = null; + if (searching && searchWas) { + if (i >= 0 && i < searchResult.size()) { + localeInfo = searchResult.get(i); + } + } else { + if (i >= 0 && i < LocaleController.getInstance().sortedLanguages.size()) { + localeInfo = LocaleController.getInstance().sortedLanguages.get(i); + } + } + if (localeInfo == null || localeInfo.pathToFile == null || getParentActivity() == null) { + return false; + } + final LocaleController.LocaleInfo finalLocaleInfo = localeInfo; + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.getString("DeleteLocalization", R.string.DeleteLocalization)); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("Delete", R.string.Delete), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + if (LocaleController.getInstance().deleteLanguage(finalLocaleInfo)) { + if (searchResult != null) { + searchResult.remove(finalLocaleInfo); + } + if (listAdapter != null) { + listAdapter.notifyDataSetChanged(); + } + if (searchListViewAdapter != null) { + searchListViewAdapter.notifyDataSetChanged(); } } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - return true; - } - }); - - listView.setOnScrollListener(new AbsListView.OnScrollListener() { - @Override - public void onScrollStateChanged(AbsListView absListView, int i) { - if (i == SCROLL_STATE_TOUCH_SCROLL && searching && searchWas) { - AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); } - } - - @Override - public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - } - }); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + return true; } - } + }); + + listView.setOnScrollListener(new AbsListView.OnScrollListener() { + @Override + public void onScrollStateChanged(AbsListView absListView, int i) { + if (i == SCROLL_STATE_TOUCH_SCROLL && searching && searchWas) { + AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); + } + } + + @Override + public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { + } + }); + return fragmentView; } @@ -285,7 +281,7 @@ public class LanguageSelectActivity extends BaseFragment { return; } long time = System.currentTimeMillis(); - ArrayList resultArray = new ArrayList(); + ArrayList resultArray = new ArrayList<>(); for (LocaleController.LocaleInfo c : LocaleController.getInstance().sortedLanguages) { if (c.name.toLowerCase().startsWith(query) || c.nameEnglish.toLowerCase().startsWith(query)) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LastSeenActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LastSeenActivity.java index daefea9ca..b2c6096be 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LastSeenActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LastSeenActivity.java @@ -99,150 +99,144 @@ public class LastSeenActivity extends BaseFragment implements NotificationCenter } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - actionBar.setTitle(LocaleController.getString("PrivacyLastSeen", R.string.PrivacyLastSeen)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } else if (id == done_button) { - if (getParentActivity() == null) { - return; - } - - if (currentType != 0) { - final SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); - boolean showed = preferences.getBoolean("privacyAlertShowed", false); - if (!showed) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setMessage(LocaleController.getString("CustomHelp", R.string.CustomHelp)); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - applyCurrentPrivacySettings(); - preferences.edit().putBoolean("privacyAlertShowed", true).commit(); - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - return; - } - } - applyCurrentPrivacySettings(); + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + actionBar.setTitle(LocaleController.getString("PrivacyLastSeen", R.string.PrivacyLastSeen)); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } else if (id == done_button) { + if (getParentActivity() == null) { + return; } - } - }); - ActionBarMenu menu = actionBar.createMenu(); - doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); - doneButton.setVisibility(View.GONE); - - listAdapter = new ListAdapter(getParentActivity()); - - fragmentView = new FrameLayout(getParentActivity()); - FrameLayout frameLayout = (FrameLayout) fragmentView; - frameLayout.setBackgroundColor(0xfff0f0f0); - - ListView listView = new ListView(getParentActivity()); - listView.setDivider(null); - listView.setDividerHeight(0); - listView.setVerticalScrollBarEnabled(false); - listView.setDrawSelectorOnTop(true); - frameLayout.addView(listView); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.gravity = Gravity.TOP; - listView.setLayoutParams(layoutParams); - listView.setAdapter(listAdapter); - listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, final int i, long l) { - if (i == nobodyRow || i == everybodyRow || i == myContactsRow) { - int newType = currentType; - if (i == nobodyRow) { - newType = 1; - } else if (i == everybodyRow) { - newType = 0; - } else if (i == myContactsRow) { - newType = 2; - } - if (newType == currentType) { + if (currentType != 0) { + final SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + boolean showed = preferences.getBoolean("privacyAlertShowed", false); + if (!showed) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.getString("CustomHelp", R.string.CustomHelp)); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + applyCurrentPrivacySettings(); + preferences.edit().putBoolean("privacyAlertShowed", true).commit(); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); return; } - doneButton.setVisibility(View.VISIBLE); - currentType = newType; - updateRows(); - } else if (i == neverShareRow || i == alwaysShareRow) { - ArrayList createFromArray = null; - if (i == neverShareRow) { - createFromArray = currentMinus; - } else { - createFromArray = currentPlus; - } - if (createFromArray.isEmpty()) { - Bundle args = new Bundle(); - args.putBoolean(i == neverShareRow ? "isNeverShare" : "isAlwaysShare", true); - GroupCreateActivity fragment = new GroupCreateActivity(args); - fragment.setDelegate(new GroupCreateActivity.GroupCreateActivityDelegate() { - @Override - public void didSelectUsers(ArrayList ids) { - if (i == neverShareRow) { - currentMinus = ids; + } + applyCurrentPrivacySettings(); + } + } + }); + + ActionBarMenu menu = actionBar.createMenu(); + doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + doneButton.setVisibility(View.GONE); + + listAdapter = new ListAdapter(context); + + fragmentView = new FrameLayout(context); + FrameLayout frameLayout = (FrameLayout) fragmentView; + frameLayout.setBackgroundColor(0xfff0f0f0); + + ListView listView = new ListView(context); + listView.setDivider(null); + listView.setDividerHeight(0); + listView.setVerticalScrollBarEnabled(false); + listView.setDrawSelectorOnTop(true); + frameLayout.addView(listView); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP; + listView.setLayoutParams(layoutParams); + listView.setAdapter(listAdapter); + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, final int i, long l) { + if (i == nobodyRow || i == everybodyRow || i == myContactsRow) { + int newType = currentType; + if (i == nobodyRow) { + newType = 1; + } else if (i == everybodyRow) { + newType = 0; + } else if (i == myContactsRow) { + newType = 2; + } + if (newType == currentType) { + return; + } + doneButton.setVisibility(View.VISIBLE); + currentType = newType; + updateRows(); + } else if (i == neverShareRow || i == alwaysShareRow) { + ArrayList createFromArray = null; + if (i == neverShareRow) { + createFromArray = currentMinus; + } else { + createFromArray = currentPlus; + } + if (createFromArray.isEmpty()) { + Bundle args = new Bundle(); + args.putBoolean(i == neverShareRow ? "isNeverShare" : "isAlwaysShare", true); + GroupCreateActivity fragment = new GroupCreateActivity(args); + fragment.setDelegate(new GroupCreateActivity.GroupCreateActivityDelegate() { + @Override + public void didSelectUsers(ArrayList ids) { + if (i == neverShareRow) { + currentMinus = ids; + for (Integer id : currentMinus) { + currentPlus.remove(id); + } + } else { + currentPlus = ids; + for (Integer id : currentPlus) { + currentMinus.remove(id); + } + } + doneButton.setVisibility(View.VISIBLE); + listAdapter.notifyDataSetChanged(); + } + }); + presentFragment(fragment); + } else { + LastSeenUsersActivity fragment = new LastSeenUsersActivity(createFromArray, i == alwaysShareRow); + fragment.setDelegate(new LastSeenUsersActivity.LastSeenUsersActivityDelegate() { + @Override + public void didUpdatedUserList(ArrayList ids, boolean added) { + if (i == neverShareRow) { + currentMinus = ids; + if (added) { for (Integer id : currentMinus) { currentPlus.remove(id); } - } else { - currentPlus = ids; + } + } else { + currentPlus = ids; + if (added) { for (Integer id : currentPlus) { currentMinus.remove(id); } } - doneButton.setVisibility(View.VISIBLE); - listAdapter.notifyDataSetChanged(); } - }); - presentFragment(fragment); - } else { - LastSeenUsersActivity fragment = new LastSeenUsersActivity(createFromArray, i == alwaysShareRow); - fragment.setDelegate(new LastSeenUsersActivity.LastSeenUsersActivityDelegate() { - @Override - public void didUpdatedUserList(ArrayList ids, boolean added) { - if (i == neverShareRow) { - currentMinus = ids; - if (added) { - for (Integer id : currentMinus) { - currentPlus.remove(id); - } - } - } else { - currentPlus = ids; - if (added) { - for (Integer id : currentPlus) { - currentMinus.remove(id); - } - } - } - doneButton.setVisibility(View.VISIBLE); - listAdapter.notifyDataSetChanged(); - } - }); - presentFragment(fragment); - } + doneButton.setVisibility(View.VISIBLE); + listAdapter.notifyDataSetChanged(); + } + }); + presentFragment(fragment); } } - }); - } else { - ViewGroup parent = (ViewGroup) fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); } - } + }); + return fragmentView; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LastSeenUsersActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LastSeenUsersActivity.java index 4f8347b18..a0ce4a77e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LastSeenUsersActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LastSeenUsersActivity.java @@ -40,8 +40,8 @@ import java.util.ArrayList; public class LastSeenUsersActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate { - public static interface LastSeenUsersActivityDelegate { - public abstract void didUpdatedUserList(ArrayList ids, boolean added); + public interface LastSeenUsersActivityDelegate { + void didUpdatedUserList(ArrayList ids, boolean added); } private ListView listView; @@ -75,127 +75,121 @@ public class LastSeenUsersActivity extends BaseFragment implements NotificationC } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - if (isAlwaysShare) { - actionBar.setTitle(LocaleController.getString("AlwaysShareWithTitle", R.string.AlwaysShareWithTitle)); - } else { - actionBar.setTitle(LocaleController.getString("NeverShareWithTitle", R.string.NeverShareWithTitle)); - } - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } else if (id == block_user) { - Bundle args = new Bundle(); - args.putBoolean(isAlwaysShare ? "isAlwaysShare" : "isNeverShare", true); - GroupCreateActivity fragment = new GroupCreateActivity(args); - fragment.setDelegate(new GroupCreateActivity.GroupCreateActivityDelegate() { - @Override - public void didSelectUsers(ArrayList ids) { - for (Integer id : ids) { - if (uidArray.contains(id)) { - continue; - } - uidArray.add(id); - } - listViewAdapter.notifyDataSetChanged(); - if (delegate != null) { - delegate.didUpdatedUserList(uidArray, true); - } - } - }); - presentFragment(fragment); - } - } - }); - - ActionBarMenu menu = actionBar.createMenu(); - menu.addItem(block_user, R.drawable.plus); - - fragmentView = new FrameLayout(getParentActivity()); - FrameLayout frameLayout = (FrameLayout) fragmentView; - - TextView emptyTextView = new TextView(getParentActivity()); - emptyTextView.setTextColor(0xff808080); - emptyTextView.setTextSize(20); - emptyTextView.setGravity(Gravity.CENTER); - emptyTextView.setVisibility(View.INVISIBLE); - emptyTextView.setText(LocaleController.getString("NoContacts", R.string.NoContacts)); - frameLayout.addView(emptyTextView); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) emptyTextView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.gravity = Gravity.TOP; - emptyTextView.setLayoutParams(layoutParams); - emptyTextView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return true; - } - }); - - listView = new ListView(getParentActivity()); - listView.setEmptyView(emptyTextView); - listView.setVerticalScrollBarEnabled(false); - listView.setDivider(null); - listView.setDividerHeight(0); - listView.setAdapter(listViewAdapter = new ListAdapter(getParentActivity())); - if (Build.VERSION.SDK_INT >= 11) { - listView.setVerticalScrollbarPosition(LocaleController.isRTL ? ListView.SCROLLBAR_POSITION_LEFT : ListView.SCROLLBAR_POSITION_RIGHT); - } - frameLayout.addView(listView); - layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - listView.setLayoutParams(layoutParams); - - listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, int i, long l) { - if (i < uidArray.size()) { - Bundle args = new Bundle(); - args.putInt("user_id", uidArray.get(i)); - presentFragment(new ProfileActivity(args)); - } - } - }); - - listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { - @Override - public boolean onItemLongClick(AdapterView adapterView, View view, int i, long l) { - if (i < 0 || i >= uidArray.size() || getParentActivity() == null) { - return true; - } - selectedUserId = uidArray.get(i); - - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - CharSequence[] items = new CharSequence[] {LocaleController.getString("Delete", R.string.Delete)}; - builder.setItems(items, new DialogInterface.OnClickListener() { + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + if (isAlwaysShare) { + actionBar.setTitle(LocaleController.getString("AlwaysShareWithTitle", R.string.AlwaysShareWithTitle)); + } else { + actionBar.setTitle(LocaleController.getString("NeverShareWithTitle", R.string.NeverShareWithTitle)); + } + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } else if (id == block_user) { + Bundle args = new Bundle(); + args.putBoolean(isAlwaysShare ? "isAlwaysShare" : "isNeverShare", true); + GroupCreateActivity fragment = new GroupCreateActivity(args); + fragment.setDelegate(new GroupCreateActivity.GroupCreateActivityDelegate() { @Override - public void onClick(DialogInterface dialogInterface, int i) { - if (i == 0) { - uidArray.remove((Integer)selectedUserId); - listViewAdapter.notifyDataSetChanged(); - if (delegate != null) { - delegate.didUpdatedUserList(uidArray, false); + public void didSelectUsers(ArrayList ids) { + for (Integer id : ids) { + if (uidArray.contains(id)) { + continue; } + uidArray.add(id); + } + listViewAdapter.notifyDataSetChanged(); + if (delegate != null) { + delegate.didUpdatedUserList(uidArray, true); } } }); - showAlertDialog(builder); + presentFragment(fragment); + } + } + }); + + ActionBarMenu menu = actionBar.createMenu(); + menu.addItem(block_user, R.drawable.plus); + + fragmentView = new FrameLayout(context); + FrameLayout frameLayout = (FrameLayout) fragmentView; + + TextView emptyTextView = new TextView(context); + emptyTextView.setTextColor(0xff808080); + emptyTextView.setTextSize(20); + emptyTextView.setGravity(Gravity.CENTER); + emptyTextView.setVisibility(View.INVISIBLE); + emptyTextView.setText(LocaleController.getString("NoContacts", R.string.NoContacts)); + frameLayout.addView(emptyTextView); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) emptyTextView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP; + emptyTextView.setLayoutParams(layoutParams); + emptyTextView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + listView = new ListView(context); + listView.setEmptyView(emptyTextView); + listView.setVerticalScrollBarEnabled(false); + listView.setDivider(null); + listView.setDividerHeight(0); + listView.setAdapter(listViewAdapter = new ListAdapter(context)); + if (Build.VERSION.SDK_INT >= 11) { + listView.setVerticalScrollbarPosition(LocaleController.isRTL ? ListView.SCROLLBAR_POSITION_LEFT : ListView.SCROLLBAR_POSITION_RIGHT); + } + frameLayout.addView(listView); + layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + listView.setLayoutParams(layoutParams); + + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, int i, long l) { + if (i < uidArray.size()) { + Bundle args = new Bundle(); + args.putInt("user_id", uidArray.get(i)); + presentFragment(new ProfileActivity(args)); + } + } + }); + + listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView adapterView, View view, int i, long l) { + if (i < 0 || i >= uidArray.size() || getParentActivity() == null) { return true; } - }); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); + selectedUserId = uidArray.get(i); + + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + CharSequence[] items = new CharSequence[]{LocaleController.getString("Delete", R.string.Delete)}; + builder.setItems(items, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + if (i == 0) { + uidArray.remove((Integer) selectedUserId); + listViewAdapter.notifyDataSetChanged(); + if (delegate != null) { + delegate.didUpdatedUserList(uidArray, false); + } + } + } + }); + showAlertDialog(builder); + return true; } - } + }); + return fragmentView; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java index ea916e6af..e75d44830 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java @@ -59,6 +59,7 @@ import org.telegram.ui.Adapters.DrawerLayoutAdapter; import org.telegram.ui.ActionBar.ActionBarLayout; import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ActionBar.DrawerLayoutContainer; +import org.telegram.ui.Components.PasscodeView; import java.io.BufferedReader; import java.io.InputStream; @@ -89,14 +90,21 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa private ImageView backgroundTablet; private DrawerLayoutContainer drawerLayoutContainer; private DrawerLayoutAdapter drawerLayoutAdapter; + private PasscodeView passcodeView; + + private Intent passcodeSaveIntent; + private boolean passcodeSaveIntentIsNew; + private boolean passcodeSaveIntentIsRestore; private boolean tabletFullSize; + private Runnable lockRunnable; + @Override protected void onCreate(Bundle savedInstanceState) { ApplicationLoader.postInitApplication(); - if (!UserConfig.isClientActivated() && !UserConfig.isWaitingForPasswordEnter()) { + if (!UserConfig.isClientActivated()) { Intent intent = getIntent(); if (intent != null && intent.getAction() != null && (Intent.ACTION_SEND.equals(intent.getAction()) || intent.getAction().equals(Intent.ACTION_SEND_MULTIPLE))) { super.onCreate(savedInstanceState); @@ -122,6 +130,10 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa super.onCreate(savedInstanceState); + if (UserConfig.passcodeHash.length() != 0 && UserConfig.appLocked) { + UserConfig.lastPauseTime = ConnectionsManager.getInstance().getCurrentTime(); + } + int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { AndroidUtilities.statusBarHeight = getResources().getDimensionPixelSize(resourceId); @@ -193,7 +205,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa int viewX = location[0]; int viewY = location[1]; - if (x > viewX && x < viewX + layersActionBarLayout.getWidth() && y > viewY && y < viewY + layersActionBarLayout.getHeight()) { + if (layersActionBarLayout.checkTransitionAnimation() || x > viewX && x < viewX + layersActionBarLayout.getWidth() && y > viewY && y < viewY + layersActionBarLayout.getHeight()) { return false; } else { if (!layersActionBarLayout.fragmentsStack.isEmpty()) { @@ -224,7 +236,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa layersActionBarLayout.setBackgroundResource(R.drawable.boxshadow); launchLayout.addView(layersActionBarLayout); relativeLayoutParams = (RelativeLayout.LayoutParams)layersActionBarLayout.getLayoutParams(); - relativeLayoutParams.width = AndroidUtilities.dp(498); + relativeLayoutParams.width = AndroidUtilities.dp(530); relativeLayoutParams.height = AndroidUtilities.dp(528); layersActionBarLayout.setLayoutParams(relativeLayoutParams); layersActionBarLayout.init(layerFragmentsStack); @@ -254,6 +266,9 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa @Override public void onItemClick(AdapterView parent, View view, int position, long id) { if (position == 2) { + if (!MessagesController.isFeatureEnabled("chat_create", actionBarLayout.fragmentsStack.get(actionBarLayout.fragmentsStack.size() - 1))) { + return; + } presentFragment(new GroupCreateActivity()); drawerLayoutContainer.closeDrawer(false); } else if (position == 3) { @@ -264,6 +279,9 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa presentFragment(new ContactsActivity(args)); drawerLayoutContainer.closeDrawer(false); } else if (position == 4) { + if (!MessagesController.isFeatureEnabled("broadcast_create", actionBarLayout.fragmentsStack.get(actionBarLayout.fragmentsStack.size() - 1))) { + return; + } Bundle args = new Bundle(); args.putBoolean("broadcast", true); presentFragment(new GroupCreateActivity(args)); @@ -276,7 +294,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, ContactsController.getInstance().getInviteText()); - startActivity(Intent.createChooser(intent, "")); + startActivityForResult(Intent.createChooser(intent, LocaleController.getString("InviteFriends", R.string.InviteFriends)), 500); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -287,7 +305,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } else if (position == 9) { try { Intent pickIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(LocaleController.getString("TelegramFaqUrl", R.string.TelegramFaqUrl))); - startActivity(pickIntent); + startActivityForResult(pickIntent, 500); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -301,6 +319,15 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa actionBarLayout.init(mainFragmentsStack); actionBarLayout.setDelegate(this); + ApplicationLoader.loadWallpaper(); + + passcodeView = new PasscodeView(this); + drawerLayoutContainer.addView(passcodeView); + FrameLayout.LayoutParams layoutParams1 = (FrameLayout.LayoutParams) passcodeView.getLayoutParams(); + layoutParams1.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams1.height = FrameLayout.LayoutParams.MATCH_PARENT; + passcodeView.setLayoutParams(layoutParams1); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeOtherAppActivities, this); currentConnectionState = ConnectionsManager.getInstance().getConnectionState(); @@ -308,20 +335,19 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa NotificationCenter.getInstance().addObserver(this, NotificationCenter.mainUserInfoChanged); NotificationCenter.getInstance().addObserver(this, NotificationCenter.closeOtherAppActivities); NotificationCenter.getInstance().addObserver(this, NotificationCenter.didUpdatedConnectionState); - NotificationCenter.getInstance().addObserver(this, NotificationCenter.needPasswordEnter); + if (Build.VERSION.SDK_INT < 14) { + NotificationCenter.getInstance().addObserver(this, NotificationCenter.screenStateChanged); + } else { + NotificationCenter.getInstance().addObserver(this, NotificationCenter.appSwitchedToForeground); + } if (actionBarLayout.fragmentsStack.isEmpty()) { - if (!UserConfig.isClientActivated() && !UserConfig.isWaitingForPasswordEnter()) { + if (!UserConfig.isClientActivated()) { actionBarLayout.addFragmentToStack(new LoginActivity()); - drawerLayoutContainer.setAllowOpenDrawer(false); + drawerLayoutContainer.setAllowOpenDrawer(false, false); } else { - if (UserConfig.isWaitingForPasswordEnter()) { - actionBarLayout.addFragmentToStack(new AccountPasswordActivity(1)); - drawerLayoutContainer.setAllowOpenDrawer(false); - } else { - actionBarLayout.addFragmentToStack(new MessagesActivity(null)); - drawerLayoutContainer.setAllowOpenDrawer(true); - } + actionBarLayout.addFragmentToStack(new MessagesActivity(null)); + drawerLayoutContainer.setAllowOpenDrawer(true, false); } try { @@ -379,119 +405,254 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } else { allowOpen = actionBarLayout.fragmentsStack.size() <= 1; } - if (actionBarLayout.fragmentsStack.size() == 1 && (actionBarLayout.fragmentsStack.get(0) instanceof LoginActivity || actionBarLayout.fragmentsStack.get(0) instanceof AccountPasswordActivity)) { + if (actionBarLayout.fragmentsStack.size() == 1 && actionBarLayout.fragmentsStack.get(0) instanceof LoginActivity) { allowOpen = false; } - drawerLayoutContainer.setAllowOpenDrawer(allowOpen); + drawerLayoutContainer.setAllowOpenDrawer(allowOpen, false); } - handleIntent(getIntent(), false, savedInstanceState != null); + handleIntent(getIntent(), false, savedInstanceState != null, false); needLayout(); } - private void handleIntent(Intent intent, boolean isNew, boolean restore) { - boolean pushOpened = false; + private void showPasscodeActivity() { + if (passcodeView == null) { + return; + } + UserConfig.appLocked = true; + if (PhotoViewer.getInstance().isVisible()) { + PhotoViewer.getInstance().closePhoto(false, true); + } + passcodeView.onShow(); + UserConfig.isWaitingForPasscodeEnter = true; + drawerLayoutContainer.setAllowOpenDrawer(false, false); + passcodeView.setDelegate(new PasscodeView.PasscodeViewDelegate() { + @Override + public void didAcceptedPassword() { + UserConfig.isWaitingForPasscodeEnter = false; + if (passcodeSaveIntent != null) { + handleIntent(passcodeSaveIntent, passcodeSaveIntentIsNew, passcodeSaveIntentIsRestore, true); + passcodeSaveIntent = null; + } + drawerLayoutContainer.setAllowOpenDrawer(true, false); + actionBarLayout.showLastFragment(); + if (AndroidUtilities.isTablet()) { + layersActionBarLayout.showLastFragment(); + rightActionBarLayout.showLastFragment(); + } + } + }); + } - Integer push_user_id = 0; - Integer push_chat_id = 0; - Integer push_enc_id = 0; - Integer open_settings = 0; - boolean showDialogsList = false; + private boolean handleIntent(Intent intent, boolean isNew, boolean restore, boolean fromPassword) { + int flags = intent.getFlags(); + if (!fromPassword && (AndroidUtilities.needShowPasscode(true) || UserConfig.isWaitingForPasscodeEnter)) { + showPasscodeActivity(); + passcodeSaveIntent = intent; + passcodeSaveIntentIsNew = isNew; + passcodeSaveIntentIsRestore = restore; + UserConfig.saveConfig(false); + } else { + boolean pushOpened = false; - photoPathsArray = null; - videoPath = null; - sendingText = null; - documentsPathsArray = null; - documentsOriginalPathsArray = null; - documentsMimeType = null; - documentsUrisArray = null; - contactsToSend = null; + Integer push_user_id = 0; + Integer push_chat_id = 0; + Integer push_enc_id = 0; + Integer open_settings = 0; + boolean showDialogsList = false; - if (UserConfig.isClientActivated() && !UserConfig.isWaitingForPasswordEnter() && (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; - String type = intent.getType(); - if (type != null && (type.equals("text/plain") || type.equals("message/rfc822")) && (intent.getStringExtra(Intent.EXTRA_TEXT) != null || intent.getCharSequenceExtra(Intent.EXTRA_TEXT) != null)) { - String text = intent.getStringExtra(Intent.EXTRA_TEXT); - if (text == null) { - text = intent.getCharSequenceExtra(Intent.EXTRA_TEXT).toString(); - } - String subject = intent.getStringExtra(Intent.EXTRA_SUBJECT); + photoPathsArray = null; + videoPath = null; + sendingText = null; + documentsPathsArray = null; + documentsOriginalPathsArray = null; + documentsMimeType = null; + documentsUrisArray = null; + contactsToSend = null; - if (text != null && text.length() != 0) { - if ((text.startsWith("http://") || text.startsWith("https://")) && subject != null && subject.length() != 0) { - text = subject + "\n" + text; + if (UserConfig.isClientActivated() && (flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) { + if (intent != null && intent.getAction() != null && !restore) { + if (Intent.ACTION_SEND.equals(intent.getAction())) { + boolean error = false; + String type = intent.getType(); + if (type != null && (type.equals("text/plain") || type.equals("message/rfc822")) && (intent.getStringExtra(Intent.EXTRA_TEXT) != null || intent.getCharSequenceExtra(Intent.EXTRA_TEXT) != null)) { + String text = intent.getStringExtra(Intent.EXTRA_TEXT); + if (text == null) { + text = intent.getCharSequenceExtra(Intent.EXTRA_TEXT).toString(); } - sendingText = text; - } else { - error = true; - } - } else if (type != null && type.equals(ContactsContract.Contacts.CONTENT_VCARD_TYPE)) { - try { - Uri uri = (Uri) intent.getExtras().get(Intent.EXTRA_STREAM); - if (uri != null) { - ContentResolver cr = getContentResolver(); - InputStream stream = cr.openInputStream(uri); + String subject = intent.getStringExtra(Intent.EXTRA_SUBJECT); - String name = null; - String nameEncoding = null; - String nameCharset = null; - ArrayList phones = new ArrayList<>(); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream, "UTF-8")); - String line = null; - while ((line = bufferedReader.readLine()) != null) { - String[] args = line.split(":"); - if (args.length != 2) { - continue; + if (text != null && text.length() != 0) { + if ((text.startsWith("http://") || text.startsWith("https://")) && subject != null && subject.length() != 0) { + text = subject + "\n" + text; + } + sendingText = text; + } else { + error = true; + } + } else if (type != null && type.equals(ContactsContract.Contacts.CONTENT_VCARD_TYPE)) { + try { + Uri uri = (Uri) intent.getExtras().get(Intent.EXTRA_STREAM); + if (uri != null) { + ContentResolver cr = getContentResolver(); + InputStream stream = cr.openInputStream(uri); + + String name = null; + String nameEncoding = null; + String nameCharset = null; + ArrayList phones = new ArrayList<>(); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream, "UTF-8")); + String line = null; + while ((line = bufferedReader.readLine()) != null) { + String[] args = line.split(":"); + if (args.length != 2) { + continue; + } + if (args[0].startsWith("FN")) { + String[] params = args[0].split(";"); + for (String param : params) { + String[] args2 = param.split("="); + if (args2.length != 2) { + continue; + } + if (args2[0].equals("CHARSET")) { + nameCharset = args2[1]; + } else if (args2[0].equals("ENCODING")) { + nameEncoding = args2[1]; + } + } + name = args[1]; + if (nameEncoding != null && nameEncoding.equalsIgnoreCase("QUOTED-PRINTABLE")) { + while (name.endsWith("=") && nameEncoding != null) { + name = name.substring(0, name.length() - 1); + line = bufferedReader.readLine(); + if (line == null) { + break; + } + name += line; + } + byte[] bytes = Utilities.decodeQuotedPrintable(name.getBytes()); + if (bytes != null && bytes.length != 0) { + String decodedName = new String(bytes, nameCharset); + if (decodedName != null) { + name = decodedName; + } + } + } + } else if (args[0].startsWith("TEL")) { + String phone = PhoneFormat.stripExceptNumbers(args[1], true); + if (phone.length() > 0) { + phones.add(phone); + } + } } - if (args[0].startsWith("FN")) { - String[] params = args[0].split(";"); - for (String param : params) { - String[] args2 = param.split("="); - if (args2.length != 2) { - continue; - } - if (args2[0].equals("CHARSET")) { - nameCharset = args2[1]; - } else if (args2[0].equals("ENCODING")) { - nameEncoding = args2[1]; - } + try { + bufferedReader.close(); + stream.close(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + if (name != null && !phones.isEmpty()) { + contactsToSend = new ArrayList<>(); + for (String phone : phones) { + TLRPC.User user = new TLRPC.TL_userContact(); + user.phone = phone; + user.first_name = name; + user.last_name = ""; + user.id = 0; + contactsToSend.add(user); } - name = args[1]; - if (nameEncoding != null && nameEncoding.equalsIgnoreCase("QUOTED-PRINTABLE")) { - while (name.endsWith("=") && nameEncoding != null) { - name = name.substring(0, name.length() - 1); - line = bufferedReader.readLine(); - if (line == null) { - break; - } - name += line; - } - byte[] bytes = Utilities.decodeQuotedPrintable(name.getBytes()); - if (bytes != null && bytes.length != 0) { - String decodedName = new String(bytes, nameCharset); - if (decodedName != null) { - name = decodedName; - } - } + } + } else { + error = true; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + error = true; + } + } else { + Parcelable parcelable = intent.getParcelableExtra(Intent.EXTRA_STREAM); + if (parcelable != null) { + String path = null; + if (!(parcelable instanceof Uri)) { + parcelable = Uri.parse(parcelable.toString()); + } + Uri uri = (Uri) parcelable; + if (uri != null && type != null && type.startsWith("image/")) { + String tempPath = Utilities.getPath(uri); + if (photoPathsArray == null) { + photoPathsArray = new ArrayList<>(); + } + photoPathsArray.add(uri); + } else { + path = Utilities.getPath(uri); + if (path != null) { + if (path.startsWith("file:")) { + path = path.replace("file://", ""); } - } else if (args[0].startsWith("TEL")) { - String phone = PhoneFormat.stripExceptNumbers(args[1], true); - if (phone.length() > 0) { - phones.add(phone); + if (type != null && type.startsWith("video/")) { + videoPath = path; + } else { + if (documentsPathsArray == null) { + documentsPathsArray = new ArrayList<>(); + documentsOriginalPathsArray = new ArrayList<>(); + } + documentsPathsArray.add(path); + documentsOriginalPathsArray.add(uri.toString()); } + } else { + if (documentsUrisArray == null) { + documentsUrisArray = new ArrayList<>(); + } + documentsUrisArray.add(uri); + documentsMimeType = type; } } - if (name != null && !phones.isEmpty()) { - contactsToSend = new ArrayList<>(); - for (String phone : phones) { - TLRPC.User user = new TLRPC.TL_userContact(); - user.phone = phone; - user.first_name = name; - user.last_name = ""; - user.id = 0; - contactsToSend.add(user); + } else { + error = true; + } + if (error) { + Toast.makeText(this, "Unsupported content", Toast.LENGTH_SHORT).show(); + } + } + } else if (intent.getAction().equals(Intent.ACTION_SEND_MULTIPLE)) { + boolean error = false; + try { + ArrayList uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); + String type = intent.getType(); + if (uris != null) { + if (type != null && type.startsWith("image/")) { + for (Parcelable parcelable : uris) { + if (!(parcelable instanceof Uri)) { + parcelable = Uri.parse(parcelable.toString()); + } + Uri uri = (Uri) parcelable; + if (photoPathsArray == null) { + photoPathsArray = new ArrayList<>(); + } + photoPathsArray.add(uri); + } + } else { + for (Parcelable parcelable : uris) { + if (!(parcelable instanceof Uri)) { + parcelable = Uri.parse(parcelable.toString()); + } + String path = Utilities.getPath((Uri) parcelable); + String originalPath = parcelable.toString(); + if (originalPath == null) { + originalPath = path; + } + if (path != null) { + if (path.startsWith("file:")) { + path = path.replace("file://", ""); + } + if (documentsPathsArray == null) { + documentsPathsArray = new ArrayList<>(); + documentsOriginalPathsArray = new ArrayList<>(); + } + documentsPathsArray.add(path); + documentsOriginalPathsArray.add(originalPath); + } } } } else { @@ -501,335 +662,241 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa FileLog.e("tmessages", e); error = true; } - } else { - Parcelable parcelable = intent.getParcelableExtra(Intent.EXTRA_STREAM); - if (parcelable != null) { - String path = null; - if (!(parcelable instanceof Uri)) { - parcelable = Uri.parse(parcelable.toString()); - } - Uri uri = (Uri) parcelable; - if (uri != null && type != null && type.startsWith("image/")) { - String tempPath = Utilities.getPath(uri); - if (photoPathsArray == null) { - photoPathsArray = new ArrayList<>(); - } - photoPathsArray.add(uri); - } else { - path = Utilities.getPath(uri); - if (path != null) { - if (path.startsWith("file:")) { - path = path.replace("file://", ""); - } - if (type != null && type.startsWith("video/")) { - videoPath = path; - } else { - if (documentsPathsArray == null) { - documentsPathsArray = new ArrayList<>(); - documentsOriginalPathsArray = new ArrayList<>(); - } - documentsPathsArray.add(path); - documentsOriginalPathsArray.add(uri.toString()); - } - } else { - if (documentsUrisArray == null) { - documentsUrisArray = new ArrayList<>(); - } - documentsUrisArray.add(uri); - documentsMimeType = type; - } - } - } else { - error = true; - } if (error) { Toast.makeText(this, "Unsupported content", Toast.LENGTH_SHORT).show(); } - } - } else if (intent.getAction().equals(Intent.ACTION_SEND_MULTIPLE)) { - boolean error = false; - try { - ArrayList uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); - String type = intent.getType(); - if (uris != null) { - if (type != null && type.startsWith("image/")) { - for (Parcelable parcelable : uris) { - if (!(parcelable instanceof Uri)) { - parcelable = Uri.parse(parcelable.toString()); - } - Uri uri = (Uri) parcelable; - if (photoPathsArray == null) { - photoPathsArray = new ArrayList<>(); - } - photoPathsArray.add(uri); - } - } else { - for (Parcelable parcelable : uris) { - if (!(parcelable instanceof Uri)) { - parcelable = Uri.parse(parcelable.toString()); - } - String path = Utilities.getPath((Uri) parcelable); - String originalPath = parcelable.toString(); - if (originalPath == null) { - originalPath = path; - } - if (path != null) { - if (path.startsWith("file:")) { - path = path.replace("file://", ""); + } else if (Intent.ACTION_VIEW.equals(intent.getAction())) { + 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().toLowerCase(); + if (host.equals("telegram.me")) { + String path = data.getPath(); + if (path != null && path.length() >= 6) { + username = path.substring(1); } - if (documentsPathsArray == null) { - documentsPathsArray = new ArrayList<>(); - documentsOriginalPathsArray = new ArrayList<>(); - } - documentsPathsArray.add(path); - documentsOriginalPathsArray.add(originalPath); + } + } else if (scheme.equals("tg")) { + String url = data.toString().toLowerCase(); + 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"); } } } - } else { - error = true; - } - } catch (Exception e) { - FileLog.e("tmessages", e); - error = true; - } - if (error) { - Toast.makeText(this, "Unsupported content", Toast.LENGTH_SHORT).show(); - } - } else if (Intent.ACTION_VIEW.equals(intent.getAction())) { - 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().toLowerCase(); - 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().toLowerCase(); - 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); + 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); + 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.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; + }); + 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(); } - cursor.close(); + } catch (Exception e) { + FileLog.e("tmessages", e); } - } catch (Exception e) { - FileLog.e("tmessages", e); } } - } - } else if (intent.getAction().equals("org.telegram.messenger.OPEN_ACCOUNT")) { - open_settings = 1; - } 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; + } else if (intent.getAction().equals("org.telegram.messenger.OPEN_ACCOUNT")) { + open_settings = 1; + } 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; + } } } } - } - if (push_user_id != 0) { - if (push_user_id == UserConfig.getClientUserId()) { - open_settings = 1; - } else { + if (push_user_id != 0) { + if (push_user_id == UserConfig.getClientUserId()) { + open_settings = 1; + } else { + Bundle args = new Bundle(); + args.putInt("user_id", push_user_id); + ChatActivity fragment = new ChatActivity(args); + if (actionBarLayout.presentFragment(fragment, false, true, true)) { + pushOpened = true; + } + } + } else if (push_chat_id != 0) { Bundle args = new Bundle(); - args.putInt("user_id", push_user_id); + args.putInt("chat_id", push_chat_id); ChatActivity fragment = new ChatActivity(args); if (actionBarLayout.presentFragment(fragment, false, true, true)) { pushOpened = true; } - } - } else if (push_chat_id != 0) { - Bundle args = new Bundle(); - args.putInt("chat_id", push_chat_id); - ChatActivity fragment = new ChatActivity(args); - if (actionBarLayout.presentFragment(fragment, false, true, true)) { - pushOpened = true; - } - } else if (push_enc_id != 0) { - Bundle args = new Bundle(); - args.putInt("enc_id", push_enc_id); - ChatActivity fragment = new ChatActivity(args); - if (actionBarLayout.presentFragment(fragment, false, true, true)) { - pushOpened = true; - } - } else if (showDialogsList) { - if (!AndroidUtilities.isTablet()) { - actionBarLayout.removeAllFragments(); - } else { - if (!layersActionBarLayout.fragmentsStack.isEmpty()) { - for (int a = 0; a < layersActionBarLayout.fragmentsStack.size() - 1; a++) { - layersActionBarLayout.removeFragmentFromStack(layersActionBarLayout.fragmentsStack.get(0)); - a--; - } - layersActionBarLayout.closeLastFragment(false); + } else if (push_enc_id != 0) { + Bundle args = new Bundle(); + args.putInt("enc_id", push_enc_id); + ChatActivity fragment = new ChatActivity(args); + if (actionBarLayout.presentFragment(fragment, false, true, true)) { + pushOpened = true; } - } - pushOpened = false; - isNew = false; - } else if (videoPath != null || photoPathsArray != null || sendingText != null || documentsPathsArray != null || contactsToSend != null || documentsUrisArray != null) { - if (!AndroidUtilities.isTablet()) { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); - } - Bundle args = new Bundle(); - args.putBoolean("onlySelect", true); - args.putString("selectAlertString", LocaleController.getString("SendMessagesTo", R.string.SendMessagesTo)); - args.putString("selectAlertStringGroup", LocaleController.getString("SendMessagesToGroup", R.string.SendMessagesToGroup)); - MessagesActivity fragment = new MessagesActivity(args); - fragment.setDelegate(this); - boolean removeLast = false; - if (AndroidUtilities.isTablet()) { - removeLast = layersActionBarLayout.fragmentsStack.size() > 0 && layersActionBarLayout.fragmentsStack.get(layersActionBarLayout.fragmentsStack.size() - 1) instanceof MessagesActivity; - } else { - removeLast = actionBarLayout.fragmentsStack.size() > 1 && actionBarLayout.fragmentsStack.get(actionBarLayout.fragmentsStack.size() - 1) instanceof MessagesActivity; - } - actionBarLayout.presentFragment(fragment, removeLast, true, true); - pushOpened = true; - if (PhotoViewer.getInstance().isVisible()) { - PhotoViewer.getInstance().closePhoto(false); + } else if (showDialogsList) { + if (!AndroidUtilities.isTablet()) { + actionBarLayout.removeAllFragments(); + } else { + if (!layersActionBarLayout.fragmentsStack.isEmpty()) { + for (int a = 0; a < layersActionBarLayout.fragmentsStack.size() - 1; a++) { + layersActionBarLayout.removeFragmentFromStack(layersActionBarLayout.fragmentsStack.get(0)); + a--; + } + layersActionBarLayout.closeLastFragment(false); + } + } + pushOpened = false; + isNew = false; + } else if (videoPath != null || photoPathsArray != null || sendingText != null || documentsPathsArray != null || contactsToSend != null || documentsUrisArray != null) { + if (!AndroidUtilities.isTablet()) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); + } + Bundle args = new Bundle(); + args.putBoolean("onlySelect", true); + args.putString("selectAlertString", LocaleController.getString("SendMessagesTo", R.string.SendMessagesTo)); + args.putString("selectAlertStringGroup", LocaleController.getString("SendMessagesToGroup", R.string.SendMessagesToGroup)); + MessagesActivity fragment = new MessagesActivity(args); + fragment.setDelegate(this); + boolean removeLast = false; + if (AndroidUtilities.isTablet()) { + removeLast = layersActionBarLayout.fragmentsStack.size() > 0 && layersActionBarLayout.fragmentsStack.get(layersActionBarLayout.fragmentsStack.size() - 1) instanceof MessagesActivity; + } else { + removeLast = actionBarLayout.fragmentsStack.size() > 1 && actionBarLayout.fragmentsStack.get(actionBarLayout.fragmentsStack.size() - 1) instanceof MessagesActivity; + } + actionBarLayout.presentFragment(fragment, removeLast, true, true); + pushOpened = true; + if (PhotoViewer.getInstance().isVisible()) { + PhotoViewer.getInstance().closePhoto(false, true); + } + + drawerLayoutContainer.setAllowOpenDrawer(false, false); + if (AndroidUtilities.isTablet()) { + actionBarLayout.showLastFragment(); + rightActionBarLayout.showLastFragment(); + } else { + drawerLayoutContainer.setAllowOpenDrawer(true, false); + } + } else if (open_settings != 0) { + actionBarLayout.presentFragment(new SettingsActivity(), false, true, true); + if (AndroidUtilities.isTablet()) { + actionBarLayout.showLastFragment(); + rightActionBarLayout.showLastFragment(); + drawerLayoutContainer.setAllowOpenDrawer(false, false); + } else { + drawerLayoutContainer.setAllowOpenDrawer(true, false); + } + pushOpened = true; } - if (AndroidUtilities.isTablet()) { - actionBarLayout.showLastFragment(); - rightActionBarLayout.showLastFragment(); - } - drawerLayoutContainer.setAllowOpenDrawer(false); - } else if (open_settings != 0) { - actionBarLayout.presentFragment(new SettingsActivity(), false, true, true); - drawerLayoutContainer.setAllowOpenDrawer(false); - if (AndroidUtilities.isTablet()) { - actionBarLayout.showLastFragment(); - rightActionBarLayout.showLastFragment(); - } - pushOpened = true; - } - if (!pushOpened && !isNew) { - if (AndroidUtilities.isTablet()) { - if (!UserConfig.isClientActivated() && !UserConfig.isWaitingForPasswordEnter()) { - if (layersActionBarLayout.fragmentsStack.isEmpty()) { - layersActionBarLayout.addFragmentToStack(new LoginActivity()); - drawerLayoutContainer.setAllowOpenDrawer(false); + if (!pushOpened && !isNew) { + if (AndroidUtilities.isTablet()) { + if (!UserConfig.isClientActivated()) { + if (layersActionBarLayout.fragmentsStack.isEmpty()) { + layersActionBarLayout.addFragmentToStack(new LoginActivity()); + drawerLayoutContainer.setAllowOpenDrawer(false, false); + } + } else { + if (actionBarLayout.fragmentsStack.isEmpty()) { + actionBarLayout.addFragmentToStack(new MessagesActivity(null)); + drawerLayoutContainer.setAllowOpenDrawer(true, false); + } } } else { if (actionBarLayout.fragmentsStack.isEmpty()) { - if (UserConfig.isWaitingForPasswordEnter()) { - layersActionBarLayout.addFragmentToStack(new AccountPasswordActivity(1)); - drawerLayoutContainer.setAllowOpenDrawer(false); + if (!UserConfig.isClientActivated()) { + actionBarLayout.addFragmentToStack(new LoginActivity()); + drawerLayoutContainer.setAllowOpenDrawer(false, false); } else { actionBarLayout.addFragmentToStack(new MessagesActivity(null)); - drawerLayoutContainer.setAllowOpenDrawer(true); + drawerLayoutContainer.setAllowOpenDrawer(true, false); } } } - } else { - if (actionBarLayout.fragmentsStack.isEmpty()) { - if (!UserConfig.isClientActivated() && !UserConfig.isWaitingForPasswordEnter()) { - actionBarLayout.addFragmentToStack(new LoginActivity()); - drawerLayoutContainer.setAllowOpenDrawer(false); - } else { - if (UserConfig.isWaitingForPasswordEnter()) { - actionBarLayout.addFragmentToStack(new AccountPasswordActivity(1)); - drawerLayoutContainer.setAllowOpenDrawer(false); - } else { - actionBarLayout.addFragmentToStack(new MessagesActivity(null)); - drawerLayoutContainer.setAllowOpenDrawer(true); - } - } + actionBarLayout.showLastFragment(); + if (AndroidUtilities.isTablet()) { + layersActionBarLayout.showLastFragment(); + rightActionBarLayout.showLastFragment(); } } - actionBarLayout.showLastFragment(); - if (AndroidUtilities.isTablet()) { - layersActionBarLayout.showLastFragment(); - rightActionBarLayout.showLastFragment(); - } - } - intent.setAction(null); + intent.setAction(null); + return pushOpened; + } + return false; } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); - handleIntent(intent, true, false); + handleIntent(intent, true, false, false); } @Override @@ -875,7 +942,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } } else { actionBarLayout.presentFragment(fragment, true); - SendMessagesHelper.prepareSendingVideo(videoPath, 0, 0, 0, 0, null, dialog_id); + SendMessagesHelper.prepareSendingVideo(videoPath, 0, 0, 0, 0, null, dialog_id, null); } } else { actionBarLayout.presentFragment(fragment, true); @@ -884,14 +951,14 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa fragment.processSendingText(sendingText); } if (photoPathsArray != null) { - SendMessagesHelper.prepareSendingPhotos(null, photoPathsArray, dialog_id); + SendMessagesHelper.prepareSendingPhotos(null, photoPathsArray, dialog_id, null); } if (documentsPathsArray != null || documentsUrisArray != null) { - SendMessagesHelper.prepareSendingDocuments(documentsPathsArray, documentsOriginalPathsArray, documentsUrisArray, documentsMimeType, dialog_id); + SendMessagesHelper.prepareSendingDocuments(documentsPathsArray, documentsOriginalPathsArray, documentsUrisArray, documentsMimeType, dialog_id, null); } if (contactsToSend != null && !contactsToSend.isEmpty()) { for (TLRPC.User user : contactsToSend) { - SendMessagesHelper.getInstance().sendMessage(user, dialog_id); + SendMessagesHelper.getInstance().sendMessage(user, dialog_id, null); } } } @@ -910,11 +977,19 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa return; } finished = true; + if (lockRunnable != null) { + AndroidUtilities.cancelRunOnUIThread(lockRunnable); + lockRunnable = null; + } NotificationCenter.getInstance().removeObserver(this, NotificationCenter.appDidLogout); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.mainUserInfoChanged); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.closeOtherAppActivities); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.didUpdatedConnectionState); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.needPasswordEnter); + if (Build.VERSION.SDK_INT < 14) { + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.screenStateChanged); + } else { + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.appSwitchedToForeground); + } } public void presentFragment(BaseFragment fragment) { @@ -960,9 +1035,11 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa BaseFragment chatFragment = actionBarLayout.fragmentsStack.get(1); chatFragment.onPause(); actionBarLayout.fragmentsStack.remove(1); - actionBarLayout.showLastFragment(); rightActionBarLayout.fragmentsStack.add(chatFragment); - rightActionBarLayout.showLastFragment(); + if (passcodeView.getVisibility() != View.VISIBLE) { + actionBarLayout.showLastFragment(); + rightActionBarLayout.showLastFragment(); + } } rightActionBarLayout.setVisibility(rightActionBarLayout.fragmentsStack.isEmpty() ? View.GONE : View.VISIBLE); @@ -984,7 +1061,10 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa BaseFragment chatFragment = rightActionBarLayout.fragmentsStack.get(0); chatFragment.onPause(); rightActionBarLayout.fragmentsStack.remove(0); - actionBarLayout.presentFragment(chatFragment, false, true, false); + actionBarLayout.addFragmentToStack(chatFragment); + if (passcodeView.getVisibility() != View.VISIBLE) { + actionBarLayout.showLastFragment(); + } } } } @@ -1013,6 +1093,10 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (UserConfig.passcodeHash.length() != 0 && UserConfig.lastPauseTime != 0) { + UserConfig.lastPauseTime = 0; + UserConfig.saveConfig(false); + } super.onActivityResult(requestCode, resultCode, data); if (actionBarLayout.fragmentsStack.size() != 0) { BaseFragment fragment = actionBarLayout.fragmentsStack.get(actionBarLayout.fragmentsStack.size() - 1); @@ -1033,6 +1117,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa @Override protected void onPause() { super.onPause(); + onPasscodePause(); actionBarLayout.onPause(); if (AndroidUtilities.isTablet()) { rightActionBarLayout.onPause(); @@ -1053,10 +1138,15 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa @Override protected void onResume() { super.onResume(); - actionBarLayout.onResume(); - if (AndroidUtilities.isTablet()) { - rightActionBarLayout.onResume(); - layersActionBarLayout.onResume(); + onPasscodeResume(); + if (passcodeView.getVisibility() != View.VISIBLE) { + actionBarLayout.onResume(); + if (AndroidUtilities.isTablet()) { + rightActionBarLayout.onResume(); + layersActionBarLayout.onResume(); + } + } else { + passcodeView.onResume(); } Utilities.checkForCrashes(this); Utilities.checkForUpdates(this); @@ -1100,6 +1190,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } else if (id == NotificationCenter.closeOtherAppActivities) { if (args[0] != this) { onFinish(); + finish(); } } else if (id == NotificationCenter.didUpdatedConnectionState) { int state = (Integer)args[0]; @@ -1110,28 +1201,62 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } } else if (id == NotificationCenter.mainUserInfoChanged) { drawerLayoutAdapter.notifyDataSetChanged(); - } else if (id == NotificationCenter.needPasswordEnter) { - if (AndroidUtilities.isTablet()) { - for (int a = 0; a < layersActionBarLayout.fragmentsStack.size() - 1; a++) { - layersActionBarLayout.removeFragmentFromStack(layersActionBarLayout.fragmentsStack.get(0)); - a--; + } else if (id == NotificationCenter.screenStateChanged) { + if (!ApplicationLoader.mainInterfacePaused) { + if (!ApplicationLoader.isScreenOn) { + onPasscodePause(); + } else { + onPasscodeResume(); } - for (int a = 0; a < actionBarLayout.fragmentsStack.size() - 1; a++) { - actionBarLayout.removeFragmentFromStack(actionBarLayout.fragmentsStack.get(0)); - a--; - } - rightActionBarLayout.closeLastFragment(false); - actionBarLayout.closeLastFragment(false); - layersActionBarLayout.presentFragment(new AccountPasswordActivity(1), false, true, true); - drawerLayoutContainer.setAllowOpenDrawer(false); - } else { - for (int a = 0; a < actionBarLayout.fragmentsStack.size() - 1; a++) { - actionBarLayout.removeFragmentFromStack(actionBarLayout.fragmentsStack.get(0)); - a--; - } - actionBarLayout.presentFragment(new AccountPasswordActivity(1), true); - drawerLayoutContainer.setAllowOpenDrawer(false); } + } else if (id == NotificationCenter.appSwitchedToForeground) { + onPasscodeResume(); + } + } + + private void onPasscodePause() { + if (lockRunnable != null) { + AndroidUtilities.cancelRunOnUIThread(lockRunnable); + lockRunnable = null; + } + if (UserConfig.passcodeHash.length() != 0) { + UserConfig.lastPauseTime = ConnectionsManager.getInstance().getCurrentTime(); + lockRunnable = new Runnable() { + @Override + public void run() { + if (lockRunnable == this) { + if (AndroidUtilities.needShowPasscode(true)) { + FileLog.e("tmessages", "lock app"); + showPasscodeActivity(); + } else { + FileLog.e("tmessages", "didn't pass lock check"); + } + lockRunnable = null; + } + } + }; + if (UserConfig.appLocked) { + AndroidUtilities.runOnUIThread(lockRunnable, 1000); + } else if (UserConfig.autoLockIn != 0) { + AndroidUtilities.runOnUIThread(lockRunnable, (long) UserConfig.autoLockIn * 1000 + 1000); + } + } else { + UserConfig.lastPauseTime = 0; + } + UserConfig.saveConfig(false); + } + + private void onPasscodeResume() { + if (lockRunnable != null) { + AndroidUtilities.cancelRunOnUIThread(lockRunnable); + lockRunnable = null; + } + if (AndroidUtilities.needShowPasscode(true)) { + showPasscodeActivity(); + } + if (UserConfig.lastPauseTime != 0) { + UserConfig.lastPauseTime = 0; + UserConfig.saveConfig(false); } } @@ -1191,8 +1316,12 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa @Override public void onBackPressed() { + if (passcodeView.getVisibility() == View.VISIBLE) { + finish(); + return; + } if (PhotoViewer.getInstance().isVisible()) { - PhotoViewer.getInstance().closePhoto(true); + PhotoViewer.getInstance().closePhoto(true, false); } else if (drawerLayoutContainer.isDrawerOpened()) { drawerLayoutContainer.closeDrawer(false); } else if (AndroidUtilities.isTablet()) { @@ -1246,7 +1375,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa @Override public boolean onPreIme() { if (PhotoViewer.getInstance().isVisible()) { - PhotoViewer.getInstance().closePhoto(true); + PhotoViewer.getInstance().closePhoto(true, false); return true; } return false; @@ -1266,6 +1395,9 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } else { if (actionBarLayout.fragmentsStack.size() == 1) { if (!drawerLayoutContainer.isDrawerOpened()) { + if (getCurrentFocus() != null) { + AndroidUtilities.hideKeyboard(getCurrentFocus()); + } drawerLayoutContainer.openDrawer(false); } else { drawerLayoutContainer.closeDrawer(false); @@ -1281,15 +1413,15 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa @Override public boolean needPresentFragment(BaseFragment fragment, boolean removeLast, boolean forceWithoutAnimation, ActionBarLayout layout) { if (AndroidUtilities.isTablet()) { - drawerLayoutContainer.setAllowOpenDrawer(!(fragment instanceof AccountPasswordActivity) && !(fragment instanceof LoginActivity) && layersActionBarLayout.getVisibility() != View.VISIBLE); + drawerLayoutContainer.setAllowOpenDrawer(!(fragment instanceof LoginActivity) && layersActionBarLayout.getVisibility() != View.VISIBLE, true); if (fragment instanceof MessagesActivity) { MessagesActivity messagesActivity = (MessagesActivity)fragment; - if (messagesActivity.getDelegate() == null && layout != actionBarLayout) { + if (messagesActivity.isMainDialogList() && layout != actionBarLayout) { actionBarLayout.removeAllFragments(); actionBarLayout.presentFragment(fragment, removeLast, forceWithoutAnimation, false); layersActionBarLayout.removeAllFragments(); layersActionBarLayout.setVisibility(View.GONE); - drawerLayoutContainer.setAllowOpenDrawer(true); + drawerLayoutContainer.setAllowOpenDrawer(true, false); if (!tabletFullSize) { shadowTabletSide.setVisibility(View.VISIBLE); if (rightActionBarLayout.fragmentsStack.isEmpty()) { @@ -1349,8 +1481,8 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } } else if (layout != layersActionBarLayout) { layersActionBarLayout.setVisibility(View.VISIBLE); - drawerLayoutContainer.setAllowOpenDrawer(false); - if (fragment instanceof LoginActivity || fragment instanceof AccountPasswordActivity) { + drawerLayoutContainer.setAllowOpenDrawer(false, true); + if (fragment instanceof LoginActivity) { backgroundTablet.setVisibility(View.VISIBLE); shadowTabletSide.setVisibility(View.GONE); shadowTablet.setBackgroundColor(0x00000000); @@ -1362,7 +1494,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } return true; } else { - drawerLayoutContainer.setAllowOpenDrawer(!(fragment instanceof LoginActivity) && !(fragment instanceof AccountPasswordActivity)); + drawerLayoutContainer.setAllowOpenDrawer(!(fragment instanceof LoginActivity), false); return true; } } @@ -1370,15 +1502,15 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa @Override public boolean needAddFragmentToStack(BaseFragment fragment, ActionBarLayout layout) { if (AndroidUtilities.isTablet()) { - drawerLayoutContainer.setAllowOpenDrawer(!(fragment instanceof LoginActivity) && !(fragment instanceof AccountPasswordActivity) && layersActionBarLayout.getVisibility() != View.VISIBLE); + drawerLayoutContainer.setAllowOpenDrawer(!(fragment instanceof LoginActivity) && layersActionBarLayout.getVisibility() != View.VISIBLE, true); if (fragment instanceof MessagesActivity) { MessagesActivity messagesActivity = (MessagesActivity)fragment; - if (messagesActivity.getDelegate() == null && layout != actionBarLayout) { + if (messagesActivity.isMainDialogList() && layout != actionBarLayout) { actionBarLayout.removeAllFragments(); actionBarLayout.addFragmentToStack(fragment); layersActionBarLayout.removeAllFragments(); layersActionBarLayout.setVisibility(View.GONE); - drawerLayoutContainer.setAllowOpenDrawer(true); + drawerLayoutContainer.setAllowOpenDrawer(true, false); if (!tabletFullSize) { shadowTabletSide.setVisibility(View.VISIBLE); if (rightActionBarLayout.fragmentsStack.isEmpty()) { @@ -1414,8 +1546,8 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } } else if (layout != layersActionBarLayout) { layersActionBarLayout.setVisibility(View.VISIBLE); - drawerLayoutContainer.setAllowOpenDrawer(false); - if (fragment instanceof LoginActivity || fragment instanceof AccountPasswordActivity) { + drawerLayoutContainer.setAllowOpenDrawer(false, true); + if (fragment instanceof LoginActivity) { backgroundTablet.setVisibility(View.VISIBLE); shadowTabletSide.setVisibility(View.GONE); shadowTablet.setBackgroundColor(0x00000000); @@ -1427,7 +1559,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } return true; } else { - drawerLayoutContainer.setAllowOpenDrawer(!(fragment instanceof LoginActivity) && !(fragment instanceof AccountPasswordActivity)); + drawerLayoutContainer.setAllowOpenDrawer(!(fragment instanceof LoginActivity), false); return true; } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java index 195ebf11e..86e4b1cab 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java @@ -13,7 +13,6 @@ import android.location.Location; import android.location.LocationManager; import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; import android.widget.TextView; import com.google.android.gms.maps.CameraUpdate; @@ -47,6 +46,7 @@ import org.telegram.ui.ActionBar.BaseFragment; import java.util.List; public class LocationActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate { + private GoogleMap googleMap; private TextView distanceTextView; private Marker userMarker; @@ -65,8 +65,8 @@ public class LocationActivity extends BaseFragment implements NotificationCenter private final static int map_list_menu_satellite = 3; private final static int map_list_menu_hybrid = 4; - public static interface LocationActivityDelegate { - public abstract void didSelectLocation(double latitude, double longitude); + public interface LocationActivityDelegate { + void didSelectLocation(double latitude, double longitude); } @Override @@ -91,164 +91,156 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - if (messageObject != null) { - actionBar.setTitle(LocaleController.getString("ChatLocation", R.string.ChatLocation)); - } else { - actionBar.setTitle(LocaleController.getString("ShareLocation", R.string.ShareLocation)); - } + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + if (messageObject != null) { + actionBar.setTitle(LocaleController.getString("ChatLocation", R.string.ChatLocation)); + } else { + actionBar.setTitle(LocaleController.getString("ShareLocation", R.string.ShareLocation)); + } - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } else if (id == map_list_menu_map) { + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } else if (id == map_list_menu_map) { + if (googleMap != null) { + googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); + } + } else if (id == map_list_menu_satellite) { + if (googleMap != null) { + googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE); + } + } else if (id == map_list_menu_hybrid) { + if (googleMap != null) { + googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); + } + } else if (id == map_to_my_location) { + if (myLocation != null) { + LatLng latLng = new LatLng(myLocation.getLatitude(), myLocation.getLongitude()); if (googleMap != null) { - googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); - } - } else if (id == map_list_menu_satellite) { - if (googleMap != null) { - googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE); - } - } else if (id == map_list_menu_hybrid) { - if (googleMap != null) { - googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); - } - } else if (id == map_to_my_location) { - if (myLocation != null) { - LatLng latLng = new LatLng(myLocation.getLatitude(), myLocation.getLongitude()); - if (googleMap != null) { - CameraUpdate position = CameraUpdateFactory.newLatLngZoom(latLng, googleMap.getMaxZoomLevel() - 8); - googleMap.animateCamera(position); - } + CameraUpdate position = CameraUpdateFactory.newLatLngZoom(latLng, googleMap.getMaxZoomLevel() - 8); + googleMap.animateCamera(position); } } } + } + }); + + ActionBarMenu menu = actionBar.createMenu(); + menu.addItem(map_to_my_location, R.drawable.ic_ab_location); + + ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_other); + item.addSubItem(map_list_menu_map, LocaleController.getString("Map", R.string.Map), 0); + item.addSubItem(map_list_menu_satellite, LocaleController.getString("Satellite", R.string.Satellite), 0); + item.addSubItem(map_list_menu_hybrid, LocaleController.getString("Hybrid", R.string.Hybrid), 0); + + if (messageObject != null) { + fragmentView = inflater.inflate(R.layout.location_view_layout, null, false); + } else { + fragmentView = inflater.inflate(R.layout.location_attach_layout, null, false); + } + + avatarImageView = (BackupImageView) fragmentView.findViewById(R.id.location_avatar_view); + if (avatarImageView != null) { + avatarImageView.setRoundRadius(AndroidUtilities.dp(32)); + } + nameTextView = (TextView) fragmentView.findViewById(R.id.location_name_label); + distanceTextView = (TextView) fragmentView.findViewById(R.id.location_distance_label); + View bottomView = fragmentView.findViewById(R.id.location_bottom_view); + TextView sendButton = (TextView) fragmentView.findViewById(R.id.location_send_button); + if (sendButton != null) { + sendButton.setText(LocaleController.getString("SendLocation", R.string.SendLocation).toUpperCase()); + sendButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + } + + mapView = (MapView) fragmentView.findViewById(R.id.map_view); + mapView.onCreate(null); + try { + MapsInitializer.initialize(context); + googleMap = mapView.getMap(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + + if (googleMap != null) { + googleMap.setMyLocationEnabled(true); + googleMap.getUiSettings().setMyLocationButtonEnabled(false); + googleMap.getUiSettings().setZoomControlsEnabled(false); + googleMap.getUiSettings().setCompassEnabled(false); + googleMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() { + @Override + public void onMyLocationChange(Location location) { + positionMarker(location); + } }); + myLocation = getLastLocation(); - ActionBarMenu menu = actionBar.createMenu(); - menu.addItem(map_to_my_location, R.drawable.ic_ab_location); - - ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_other); - item.addSubItem(map_list_menu_map, LocaleController.getString("Map", R.string.Map), 0); - item.addSubItem(map_list_menu_satellite, LocaleController.getString("Satellite", R.string.Satellite), 0); - item.addSubItem(map_list_menu_hybrid, LocaleController.getString("Hybrid", R.string.Hybrid), 0); - - if (messageObject != null) { - fragmentView = inflater.inflate(R.layout.location_view_layout, container, false); - } else { - fragmentView = inflater.inflate(R.layout.location_attach_layout, container, false); - } - - avatarImageView = (BackupImageView)fragmentView.findViewById(R.id.location_avatar_view); - if (avatarImageView != null) { - avatarImageView.processDetach = false; - avatarImageView.imageReceiver.setRoundRadius(AndroidUtilities.dp(32)); - } - nameTextView = (TextView)fragmentView.findViewById(R.id.location_name_label); - distanceTextView = (TextView)fragmentView.findViewById(R.id.location_distance_label); - View bottomView = fragmentView.findViewById(R.id.location_bottom_view); - TextView sendButton = (TextView) fragmentView.findViewById(R.id.location_send_button); if (sendButton != null) { - sendButton.setText(LocaleController.getString("SendLocation", R.string.SendLocation).toUpperCase()); - sendButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); - } + userLocation = new Location("network"); + userLocation.setLatitude(20.659322); + userLocation.setLongitude(-11.406250); + LatLng latLng = new LatLng(20.659322, -11.406250); + userMarker = googleMap.addMarker(new MarkerOptions().position(latLng).icon(BitmapDescriptorFactory.fromResource(R.drawable.map_pin)).draggable(true)); - mapView = (MapView)fragmentView.findViewById(R.id.map_view); - mapView.onCreate(null); - try { - MapsInitializer.initialize(getParentActivity()); - googleMap = mapView.getMap(); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - - if (googleMap != null) { - googleMap.setMyLocationEnabled(true); - googleMap.getUiSettings().setMyLocationButtonEnabled(false); - googleMap.getUiSettings().setZoomControlsEnabled(false); - googleMap.getUiSettings().setCompassEnabled(false); - googleMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() { + sendButton.setOnClickListener(new View.OnClickListener() { @Override - public void onMyLocationChange(Location location) { - positionMarker(location); + public void onClick(View view) { + if (delegate != null) { + delegate.didSelectLocation(userLocation.getLatitude(), userLocation.getLongitude()); + } + finishFragment(); } }); - myLocation = getLastLocation(); - if (sendButton != null) { - userLocation = new Location("network"); - userLocation.setLatitude(20.659322); - userLocation.setLongitude(-11.406250); - LatLng latLng = new LatLng(20.659322, -11.406250); - userMarker = googleMap.addMarker(new MarkerOptions().position(latLng).icon(BitmapDescriptorFactory.fromResource(R.drawable.map_pin)).draggable(true)); + googleMap.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener() { + @Override + public void onMarkerDragStart(Marker marker) { + } - sendButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - if (delegate != null) { - delegate.didSelectLocation(userLocation.getLatitude(), userLocation.getLongitude()); - } - finishFragment(); - } - }); + @Override + public void onMarkerDrag(Marker marker) { + userLocationMoved = true; + } - googleMap.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener() { - @Override - public void onMarkerDragStart(Marker marker) { - } - - @Override - public void onMarkerDrag(Marker marker) { - userLocationMoved = true; - } - - @Override - public void onMarkerDragEnd(Marker marker) { - LatLng latLng = marker.getPosition(); - userLocation.setLatitude(latLng.latitude); - userLocation.setLongitude(latLng.longitude); - } - }); - } - - if (bottomView != null) { - bottomView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - if (userLocation != null) { - LatLng latLng = new LatLng(userLocation.getLatitude(), userLocation.getLongitude()); - CameraUpdate position = CameraUpdateFactory.newLatLngZoom(latLng, googleMap.getMaxZoomLevel() - 8); - googleMap.animateCamera(position); - } - } - }); - } - - if (messageObject != null) { - updateUserData(); - userLocation = new Location("network"); - userLocation.setLatitude(messageObject.messageOwner.media.geo.lat); - userLocation.setLongitude(messageObject.messageOwner.media.geo._long); - LatLng latLng = new LatLng(userLocation.getLatitude(), userLocation.getLongitude()); - userMarker = googleMap.addMarker(new MarkerOptions().position(latLng). - icon(BitmapDescriptorFactory.fromResource(R.drawable.map_pin))); - CameraUpdate position = CameraUpdateFactory.newLatLngZoom(latLng, googleMap.getMaxZoomLevel() - 8); - googleMap.moveCamera(position); - } - - positionMarker(myLocation); + @Override + public void onMarkerDragEnd(Marker marker) { + LatLng latLng = marker.getPosition(); + userLocation.setLatitude(latLng.latitude); + userLocation.setLongitude(latLng.longitude); + } + }); } - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); + + if (bottomView != null) { + bottomView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (userLocation != null) { + LatLng latLng = new LatLng(userLocation.getLatitude(), userLocation.getLongitude()); + CameraUpdate position = CameraUpdateFactory.newLatLngZoom(latLng, googleMap.getMaxZoomLevel() - 8); + googleMap.animateCamera(position); + } + } + }); } + + if (messageObject != null) { + userLocation = new Location("network"); + userLocation.setLatitude(messageObject.messageOwner.media.geo.lat); + userLocation.setLongitude(messageObject.messageOwner.media.geo._long); + LatLng latLng = new LatLng(userLocation.getLatitude(), userLocation.getLongitude()); + userMarker = googleMap.addMarker(new MarkerOptions().position(latLng). + icon(BitmapDescriptorFactory.fromResource(R.drawable.map_pin))); + CameraUpdate position = CameraUpdateFactory.newLatLngZoom(latLng, googleMap.getMaxZoomLevel() - 8); + googleMap.moveCamera(position); + } + + positionMarker(myLocation); } + return fragmentView; } @@ -268,7 +260,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter private void updateUserData() { if (messageObject != null && avatarImageView != null) { int fromId = messageObject.messageOwner.from_id; - if (messageObject.messageOwner instanceof TLRPC.TL_messageForwarded) { + if (messageObject.isForwarded()) { fromId = messageObject.messageOwner.fwd_from_id; } TLRPC.User user = MessagesController.getInstance().getUser(fromId); @@ -279,6 +271,8 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } avatarImageView.setImage(photo, null, new AvatarDrawable(user)); nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name)); + } else { + avatarImageView.setImageDrawable(null); } } } @@ -292,7 +286,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter if (userLocation != null && distanceTextView != null) { float distance = location.distanceTo(userLocation); if (distance < 1000) { - distanceTextView.setText(String.format("%d %s", (int)(distance), LocaleController.getString("MetersAway", R.string.MetersAway))); + distanceTextView.setText(String.format("%d %s", (int) (distance), LocaleController.getString("MetersAway", R.string.MetersAway))); } else { distanceTextView.setText(String.format("%.2f %s", distance / 1000.0f, LocaleController.getString("KMetersAway", R.string.KMetersAway))); } @@ -321,7 +315,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter @Override public void didReceivedNotification(int id, Object... args) { if (id == NotificationCenter.updateInterfaces) { - int mask = (Integer)args[0]; + int mask = (Integer) args[0]; if ((mask & MessagesController.UPDATE_MASK_AVATAR) != 0 || (mask & MessagesController.UPDATE_MASK_NAME) != 0) { updateUserData(); } @@ -348,6 +342,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter if (mapView != null) { mapView.onResume(); } + updateUserData(); } @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java index 2814c8b32..b7b6fcf7c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java @@ -16,8 +16,10 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageInfo; +import android.graphics.Typeface; import android.os.Build; import android.os.Bundle; +import android.os.Vibrator; import android.telephony.TelephonyManager; import android.text.Editable; import android.text.InputFilter; @@ -26,12 +28,12 @@ import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextUtils; import android.text.TextWatcher; +import android.text.method.PasswordTransformationMethod; 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; @@ -58,6 +60,7 @@ 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.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.BaseFragment; @@ -79,7 +82,7 @@ import java.util.TimerTask; public class LoginActivity extends BaseFragment { private int currentViewNum = 0; - private SlideView[] views = new SlideView[3]; + private SlideView[] views = new SlideView[5]; private ProgressDialog progressDialog; private final static int done_button = 1; @@ -103,104 +106,72 @@ public class LoginActivity extends BaseFragment { } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setTitle(LocaleController.getString("AppName", R.string.AppName)); + public View createView(Context context, LayoutInflater inflater) { + actionBar.setTitle(LocaleController.getString("AppName", R.string.AppName)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == done_button) { - views[currentViewNum].onNextPressed(); - } + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == done_button) { + views[currentViewNum].onNextPressed(); + } else if (id == -1) { + onBackPressed(); } - }); - - 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); - - views[2] = new RegisterView(getParentActivity()); - views[2].setVisibility(View.GONE); - frameLayout.addView(views[2]); - layoutParams1 = (FrameLayout.LayoutParams) views[2].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[2].setLayoutParams(layoutParams1); - - try { - if (views[0] == null || views[1] == null || views[2] == 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()); + ActionBarMenu menu = actionBar.createMenu(); + menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); - Bundle savedInstanceState = loadCurrentState(); + fragmentView = new ScrollView(context); + ScrollView scrollView = (ScrollView) fragmentView; + scrollView.setFillViewport(true); + + FrameLayout frameLayout = new FrameLayout(context); + 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(context); + views[1] = new LoginActivitySmsView(context); + views[2] = new LoginActivityRegisterView(context); + views[3] = new LoginActivityPasswordView(context); + views[4] = new LoginActivityRecoverView(context); + + for (int a = 0; a < 5; a++) { + views[a].setVisibility(a == 0 ? View.VISIBLE : View.GONE); + frameLayout.addView(views[a]); + FrameLayout.LayoutParams layoutParams1 = (FrameLayout.LayoutParams) views[a].getLayoutParams(); + layoutParams1.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams1.height = a == 0 ? FrameLayout.LayoutParams.WRAP_CONTENT : FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams1.leftMargin = AndroidUtilities.dp(AndroidUtilities.isTablet() ? 26 : 18); + layoutParams1.rightMargin = AndroidUtilities.dp(AndroidUtilities.isTablet() ? 26 : 18); + layoutParams1.topMargin = AndroidUtilities.dp(30); + layoutParams1.gravity = Gravity.TOP | Gravity.LEFT; + views[a].setLayoutParams(layoutParams1); + } + + Bundle savedInstanceState = loadCurrentState(); + if (savedInstanceState != null) { + currentViewNum = savedInstanceState.getInt("currentViewNum", 0); + } + actionBar.setTitle(views[currentViewNum].getHeaderName()); + for (int a = 0; a < views.length; a++) { if (savedInstanceState != null) { - currentViewNum = savedInstanceState.getInt("currentViewNum", 0); + views[a].restoreStateParams(savedInstanceState); } - for (int a = 0; a < views.length; a++) { - SlideView v = views[a]; - if (v != null) { - if (savedInstanceState != null) { - v.restoreStateParams(savedInstanceState); - } - v.setVisibility(currentViewNum == a ? View.VISIBLE : View.GONE); - } - } - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); + if (currentViewNum == a) { + actionBar.setBackButtonImage(views[a].needBackButton() ? R.drawable.ic_ab_back : 0); + views[a].setVisibility(View.VISIBLE); + views[a].onShow(); + } else { + views[a].setVisibility(View.GONE); } } + return fragmentView; } @@ -279,7 +250,7 @@ public class LoginActivity extends BaseFragment { editor.putInt(key, (Integer) obj); } } else if (obj instanceof Bundle) { - putBundleToEditor((Bundle)obj, editor, key); + putBundleToEditor((Bundle) obj, editor, key); } } } @@ -294,18 +265,22 @@ public class LoginActivity extends BaseFragment { } clearCurrentState(); return true; - } else if (currentViewNum != 1 && currentViewNum != 2) { + } else if (currentViewNum == 3) { + views[currentViewNum].onBackPressed(); setPage(0, true, null, true); + } else if (currentViewNum == 4) { + views[currentViewNum].onBackPressed(); + setPage(3, true, null, true); } return false; } - public void needShowAlert(final String text) { + public void needShowAlert(String title, String text) { if (text == null || getParentActivity() == null) { return; } AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setTitle(title); builder.setMessage(text); builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null); showAlertDialog(builder); @@ -335,10 +310,11 @@ public class LoginActivity extends BaseFragment { } public void setPage(int page, boolean animated, Bundle params, boolean back) { - if(android.os.Build.VERSION.SDK_INT > 13) { + if (android.os.Build.VERSION.SDK_INT > 13) { final SlideView outView = views[currentViewNum]; final SlideView newView = views[page]; currentViewNum = page; + actionBar.setBackButtonImage(newView.needBackButton() ? R.drawable.ic_ab_back : 0); newView.setParams(params); actionBar.setTitle(newView.getHeaderName()); @@ -382,6 +358,7 @@ public class LoginActivity extends BaseFragment { } }).setDuration(300).translationX(0).start(); } else { + actionBar.setBackButtonImage(views[page].needBackButton() ? R.drawable.ic_ab_back : 0); views[currentViewNum].setVisibility(View.GONE); currentViewNum = page; views[page].setParams(params); @@ -414,12 +391,8 @@ public class LoginActivity extends BaseFragment { public void needFinishActivity() { clearCurrentState(); - if (UserConfig.isWaitingForPasswordEnter()) { - presentFragment(new AccountPasswordActivity(1), true); - } else { - presentFragment(new MessagesActivity(null), true); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.mainUserInfoChanged); - } + presentFragment(new MessagesActivity(null), true); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.mainUserInfoChanged); } public class PhoneView extends SlideView implements AdapterView.OnItemSelectedListener { @@ -457,8 +430,6 @@ public class LoginActivity extends BaseFragment { 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() { @@ -483,9 +454,9 @@ public class LoginActivity extends BaseFragment { 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); + layoutParams.leftMargin = AndroidUtilities.dp(4); + layoutParams.rightMargin = AndroidUtilities.dp(4); view.setLayoutParams(layoutParams); LinearLayout linearLayout = new LinearLayout(context); @@ -505,7 +476,6 @@ public class LoginActivity extends BaseFragment { 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); @@ -597,7 +567,6 @@ public class LoginActivity extends BaseFragment { 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 @@ -615,7 +584,7 @@ public class LoginActivity extends BaseFragment { int toDelete = 0; for (int a = start; a >= 0; a--) { substr = str.substring(a, a + 1); - if(phoneChars.contains(substr)) { + if (phoneChars.contains(substr)) { break; } toDelete++; @@ -667,8 +636,6 @@ public class LoginActivity extends BaseFragment { 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; @@ -685,6 +652,7 @@ public class LoginActivity extends BaseFragment { codesMap.put(args[0], args[2]); languageMap.put(args[1], args[2]); } + reader.close(); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -699,7 +667,7 @@ public class LoginActivity extends BaseFragment { String country = null; try { - TelephonyManager telephonyManager = (TelephonyManager)ApplicationLoader.applicationContext.getSystemService(Context.TELEPHONY_SERVICE); + TelephonyManager telephonyManager = (TelephonyManager) ApplicationLoader.applicationContext.getSystemService(Context.TELEPHONY_SERVICE); if (telephonyManager != null) { country = telephonyManager.getSimCountryIso().toUpperCase(); } @@ -791,14 +759,14 @@ public class LoginActivity extends BaseFragment { return; } if (countryState == 1) { - needShowAlert(LocaleController.getString("ChooseCountry", R.string.ChooseCountry)); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.getString("ChooseCountry", R.string.ChooseCountry)); return; } else if (countryState == 2 && !BuildVars.DEBUG_VERSION) { - needShowAlert(LocaleController.getString("WrongCountry", R.string.WrongCountry)); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.getString("WrongCountry", R.string.WrongCountry)); return; } if (codeField.length() == 0) { - needShowAlert(LocaleController.getString("InvalidPhoneNumber", R.string.InvalidPhoneNumber)); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.getString("InvalidPhoneNumber", R.string.InvalidPhoneNumber)); return; } TLRPC.TL_auth_sendCode req = new TLRPC.TL_auth_sendCode(); @@ -815,6 +783,12 @@ public class LoginActivity extends BaseFragment { final Bundle params = new Bundle(); params.putString("phone", "+" + codeField.getText() + phoneField.getText()); + try { + params.putString("ephone", "+" + PhoneFormat.stripExceptNumbers(codeField.getText().toString()) + " " + PhoneFormat.stripExceptNumbers(phoneField.getText().toString())); + } catch (Exception e) { + FileLog.e("tmessages", e); + params.putString("ephone", "+" + phone); + } params.putString("phoneFormated", phone); nextPressed = true; needShowProgress(); @@ -826,25 +800,22 @@ public class LoginActivity extends BaseFragment { public void run() { nextPressed = false; if (error == null) { - final TLRPC.TL_auth_sentCode res = (TLRPC.TL_auth_sentCode)response; + final TLRPC.TL_auth_sentCode res = (TLRPC.TL_auth_sentCode) response; params.putString("phoneHash", res.phone_code_hash); params.putInt("calltime", res.send_call_timeout * 1000); - if (res.phone_registered) { - params.putString("registered", "true"); - } setPage(1, true, params, false); } else { if (error.text != null) { if (error.text.contains("PHONE_NUMBER_INVALID")) { - needShowAlert(LocaleController.getString("InvalidPhoneNumber", R.string.InvalidPhoneNumber)); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), 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)); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.getString("InvalidCode", R.string.InvalidCode)); } else if (error.text.contains("PHONE_CODE_EXPIRED")) { - needShowAlert(LocaleController.getString("CodeExpired", R.string.CodeExpired)); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.getString("CodeExpired", R.string.CodeExpired)); } else if (error.text.startsWith("FLOOD_WAIT")) { - needShowAlert(LocaleController.getString("FloodWait", R.string.FloodWait)); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.getString("FloodWait", R.string.FloodWait)); } else if (error.code != -1000) { - needShowAlert(error.text); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), error.text); } } } @@ -898,7 +869,7 @@ public class LoginActivity extends BaseFragment { private String phoneHash; private String requestPhone; - private String registered; + private String emailPhone; private EditText codeField; private TextView confirmTextView; private TextView timeText; @@ -931,8 +902,6 @@ public class LoginActivity extends BaseFragment { 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); @@ -951,8 +920,6 @@ public class LoginActivity extends BaseFragment { 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 @@ -976,8 +943,6 @@ public class LoginActivity extends BaseFragment { 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); problemText = new TextView(context); @@ -994,8 +959,6 @@ public class LoginActivity extends BaseFragment { layoutParams.height = LayoutParams.WRAP_CONTENT; layoutParams.gravity = Gravity.LEFT; layoutParams.topMargin = AndroidUtilities.dp(20); - layoutParams.leftMargin = AndroidUtilities.dp(24); - layoutParams.rightMargin = AndroidUtilities.dp(24); problemText.setLayoutParams(layoutParams); problemText.setOnClickListener(new OnClickListener() { @Override @@ -1006,12 +969,12 @@ public class LoginActivity extends BaseFragment { Intent mailer = new Intent(Intent.ACTION_SEND); mailer.setType("message/rfc822"); - mailer.putExtra(Intent.EXTRA_EMAIL, new String[]{"sms@telegram.org"}); - mailer.putExtra(Intent.EXTRA_SUBJECT, "Android registration/login issue " + version + " " + requestPhone); + mailer.putExtra(Intent.EXTRA_EMAIL, new String[]{"sms@stel.com"}); + mailer.putExtra(Intent.EXTRA_SUBJECT, "Android registration/login issue " + version + " " + emailPhone); mailer.putExtra(Intent.EXTRA_TEXT, "Phone: " + requestPhone + "\nApp version: " + version + "\nOS version: SDK " + Build.VERSION.SDK_INT + "\nDevice Name: " + Build.MANUFACTURER + Build.MODEL + "\nLocale: " + Locale.getDefault() + "\nError: " + lastError); getContext().startActivity(Intent.createChooser(mailer, "Send email...")); } catch (Exception e) { - needShowAlert(LocaleController.getString("NoMailInstalled", R.string.NoMailInstalled)); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.getString("NoMailInstalled", R.string.NoMailInstalled)); } } }); @@ -1036,8 +999,6 @@ public class LoginActivity extends BaseFragment { 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() { @@ -1065,9 +1026,9 @@ public class LoginActivity extends BaseFragment { currentParams = params; waitingForSms = true; String phone = params.getString("phone"); + emailPhone = params.getString("ephone"); requestPhone = params.getString("phoneFormated"); phoneHash = params.getString("phoneHash"); - registered = params.getString("registered"); time = params.getInt("calltime"); if (phone == null) { @@ -1128,7 +1089,7 @@ public class LoginActivity extends BaseFragment { private void destroyCodeTimer() { try { - synchronized(timerSync) { + synchronized (timerSync) { if (codeTimer != null) { codeTimer.cancel(); codeTimer = null; @@ -1187,7 +1148,7 @@ public class LoginActivity extends BaseFragment { private void destroyTimer() { try { - synchronized(timerSync) { + synchronized (timerSync) { if (timeTimer != null) { timeTimer.cancel(); timeTimer = null; @@ -1219,10 +1180,10 @@ public class LoginActivity extends BaseFragment { AndroidUtilities.runOnUIThread(new Runnable() { @Override public void run() { - needHideProgress(); nextPressed = false; if (error == null) { - TLRPC.TL_auth_authorization res = (TLRPC.TL_auth_authorization)response; + needHideProgress(); + TLRPC.TL_auth_authorization res = (TLRPC.TL_auth_authorization) response; destroyTimer(); destroyCodeTimer(); UserConfig.clearConfig(); @@ -1238,10 +1199,17 @@ public class LoginActivity extends BaseFragment { MessagesController.getInstance().getBlockedUsers(true); needFinishActivity(); ConnectionsManager.getInstance().initPushConnection(); + Utilities.stageQueue.postRunnable(new Runnable() { + @Override + public void run() { + ConnectionsManager.getInstance().updateDcSettings(0); + } + }); } else { lastError = error.text; - if (error.text.contains("PHONE_NUMBER_UNOCCUPIED") && registered == null) { + if (error.text.contains("PHONE_NUMBER_UNOCCUPIED")) { + needHideProgress(); Bundle params = new Bundle(); params.putString("phoneFormated", requestPhone); params.putString("phoneHash", phoneHash); @@ -1250,21 +1218,47 @@ public class LoginActivity extends BaseFragment { destroyTimer(); destroyCodeTimer(); } else if (error.text.contains("SESSION_PASSWORD_NEEDED")) { - needFinishActivity(); + TLRPC.TL_account_getPassword req2 = new TLRPC.TL_account_getPassword(); + ConnectionsManager.getInstance().performRpc(req2, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(final TLObject response, final TLRPC.TL_error error) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + needHideProgress(); + if (error == null) { + TLRPC.TL_account_password password = (TLRPC.TL_account_password) response; + Bundle bundle = new Bundle(); + bundle.putString("current_salt", Utilities.bytesToHex(password.current_salt)); + bundle.putString("hint", password.hint); + bundle.putString("email_unconfirmed_pattern", password.email_unconfirmed_pattern); + bundle.putString("phoneFormated", requestPhone); + bundle.putString("phoneHash", phoneHash); + bundle.putString("code", req.phone_code); + bundle.putInt("has_recovery", password.has_recovery ? 1 : 0); + setPage(3, true, bundle, false); + } else { + needShowAlert(LocaleController.getString("AppName", R.string.AppName), error.text); + } + } + }); + } + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors | RPCRequest.RPCRequestClassWithoutLogin); destroyTimer(); destroyCodeTimer(); } else { + needHideProgress(); createTimer(); if (error.text.contains("PHONE_NUMBER_INVALID")) { - needShowAlert(LocaleController.getString("InvalidPhoneNumber", R.string.InvalidPhoneNumber)); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), 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)); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.getString("InvalidCode", R.string.InvalidCode)); } else if (error.text.contains("PHONE_CODE_EXPIRED")) { - needShowAlert(LocaleController.getString("CodeExpired", R.string.CodeExpired)); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.getString("CodeExpired", R.string.CodeExpired)); } else if (error.text.startsWith("FLOOD_WAIT")) { - needShowAlert(LocaleController.getString("FloodWait", R.string.FloodWait)); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.getString("FloodWait", R.string.FloodWait)); } else { - needShowAlert(error.text); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), error.text); } } } @@ -1352,7 +1346,635 @@ public class LoginActivity extends BaseFragment { } } - public class RegisterView extends SlideView { + public class LoginActivityPasswordView extends SlideView { + + private EditText codeField; + private TextView confirmTextView; + private TextView resetAccountButton; + private TextView resetAccountText; + + private Bundle currentParams; + private boolean nextPressed; + private byte[] current_salt; + private String hint; + private String email_unconfirmed_pattern; + private boolean has_recovery; + private String requestPhone; + private String phoneHash; + private String phoneCode; + + public LoginActivityPasswordView(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); + confirmTextView.setText(LocaleController.getString("LoginPasswordText", R.string.LoginPasswordText)); + addView(confirmTextView); + LayoutParams layoutParams = (LayoutParams) confirmTextView.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.LEFT; + confirmTextView.setLayoutParams(layoutParams); + + codeField = new EditText(context); + codeField.setTextColor(0xff212121); + AndroidUtilities.clearCursorDrawable(codeField); + codeField.setHintTextColor(0xff979797); + codeField.setHint(LocaleController.getString("LoginPassword", R.string.LoginPassword)); + codeField.setImeOptions(EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NO_EXTRACT_UI); + codeField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + codeField.setMaxLines(1); + codeField.setPadding(0, 0, 0, 0); + codeField.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); + codeField.setTransformationMethod(PasswordTransformationMethod.getInstance()); + codeField.setTypeface(Typeface.DEFAULT); + 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); + 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; + } + }); + + TextView cancelButton = new TextView(context); + cancelButton.setGravity(Gravity.LEFT | Gravity.TOP); + cancelButton.setTextColor(0xff4d83b3); + cancelButton.setText(LocaleController.getString("ForgotPassword", R.string.ForgotPassword)); + cancelButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + cancelButton.setLineSpacing(AndroidUtilities.dp(2), 1.0f); + cancelButton.setPadding(0, AndroidUtilities.dp(14), 0, 0); + addView(cancelButton); + layoutParams = (LayoutParams) cancelButton.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + cancelButton.setLayoutParams(layoutParams); + cancelButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + if (has_recovery) { + needShowProgress(); + TLRPC.TL_auth_requestPasswordRecovery req = new TLRPC.TL_auth_requestPasswordRecovery(); + 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(); + if (error == null) { + final TLRPC.TL_auth_passwordRecovery res = (TLRPC.TL_auth_passwordRecovery) response; + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.formatString("RestoreEmailSent", R.string.RestoreEmailSent, res.email_pattern)); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + Bundle bundle = new Bundle(); + bundle.putString("email_unconfirmed_pattern", res.email_pattern); + setPage(4, true, bundle, false); + } + }); + AlertDialog dialog = showAlertDialog(builder); + if (dialog != null) { + dialog.setCanceledOnTouchOutside(false); + dialog.setCancelable(false); + } + } else { + if (error.text.startsWith("FLOOD_WAIT")) { + int time = Utilities.parseInt(error.text); + String timeString; + if (time < 60) { + timeString = LocaleController.formatPluralString("Seconds", time); + } else { + timeString = LocaleController.formatPluralString("Minutes", time / 60); + } + needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.formatString("FloodWaitTime", R.string.FloodWaitTime, timeString)); + } else { + needShowAlert(LocaleController.getString("AppName", R.string.AppName), error.text); + } + } + } + }); + } + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors | RPCRequest.RPCRequestClassWithoutLogin); + } else { + resetAccountText.setVisibility(VISIBLE); + resetAccountButton.setVisibility(VISIBLE); + AndroidUtilities.hideKeyboard(codeField); + needShowAlert(LocaleController.getString("RestorePasswordNoEmailTitle", R.string.RestorePasswordNoEmailTitle), LocaleController.getString("RestorePasswordNoEmailText", R.string.RestorePasswordNoEmailText)); + } + } + }); + + resetAccountButton = new TextView(context); + resetAccountButton.setGravity(Gravity.LEFT | Gravity.TOP); + resetAccountButton.setTextColor(0xffff6666); + resetAccountButton.setVisibility(GONE); + resetAccountButton.setText(LocaleController.getString("ResetMyAccount", R.string.ResetMyAccount)); + resetAccountButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + resetAccountButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + resetAccountButton.setLineSpacing(AndroidUtilities.dp(2), 1.0f); + resetAccountButton.setPadding(0, AndroidUtilities.dp(14), 0, 0); + addView(resetAccountButton); + layoutParams = (LayoutParams) resetAccountButton.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + layoutParams.topMargin = AndroidUtilities.dp(34); + resetAccountButton.setLayoutParams(layoutParams); + resetAccountButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.getString("ResetMyAccountWarningText", R.string.ResetMyAccountWarningText)); + builder.setTitle(LocaleController.getString("ResetMyAccountWarning", R.string.ResetMyAccountWarning)); + builder.setPositiveButton(LocaleController.getString("ResetMyAccountWarningReset", R.string.ResetMyAccountWarningReset), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + needShowProgress(); + TLRPC.TL_account_deleteAccount req = new TLRPC.TL_account_deleteAccount(); + req.reason = "Forgot password"; + ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, final TLRPC.TL_error error) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + needHideProgress(); + if (error == null) { + Bundle params = new Bundle(); + params.putString("phoneFormated", requestPhone); + params.putString("phoneHash", phoneHash); + params.putString("code", phoneCode); + setPage(2, true, params, false); + } else { + needShowAlert(LocaleController.getString("AppName", R.string.AppName), error.text); + } + } + }); + } + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassWithoutLogin | RPCRequest.RPCRequestClassFailOnServerErrors); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } + }); + + resetAccountText = new TextView(context); + resetAccountText.setGravity(Gravity.LEFT | Gravity.TOP); + resetAccountText.setVisibility(GONE); + resetAccountText.setTextColor(0xff757575); + resetAccountText.setText(LocaleController.getString("ResetMyAccountText", R.string.ResetMyAccountText)); + resetAccountText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + resetAccountText.setLineSpacing(AndroidUtilities.dp(2), 1.0f); + addView(resetAccountText); + layoutParams = (LayoutParams) resetAccountText.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + layoutParams.bottomMargin = AndroidUtilities.dp(14); + layoutParams.topMargin = AndroidUtilities.dp(7); + resetAccountText.setLayoutParams(layoutParams); + } + + @Override + public String getHeaderName() { + return LocaleController.getString("LoginPassword", R.string.LoginPassword); + } + + @Override + public void setParams(Bundle params) { + if (params == null) { + return; + } + if (params.isEmpty()) { + resetAccountButton.setVisibility(VISIBLE); + resetAccountText.setVisibility(VISIBLE); + AndroidUtilities.hideKeyboard(codeField); + return; + } + resetAccountButton.setVisibility(GONE); + resetAccountText.setVisibility(GONE); + codeField.setText(""); + currentParams = params; + current_salt = Utilities.hexToBytes(currentParams.getString("current_salt")); + hint = currentParams.getString("hint"); + has_recovery = currentParams.getInt("has_recovery") == 1; + email_unconfirmed_pattern = currentParams.getString("email_unconfirmed_pattern"); + requestPhone = params.getString("phoneFormated"); + phoneHash = params.getString("phoneHash"); + phoneCode = params.getString("code"); + + AndroidUtilities.showKeyboard(codeField); + codeField.requestFocus(); + + + if (hint != null && hint.length() > 0) { + codeField.setHint(hint); + } else { + codeField.setHint(LocaleController.getString("LoginPassword", R.string.LoginPassword)); + } + } + + private void onPasscodeError(boolean clear) { + if (getParentActivity() == null) { + return; + } + Vibrator v = (Vibrator) getParentActivity().getSystemService(Context.VIBRATOR_SERVICE); + if (v != null) { + v.vibrate(200); + } + if (clear) { + codeField.setText(""); + } + AndroidUtilities.shakeTextView(confirmTextView, 2, 0); + } + + @Override + public void onNextPressed() { + if (nextPressed) { + return; + } + + String oldPassword = codeField.getText().toString(); + if (oldPassword.length() == 0) { + onPasscodeError(false); + return; + } + nextPressed = true; + byte[] oldPasswordBytes = null; + try { + oldPasswordBytes = oldPassword.getBytes("UTF-8"); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + + needShowProgress(); + byte[] hash = new byte[current_salt.length * 2 + oldPasswordBytes.length]; + System.arraycopy(current_salt, 0, hash, 0, current_salt.length); + System.arraycopy(oldPasswordBytes, 0, hash, current_salt.length, oldPasswordBytes.length); + System.arraycopy(current_salt, 0, hash, hash.length - current_salt.length, current_salt.length); + + final TLRPC.TL_auth_checkPassword req = new TLRPC.TL_auth_checkPassword(); + req.password_hash = Utilities.computeSHA256(hash, 0, hash.length); + 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.TL_auth_authorization res = (TLRPC.TL_auth_authorization) response; + UserConfig.clearConfig(); + MessagesController.getInstance().cleanUp(); + UserConfig.setCurrentUser(res.user); + UserConfig.saveConfig(true); + MessagesStorage.getInstance().cleanUp(true); + ArrayList users = new ArrayList<>(); + users.add(res.user); + MessagesStorage.getInstance().putUsersAndChats(users, null, true, true); + MessagesController.getInstance().putUser(res.user, false); + ContactsController.getInstance().checkAppAccount(); + MessagesController.getInstance().getBlockedUsers(true); + needFinishActivity(); + ConnectionsManager.getInstance().initPushConnection(); + Utilities.stageQueue.postRunnable(new Runnable() { + @Override + public void run() { + ConnectionsManager.getInstance().updateDcSettings(0); + } + }); + } else { + if (error.text.equals("PASSWORD_HASH_INVALID")) { + onPasscodeError(true); + } else if (error.text.startsWith("FLOOD_WAIT")) { + int time = Utilities.parseInt(error.text); + String timeString; + if (time < 60) { + timeString = LocaleController.formatPluralString("Seconds", time); + } else { + timeString = LocaleController.formatPluralString("Minutes", time / 60); + } + needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.formatString("FloodWaitTime", R.string.FloodWaitTime, timeString)); + } else { + needShowAlert(LocaleController.getString("AppName", R.string.AppName), error.text); + } + } + } + }); + } + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors | RPCRequest.RPCRequestClassWithoutLogin); + } + + @Override + public boolean needBackButton() { + return true; + } + + @Override + public void onBackPressed() { + currentParams = null; + } + + @Override + public void onShow() { + super.onShow(); + if (codeField != null) { + codeField.requestFocus(); + codeField.setSelection(codeField.length()); + } + } + + @Override + public void saveStateParams(Bundle bundle) { + String code = codeField.getText().toString(); + if (code != null && code.length() != 0) { + bundle.putString("passview_code", code); + } + if (currentParams != null) { + bundle.putBundle("passview_params", currentParams); + } + } + + @Override + public void restoreStateParams(Bundle bundle) { + currentParams = bundle.getBundle("passview_params"); + if (currentParams != null) { + setParams(currentParams); + } + String code = bundle.getString("passview_code"); + if (code != null) { + codeField.setText(code); + } + } + } + + public class LoginActivityRecoverView extends SlideView { + + private EditText codeField; + private TextView confirmTextView; + private TextView cancelButton; + + private Bundle currentParams; + private boolean nextPressed; + private String email_unconfirmed_pattern; + + public LoginActivityRecoverView(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); + confirmTextView.setText(LocaleController.getString("RestoreEmailSentInfo", R.string.RestoreEmailSentInfo)); + addView(confirmTextView); + LayoutParams layoutParams = (LayoutParams) confirmTextView.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.LEFT; + confirmTextView.setLayoutParams(layoutParams); + + codeField = new EditText(context); + codeField.setTextColor(0xff212121); + AndroidUtilities.clearCursorDrawable(codeField); + codeField.setHintTextColor(0xff979797); + codeField.setHint(LocaleController.getString("PasswordCode", R.string.PasswordCode)); + codeField.setImeOptions(EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NO_EXTRACT_UI); + codeField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + codeField.setMaxLines(1); + codeField.setPadding(0, 0, 0, 0); + codeField.setInputType(InputType.TYPE_CLASS_PHONE); + codeField.setTransformationMethod(PasswordTransformationMethod.getInstance()); + codeField.setTypeface(Typeface.DEFAULT); + 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); + 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; + } + }); + + cancelButton = new TextView(context); + cancelButton.setGravity(Gravity.LEFT | Gravity.BOTTOM); + cancelButton.setTextColor(0xff4d83b3); + cancelButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + cancelButton.setLineSpacing(AndroidUtilities.dp(2), 1.0f); + cancelButton.setPadding(0, AndroidUtilities.dp(14), 0, 0); + addView(cancelButton); + layoutParams = (LayoutParams) cancelButton.getLayoutParams(); + layoutParams.width = LayoutParams.WRAP_CONTENT; + layoutParams.height = LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.BOTTOM | Gravity.LEFT; + layoutParams.bottomMargin = AndroidUtilities.dp(14); + cancelButton.setLayoutParams(layoutParams); + cancelButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.getString("RestoreEmailTroubleText", R.string.RestoreEmailTroubleText)); + builder.setTitle(LocaleController.getString("RestorePasswordNoEmailTitle", R.string.RestorePasswordNoEmailTitle)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + setPage(3, true, new Bundle(), true); + } + }); + AlertDialog dialog = showAlertDialog(builder); + if (dialog != null) { + dialog.setCanceledOnTouchOutside(false); + dialog.setCancelable(false); + } + } + }); + } + + @Override + public boolean needBackButton() { + return true; + } + + @Override + public String getHeaderName() { + return LocaleController.getString("LoginPassword", R.string.LoginPassword); + } + + @Override + public void setParams(Bundle params) { + if (params == null) { + return; + } + codeField.setText(""); + currentParams = params; + email_unconfirmed_pattern = currentParams.getString("email_unconfirmed_pattern"); + cancelButton.setText(LocaleController.formatString("RestoreEmailTrouble", R.string.RestoreEmailTrouble, email_unconfirmed_pattern)); + + AndroidUtilities.showKeyboard(codeField); + codeField.requestFocus(); + } + + private void onPasscodeError(boolean clear) { + if (getParentActivity() == null) { + return; + } + Vibrator v = (Vibrator) getParentActivity().getSystemService(Context.VIBRATOR_SERVICE); + if (v != null) { + v.vibrate(200); + } + if (clear) { + codeField.setText(""); + } + AndroidUtilities.shakeTextView(confirmTextView, 2, 0); + } + + @Override + public void onNextPressed() { + if (nextPressed) { + return; + } + + String oldPassword = codeField.getText().toString(); + if (oldPassword.length() == 0) { + onPasscodeError(false); + return; + } + nextPressed = true; + byte[] oldPasswordBytes = null; + try { + oldPasswordBytes = oldPassword.getBytes("UTF-8"); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + + String code = codeField.getText().toString(); + if (code.length() == 0) { + onPasscodeError(false); + return; + } + needShowProgress(); + TLRPC.TL_auth_recoverPassword req = new TLRPC.TL_auth_recoverPassword(); + req.code = code; + 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.TL_auth_authorization res = (TLRPC.TL_auth_authorization) response; + UserConfig.clearConfig(); + MessagesController.getInstance().cleanUp(); + UserConfig.setCurrentUser(res.user); + UserConfig.saveConfig(true); + MessagesStorage.getInstance().cleanUp(true); + ArrayList users = new ArrayList<>(); + users.add(res.user); + MessagesStorage.getInstance().putUsersAndChats(users, null, true, true); + MessagesController.getInstance().putUser(res.user, false); + ContactsController.getInstance().checkAppAccount(); + MessagesController.getInstance().getBlockedUsers(true); + needFinishActivity(); + ConnectionsManager.getInstance().initPushConnection(); + Utilities.stageQueue.postRunnable(new Runnable() { + @Override + public void run() { + ConnectionsManager.getInstance().updateDcSettings(0); + } + }); + } else { + if (error.text.startsWith("CODE_INVALID")) { + onPasscodeError(true); + } else if (error.text.startsWith("FLOOD_WAIT")) { + int time = Utilities.parseInt(error.text); + String timeString; + if (time < 60) { + timeString = LocaleController.formatPluralString("Seconds", time); + } else { + timeString = LocaleController.formatPluralString("Minutes", time / 60); + } + needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.formatString("FloodWaitTime", R.string.FloodWaitTime, timeString)); + } else { + needShowAlert(LocaleController.getString("AppName", R.string.AppName), error.text); + } + } + } + }); + } + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors | RPCRequest.RPCRequestClassWithoutLogin); + } + + @Override + public void onBackPressed() { + currentParams = null; + } + + @Override + public void onShow() { + super.onShow(); + if (codeField != null) { + codeField.requestFocus(); + codeField.setSelection(codeField.length()); + } + } + + @Override + public void saveStateParams(Bundle bundle) { + String code = codeField.getText().toString(); + if (code != null && code.length() != 0) { + bundle.putString("recoveryview_code", code); + } + if (currentParams != null) { + bundle.putBundle("recoveryview_params", currentParams); + } + } + + @Override + public void restoreStateParams(Bundle bundle) { + currentParams = bundle.getBundle("recoveryview_params"); + if (currentParams != null) { + setParams(currentParams); + } + String code = bundle.getString("recoveryview_code"); + if (code != null) { + codeField.setText(code); + } + } + } + + public class LoginActivityRegisterView extends SlideView { private EditText firstNameField; private EditText lastNameField; @@ -1362,7 +1984,7 @@ public class LoginActivity extends BaseFragment { private Bundle currentParams; private boolean nextPressed = false; - public RegisterView(Context context) { + public LoginActivityRegisterView(Context context) { super(context); setOrientation(VERTICAL); @@ -1377,8 +1999,6 @@ public class LoginActivity extends BaseFragment { layoutParams.width = LayoutParams.WRAP_CONTENT; layoutParams.height = LayoutParams.WRAP_CONTENT; layoutParams.topMargin = AndroidUtilities.dp(8); - layoutParams.leftMargin = AndroidUtilities.dp(24); - layoutParams.rightMargin = AndroidUtilities.dp(24); layoutParams.gravity = Gravity.LEFT; textView.setLayoutParams(layoutParams); @@ -1395,8 +2015,6 @@ public class LoginActivity extends BaseFragment { layoutParams = (LayoutParams) firstNameField.getLayoutParams(); layoutParams.width = LayoutParams.MATCH_PARENT; layoutParams.height = AndroidUtilities.dp(36); - layoutParams.leftMargin = AndroidUtilities.dp(24); - layoutParams.rightMargin = AndroidUtilities.dp(24); layoutParams.topMargin = AndroidUtilities.dp(26); firstNameField.setLayoutParams(layoutParams); firstNameField.setOnEditorActionListener(new TextView.OnEditorActionListener() { @@ -1423,8 +2041,6 @@ public class LoginActivity extends BaseFragment { layoutParams = (LayoutParams) lastNameField.getLayoutParams(); layoutParams.width = LayoutParams.MATCH_PARENT; layoutParams.height = AndroidUtilities.dp(36); - layoutParams.leftMargin = AndroidUtilities.dp(24); - layoutParams.rightMargin = AndroidUtilities.dp(24); layoutParams.topMargin = AndroidUtilities.dp(10); lastNameField.setLayoutParams(layoutParams); @@ -1449,8 +2065,6 @@ public class LoginActivity extends BaseFragment { 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.setOnClickListener(new OnClickListener() { @Override @@ -1541,25 +2155,31 @@ public class LoginActivity extends BaseFragment { MessagesController.getInstance().getBlockedUsers(true); needFinishActivity(); ConnectionsManager.getInstance().initPushConnection(); + Utilities.stageQueue.postRunnable(new Runnable() { + @Override + public void run() { + ConnectionsManager.getInstance().updateDcSettings(0); + } + }); } else { if (error.text.contains("PHONE_NUMBER_INVALID")) { - needShowAlert(LocaleController.getString("InvalidPhoneNumber", R.string.InvalidPhoneNumber)); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), 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)); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.getString("InvalidCode", R.string.InvalidCode)); } else if (error.text.contains("PHONE_CODE_EXPIRED")) { - needShowAlert(LocaleController.getString("CodeExpired", R.string.CodeExpired)); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.getString("CodeExpired", R.string.CodeExpired)); } else if (error.text.contains("FIRSTNAME_INVALID")) { - needShowAlert(LocaleController.getString("InvalidFirstName", R.string.InvalidFirstName)); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.getString("InvalidFirstName", R.string.InvalidFirstName)); } else if (error.text.contains("LASTNAME_INVALID")) { - needShowAlert(LocaleController.getString("InvalidLastName", R.string.InvalidLastName)); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.getString("InvalidLastName", R.string.InvalidLastName)); } else { - needShowAlert(error.text); + needShowAlert(LocaleController.getString("AppName", R.string.AppName), error.text); } } } }); } - }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassWithoutLogin); + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassWithoutLogin | RPCRequest.RPCRequestClassFailOnServerErrors); } @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java index 811f0f3e4..90d6f84fb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java @@ -33,47 +33,56 @@ import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.EditText; import android.widget.FrameLayout; -import android.widget.GridView; import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; import org.telegram.android.MessagesController; -import org.telegram.android.SendMessagesHelper; import org.telegram.android.query.SharedMediaQuery; import org.telegram.messenger.ApplicationLoader; +import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLoader; +import org.telegram.messenger.FileLog; +import org.telegram.messenger.RPCRequest; +import org.telegram.messenger.TLObject; import org.telegram.messenger.TLRPC; import org.telegram.android.MessageObject; import org.telegram.android.NotificationCenter; import org.telegram.messenger.R; +import org.telegram.messenger.Utilities; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; import org.telegram.ui.ActionBar.ActionBarPopupWindow; -import org.telegram.ui.Adapters.BaseFragmentAdapter; import org.telegram.ui.ActionBar.ActionBar; +import org.telegram.ui.Adapters.BaseFragmentAdapter; +import org.telegram.ui.Adapters.BaseSectionsAdapter; import org.telegram.ui.AnimationCompat.AnimatorSetProxy; import org.telegram.ui.AnimationCompat.ObjectAnimatorProxy; +import org.telegram.ui.Cells.GreySectionCell; import org.telegram.ui.Cells.LoadingCell; import org.telegram.ui.Cells.SharedDocumentCell; +import org.telegram.ui.Cells.SharedMediaSectionCell; +import org.telegram.ui.Cells.SharedPhotoVideoCell; import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.ActionBar.BaseFragment; +import org.telegram.ui.Components.SectionsListView; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.Timer; +import java.util.TimerTask; public class MediaActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate, PhotoViewer.PhotoViewerProvider { - private GridView listView; - private ListView mediaListView; - private ListAdapter listAdapter; + private SharedPhotoVideoAdapter photoVideoAdapter; private SharedDocumentsAdapter documentsAdapter; + private DocumentsSearchAdapter documentsSearchAdapter; + private SectionsListView listView; private LinearLayout progressView; private TextView emptyTextView; private ImageView emptyImageView; @@ -83,6 +92,10 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No private ActionBarMenuItem searchItem; private TextView selectedMessagesCountTextView; private ActionBarPopupWindow.ActionBarPopupWindowLayout popupLayout; + private ArrayList cellCache = new ArrayList<>(6); + + private boolean searchWas; + private boolean searching; private HashMap selectedFiles = new HashMap<>(); private ArrayList actionModeViews = new ArrayList<>(); @@ -90,16 +103,79 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No private long dialog_id; private int selectedMode; - private int itemWidth = 100; + private int columnsCount = 4; private class SharedMediaData { private ArrayList messages = new ArrayList<>(); private HashMap messagesDict = new HashMap<>(); + private ArrayList sections = new ArrayList<>(); + private HashMap> sectionArrays = new HashMap<>(); private int totalCount; private boolean loading; private boolean endReached; private boolean cacheEndReached; private int max_id; + + public boolean addMessage(MessageObject messageObject, boolean isNew, boolean enc) { + if (messagesDict.containsKey(messageObject.getId())) { + return false; + } + ArrayList messageObjects = sectionArrays.get(messageObject.monthKey); + if (messageObjects == null) { + messageObjects = new ArrayList<>(); + sectionArrays.put(messageObject.monthKey, messageObjects); + if (isNew) { + sections.add(0, messageObject.monthKey); + } else { + sections.add(messageObject.monthKey); + } + } + if (isNew) { + messageObjects.add(0, messageObject); + messages.add(0, messageObject); + } else { + messageObjects.add(messageObject); + messages.add(messageObject); + } + messagesDict.put(messageObject.getId(), messageObject); + if (!enc) { + if (messageObject.getId() > 0) { + max_id = Math.min(messageObject.getId(), max_id); + } + } else { + max_id = Math.max(messageObject.getId(), max_id); + } + return true; + } + + public boolean deleteMessage(int mid) { + MessageObject messageObject = messagesDict.get(mid); + if (messageObject == null) { + return false; + } + ArrayList messageObjects = sectionArrays.get(messageObject.monthKey); + if (messageObjects == null) { + return false; + } + messageObjects.remove(messageObject); + messages.remove(messageObject); + messagesDict.remove(messageObject.getId()); + if (messageObjects.isEmpty()) { + sectionArrays.remove(messageObject.monthKey); + sections.remove(messageObject.monthKey); + } + totalCount--; + return true; + } + + public void replaceMid(int oldMid, int newMid) { + MessageObject obj = messagesDict.get(oldMid); + if (obj != null) { + messagesDict.remove(oldMid); + messagesDict.put(newMid, obj); + obj.messageOwner.id = newMid; + } + } } private SharedMediaData sharedMediaData[] = new SharedMediaData[3]; @@ -140,470 +216,358 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setTitle(""); - actionBar.setAllowOverlayTitle(false); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - if (Build.VERSION.SDK_INT < 11 && listView != null) { - listView.setAdapter(null); - listView = null; - listAdapter = null; - } - finishFragment(); - } else if (id == -2) { - selectedFiles.clear(); - actionBar.hideActionMode(); - mediaListView.invalidateViews(); - } else if (id == shared_media_item) { - if (selectedMode == 0) { - return; - } - selectedMode = 0; - switchToCurrentSelectedMode(); - } else if (id == files_item) { - if (selectedMode == 1) { - return; - } - selectedMode = 1; - switchToCurrentSelectedMode(); - } else if (id == delete) { - if (getParentActivity() == null) { - return; - } - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setMessage(LocaleController.formatString("AreYouSureDeleteMessages", R.string.AreYouSureDeleteMessages, LocaleController.formatPluralString("files", selectedFiles.size()))); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - ArrayList ids = new ArrayList<>(selectedFiles.keySet()); - ArrayList random_ids = null; - TLRPC.EncryptedChat currentEncryptedChat = null; - if ((int) dialog_id == 0) { - currentEncryptedChat = MessagesController.getInstance().getEncryptedChat((int) (dialog_id >> 32)); - } - if (currentEncryptedChat != null) { - random_ids = new ArrayList<>(); - for (HashMap.Entry entry : selectedFiles.entrySet()) { - MessageObject msg = entry.getValue(); - if (msg.messageOwner.random_id != 0 && msg.type != 10) { - random_ids.add(msg.messageOwner.random_id); - } - } - } - MessagesController.getInstance().deleteMessages(ids, random_ids, currentEncryptedChat); - actionBar.hideActionMode(); - selectedFiles.clear(); - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } else if (id == forward) { - Bundle args = new Bundle(); - args.putBoolean("onlySelect", true); - args.putBoolean("serverOnly", true); - args.putString("selectAlertString", LocaleController.getString("ForwardMessagesTo", R.string.ForwardMessagesTo)); - args.putString("selectAlertStringGroup", LocaleController.getString("ForwardMessagesToGroup", R.string.ForwardMessagesToGroup)); - MessagesActivity fragment = new MessagesActivity(args); - fragment.setDelegate(new MessagesActivity.MessagesActivityDelegate() { - @Override - public void didSelectDialog(MessagesActivity fragment, long did, boolean param) { - int lower_part = (int)did; - if (lower_part != 0) { - Bundle args = new Bundle(); - args.putBoolean("scrollToTopOnResume", true); - if (lower_part > 0) { - args.putInt("user_id", lower_part); - } else if (lower_part < 0) { - args.putInt("chat_id", -lower_part); - } - - ArrayList ids = new ArrayList<>(selectedFiles.keySet()); - Collections.sort(ids); - for (Integer id : ids) { - if (id > 0) { - SendMessagesHelper.getInstance().sendMessage(selectedFiles.get(id), did); - } - } - selectedFiles.clear(); - actionBar.hideActionMode(); - - NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); - ChatActivity chatActivity = new ChatActivity(args); - presentFragment(chatActivity, true); - - if (!AndroidUtilities.isTablet()) { - removeSelfFromStack(); - Activity parentActivity = getParentActivity(); - if (parentActivity == null) { - parentActivity = chatActivity.getParentActivity(); - } - if (parentActivity != null) { - parentActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); - } - } - } else { - fragment.finishFragment(); - } - } - }); - presentFragment(fragment); + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setTitle(""); + actionBar.setAllowOverlayTitle(false); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + if (Build.VERSION.SDK_INT < 11 && listView != null) { + listView.setAdapter(null); + listView = null; + photoVideoAdapter = null; + documentsAdapter = null; } - } - }); - - selectedFiles.clear(); - actionModeViews.clear(); - - final ActionBarMenu menu = actionBar.createMenu(); - searchItem = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true).setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() { - @Override - public void onSearchExpand() { - dropDownContainer.setVisibility(View.GONE); - } - - @Override - public void onSearchCollapse() { - dropDownContainer.setVisibility(View.VISIBLE); - } - - @Override - public void onTextChanged(EditText editText) { - - } - }); - searchItem.getSearchField().setHint(LocaleController.getString("Search", R.string.Search)); - searchItem.setVisibility(View.GONE); - - dropDownContainer = new ActionBarMenuItem(getParentActivity(), menu, R.drawable.bar_selector); - dropDownContainer.setSubMenuOpenSide(1); - dropDownContainer.addSubItem(shared_media_item, LocaleController.getString("SharedMedia", R.string.SharedMedia), 0); - dropDownContainer.addSubItem(files_item, LocaleController.getString("DocumentsTitle", R.string.DocumentsTitle), 0); - actionBar.addView(dropDownContainer); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) dropDownContainer.getLayoutParams(); - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.rightMargin = AndroidUtilities.dp(40); - layoutParams.leftMargin = AndroidUtilities.isTablet() ? AndroidUtilities.dp(64) : AndroidUtilities.dp(56); - layoutParams.gravity = Gravity.TOP | Gravity.LEFT; - dropDownContainer.setLayoutParams(layoutParams); - dropDownContainer.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - dropDownContainer.toggleSubMenu(); - } - }); - - dropDown = new TextView(getParentActivity()); - dropDown.setGravity(Gravity.LEFT); - dropDown.setSingleLine(true); - dropDown.setLines(1); - dropDown.setMaxLines(1); - dropDown.setEllipsize(TextUtils.TruncateAt.END); - dropDown.setTextColor(0xffffffff); - dropDown.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); - dropDown.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_arrow_drop_down, 0); - dropDown.setCompoundDrawablePadding(AndroidUtilities.dp(4)); - dropDown.setPadding(0, 0, AndroidUtilities.dp(10), 0); - dropDownContainer.addView(dropDown); - layoutParams = (FrameLayout.LayoutParams) dropDown.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.leftMargin = AndroidUtilities.dp(16); - layoutParams.gravity = Gravity.CENTER_VERTICAL; - dropDown.setLayoutParams(layoutParams); - - final ActionBarMenu actionMode = actionBar.createActionMode(); - actionModeViews.add(actionMode.addItem(-2, R.drawable.ic_ab_back_grey, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); - - selectedMessagesCountTextView = new TextView(actionMode.getContext()); - selectedMessagesCountTextView.setTextSize(18); - selectedMessagesCountTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); - selectedMessagesCountTextView.setTextColor(0xff737373); - selectedMessagesCountTextView.setSingleLine(true); - selectedMessagesCountTextView.setLines(1); - selectedMessagesCountTextView.setEllipsize(TextUtils.TruncateAt.END); - selectedMessagesCountTextView.setPadding(AndroidUtilities.dp(11), 0, 0, AndroidUtilities.dp(2)); - selectedMessagesCountTextView.setGravity(Gravity.CENTER_VERTICAL); - selectedMessagesCountTextView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return true; - } - }); - actionMode.addView(selectedMessagesCountTextView); - LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams)selectedMessagesCountTextView.getLayoutParams(); - layoutParams1.weight = 1; - layoutParams1.width = 0; - layoutParams1.height = LinearLayout.LayoutParams.MATCH_PARENT; - selectedMessagesCountTextView.setLayoutParams(layoutParams1); - - if ((int) dialog_id != 0) { - actionModeViews.add(actionMode.addItem(forward, R.drawable.ic_ab_fwd_forward, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); - } - actionModeViews.add(actionMode.addItem(delete, R.drawable.ic_ab_fwd_delete, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); - - - FrameLayout frameLayout; - fragmentView = frameLayout = new FrameLayout(getParentActivity()); - fragmentView.setBackgroundColor(0xfff0f0f0); - - mediaListView = new ListView(getParentActivity()); - mediaListView.setDivider(null); - mediaListView.setDividerHeight(0); - mediaListView.setVerticalScrollBarEnabled(false); - mediaListView.setDrawSelectorOnTop(true); - frameLayout.addView(mediaListView); - layoutParams = (FrameLayout.LayoutParams) mediaListView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.gravity = Gravity.TOP; - mediaListView.setLayoutParams(layoutParams); - mediaListView.setAdapter(documentsAdapter = new SharedDocumentsAdapter(getParentActivity())); - mediaListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, final int i, long l) { - if (view instanceof SharedDocumentCell) { - SharedDocumentCell cell = (SharedDocumentCell) view; - MessageObject message = cell.getDocument(); - if (actionBar.isActionModeShowed()) { - if (selectedFiles.containsKey(message.messageOwner.id)) { - selectedFiles.remove(message.messageOwner.id); - } else { - selectedFiles.put(message.messageOwner.id, message); - } - if (selectedFiles.isEmpty()) { - actionBar.hideActionMode(); - } else { - selectedMessagesCountTextView.setText(String.format("%d", selectedFiles.size())); - } - scrolling = false; - if (view instanceof SharedDocumentCell) { - ((SharedDocumentCell) view).setChecked(selectedFiles.containsKey(message.messageOwner.id), true); - } - } else { - if (cell.isLoaded()) { - File f = null; - String fileName = FileLoader.getAttachFileName(message.messageOwner.media.document); - if (message.messageOwner.attachPath != null && message.messageOwner.attachPath.length() != 0) { - f = new File(message.messageOwner.attachPath); - } - if (f == null || f != null && !f.exists()) { - f = FileLoader.getPathToMessage(message.messageOwner); - } - if (f != null && f.exists()) { - String realMimeType = null; - try { - Intent intent = new Intent(Intent.ACTION_VIEW); - MimeTypeMap myMime = MimeTypeMap.getSingleton(); - int idx = fileName.lastIndexOf("."); - if (idx != -1) { - String ext = fileName.substring(idx + 1); - realMimeType = myMime.getMimeTypeFromExtension(ext.toLowerCase()); - if (realMimeType == null) { - realMimeType = message.messageOwner.media.document.mime_type; - if (realMimeType == null || realMimeType.length() == 0) { - realMimeType = null; - } - } - if (realMimeType != null) { - intent.setDataAndType(Uri.fromFile(f), realMimeType); - } else { - intent.setDataAndType(Uri.fromFile(f), "text/plain"); - } - } else { - intent.setDataAndType(Uri.fromFile(f), "text/plain"); - } - if (realMimeType != null) { - try { - getParentActivity().startActivity(intent); - } catch (Exception e) { - intent.setDataAndType(Uri.fromFile(f), "text/plain"); - getParentActivity().startActivity(intent); - } - } else { - getParentActivity().startActivity(intent); - } - } catch (Exception e) { - if (getParentActivity() == null) { - return; - } - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null); - builder.setMessage(LocaleController.formatString("NoHandleAppInstalled", R.string.NoHandleAppInstalled, message.messageOwner.media.document.mime_type)); - showAlertDialog(builder); - } - } - } else if (!cell.isLoading()) { - FileLoader.getInstance().loadFile(cell.getDocument().messageOwner.media.document, true, false); - cell.updateFileExistIcon(); - } else { - FileLoader.getInstance().cancelLoadFile(cell.getDocument().messageOwner.media.document); - cell.updateFileExistIcon(); - } - } - } - } - }); - mediaListView.setOnScrollListener(new AbsListView.OnScrollListener() { - @Override - public void onScrollStateChanged(AbsListView view, int scrollState) { - scrolling = scrollState != SCROLL_STATE_IDLE; - } - - @Override - public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - if (visibleItemCount != 0 && firstVisibleItem + visibleItemCount > totalItemCount - 2 && !sharedMediaData[1].loading && !sharedMediaData[1].endReached) { - sharedMediaData[1].loading = true; - SharedMediaQuery.loadMedia(dialog_id, 0, 50, sharedMediaData[1].max_id, SharedMediaQuery.MEDIA_FILE, !sharedMediaData[1].cacheEndReached, classGuid); - } - } - }); - mediaListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { - @Override - public boolean onItemLongClick(AdapterView parent, View view, int i, long id) { - if (actionBar.isActionModeShowed() || i < 0 || i >= sharedMediaData[1].messages.size()) { - return false; - } - MessageObject item = sharedMediaData[1].messages.get(i); - selectedFiles.put(item.messageOwner.id, item); - selectedMessagesCountTextView.setText(String.format("%d", selectedFiles.size())); - if (Build.VERSION.SDK_INT >= 11) { - AnimatorSetProxy animatorSet = new AnimatorSetProxy(); - ArrayList animators = new ArrayList<>(); - for (int a = 0; a < actionModeViews.size(); a++) { - View view2 = actionModeViews.get(a); - AndroidUtilities.clearDrawableAnimation(view2); - if (a < 1) { - animators.add(ObjectAnimatorProxy.ofFloat(view2, "translationX", -AndroidUtilities.dp(56), 0)); - } else { - animators.add(ObjectAnimatorProxy.ofFloat(view2, "scaleY", 0.1f, 1.0f)); - } - } - animatorSet.playTogether(animators); - animatorSet.setDuration(250); - animatorSet.start(); - } - scrolling = false; - if (view instanceof SharedDocumentCell) { - ((SharedDocumentCell) view).setChecked(true, true); - } - actionBar.showActionMode(); - return true; - } - }); - - listView = new GridView(getParentActivity()); - listView.setPadding(AndroidUtilities.dp(2), 0, AndroidUtilities.dp(2), AndroidUtilities.dp(2)); - listView.setClipToPadding(false); - listView.setDrawSelectorOnTop(true); - listView.setVerticalSpacing(AndroidUtilities.dp(4)); - listView.setHorizontalSpacing(AndroidUtilities.dp(4)); - listView.setSelector(R.drawable.list_selector); - listView.setGravity(Gravity.CENTER); - listView.setNumColumns(GridView.AUTO_FIT); - listView.setStretchMode(GridView.STRETCH_COLUMN_WIDTH); - frameLayout.addView(listView); - layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - listView.setLayoutParams(layoutParams); - listView.setAdapter(listAdapter = new ListAdapter(getParentActivity())); - listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, int i, long l) { - if (i < 0 || i >= sharedMediaData[selectedMode].messages.size()) { + finishFragment(); + } else if (id == -2) { + selectedFiles.clear(); + actionBar.hideActionMode(); + listView.invalidateViews(); + } else if (id == shared_media_item) { + if (selectedMode == 0) { return; } - if (selectedMode == 0) { - PhotoViewer.getInstance().setParentActivity(getParentActivity()); - PhotoViewer.getInstance().openPhoto(sharedMediaData[selectedMode].messages, i, MediaActivity.this); - } else if (selectedMode == 1) { - + selectedMode = 0; + switchToCurrentSelectedMode(); + } else if (id == files_item) { + if (selectedMode == 1) { + return; } - } - }); - listView.setOnScrollListener(new AbsListView.OnScrollListener() { - @Override - public void onScrollStateChanged(AbsListView absListView, int i) { - - } - - @Override - public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - if (visibleItemCount != 0 && firstVisibleItem + visibleItemCount > totalItemCount - 2 && !sharedMediaData[0].loading && !sharedMediaData[0].endReached) { - sharedMediaData[0].loading = true; - SharedMediaQuery.loadMedia(dialog_id, 0, 50, sharedMediaData[0].max_id, SharedMediaQuery.MEDIA_PHOTOVIDEO, !sharedMediaData[0].cacheEndReached, classGuid); + selectedMode = 1; + switchToCurrentSelectedMode(); + } else if (id == delete) { + if (getParentActivity() == null) { + return; } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.formatString("AreYouSureDeleteMessages", R.string.AreYouSureDeleteMessages, LocaleController.formatPluralString("items", selectedFiles.size()))); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + ArrayList ids = new ArrayList<>(selectedFiles.keySet()); + ArrayList random_ids = null; + TLRPC.EncryptedChat currentEncryptedChat = null; + if ((int) dialog_id == 0) { + currentEncryptedChat = MessagesController.getInstance().getEncryptedChat((int) (dialog_id >> 32)); + } + if (currentEncryptedChat != null) { + random_ids = new ArrayList<>(); + for (HashMap.Entry entry : selectedFiles.entrySet()) { + MessageObject msg = entry.getValue(); + if (msg.messageOwner.random_id != 0 && msg.type != 10) { + random_ids.add(msg.messageOwner.random_id); + } + } + } + MessagesController.getInstance().deleteMessages(ids, random_ids, currentEncryptedChat); + actionBar.hideActionMode(); + selectedFiles.clear(); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } else if (id == forward) { + Bundle args = new Bundle(); + args.putBoolean("onlySelect", true); + args.putBoolean("serverOnly", true); + MessagesActivity fragment = new MessagesActivity(args); + fragment.setDelegate(new MessagesActivity.MessagesActivityDelegate() { + @Override + public void didSelectDialog(MessagesActivity fragment, long did, boolean param) { + int lower_part = (int) did; + if (lower_part != 0) { + Bundle args = new Bundle(); + args.putBoolean("scrollToTopOnResume", true); + if (lower_part > 0) { + args.putInt("user_id", lower_part); + } else if (lower_part < 0) { + args.putInt("chat_id", -lower_part); + } + + ArrayList fmessages = new ArrayList<>(); + ArrayList ids = new ArrayList<>(selectedFiles.keySet()); + Collections.sort(ids); + for (Integer id : ids) { + if (id > 0) { + fmessages.add(selectedFiles.get(id)); + } + } + selectedFiles.clear(); + actionBar.hideActionMode(); + + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); + ChatActivity chatActivity = new ChatActivity(args); + presentFragment(chatActivity, true); + chatActivity.showReplyPanel(true, null, fmessages, null, false, false); + + if (!AndroidUtilities.isTablet()) { + removeSelfFromStack(); + Activity parentActivity = getParentActivity(); + if (parentActivity == null) { + parentActivity = chatActivity.getParentActivity(); + } + if (parentActivity != null) { + parentActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + } + } + } else { + fragment.finishFragment(); + } + } + }); + presentFragment(fragment); } - }); - - emptyView = new LinearLayout(getParentActivity()); - emptyView.setOrientation(LinearLayout.VERTICAL); - emptyView.setGravity(Gravity.CENTER); - emptyView.setVisibility(View.GONE); - frameLayout.addView(emptyView); - layoutParams = (FrameLayout.LayoutParams) emptyView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - emptyView.setLayoutParams(layoutParams); - emptyView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return true; - } - }); - - emptyImageView = new ImageView(getParentActivity()); - emptyView.addView(emptyImageView); - layoutParams1 = (LinearLayout.LayoutParams) emptyImageView.getLayoutParams(); - layoutParams1.width = LinearLayout.LayoutParams.WRAP_CONTENT; - layoutParams1.height = LinearLayout.LayoutParams.WRAP_CONTENT; - emptyImageView.setLayoutParams(layoutParams1); - - emptyTextView = new TextView(getParentActivity()); - emptyTextView.setTextColor(0xff8a8a8a); - emptyTextView.setGravity(Gravity.CENTER); - emptyTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 17); - emptyTextView.setPadding(AndroidUtilities.dp(40), 0, AndroidUtilities.dp(40), AndroidUtilities.dp(128)); - emptyView.addView(emptyTextView); - layoutParams1 = (LinearLayout.LayoutParams) emptyTextView.getLayoutParams(); - layoutParams1.topMargin = AndroidUtilities.dp(24); - layoutParams1.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams1.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams1.gravity = Gravity.CENTER; - emptyTextView.setLayoutParams(layoutParams1); - - progressView = new LinearLayout(getParentActivity()); - progressView.setGravity(Gravity.CENTER); - progressView.setOrientation(LinearLayout.VERTICAL); - progressView.setVisibility(View.GONE); - frameLayout.addView(progressView); - layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - progressView.setLayoutParams(layoutParams); - - ProgressBar progressBar = new ProgressBar(getParentActivity()); - progressView.addView(progressBar); - layoutParams1 = (LinearLayout.LayoutParams) progressBar.getLayoutParams(); - layoutParams1.width = LinearLayout.LayoutParams.WRAP_CONTENT; - layoutParams1.height = LinearLayout.LayoutParams.WRAP_CONTENT; - progressBar.setLayoutParams(layoutParams1); - - switchToCurrentSelectedMode(); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); } + }); + + selectedFiles.clear(); + actionModeViews.clear(); + + final ActionBarMenu menu = actionBar.createMenu(); + searchItem = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true).setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() { + @Override + public void onSearchExpand() { + dropDownContainer.setVisibility(View.GONE); + searching = true; + } + + @Override + public boolean onSearchCollapse() { + dropDownContainer.setVisibility(View.VISIBLE); + documentsSearchAdapter.searchDocuments(null); + searching = false; + searchWas = false; + switchToCurrentSelectedMode(); + + return true; + } + + @Override + public void onTextChanged(EditText editText) { + if (documentsSearchAdapter == null) { + return; + } + String text = editText.getText().toString(); + if (text.length() != 0) { + searchWas = true; + switchToCurrentSelectedMode(); + } + documentsSearchAdapter.searchDocuments(text); + } + }); + searchItem.getSearchField().setHint(LocaleController.getString("Search", R.string.Search)); + searchItem.setVisibility(View.GONE); + + dropDownContainer = new ActionBarMenuItem(context, menu, R.drawable.bar_selector); + dropDownContainer.setSubMenuOpenSide(1); + dropDownContainer.addSubItem(shared_media_item, LocaleController.getString("SharedMediaTitle", R.string.SharedMediaTitle), 0); + dropDownContainer.addSubItem(files_item, LocaleController.getString("DocumentsTitle", R.string.DocumentsTitle), 0); + actionBar.addView(dropDownContainer); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) dropDownContainer.getLayoutParams(); + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.rightMargin = AndroidUtilities.dp(40); + layoutParams.leftMargin = AndroidUtilities.isTablet() ? AndroidUtilities.dp(64) : AndroidUtilities.dp(56); + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + dropDownContainer.setLayoutParams(layoutParams); + dropDownContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + dropDownContainer.toggleSubMenu(); + } + }); + + dropDown = new TextView(context); + dropDown.setGravity(Gravity.LEFT); + dropDown.setSingleLine(true); + dropDown.setLines(1); + dropDown.setMaxLines(1); + dropDown.setEllipsize(TextUtils.TruncateAt.END); + dropDown.setTextColor(0xffffffff); + dropDown.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + dropDown.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_arrow_drop_down, 0); + dropDown.setCompoundDrawablePadding(AndroidUtilities.dp(4)); + dropDown.setPadding(0, 0, AndroidUtilities.dp(10), 0); + dropDownContainer.addView(dropDown); + layoutParams = (FrameLayout.LayoutParams) dropDown.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.leftMargin = AndroidUtilities.dp(16); + layoutParams.gravity = Gravity.CENTER_VERTICAL; + dropDown.setLayoutParams(layoutParams); + + final ActionBarMenu actionMode = actionBar.createActionMode(); + actionModeViews.add(actionMode.addItem(-2, R.drawable.ic_ab_back_grey, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); + + selectedMessagesCountTextView = new TextView(actionMode.getContext()); + selectedMessagesCountTextView.setTextSize(18); + selectedMessagesCountTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + selectedMessagesCountTextView.setTextColor(0xff737373); + selectedMessagesCountTextView.setSingleLine(true); + selectedMessagesCountTextView.setLines(1); + selectedMessagesCountTextView.setEllipsize(TextUtils.TruncateAt.END); + selectedMessagesCountTextView.setPadding(AndroidUtilities.dp(11), 0, 0, AndroidUtilities.dp(2)); + selectedMessagesCountTextView.setGravity(Gravity.CENTER_VERTICAL); + selectedMessagesCountTextView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + actionMode.addView(selectedMessagesCountTextView); + LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams) selectedMessagesCountTextView.getLayoutParams(); + layoutParams1.weight = 1; + layoutParams1.width = 0; + layoutParams1.height = LinearLayout.LayoutParams.MATCH_PARENT; + selectedMessagesCountTextView.setLayoutParams(layoutParams1); + + if ((int) dialog_id != 0) { + actionModeViews.add(actionMode.addItem(forward, R.drawable.ic_ab_fwd_forward, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); } + actionModeViews.add(actionMode.addItem(delete, R.drawable.ic_ab_fwd_delete, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); + + photoVideoAdapter = new SharedPhotoVideoAdapter(context); + documentsAdapter = new SharedDocumentsAdapter(context); + documentsSearchAdapter = new DocumentsSearchAdapter(context); + + FrameLayout frameLayout; + fragmentView = frameLayout = new FrameLayout(context); + + listView = new SectionsListView(context); + listView.setDivider(null); + listView.setDividerHeight(0); + listView.setDrawSelectorOnTop(true); + listView.setClipToPadding(false); + frameLayout.addView(listView); + layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP; + listView.setLayoutParams(layoutParams); + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, final int i, long l) { + if (selectedMode == 1 && view instanceof SharedDocumentCell) { + SharedDocumentCell cell = (SharedDocumentCell) view; + MessageObject message = cell.getDocument(); + MediaActivity.this.onItemClick(i, view, message, 0); + } + } + }); + listView.setOnScrollListener(new AbsListView.OnScrollListener() { + @Override + public void onScrollStateChanged(AbsListView view, int scrollState) { + if (scrollState == SCROLL_STATE_TOUCH_SCROLL && searching && searchWas) { + AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); + } + scrolling = scrollState != SCROLL_STATE_IDLE; + } + + @Override + public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { + if (searching && searchWas) { + return; + } + if (visibleItemCount != 0 && firstVisibleItem + visibleItemCount > totalItemCount - 2 && !sharedMediaData[selectedMode].loading && !sharedMediaData[selectedMode].endReached) { + sharedMediaData[selectedMode].loading = true; + int type; + if (selectedMode == 0) { + type = SharedMediaQuery.MEDIA_PHOTOVIDEO; + } else if (selectedMode == 1) { + type = SharedMediaQuery.MEDIA_FILE; + } else { + type = SharedMediaQuery.MEDIA_AUDIO; + } + SharedMediaQuery.loadMedia(dialog_id, 0, 50, sharedMediaData[selectedMode].max_id, type, !sharedMediaData[selectedMode].cacheEndReached, classGuid); + } + } + }); + listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, int i, long id) { + if (selectedMode == 1 && view instanceof SharedDocumentCell) { + SharedDocumentCell cell = (SharedDocumentCell) view; + MessageObject message = cell.getDocument(); + return MediaActivity.this.onItemLongClick(message, view, 0); + } + return false; + } + }); + + for (int a = 0; a < 6; a++) { + cellCache.add(new SharedPhotoVideoCell(context)); + } + + emptyView = new LinearLayout(context); + emptyView.setOrientation(LinearLayout.VERTICAL); + emptyView.setGravity(Gravity.CENTER); + emptyView.setVisibility(View.GONE); + emptyView.setBackgroundColor(0xfff0f0f0); + frameLayout.addView(emptyView); + layoutParams = (FrameLayout.LayoutParams) emptyView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + emptyView.setLayoutParams(layoutParams); + emptyView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + emptyImageView = new ImageView(context); + emptyView.addView(emptyImageView); + layoutParams1 = (LinearLayout.LayoutParams) emptyImageView.getLayoutParams(); + layoutParams1.width = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams1.height = LinearLayout.LayoutParams.WRAP_CONTENT; + emptyImageView.setLayoutParams(layoutParams1); + + emptyTextView = new TextView(context); + emptyTextView.setTextColor(0xff8a8a8a); + emptyTextView.setGravity(Gravity.CENTER); + emptyTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 17); + emptyTextView.setPadding(AndroidUtilities.dp(40), 0, AndroidUtilities.dp(40), AndroidUtilities.dp(128)); + emptyView.addView(emptyTextView); + layoutParams1 = (LinearLayout.LayoutParams) emptyTextView.getLayoutParams(); + layoutParams1.topMargin = AndroidUtilities.dp(24); + layoutParams1.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams1.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams1.gravity = Gravity.CENTER; + emptyTextView.setLayoutParams(layoutParams1); + + progressView = new LinearLayout(context); + progressView.setGravity(Gravity.CENTER); + progressView.setOrientation(LinearLayout.VERTICAL); + progressView.setVisibility(View.GONE); + progressView.setBackgroundColor(0xfff0f0f0); + frameLayout.addView(progressView); + layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + progressView.setLayoutParams(layoutParams); + + ProgressBar progressBar = new ProgressBar(context); + progressView.addView(progressBar); + layoutParams1 = (LinearLayout.LayoutParams) progressBar.getLayoutParams(); + layoutParams1.width = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams1.height = LinearLayout.LayoutParams.WRAP_CONTENT; + progressBar.setLayoutParams(layoutParams1); + + switchToCurrentSelectedMode(); + return fragmentView; } @@ -621,16 +585,7 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No boolean added = false; boolean enc = ((int) dialog_id) == 0; for (MessageObject message : arr) { - if (!sharedMediaData[type].messagesDict.containsKey(message.messageOwner.id)) { - if (!enc) { - if (message.messageOwner.id > 0) { - sharedMediaData[type].max_id = Math.min(message.messageOwner.id, sharedMediaData[type].max_id); - } - } else { - sharedMediaData[type].max_id = Math.max(message.messageOwner.id, sharedMediaData[type].max_id); - } - sharedMediaData[type].messagesDict.put(message.messageOwner.id, message); - sharedMediaData[type].messages.add(message); + if (sharedMediaData[type].addMessage(message, false, enc)) { added = true; } } @@ -641,25 +596,23 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No if (progressView != null) { progressView.setVisibility(View.GONE); } - if (type == 0) { - if (listView != null) { - if (listView.getEmptyView() == null) { - listView.setEmptyView(emptyView); - } - } - } else if (type == 1) { - if (mediaListView != null) { - if (mediaListView.getEmptyView() == null) { - mediaListView.setEmptyView(emptyView); - } + if (selectedMode == type && listView != null) { + if (listView.getEmptyView() == null) { + listView.setEmptyView(emptyView); } } - if (listAdapter != null) { - listAdapter.notifyDataSetChanged(); + scrolling = true; + if (selectedMode == 0 && type == 0) { + if (photoVideoAdapter != null) { + photoVideoAdapter.notifyDataSetChanged(); + } + } else if (selectedMode == 1 && type == 1) { + if (documentsAdapter != null) { + documentsAdapter.notifyDataSetChanged(); + } } - if (documentsAdapter != null) { - scrolling = true; - documentsAdapter.notifyDataSetChanged(); + if (selectedMode == 1) { + searchItem.setVisibility(!sharedMediaData[selectedMode].messages.isEmpty() && !searching ? View.VISIBLE : View.GONE); } } } else if (id == NotificationCenter.messagesDeleted) { @@ -667,28 +620,30 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No boolean updated = false; for (Integer ids : markAsDeletedMessages) { for (SharedMediaData data : sharedMediaData) { - MessageObject obj = data.messagesDict.get(ids); - if (obj != null) { - data.messages.remove(obj); - data.messagesDict.remove(ids); - data.totalCount--; + if (data.deleteMessage(ids)) { updated = true; } } } - if (updated && listAdapter != null) { - listAdapter.notifyDataSetChanged(); - } - if (documentsAdapter != null) { + if (updated) { scrolling = true; - documentsAdapter.notifyDataSetChanged(); + if (photoVideoAdapter != null) { + photoVideoAdapter.notifyDataSetChanged(); + } + if (documentsAdapter != null) { + documentsAdapter.notifyDataSetChanged(); + } + if (selectedMode == 1) { + searchItem.setVisibility(!sharedMediaData[selectedMode].messages.isEmpty() && !searching ? View.VISIBLE : View.GONE); + } } } else if (id == NotificationCenter.didReceivedNewMessages) { long uid = (Long) args[0]; if (uid == dialog_id) { boolean markAsRead = false; ArrayList arr = (ArrayList) args[1]; - + boolean enc = ((int) dialog_id) == 0; + boolean updated = false; for (MessageObject obj : arr) { if (obj.messageOwner.media == null) { continue; @@ -697,38 +652,28 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No if (type == -1) { return; } - if (sharedMediaData[type].messagesDict.containsKey(obj.messageOwner.id)) { - continue; + if (sharedMediaData[type].addMessage(obj, true, enc)) { + updated = true; } - boolean enc = ((int) dialog_id) == 0; - if (!enc) { - if (obj.messageOwner.id > 0) { - sharedMediaData[type].max_id = Math.min(obj.messageOwner.id, sharedMediaData[type].max_id); - } - } else { - sharedMediaData[type].max_id = Math.max(obj.messageOwner.id, sharedMediaData[type].max_id); - } - sharedMediaData[type].messagesDict.put(obj.messageOwner.id, obj); - sharedMediaData[type].messages.add(0, obj); } - if (listAdapter != null) { - listAdapter.notifyDataSetChanged(); - } - if (documentsAdapter != null) { + if (updated) { scrolling = true; - documentsAdapter.notifyDataSetChanged(); + if (photoVideoAdapter != null) { + photoVideoAdapter.notifyDataSetChanged(); + } + if (documentsAdapter != null) { + documentsAdapter.notifyDataSetChanged(); + } + if (selectedMode == 1) { + searchItem.setVisibility(!sharedMediaData[selectedMode].messages.isEmpty() && !searching ? View.VISIBLE : View.GONE); + } } } } else if (id == NotificationCenter.messageReceivedByServer) { Integer msgId = (Integer) args[0]; + Integer newMsgId = (Integer) args[1]; for (SharedMediaData data : sharedMediaData) { - MessageObject obj = data.messagesDict.get(msgId); - if (obj != null) { - Integer newMsgId = (Integer) args[1]; - data.messagesDict.remove(msgId); - data.messagesDict.put(newMsgId, obj); - obj.messageOwner.id = newMsgId; - } + data.replaceMid(msgId, newMsgId); } } } @@ -736,48 +681,65 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No @Override public void onResume() { super.onResume(); - if (listAdapter != null) { - listAdapter.notifyDataSetChanged(); + scrolling = true; + if (photoVideoAdapter != null) { + photoVideoAdapter.notifyDataSetChanged(); } if (documentsAdapter != null) { - scrolling = true; documentsAdapter.notifyDataSetChanged(); } - fixLayout(); + fixLayoutInternal(); } @Override public void onConfigurationChanged(android.content.res.Configuration newConfig) { super.onConfigurationChanged(newConfig); - fixLayout(); + if (listView != null) { + ViewTreeObserver obs = listView.getViewTreeObserver(); + obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + listView.getViewTreeObserver().removeOnPreDrawListener(this); + fixLayoutInternal(); + return false; + } + }); + } + } + + @Override + public void updatePhotoAtIndex(int index) { + } @Override public PhotoViewer.PlaceProviderObject getPlaceForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index) { - if (messageObject == null || listView == null) { + if (messageObject == null || listView == null || selectedMode != 0) { return null; } int count = listView.getChildCount(); for (int a = 0; a < count; a++) { View view = listView.getChildAt(a); - BackupImageView imageView = (BackupImageView)view.findViewById(R.id.media_photo_image); - if (imageView != null) { - int num = (Integer)imageView.getTag(); - if (num < 0 || num >= sharedMediaData[0].messages.size()) { - continue; - } - MessageObject message = sharedMediaData[0].messages.get(num); - if (message != null && message.messageOwner.id == messageObject.messageOwner.id) { - int coords[] = new int[2]; - imageView.getLocationInWindow(coords); - PhotoViewer.PlaceProviderObject object = new PhotoViewer.PlaceProviderObject(); - object.viewX = coords[0]; - object.viewY = coords[1] - AndroidUtilities.statusBarHeight; - object.parentView = listView; - object.imageReceiver = imageView.imageReceiver; - object.thumb = object.imageReceiver.getBitmap(); - return object; + if (view instanceof SharedPhotoVideoCell) { + SharedPhotoVideoCell cell = (SharedPhotoVideoCell) view; + for (int i = 0; i < 6; i++) { + MessageObject message = cell.getMessageObject(i); + if (message == null) { + break; + } + BackupImageView imageView = cell.getImageView(i); + if (message.getId() == messageObject.getId()) { + int coords[] = new int[2]; + imageView.getLocationInWindow(coords); + PhotoViewer.PlaceProviderObject object = new PhotoViewer.PlaceProviderObject(); + object.viewX = coords[0]; + object.viewY = coords[1] - AndroidUtilities.statusBarHeight; + object.parentView = listView; + object.imageReceiver = imageView.getImageReceiver(); + object.thumb = object.imageReceiver.getBitmap(); + return object; + } } } } @@ -811,106 +773,222 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No public int getSelectedCount() { return 0; } private void switchToCurrentSelectedMode() { - if (selectedMode == 0) { - mediaListView.setEmptyView(null); - mediaListView.setVisibility(View.GONE); - mediaListView.setAdapter(null); - - listView.setAdapter(listAdapter); - - dropDown.setText(LocaleController.getString("SharedMedia", R.string.SharedMedia)); - emptyImageView.setImageResource(R.drawable.tip1); - emptyTextView.setText(LocaleController.getString("NoMedia", R.string.NoMedia)); - searchItem.setVisibility(View.GONE); - if (sharedMediaData[selectedMode].loading && sharedMediaData[selectedMode].messages.isEmpty()) { - progressView.setVisibility(View.VISIBLE); - listView.setEmptyView(null); - emptyView.setVisibility(View.GONE); - } else { - progressView.setVisibility(View.GONE); - listView.setEmptyView(emptyView); + if (searching && searchWas) { + if (listView != null) { + listView.setAdapter(documentsSearchAdapter); + documentsSearchAdapter.notifyDataSetChanged(); } - listView.setVisibility(View.VISIBLE); - } else if (selectedMode == 1) { - listView.setEmptyView(null); - listView.setVisibility(View.GONE); - listView.setAdapter(null); - - mediaListView.setAdapter(documentsAdapter); - - dropDown.setText(LocaleController.getString("DocumentsTitle", R.string.DocumentsTitle)); - int lower_id = (int) dialog_id; - emptyImageView.setImageResource(R.drawable.tip2); - emptyTextView.setText(LocaleController.getString("NoSharedFiles", R.string.NoSharedFiles)); - //searchItem.setVisibility(View.VISIBLE); - if (!sharedMediaData[1].loading && !sharedMediaData[1].endReached && sharedMediaData[1].messages.isEmpty()) { - sharedMediaData[selectedMode].loading = true; - SharedMediaQuery.loadMedia(dialog_id, 0, 50, 0, SharedMediaQuery.MEDIA_FILE, true, classGuid); + if (emptyTextView != null) { + emptyTextView.setText(LocaleController.getString("NoResult", R.string.NoResult)); + emptyTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); + emptyImageView.setVisibility(View.GONE); } - mediaListView.setVisibility(View.VISIBLE); - - if (sharedMediaData[selectedMode].loading && sharedMediaData[selectedMode].messages.isEmpty()) { - progressView.setVisibility(View.VISIBLE); - mediaListView.setEmptyView(null); - emptyView.setVisibility(View.GONE); - } else { - progressView.setVisibility(View.GONE); - mediaListView.setEmptyView(emptyView); - } - } - } - - private void fixLayout() { - if (listView != null) { - ViewTreeObserver obs = listView.getViewTreeObserver(); - obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { - WindowManager manager = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); - int rotation = manager.getDefaultDisplay().getRotation(); - - if (AndroidUtilities.isTablet()) { - listView.setNumColumns(4); - itemWidth = AndroidUtilities.dp(490) / 4 - AndroidUtilities.dp(2) * 3; - listView.setColumnWidth(itemWidth); - emptyTextView.setPadding(AndroidUtilities.dp(40), 0, AndroidUtilities.dp(40), AndroidUtilities.dp(128)); - } else { - if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { - listView.setNumColumns(6); - itemWidth = AndroidUtilities.displaySize.x / 6 - AndroidUtilities.dp(2) * 5; - listView.setColumnWidth(itemWidth); - emptyTextView.setPadding(AndroidUtilities.dp(40), 0, AndroidUtilities.dp(40), 0); - } else { - listView.setNumColumns(4); - itemWidth = AndroidUtilities.displaySize.x / 4 - AndroidUtilities.dp(2) * 3; - listView.setColumnWidth(itemWidth); - emptyTextView.setPadding(AndroidUtilities.dp(40), 0, AndroidUtilities.dp(40), AndroidUtilities.dp(128)); - } - } - listView.setPadding(listView.getPaddingLeft(), AndroidUtilities.dp(4), listView.getPaddingRight(), listView.getPaddingBottom()); - listAdapter.notifyDataSetChanged(); - listView.getViewTreeObserver().removeOnPreDrawListener(this); - - if (dropDownContainer != null) { - if (!AndroidUtilities.isTablet()) { - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) dropDownContainer.getLayoutParams(); - layoutParams.topMargin = (Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0); - dropDownContainer.setLayoutParams(layoutParams); - } - - if (!AndroidUtilities.isTablet() && ApplicationLoader.applicationContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { - dropDown.setTextSize(18); - } else { - dropDown.setTextSize(20); - } - } - return false; + } else { + emptyTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 17); + emptyImageView.setVisibility(View.VISIBLE); + if (selectedMode == 0) { + listView.setAdapter(photoVideoAdapter); + dropDown.setText(LocaleController.getString("SharedMediaTitle", R.string.SharedMediaTitle)); + emptyImageView.setImageResource(R.drawable.tip1); + emptyTextView.setText(LocaleController.getString("NoMedia", R.string.NoMedia)); + searchItem.setVisibility(View.GONE); + if (sharedMediaData[selectedMode].loading && sharedMediaData[selectedMode].messages.isEmpty()) { + progressView.setVisibility(View.VISIBLE); + listView.setEmptyView(null); + emptyView.setVisibility(View.GONE); + } else { + progressView.setVisibility(View.GONE); + listView.setEmptyView(emptyView); } - }); + listView.setVisibility(View.VISIBLE); + listView.setPadding(0, 0, 0, AndroidUtilities.dp(4)); + } else if (selectedMode == 1) { + listView.setAdapter(documentsAdapter); + dropDown.setText(LocaleController.getString("DocumentsTitle", R.string.DocumentsTitle)); + int lower_id = (int) dialog_id; + emptyImageView.setImageResource(R.drawable.tip2); + emptyTextView.setText(LocaleController.getString("NoSharedFiles", R.string.NoSharedFiles)); + searchItem.setVisibility(!sharedMediaData[1].messages.isEmpty() ? View.VISIBLE : View.GONE); + if (!sharedMediaData[1].loading && !sharedMediaData[1].endReached && sharedMediaData[1].messages.isEmpty()) { + sharedMediaData[selectedMode].loading = true; + SharedMediaQuery.loadMedia(dialog_id, 0, 50, 0, SharedMediaQuery.MEDIA_FILE, true, classGuid); + } + listView.setVisibility(View.VISIBLE); + if (sharedMediaData[selectedMode].loading && sharedMediaData[selectedMode].messages.isEmpty()) { + progressView.setVisibility(View.VISIBLE); + listView.setEmptyView(null); + emptyView.setVisibility(View.GONE); + } else { + progressView.setVisibility(View.GONE); + listView.setEmptyView(emptyView); + } + listView.setPadding(0, 0, 0, AndroidUtilities.dp(4)); + } } } - private class SharedDocumentsAdapter extends BaseFragmentAdapter { + private boolean onItemLongClick(MessageObject item, View view, int a) { + if (actionBar.isActionModeShowed()) { + return false; + } + selectedFiles.put(item.getId(), item); + selectedMessagesCountTextView.setText(String.format("%d", selectedFiles.size())); + if (Build.VERSION.SDK_INT >= 11) { + AnimatorSetProxy animatorSet = new AnimatorSetProxy(); + ArrayList animators = new ArrayList<>(); + for (int i = 0; i < actionModeViews.size(); i++) { + View view2 = actionModeViews.get(i); + AndroidUtilities.clearDrawableAnimation(view2); + if (i < 1) { + animators.add(ObjectAnimatorProxy.ofFloat(view2, "translationX", -AndroidUtilities.dp(56), 0)); + } else { + animators.add(ObjectAnimatorProxy.ofFloat(view2, "scaleY", 0.1f, 1.0f)); + } + } + animatorSet.playTogether(animators); + animatorSet.setDuration(250); + animatorSet.start(); + } + scrolling = false; + if (view instanceof SharedDocumentCell) { + ((SharedDocumentCell) view).setChecked(true, true); + } else if (view instanceof SharedPhotoVideoCell) { + ((SharedPhotoVideoCell) view).setChecked(a, true, true); + } + actionBar.showActionMode(); + return true; + } + + private void onItemClick(int index, View view, MessageObject message, int a) { + if (message == null) { + return; + } + if (actionBar.isActionModeShowed()) { + if (selectedFiles.containsKey(message.getId())) { + selectedFiles.remove(message.getId()); + } else { + selectedFiles.put(message.getId(), message); + } + if (selectedFiles.isEmpty()) { + actionBar.hideActionMode(); + } else { + selectedMessagesCountTextView.setText(String.format("%d", selectedFiles.size())); + } + scrolling = false; + if (view instanceof SharedDocumentCell) { + ((SharedDocumentCell) view).setChecked(selectedFiles.containsKey(message.getId()), true); + } else if (view instanceof SharedPhotoVideoCell) { + ((SharedPhotoVideoCell) view).setChecked(a, selectedFiles.containsKey(message.getId()), true); + } + } else { + if (selectedMode == 0) { + PhotoViewer.getInstance().setParentActivity(getParentActivity()); + PhotoViewer.getInstance().openPhoto(sharedMediaData[selectedMode].messages, index, this); + } else if (selectedMode == 1) { + if (view instanceof SharedDocumentCell) { + SharedDocumentCell cell = (SharedDocumentCell) view; + if (cell.isLoaded()) { + File f = null; + String fileName = FileLoader.getAttachFileName(message.messageOwner.media.document); + if (message.messageOwner.attachPath != null && message.messageOwner.attachPath.length() != 0) { + f = new File(message.messageOwner.attachPath); + } + if (f == null || f != null && !f.exists()) { + f = FileLoader.getPathToMessage(message.messageOwner); + } + if (f != null && f.exists()) { + String realMimeType = null; + try { + Intent intent = new Intent(Intent.ACTION_VIEW); + MimeTypeMap myMime = MimeTypeMap.getSingleton(); + int idx = fileName.lastIndexOf("."); + if (idx != -1) { + String ext = fileName.substring(idx + 1); + realMimeType = myMime.getMimeTypeFromExtension(ext.toLowerCase()); + if (realMimeType == null) { + realMimeType = message.messageOwner.media.document.mime_type; + if (realMimeType == null || realMimeType.length() == 0) { + realMimeType = null; + } + } + if (realMimeType != null) { + intent.setDataAndType(Uri.fromFile(f), realMimeType); + } else { + intent.setDataAndType(Uri.fromFile(f), "text/plain"); + } + } else { + intent.setDataAndType(Uri.fromFile(f), "text/plain"); + } + if (realMimeType != null) { + try { + getParentActivity().startActivityForResult(intent, 500); + } catch (Exception e) { + intent.setDataAndType(Uri.fromFile(f), "text/plain"); + getParentActivity().startActivityForResult(intent, 500); + } + } else { + getParentActivity().startActivityForResult(intent, 500); + } + } catch (Exception e) { + if (getParentActivity() == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null); + builder.setMessage(LocaleController.formatString("NoHandleAppInstalled", R.string.NoHandleAppInstalled, message.messageOwner.media.document.mime_type)); + showAlertDialog(builder); + } + } + } else if (!cell.isLoading()) { + FileLoader.getInstance().loadFile(cell.getDocument().messageOwner.media.document, true, false); + cell.updateFileExistIcon(); + } else { + FileLoader.getInstance().cancelLoadFile(cell.getDocument().messageOwner.media.document); + cell.updateFileExistIcon(); + } + } + } + } + } + + private void fixLayoutInternal() { + if (listView == null) { + return; + } + WindowManager manager = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); + int rotation = manager.getDefaultDisplay().getRotation(); + + if (AndroidUtilities.isTablet()) { + columnsCount = 4; + emptyTextView.setPadding(AndroidUtilities.dp(40), 0, AndroidUtilities.dp(40), AndroidUtilities.dp(128)); + } else { + if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { + columnsCount = 6; + emptyTextView.setPadding(AndroidUtilities.dp(40), 0, AndroidUtilities.dp(40), 0); + } else { + columnsCount = 4; + emptyTextView.setPadding(AndroidUtilities.dp(40), 0, AndroidUtilities.dp(40), AndroidUtilities.dp(128)); + } + } + photoVideoAdapter.notifyDataSetChanged(); + + if (dropDownContainer != null) { + if (!AndroidUtilities.isTablet()) { + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) dropDownContainer.getLayoutParams(); + layoutParams.topMargin = (Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0); + dropDownContainer.setLayoutParams(layoutParams); + } + + if (!AndroidUtilities.isTablet() && ApplicationLoader.applicationContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + dropDown.setTextSize(18); + } else { + dropDown.setTextSize(20); + } + } + } + + private class SharedDocumentsAdapter extends BaseSectionsAdapter { private Context mContext; public SharedDocumentsAdapter(Context context) { @@ -918,204 +996,457 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No } @Override - public boolean areAllItemsEnabled() { - return false; - } - - @Override - public boolean isEnabled(int i) { - return i != sharedMediaData[1].messages.size(); - } - - @Override - public int getCount() { - return sharedMediaData[1].messages.size() + (sharedMediaData[1].messages.isEmpty() || sharedMediaData[1].endReached ? 0 : 1); - } - - @Override - public Object getItem(int i) { + public Object getItem(int section, int position) { return null; } @Override - public long getItemId(int i) { - return i; + public boolean isRowEnabled(int section, int row) { + return row != 0; } @Override - public boolean hasStableIds() { - return true; + public int getSectionCount() { + return sharedMediaData[1].sections.size() + (sharedMediaData[1].sections.isEmpty() || sharedMediaData[1].endReached ? 0 : 1); } @Override - public View getView(int i, View view, ViewGroup viewGroup) { - int type = getItemViewType(i); - if (type == 0) { - if (view == null) { - view = new SharedDocumentCell(mContext); - } - SharedDocumentCell sharedDocumentCell = (SharedDocumentCell) view; - sharedDocumentCell.setDocument(sharedMediaData[1].messages.get(i), i != sharedMediaData[1].messages.size() - 1 || sharedMediaData[1].loading); - if (actionBar.isActionModeShowed()) { - sharedDocumentCell.setChecked(selectedFiles.containsKey(sharedMediaData[1].messages.get(i).messageOwner.id), !scrolling); + public int getCountForSection(int section) { + if (section < sharedMediaData[1].sections.size()) { + return sharedMediaData[1].sectionArrays.get(sharedMediaData[1].sections.get(section)).size() + 1; + } + return 1; + } + + @Override + public View getSectionHeaderView(int section, View convertView, ViewGroup parent) { + if (convertView == null) { + convertView = new GreySectionCell(mContext); + } + if (section < sharedMediaData[1].sections.size()) { + String name = sharedMediaData[1].sections.get(section); + ArrayList messageObjects = sharedMediaData[1].sectionArrays.get(name); + MessageObject messageObject = messageObjects.get(0); + ((GreySectionCell) convertView).setText(LocaleController.formatterMonthYear.format((long) messageObject.messageOwner.date * 1000).toUpperCase()); + } + return convertView; + } + + @Override + public View getItemView(int section, int position, View convertView, ViewGroup parent) { + if (section < sharedMediaData[1].sections.size()) { + String name = sharedMediaData[1].sections.get(section); + ArrayList messageObjects = sharedMediaData[1].sectionArrays.get(name); + if (position == 0) { + if (convertView == null) { + convertView = new GreySectionCell(mContext); + } + MessageObject messageObject = messageObjects.get(0); + ((GreySectionCell) convertView).setText(LocaleController.formatterMonthYear.format((long) messageObject.messageOwner.date * 1000).toUpperCase()); } else { - sharedDocumentCell.setChecked(false, !scrolling); + if (convertView == null) { + convertView = new SharedDocumentCell(mContext); + } + SharedDocumentCell sharedDocumentCell = (SharedDocumentCell) convertView; + MessageObject messageObject = messageObjects.get(position - 1); + sharedDocumentCell.setDocument(messageObject, position != messageObjects.size() || section == sharedMediaData[1].sections.size() - 1 && sharedMediaData[1].loading); + if (actionBar.isActionModeShowed()) { + sharedDocumentCell.setChecked(selectedFiles.containsKey(messageObject.getId()), !scrolling); + } else { + sharedDocumentCell.setChecked(false, !scrolling); + } } - } else if (type == 1) { - if (view == null) { - view = new LoadingCell(mContext); + } else { + if (convertView == null) { + convertView = new LoadingCell(mContext); } } - return view; + return convertView; } @Override - public int getItemViewType(int i) { - if (i == sharedMediaData[1].messages.size()) { - return 1; + public int getItemViewType(int section, int position) { + if (section < sharedMediaData[1].sections.size()) { + if (position == 0) { + return 0; + } else { + return 1; + } } - return 0; - } - - @Override - public int getViewTypeCount() { return 2; } - @Override - public boolean isEmpty() { - return sharedMediaData[1].messages.isEmpty(); - } - } - - private class ListAdapter extends BaseFragmentAdapter { - private Context mContext; - - public ListAdapter(Context context) { - mContext = context; - } - - @Override - public boolean areAllItemsEnabled() { - return false; - } - - @Override - public boolean isEnabled(int i) { - return i != sharedMediaData[0].messages.size(); - } - - @Override - public int getCount() { - return sharedMediaData[0].messages.size() + (sharedMediaData[0].messages.isEmpty() || sharedMediaData[0].endReached ? 0 : 1); - } - - @Override - public Object getItem(int i) { - return null; - } - - @Override - public long getItemId(int i) { - return i; - } - - @Override - public boolean hasStableIds() { - return true; - } - - @Override - public View getView(int i, View view, ViewGroup viewGroup) { - int type = getItemViewType(i); - if (type == 0) { - MessageObject message = sharedMediaData[0].messages.get(i); - if (view == null) { - LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - view = li.inflate(R.layout.media_photo_layout, viewGroup, false); - } - ViewGroup.LayoutParams params = view.getLayoutParams(); - params.width = itemWidth; - params.height = itemWidth; - view.setLayoutParams(params); - - BackupImageView imageView = (BackupImageView)view.findViewById(R.id.media_photo_image); - imageView.setTag(i); - - imageView.imageReceiver.setParentMessageObject(message); - imageView.imageReceiver.setNeedsQualityThumb(true); - imageView.imageReceiver.setShouldGenerateQualityThumb(true); - if (message.messageOwner.media != null && message.messageOwner.media.photo != null && !message.messageOwner.media.photo.sizes.isEmpty()) { - TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(message.photoThumbs, 80); - imageView.setImage(null, null, null, mContext.getResources().getDrawable(R.drawable.photo_placeholder_in), null, photoSize.location, "b", 0); - } else { - imageView.setImageResource(R.drawable.photo_placeholder_in); - } - imageView.imageReceiver.setVisible(!PhotoViewer.getInstance().isShowingImage(message), false); - } else if (type == 1) { - MessageObject message = sharedMediaData[0].messages.get(i); - if (view == null) { - LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - view = li.inflate(R.layout.media_video_layout, viewGroup, false); - } - ViewGroup.LayoutParams params = view.getLayoutParams(); - params.width = itemWidth; - params.height = itemWidth; - view.setLayoutParams(params); - - TextView textView = (TextView)view.findViewById(R.id.chat_video_time); - BackupImageView imageView = (BackupImageView)view.findViewById(R.id.media_photo_image); - imageView.setTag(i); - - imageView.imageReceiver.setParentMessageObject(message); - imageView.imageReceiver.setNeedsQualityThumb(true); - imageView.imageReceiver.setShouldGenerateQualityThumb(true); - if (message.messageOwner.media.video != null && message.messageOwner.media.video.thumb != null) { - int duration = message.messageOwner.media.video.duration; - int minutes = duration / 60; - int seconds = duration - minutes * 60; - textView.setText(String.format("%d:%02d", minutes, seconds)); - TLRPC.FileLocation location = message.messageOwner.media.video.thumb.location; - imageView.setImage(null, null, null, mContext.getResources().getDrawable(R.drawable.photo_placeholder_in), null, location, "b", 0); - textView.setVisibility(View.VISIBLE); - } else { - textView.setVisibility(View.GONE); - imageView.setImageResource(R.drawable.photo_placeholder_in); - } - imageView.imageReceiver.setVisible(!PhotoViewer.getInstance().isShowingImage(message), false); - } else if (type == 2) { - if (view == null) { - LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - view = li.inflate(R.layout.media_loading_layout, viewGroup, false); - } - ViewGroup.LayoutParams params = view.getLayoutParams(); - params.width = itemWidth; - params.height = itemWidth; - view.setLayoutParams(params); - } - return view; - } - - @Override - public int getItemViewType(int i) { - if (i == sharedMediaData[0].messages.size()) { - return 2; - } - MessageObject message = sharedMediaData[0].messages.get(i); - if (message.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) { - return 1; - } - return 0; - } - @Override public int getViewTypeCount() { return 3; } + } + + private class SharedPhotoVideoAdapter extends BaseSectionsAdapter { + private Context mContext; + + public SharedPhotoVideoAdapter(Context context) { + mContext = context; + } + + @Override + public Object getItem(int section, int position) { + return null; + } + + @Override + public boolean isRowEnabled(int section, int row) { + return false; + } + + @Override + public int getSectionCount() { + return sharedMediaData[0].sections.size() + (sharedMediaData[0].sections.isEmpty() || sharedMediaData[0].endReached ? 0 : 1); + } + + @Override + public int getCountForSection(int section) { + if (section < sharedMediaData[0].sections.size()) { + return (int) Math.ceil(sharedMediaData[0].sectionArrays.get(sharedMediaData[0].sections.get(section)).size() / (float)columnsCount) + 1; + } + return 1; + } + + @Override + public View getSectionHeaderView(int section, View convertView, ViewGroup parent) { + if (convertView == null) { + convertView = new SharedMediaSectionCell(mContext); + convertView.setBackgroundColor(0xffffffff); + } + if (section < sharedMediaData[0].sections.size()) { + String name = sharedMediaData[0].sections.get(section); + ArrayList messageObjects = sharedMediaData[0].sectionArrays.get(name); + MessageObject messageObject = messageObjects.get(0); + ((SharedMediaSectionCell) convertView).setText(LocaleController.formatterMonthYear.format((long) messageObject.messageOwner.date * 1000).toUpperCase()); + } + return convertView; + } + + @Override + public View getItemView(int section, int position, View convertView, ViewGroup parent) { + if (section < sharedMediaData[0].sections.size()) { + String name = sharedMediaData[0].sections.get(section); + ArrayList messageObjects = sharedMediaData[0].sectionArrays.get(name); + if (position == 0) { + if (convertView == null) { + convertView = new SharedMediaSectionCell(mContext); + } + MessageObject messageObject = messageObjects.get(0); + ((SharedMediaSectionCell) convertView).setText(LocaleController.formatterMonthYear.format((long) messageObject.messageOwner.date * 1000).toUpperCase()); + } else { + SharedPhotoVideoCell cell = null; + if (convertView == null) { + if (!cellCache.isEmpty()) { + convertView = cellCache.get(0); + cellCache.remove(0); + } else { + convertView = new SharedPhotoVideoCell(mContext); + } + cell = (SharedPhotoVideoCell) convertView; + cell.setDelegate(new SharedPhotoVideoCell.SharedPhotoVideoCellDelegate() { + @Override + public void didClickItem(SharedPhotoVideoCell cell, int index, MessageObject messageObject, int a) { + onItemClick(index, cell, messageObject, a); + } + + @Override + public boolean didLongClickItem(SharedPhotoVideoCell cell, int index, MessageObject messageObject, int a) { + return onItemLongClick(messageObject, cell, a); + } + }); + } else { + cell = (SharedPhotoVideoCell) convertView; + } + cell.setItemsCount(columnsCount); + for (int a = 0; a < columnsCount; a++) { + int index = (position - 1) * columnsCount + a; + if (index < messageObjects.size()) { + MessageObject messageObject = messageObjects.get(index); + cell.setIsFirst(position == 1); + cell.setItem(a, sharedMediaData[0].messages.indexOf(messageObject), messageObject); + + if (actionBar.isActionModeShowed()) { + cell.setChecked(a, selectedFiles.containsKey(messageObject.getId()), !scrolling); + } else { + cell.setChecked(a, false, !scrolling); + } + } else { + cell.setItem(a, index, null); + } + } + cell.requestLayout(); + } + } else { + if (convertView == null) { + convertView = new LoadingCell(mContext); + } + } + return convertView; + } + + @Override + public int getItemViewType(int section, int position) { + if (section < sharedMediaData[0].sections.size()) { + if (position == 0) { + return 0; + } else { + return 1; + } + } + return 2; + } + + @Override + public int getViewTypeCount() { + return 3; + } + } + + public class DocumentsSearchAdapter extends BaseFragmentAdapter { + private Context mContext; + private ArrayList searchResult = new ArrayList<>(); + private Timer searchTimer; + protected ArrayList globalSearch = new ArrayList<>(); + private long reqId = 0; + private int lastReqId; + + public DocumentsSearchAdapter(Context context) { + mContext = context; + } + + public void queryServerSearch(final String query, final int max_id) { + int uid = (int) dialog_id; + if (uid == 0) { + return; + } + if (reqId != 0) { + ConnectionsManager.getInstance().cancelRpc(reqId, true); + reqId = 0; + } + if (query == null || query.length() == 0) { + globalSearch.clear(); + lastReqId = 0; + notifyDataSetChanged(); + return; + } + TLRPC.TL_messages_search req = new TLRPC.TL_messages_search(); + req.offset = 0; + req.limit = 50; + req.max_id = max_id; + req.filter = new TLRPC.TL_inputMessagesFilterDocument(); + req.q = query; + if (uid < 0) { + req.peer = new TLRPC.TL_inputPeerChat(); + req.peer.chat_id = -uid; + } else { + TLRPC.User user = MessagesController.getInstance().getUser(uid); + if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { + req.peer = new TLRPC.TL_inputPeerForeign(); + req.peer.access_hash = user.access_hash; + } else { + req.peer = new TLRPC.TL_inputPeerContact(); + } + req.peer.user_id = uid; + } + final int currentReqId = ++lastReqId; + reqId = ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, TLRPC.TL_error error) { + final ArrayList messageObjects = new ArrayList<>(); + if (error == null) { + TLRPC.messages_Messages res = (TLRPC.messages_Messages) response; + for (TLRPC.Message message : res.messages) { + messageObjects.add(new MessageObject(message, null, false)); + } + } + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (currentReqId == lastReqId) { + globalSearch = messageObjects; + notifyDataSetChanged(); + } + reqId = 0; + } + }); + } + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors); + ConnectionsManager.getInstance().bindRequestToGuid(reqId, classGuid); + } + + public void searchDocuments(final String query) { + try { + if (searchTimer != null) { + searchTimer.cancel(); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + if (query == null) { + searchResult.clear(); + notifyDataSetChanged(); + } else { + searchTimer = new Timer(); + searchTimer.schedule(new TimerTask() { + @Override + public void run() { + try { + searchTimer.cancel(); + searchTimer = null; + } catch (Exception e) { + FileLog.e("tmessages", e); + } + processSearch(query); + } + }, 200, 300); + } + } + + private void processSearch(final String query) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (!sharedMediaData[1].messages.isEmpty()) { + MessageObject messageObject = sharedMediaData[1].messages.get(sharedMediaData[1].messages.size() - 1); + queryServerSearch(query, messageObject.getId()); + } + final ArrayList copy = new ArrayList<>(); + copy.addAll(sharedMediaData[1].messages); + Utilities.searchQueue.postRunnable(new Runnable() { + @Override + public void run() { + String search1 = query.trim().toLowerCase(); + if (search1.length() == 0) { + updateSearchResults(new ArrayList()); + return; + } + String search2 = LocaleController.getInstance().getTranslitString(search1); + if (search1.equals(search2) || search2.length() == 0) { + search2 = null; + } + String search[] = new String[1 + (search2 != null ? 1 : 0)]; + search[0] = search1; + if (search2 != null) { + search[1] = search2; + } + + ArrayList resultArray = new ArrayList<>(); + + for (MessageObject messageObject : copy) { + for (String q : search) { + String name = messageObject.getDocumentName(); + if (name == null || name.length() == 0) { + continue; + } + name = name.toLowerCase(); + if (name.contains(q)) { + resultArray.add(messageObject); + break; + } + } + } + + updateSearchResults(resultArray); + } + }); + } + }); + } + + private void updateSearchResults(final ArrayList documents) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + searchResult = documents; + notifyDataSetChanged(); + } + }); + } + + @Override + public boolean areAllItemsEnabled() { + return false; + } + + @Override + public boolean isEnabled(int i) { + return i != searchResult.size(); + } + + @Override + public int getCount() { + int count = searchResult.size(); + int globalCount = globalSearch.size(); + if (globalCount != 0) { + count += globalCount; + } + return count; + } + + public boolean isGlobalSearch(int i) { + int localCount = searchResult.size(); + int globalCount = globalSearch.size(); + if (i >= 0 && i < localCount) { + return false; + } else if (i > localCount && i <= globalCount + localCount) { + return true; + } + return false; + } + + @Override + public MessageObject getItem(int i) { + if (i < searchResult.size()) { + return searchResult.get(i); + } else { + return globalSearch.get(i - searchResult.size()); + } + } + + @Override + public long getItemId(int i) { + return i; + } + + @Override + public boolean hasStableIds() { + return true; + } + + @Override + public View getView(int i, View view, ViewGroup viewGroup) { + if (view == null) { + view = new SharedDocumentCell(mContext); + } + SharedDocumentCell sharedDocumentCell = (SharedDocumentCell) view; + MessageObject messageObject = getItem(i); + sharedDocumentCell.setDocument(messageObject, i != getCount() - 1); + if (actionBar.isActionModeShowed()) { + sharedDocumentCell.setChecked(selectedFiles.containsKey(messageObject.getId()), !scrolling); + } else { + sharedDocumentCell.setChecked(false, !scrolling); + } + return view; + } + + @Override + public int getItemViewType(int i) { + return 0; + } + + @Override + public int getViewTypeCount() { + return 1; + } @Override public boolean isEmpty() { - return sharedMediaData[0].messages.isEmpty(); + return searchResult.isEmpty() && globalSearch.isEmpty(); } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java index d79c4cfe3..4d56274f6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java @@ -11,6 +11,7 @@ package org.telegram.ui; import android.animation.ObjectAnimator; import android.animation.StateListAnimator; import android.app.AlertDialog; +import android.content.Context; import android.content.DialogInterface; import android.content.res.Configuration; import android.graphics.Outline; @@ -26,7 +27,6 @@ import android.view.ViewTreeObserver; import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.AbsListView; import android.widget.AdapterView; -import android.widget.BaseAdapter; import android.widget.CheckBox; import android.widget.EditText; import android.widget.FrameLayout; @@ -67,6 +67,7 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter private View searchEmptyView; private View progressView; private View emptyView; + private ActionBarMenuItem passcodeItem; private ImageView floatingButton; private int prevPosition; private int prevTop; @@ -83,13 +84,16 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter private boolean searchWas = false; private boolean onlySelect = false; private long selectedDialog; + private String searchString; private MessagesActivityDelegate delegate; private long openedDialogId = 0; - public static interface MessagesActivityDelegate { - public abstract void didSelectDialog(MessagesActivity fragment, long dialog_id, boolean param); + private static final int passcode_menu_item = 1; + + public interface MessagesActivityDelegate { + void didSelectDialog(MessagesActivity fragment, long dialog_id, boolean param); } public MessagesActivity(Bundle args) { @@ -99,14 +103,6 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter @Override public boolean onFragmentCreate() { super.onFragmentCreate(); - NotificationCenter.getInstance().addObserver(this, NotificationCenter.dialogsNeedReload); - NotificationCenter.getInstance().addObserver(this, NotificationCenter.emojiDidLoaded); - NotificationCenter.getInstance().addObserver(this, NotificationCenter.updateInterfaces); - NotificationCenter.getInstance().addObserver(this, NotificationCenter.encryptedChatUpdated); - NotificationCenter.getInstance().addObserver(this, NotificationCenter.contactsDidLoaded); - NotificationCenter.getInstance().addObserver(this, NotificationCenter.appDidLogout); - NotificationCenter.getInstance().addObserver(this, NotificationCenter.openedChatChanged); - NotificationCenter.getInstance().addObserver(this, NotificationCenter.notificationsSettingsUpdated); if (getArguments() != null) { onlySelect = arguments.getBoolean("onlySelect", false); @@ -114,6 +110,23 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter selectAlertString = arguments.getString("selectAlertString"); selectAlertStringGroup = arguments.getString("selectAlertStringGroup"); } + + if (searchString == null) { + NotificationCenter.getInstance().addObserver(this, NotificationCenter.dialogsNeedReload); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.emojiDidLoaded); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.updateInterfaces); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.encryptedChatUpdated); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.contactsDidLoaded); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.appDidLogout); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.openedChatChanged); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.notificationsSettingsUpdated); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.messageReceivedByAck); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.messageReceivedByServer); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.messageSendError); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.didSetPasscode); + } + + if (!dialogsLoaded) { MessagesController.getInstance().loadDialogs(0, 0, 100, true); ContactsController.getInstance().checkInviteText(); @@ -125,400 +138,474 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter @Override public void onFragmentDestroy() { super.onFragmentDestroy(); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.dialogsNeedReload); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.emojiDidLoaded); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.updateInterfaces); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.encryptedChatUpdated); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.contactsDidLoaded); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.appDidLogout); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.openedChatChanged); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.notificationsSettingsUpdated); + if (searchString == null) { + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.dialogsNeedReload); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.emojiDidLoaded); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.updateInterfaces); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.encryptedChatUpdated); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.contactsDidLoaded); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.appDidLogout); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.openedChatChanged); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.notificationsSettingsUpdated); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.messageReceivedByAck); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.messageReceivedByServer); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.messageSendError); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.didSetPasscode); + } delegate = null; } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - ActionBarMenu menu = actionBar.createMenu(); - ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true).setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() { - @Override - public void onSearchExpand() { - searching = true; - if (messagesListView != null) { + public View createView(Context context, LayoutInflater inflater) { + searching = false; + searchWas = false; + + ActionBarMenu menu = actionBar.createMenu(); + if (!onlySelect && searchString == null) { + passcodeItem = menu.addItem(passcode_menu_item, R.drawable.lock_close); + updatePasscodeButton(); + } + ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true).setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() { + @Override + public void onSearchExpand() { + searching = true; + if (messagesListView != null) { + if (searchString != null) { + messagesListView.setEmptyView(progressView); + searchEmptyView.setVisibility(View.INVISIBLE); + } else { messagesListView.setEmptyView(searchEmptyView); - emptyView.setVisibility(View.GONE); - progressView.setVisibility(View.GONE); - if (!onlySelect) { - floatingButton.setVisibility(View.GONE); - } + progressView.setVisibility(View.INVISIBLE); + } + emptyView.setVisibility(View.INVISIBLE); + if (!onlySelect) { + floatingButton.setVisibility(View.GONE); } } + updatePasscodeButton(); + } - @Override - public void onSearchCollapse() { - searching = false; - searchWas = false; - if (messagesListView != null) { - if (MessagesController.getInstance().loadingDialogs && MessagesController.getInstance().dialogs.isEmpty()) { - searchEmptyView.setVisibility(View.GONE); - emptyView.setVisibility(View.GONE); - progressView.setVisibility(View.VISIBLE); - messagesListView.setEmptyView(progressView); - } else { - messagesListView.setEmptyView(emptyView); - searchEmptyView.setVisibility(View.GONE); - progressView.setVisibility(View.GONE); - } - if (!onlySelect) { - floatingButton.setVisibility(View.VISIBLE); - floatingHidden = true; - ViewProxy.setTranslationY(floatingButton, AndroidUtilities.dp(100)); - hideFloatingButton(false); - } - if (messagesListView.getAdapter() != dialogsAdapter) { - messagesListView.setAdapter(dialogsAdapter); - dialogsAdapter.notifyDataSetChanged(); - } + @Override + public boolean onSearchCollapse() { + if (searchString != null) { + finishFragment(); + return false; + } + searching = false; + searchWas = false; + if (messagesListView != null) { + if (MessagesController.getInstance().loadingDialogs && MessagesController.getInstance().dialogs.isEmpty()) { + searchEmptyView.setVisibility(View.INVISIBLE); + emptyView.setVisibility(View.INVISIBLE); + progressView.setVisibility(View.VISIBLE); + messagesListView.setEmptyView(progressView); + } else { + messagesListView.setEmptyView(emptyView); + searchEmptyView.setVisibility(View.INVISIBLE); + progressView.setVisibility(View.INVISIBLE); } - if (dialogsSearchAdapter != null) { - dialogsSearchAdapter.searchDialogs(null, false); + if (!onlySelect) { + floatingButton.setVisibility(View.VISIBLE); + floatingHidden = true; + ViewProxy.setTranslationY(floatingButton, AndroidUtilities.dp(100)); + hideFloatingButton(false); + } + if (messagesListView.getAdapter() != dialogsAdapter) { + messagesListView.setAdapter(dialogsAdapter); + dialogsAdapter.notifyDataSetChanged(); } } + if (dialogsSearchAdapter != null) { + dialogsSearchAdapter.searchDialogs(null, false); + } + updatePasscodeButton(); + return true; + } - @Override - public void onTextChanged(EditText editText) { - String text = editText.getText().toString(); - if (text.length() != 0) { - searchWas = true; - if (dialogsSearchAdapter != null) { - messagesListView.setAdapter(dialogsSearchAdapter); - dialogsSearchAdapter.notifyDataSetChanged(); - } - if (searchEmptyView != null && messagesListView.getEmptyView() == emptyView) { - messagesListView.setEmptyView(searchEmptyView); - emptyView.setVisibility(View.GONE); - progressView.setVisibility(View.GONE); - } - } + @Override + public void onTextChanged(EditText editText) { + String text = editText.getText().toString(); + if (text.length() != 0) { + searchWas = true; if (dialogsSearchAdapter != null) { - dialogsSearchAdapter.searchDialogs(text, serverOnly); + messagesListView.setAdapter(dialogsSearchAdapter); + dialogsSearchAdapter.notifyDataSetChanged(); + } + if (searchEmptyView != null && messagesListView.getEmptyView() == emptyView) { + messagesListView.setEmptyView(searchEmptyView); + emptyView.setVisibility(View.INVISIBLE); + progressView.setVisibility(View.INVISIBLE); } } - }); - item.getSearchField().setHint(LocaleController.getString("Search", R.string.Search)); - if (onlySelect) { + if (dialogsSearchAdapter != null) { + dialogsSearchAdapter.searchDialogs(text, serverOnly); + } + } + }); + item.getSearchField().setHint(LocaleController.getString("Search", R.string.Search)); + if (onlySelect) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setTitle(LocaleController.getString("SelectChat", R.string.SelectChat)); + } else { + if (searchString != null) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setTitle(LocaleController.getString("SelectChat", R.string.SelectChat)); } else { actionBar.setBackButtonDrawable(new MenuDrawable()); - actionBar.setTitle(LocaleController.getString("AppName", R.string.AppName)); } - actionBar.setAllowOverlayTitle(true); + actionBar.setTitle(LocaleController.getString("AppName", R.string.AppName)); + } + actionBar.setAllowOverlayTitle(true); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - if (onlySelect) { - finishFragment(); - } else if (parentLayout != null) { - parentLayout.getDrawerLayoutContainer().openDrawer(false); - } + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + if (onlySelect) { + finishFragment(); + } else if (parentLayout != null) { + parentLayout.getDrawerLayoutContainer().openDrawer(false); } + } else if (id == passcode_menu_item) { + UserConfig.appLocked = !UserConfig.appLocked; + UserConfig.saveConfig(false); + updatePasscodeButton(); } - }); + } + }); - searching = false; - searchWas = false; + fragmentView = inflater.inflate(R.layout.messages_list, null, false); - fragmentView = inflater.inflate(R.layout.messages_list, container, false); - - dialogsAdapter = new DialogsAdapter(getParentActivity(), serverOnly); + if (searchString == null) { + dialogsAdapter = new DialogsAdapter(context, serverOnly); if (AndroidUtilities.isTablet() && openedDialogId != 0) { dialogsAdapter.setOpenedDialogId(openedDialogId); } - dialogsSearchAdapter = new DialogsSearchAdapter(getParentActivity(), !onlySelect); - dialogsSearchAdapter.setDelegate(new DialogsSearchAdapter.MessagesActivitySearchAdapterDelegate() { - @Override - public void searchStateChanged(boolean search) { - if (searching && searchWas && messagesListView != null) { - progressView.setVisibility(search ? View.VISIBLE : View.GONE); - searchEmptyView.setVisibility(search ? View.GONE : View.VISIBLE); - messagesListView.setEmptyView(search ? progressView : searchEmptyView); - } + } + int type = 0; + if (searchString != null) { + type = 2; + } else if (!onlySelect) { + type = 1; + } + dialogsSearchAdapter = new DialogsSearchAdapter(context, type); + dialogsSearchAdapter.setDelegate(new DialogsSearchAdapter.MessagesActivitySearchAdapterDelegate() { + @Override + public void searchStateChanged(boolean search) { + if (searching && searchWas && messagesListView != null) { + progressView.setVisibility(search ? View.VISIBLE : View.INVISIBLE); + searchEmptyView.setVisibility(search ? View.INVISIBLE : View.VISIBLE); + messagesListView.setEmptyView(search ? progressView : searchEmptyView); } - }); + } + }); - messagesListView = (ListView)fragmentView.findViewById(R.id.messages_list_view); + messagesListView = (ListView) fragmentView.findViewById(R.id.messages_list_view); + if (dialogsAdapter != null) { messagesListView.setAdapter(dialogsAdapter); - if (Build.VERSION.SDK_INT >= 11) { - messagesListView.setVerticalScrollbarPosition(LocaleController.isRTL ? ListView.SCROLLBAR_POSITION_LEFT : ListView.SCROLLBAR_POSITION_RIGHT); - } + } + if (Build.VERSION.SDK_INT >= 11) { + messagesListView.setVerticalScrollbarPosition(LocaleController.isRTL ? ListView.SCROLLBAR_POSITION_LEFT : ListView.SCROLLBAR_POSITION_RIGHT); + } - progressView = fragmentView.findViewById(R.id.progressLayout); - dialogsAdapter.notifyDataSetChanged(); - searchEmptyView = fragmentView.findViewById(R.id.search_empty_view); - searchEmptyView.setOnTouchListener(new View.OnTouchListener() { + progressView = fragmentView.findViewById(R.id.progressLayout); + searchEmptyView = fragmentView.findViewById(R.id.search_empty_view); + searchEmptyView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + emptyView = fragmentView.findViewById(R.id.list_empty_view); + emptyView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + + TextView textView = (TextView) fragmentView.findViewById(R.id.list_empty_view_text1); + textView.setText(LocaleController.getString("NoChats", R.string.NoChats)); + textView = (TextView) fragmentView.findViewById(R.id.list_empty_view_text2); + String help = LocaleController.getString("NoChatsHelp", R.string.NoChatsHelp); + if (AndroidUtilities.isTablet() && !AndroidUtilities.isSmallTablet()) { + help = help.replace("\n", " "); + } + textView.setText(help); + textView = (TextView) fragmentView.findViewById(R.id.search_empty_text); + textView.setText(LocaleController.getString("NoResult", R.string.NoResult)); + + floatingButton = (ImageView) fragmentView.findViewById(R.id.floating_button); + floatingButton.setVisibility(onlySelect ? View.GONE : View.VISIBLE); + floatingButton.setScaleType(ImageView.ScaleType.CENTER); + if (Build.VERSION.SDK_INT >= 21) { + StateListAnimator animator = new StateListAnimator(); + animator.addState(new int[]{android.R.attr.state_pressed}, ObjectAnimator.ofFloat(floatingButton, "translationZ", AndroidUtilities.dp(2), AndroidUtilities.dp(4)).setDuration(200)); + animator.addState(new int[]{}, ObjectAnimator.ofFloat(floatingButton, "translationZ", AndroidUtilities.dp(4), AndroidUtilities.dp(2)).setDuration(200)); + floatingButton.setStateListAnimator(animator); + floatingButton.setOutlineProvider(new ViewOutlineProvider() { @Override - public boolean onTouch(View v, MotionEvent event) { - return true; + public void getOutline(View view, Outline outline) { + outline.setOval(0, 0, AndroidUtilities.dp(56), AndroidUtilities.dp(56)); } }); - emptyView = fragmentView.findViewById(R.id.list_empty_view); - emptyView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return true; - } - }); - - - TextView textView = (TextView)fragmentView.findViewById(R.id.list_empty_view_text1); - textView.setText(LocaleController.getString("NoChats", R.string.NoChats)); - textView = (TextView)fragmentView.findViewById(R.id.list_empty_view_text2); - textView.setText(LocaleController.getString("NoChatsHelp", R.string.NoChatsHelp)); - textView = (TextView)fragmentView.findViewById(R.id.search_empty_text); - textView.setText(LocaleController.getString("NoResult", R.string.NoResult)); - - floatingButton = (ImageView) fragmentView.findViewById(R.id.floating_button); - floatingButton.setVisibility(onlySelect ? View.GONE : View.VISIBLE); - floatingButton.setScaleType(ImageView.ScaleType.CENTER); - if (Build.VERSION.SDK_INT >= 21) { - StateListAnimator animator = new StateListAnimator(); - animator.addState(new int[] {android.R.attr.state_pressed}, ObjectAnimator.ofFloat(floatingButton, "translationZ", AndroidUtilities.dp(2), AndroidUtilities.dp(4)).setDuration(200)); - animator.addState(new int[] {}, ObjectAnimator.ofFloat(floatingButton, "translationZ", AndroidUtilities.dp(4), AndroidUtilities.dp(2)).setDuration(200)); - floatingButton.setStateListAnimator(animator); - floatingButton.setOutlineProvider(new ViewOutlineProvider() { - @Override - public void getOutline(View view, Outline outline) { - outline.setOval(0, 0, AndroidUtilities.dp(56), AndroidUtilities.dp(56)); - } - }); + } + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) floatingButton.getLayoutParams(); + layoutParams.leftMargin = LocaleController.isRTL ? AndroidUtilities.dp(14) : 0; + layoutParams.rightMargin = LocaleController.isRTL ? 0 : AndroidUtilities.dp(14); + layoutParams.gravity = (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.BOTTOM; + floatingButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Bundle args = new Bundle(); + args.putBoolean("destroyAfterSelect", true); + presentFragment(new ContactsActivity(args)); } - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)floatingButton.getLayoutParams(); - layoutParams.leftMargin = LocaleController.isRTL ? AndroidUtilities.dp(14) : 0; - layoutParams.rightMargin = LocaleController.isRTL ? 0 : AndroidUtilities.dp(14); - layoutParams.gravity = (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.BOTTOM; - floatingButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Bundle args = new Bundle(); - args.putBoolean("destroyAfterSelect", true); - presentFragment(new ContactsActivity(args)); + }); + + if (MessagesController.getInstance().loadingDialogs && MessagesController.getInstance().dialogs.isEmpty()) { + searchEmptyView.setVisibility(View.INVISIBLE); + emptyView.setVisibility(View.INVISIBLE); + progressView.setVisibility(View.VISIBLE); + messagesListView.setEmptyView(progressView); + } else { + messagesListView.setEmptyView(emptyView); + searchEmptyView.setVisibility(View.INVISIBLE); + progressView.setVisibility(View.INVISIBLE); + } + + messagesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, int i, long l) { + if (messagesListView == null || messagesListView.getAdapter() == null) { + return; } - }); - - if (MessagesController.getInstance().loadingDialogs && MessagesController.getInstance().dialogs.isEmpty()) { - searchEmptyView.setVisibility(View.GONE); - emptyView.setVisibility(View.GONE); - progressView.setVisibility(View.VISIBLE); - messagesListView.setEmptyView(progressView); - } else { - messagesListView.setEmptyView(emptyView); - searchEmptyView.setVisibility(View.GONE); - progressView.setVisibility(View.GONE); - } - - messagesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, int i, long l) { - if (messagesListView == null || messagesListView.getAdapter() == null) { + long dialog_id = 0; + int message_id = 0; + BaseFragmentAdapter adapter = (BaseFragmentAdapter) messagesListView.getAdapter(); + if (adapter == dialogsAdapter) { + TLRPC.TL_dialog dialog = dialogsAdapter.getItem(i); + if (dialog == null) { return; } - long dialog_id = 0; - int message_id = 0; - BaseFragmentAdapter adapter = (BaseFragmentAdapter)messagesListView.getAdapter(); - if (adapter == dialogsAdapter) { - TLRPC.TL_dialog dialog = dialogsAdapter.getItem(i); - if (dialog == null) { + dialog_id = dialog.id; + } else if (adapter == dialogsSearchAdapter) { + Object obj = dialogsSearchAdapter.getItem(i); + if (obj instanceof TLRPC.User) { + dialog_id = ((TLRPC.User) obj).id; + if (dialogsSearchAdapter.isGlobalSearch(i)) { + ArrayList users = new ArrayList<>(); + users.add((TLRPC.User) obj); + MessagesController.getInstance().putUsers(users, false); + MessagesStorage.getInstance().putUsersAndChats(users, null, false, true); + } + } else if (obj instanceof TLRPC.Chat) { + if (((TLRPC.Chat) obj).id > 0) { + dialog_id = -((TLRPC.Chat) obj).id; + } else { + dialog_id = AndroidUtilities.makeBroadcastId(((TLRPC.Chat) obj).id); + } + } else if (obj instanceof TLRPC.EncryptedChat) { + dialog_id = ((long) ((TLRPC.EncryptedChat) obj).id) << 32; + } else if (obj instanceof MessageObject) { + MessageObject messageObject = (MessageObject) obj; + dialog_id = messageObject.getDialogId(); + message_id = messageObject.getId(); + dialogsSearchAdapter.addHashtagsFromMessage(dialogsSearchAdapter.getLastSearchString()); + } else if (obj instanceof String) { + actionBar.openSearchField((String) obj); + } + } + + if (dialog_id == 0) { + return; + } + + if (onlySelect) { + didSelectResult(dialog_id, true, false); + } else { + Bundle args = new Bundle(); + int lower_part = (int) dialog_id; + int high_id = (int) (dialog_id >> 32); + if (lower_part != 0) { + if (high_id == 1) { + args.putInt("chat_id", lower_part); + } else { + if (lower_part > 0) { + args.putInt("user_id", lower_part); + } else if (lower_part < 0) { + args.putInt("chat_id", -lower_part); + } + } + } else { + args.putInt("enc_id", high_id); + } + if (message_id != 0) { + args.putInt("message_id", message_id); + } else { + if (actionBar != null) { + actionBar.closeSearchField(); + } + } + if (AndroidUtilities.isTablet()) { + if (openedDialogId == dialog_id) { return; } - dialog_id = dialog.id; - } else if (adapter == dialogsSearchAdapter) { - Object obj = dialogsSearchAdapter.getItem(i); - if (obj instanceof TLRPC.User) { - dialog_id = ((TLRPC.User) obj).id; - if (dialogsSearchAdapter.isGlobalSearch(i)) { - ArrayList users = new ArrayList<>(); - users.add((TLRPC.User)obj); - MessagesController.getInstance().putUsers(users, false); - MessagesStorage.getInstance().putUsersAndChats(users, null, false, true); - } - } else if (obj instanceof TLRPC.Chat) { - if (((TLRPC.Chat) obj).id > 0) { - dialog_id = -((TLRPC.Chat) obj).id; - } else { - dialog_id = AndroidUtilities.makeBroadcastId(((TLRPC.Chat) obj).id); - } - } else if (obj instanceof TLRPC.EncryptedChat) { - dialog_id = ((long)((TLRPC.EncryptedChat) obj).id) << 32; - } else if (obj instanceof MessageObject) { - MessageObject messageObject = (MessageObject)obj; - dialog_id = messageObject.getDialogId(); - message_id = messageObject.messageOwner.id; - } - } - - if (dialog_id == 0) { - return; - } - - if (onlySelect) { - didSelectResult(dialog_id, true, false); - } else { - Bundle args = new Bundle(); - int lower_part = (int)dialog_id; - int high_id = (int)(dialog_id >> 32); - if (lower_part != 0) { - if (high_id == 1) { - args.putInt("chat_id", lower_part); - } else { - if (lower_part > 0) { - args.putInt("user_id", lower_part); - } else if (lower_part < 0) { - args.putInt("chat_id", -lower_part); - } - } - } else { - args.putInt("enc_id", high_id); - } - if (message_id != 0) { - args.putInt("message_id", message_id); - } else { - if (actionBar != null) { - actionBar.closeSearchField(); - } - } - if (AndroidUtilities.isTablet()) { - if (openedDialogId == dialog_id) { - return; - } + if (dialogsAdapter != null) { dialogsAdapter.setOpenedDialogId(openedDialogId = dialog_id); updateVisibleRows(MessagesController.UPDATE_MASK_SELECT_DIALOG); } + } + if (searchString != null) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); + presentFragment(new ChatActivity(args)); + } else { presentFragment(new ChatActivity(args)); } } - }); + } + }); - messagesListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { - @Override - public boolean onItemLongClick(AdapterView adapterView, View view, int i, long l) { - if (onlySelect || searching && searchWas || getParentActivity() == null) { + messagesListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView adapterView, View view, int i, long l) { + if (onlySelect || searching && searchWas || getParentActivity() == null) { + if (searchWas && searching) { + BaseFragmentAdapter adapter = (BaseFragmentAdapter) messagesListView.getAdapter(); + if (adapter == dialogsSearchAdapter) { + Object item = adapter.getItem(i); + if (item instanceof String) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setMessage(LocaleController.getString("ClearSearch", R.string.ClearSearch)); + builder.setPositiveButton(LocaleController.getString("ClearButton", R.string.ClearButton).toUpperCase(), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + dialogsSearchAdapter.clearRecentHashtags(); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + return true; + } + } + } + return false; + } + TLRPC.TL_dialog dialog; + if (serverOnly) { + if (i >= MessagesController.getInstance().dialogsServerOnly.size()) { return false; } - TLRPC.TL_dialog dialog; - if (serverOnly) { - if (i >= MessagesController.getInstance().dialogsServerOnly.size()) { - return false; - } - dialog = MessagesController.getInstance().dialogsServerOnly.get(i); - } else { - if (i >= MessagesController.getInstance().dialogs.size()) { - return false; - } - dialog = MessagesController.getInstance().dialogs.get(i); + dialog = MessagesController.getInstance().dialogsServerOnly.get(i); + } else { + if (i >= MessagesController.getInstance().dialogs.size()) { + return false; } - selectedDialog = dialog.id; + dialog = MessagesController.getInstance().dialogs.get(i); + } + selectedDialog = dialog.id; - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - int lower_id = (int)selectedDialog; - int high_id = (int)(selectedDialog >> 32); + int lower_id = (int) selectedDialog; + int high_id = (int) (selectedDialog >> 32); - final boolean isChat = lower_id < 0 && high_id != 1; - builder.setItems(new CharSequence[]{LocaleController.getString("ClearHistory", R.string.ClearHistory), - isChat ? LocaleController.getString("DeleteChat", R.string.DeleteChat) : LocaleController.getString("Delete", R.string.Delete)}, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, final int which) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - if (which == 0) { - builder.setMessage(LocaleController.getString("AreYouSureClearHistory", R.string.AreYouSureClearHistory)); + final boolean isChat = lower_id < 0 && high_id != 1; + builder.setItems(new CharSequence[]{LocaleController.getString("ClearHistory", R.string.ClearHistory), + isChat ? LocaleController.getString("DeleteChat", R.string.DeleteChat) : LocaleController.getString("Delete", R.string.Delete)}, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, final int which) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + if (which == 0) { + builder.setMessage(LocaleController.getString("AreYouSureClearHistory", R.string.AreYouSureClearHistory)); + } else { + if (isChat) { + builder.setMessage(LocaleController.getString("AreYouSureDeleteAndExit", R.string.AreYouSureDeleteAndExit)); } else { - if (isChat) { - builder.setMessage(LocaleController.getString("AreYouSureDeleteAndExit", R.string.AreYouSureDeleteAndExit)); + builder.setMessage(LocaleController.getString("AreYouSureDeleteThisChat", R.string.AreYouSureDeleteThisChat)); + } + } + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + if (which != 0) { + if (isChat) { + MessagesController.getInstance().deleteUserFromChat((int) -selectedDialog, MessagesController.getInstance().getUser(UserConfig.getClientUserId()), null); + } else { + MessagesController.getInstance().deleteDialog(selectedDialog, 0, false); + } + if (AndroidUtilities.isTablet()) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats, selectedDialog); + } } else { - builder.setMessage(LocaleController.getString("AreYouSureDeleteThisChat", R.string.AreYouSureDeleteThisChat)); + MessagesController.getInstance().deleteDialog(selectedDialog, 0, true); } } - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - MessagesController.getInstance().deleteDialog(selectedDialog, 0, which == 0); - if (which != 0) { - if (isChat) { - MessagesController.getInstance().deleteUserFromChat((int) -selectedDialog, MessagesController.getInstance().getUser(UserConfig.getClientUserId()), null); - } - if (AndroidUtilities.isTablet()) { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats, selectedDialog); - } - } - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - return true; - } - }); - - messagesListView.setOnScrollListener(new AbsListView.OnScrollListener() { - @Override - public void onScrollStateChanged(AbsListView absListView, int i) { - if (i == SCROLL_STATE_TOUCH_SCROLL && searching && searchWas) { - AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); } - } - - @Override - public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - if (searching && searchWas) { - if (visibleItemCount > 0 && absListView.getLastVisiblePosition() == totalItemCount - 1 && !dialogsSearchAdapter.isMessagesSearchEndReached()) { - dialogsSearchAdapter.loadMoreSearchMessages(); - } - return; - } - if (visibleItemCount > 0) { - if (absListView.getLastVisiblePosition() == MessagesController.getInstance().dialogs.size() && !serverOnly || absListView.getLastVisiblePosition() == MessagesController.getInstance().dialogsServerOnly.size() && serverOnly) { - MessagesController.getInstance().loadDialogs(MessagesController.getInstance().dialogs.size(), MessagesController.getInstance().dialogsServerOnly.size(), 100, true); - } - } - - if (floatingButton.getVisibility() != View.GONE) { - final View topChild = absListView.getChildAt(0); - int firstViewTop = 0; - if (topChild != null) { - firstViewTop = topChild.getTop(); - } - boolean goingDown; - boolean changed = true; - if (prevPosition == firstVisibleItem) { - final int topDelta = prevTop - firstViewTop; - goingDown = firstViewTop < prevTop; - changed = Math.abs(topDelta) > 1; - } else { - goingDown = firstVisibleItem > prevPosition; - } - if (changed && scrollUpdated) { - hideFloatingButton(goingDown); - } - prevPosition = firstVisibleItem; - prevTop = firstViewTop; - scrollUpdated = true; - } - } - }); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + return true; } + }); + + messagesListView.setOnScrollListener(new AbsListView.OnScrollListener() { + @Override + public void onScrollStateChanged(AbsListView absListView, int i) { + if (i == SCROLL_STATE_TOUCH_SCROLL && searching && searchWas) { + AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); + } + } + + @Override + public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { + if (searching && searchWas) { + if (visibleItemCount > 0 && absListView.getLastVisiblePosition() == totalItemCount - 1 && !dialogsSearchAdapter.isMessagesSearchEndReached()) { + dialogsSearchAdapter.loadMoreSearchMessages(); + } + return; + } + if (visibleItemCount > 0) { + if (absListView.getLastVisiblePosition() == MessagesController.getInstance().dialogs.size() && !serverOnly || absListView.getLastVisiblePosition() == MessagesController.getInstance().dialogsServerOnly.size() && serverOnly) { + MessagesController.getInstance().loadDialogs(MessagesController.getInstance().dialogs.size(), MessagesController.getInstance().dialogsServerOnly.size(), 100, true); + } + } + + if (floatingButton.getVisibility() != View.GONE) { + final View topChild = absListView.getChildAt(0); + int firstViewTop = 0; + if (topChild != null) { + firstViewTop = topChild.getTop(); + } + boolean goingDown; + boolean changed = true; + if (prevPosition == firstVisibleItem) { + final int topDelta = prevTop - firstViewTop; + goingDown = firstViewTop < prevTop; + changed = Math.abs(topDelta) > 1; + } else { + goingDown = firstVisibleItem > prevPosition; + } + if (changed && scrollUpdated) { + hideFloatingButton(goingDown); + } + prevPosition = firstVisibleItem; + prevTop = firstViewTop; + scrollUpdated = true; + } + } + }); + + if (searchString != null) { + actionBar.openSearchField(searchString); } + return fragmentView; } @@ -559,29 +646,30 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter public void didReceivedNotification(int id, Object... args) { if (id == NotificationCenter.dialogsNeedReload) { if (dialogsAdapter != null) { - dialogsAdapter.notifyDataSetChanged(); + if (dialogsAdapter.isDataSetChanged()) { + dialogsAdapter.notifyDataSetChanged(); + } else { + updateVisibleRows(MessagesController.UPDATE_MASK_NEW_MESSAGE); + } } if (dialogsSearchAdapter != null) { dialogsSearchAdapter.notifyDataSetChanged(); } if (messagesListView != null) { try { - if (messagesListView.getAdapter() != null && messagesListView.getAdapter() instanceof BaseAdapter) { - ((BaseAdapter) messagesListView.getAdapter()).notifyDataSetChanged(); - } if (MessagesController.getInstance().loadingDialogs && MessagesController.getInstance().dialogs.isEmpty()) { - searchEmptyView.setVisibility(View.GONE); - emptyView.setVisibility(View.GONE); + searchEmptyView.setVisibility(View.INVISIBLE); + emptyView.setVisibility(View.INVISIBLE); messagesListView.setEmptyView(progressView); } else { if (searching && searchWas) { messagesListView.setEmptyView(searchEmptyView); - emptyView.setVisibility(View.GONE); + emptyView.setVisibility(View.INVISIBLE); } else { messagesListView.setEmptyView(emptyView); - searchEmptyView.setVisibility(View.GONE); + searchEmptyView.setVisibility(View.INVISIBLE); } - progressView.setVisibility(View.GONE); + progressView.setVisibility(View.INVISIBLE); } } catch (Exception e) { FileLog.e("tmessages", e); //TODO fix it in other way? @@ -616,9 +704,27 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter updateVisibleRows(MessagesController.UPDATE_MASK_SELECT_DIALOG); } } else if (id == NotificationCenter.notificationsSettingsUpdated) { - if (messagesListView != null) { - updateVisibleRows(0); + updateVisibleRows(0); + } else if (id == NotificationCenter.messageReceivedByAck || id == NotificationCenter.messageReceivedByServer || id == NotificationCenter.messageSendError) { + updateVisibleRows(MessagesController.UPDATE_MASK_SEND_STATE); + } else if (id == NotificationCenter.didSetPasscode) { + updatePasscodeButton(); + } + } + + private void updatePasscodeButton() { + if (passcodeItem == null) { + return; + } + if (UserConfig.passcodeHash.length() != 0 && !searching) { + passcodeItem.setVisibility(View.VISIBLE); + if (UserConfig.appLocked) { + passcodeItem.setIcon(R.drawable.lock_close); + } else { + passcodeItem.setIcon(R.drawable.lock_open); } + } else { + passcodeItem.setVisibility(View.GONE); } } @@ -642,13 +748,14 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter View child = messagesListView.getChildAt(a); if (child instanceof DialogCell) { DialogCell cell = (DialogCell) child; - if ((mask & MessagesController.UPDATE_MASK_SELECT_DIALOG) != 0) { + if ((mask & MessagesController.UPDATE_MASK_NEW_MESSAGE) != 0) { + cell.checkCurrentDialogIndex(); if (!serverOnly && AndroidUtilities.isTablet()) { - if (cell.getDialogId() == openedDialogId) { - child.setBackgroundColor(0x0f000000); - } else { - child.setBackgroundColor(0); - } + child.setBackgroundColor(cell.getDialogId() == openedDialogId ? 0x0f000000 : 0); + } + } else if ((mask & MessagesController.UPDATE_MASK_SELECT_DIALOG) != 0) { + if (!serverOnly && AndroidUtilities.isTablet()) { + child.setBackgroundColor(cell.getDialogId() == openedDialogId ? 0x0f000000 : 0); } } else { cell.update(mask); @@ -663,8 +770,12 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter this.delegate = delegate; } - public MessagesActivityDelegate getDelegate() { - return delegate; + public void setSearchString(String string) { + searchString = string; + } + + public boolean isMainDialogList() { + return delegate == null && searchString == null; } private void didSelectResult(final long dialog_id, boolean useAlert, final boolean param) { @@ -714,13 +825,13 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter builder.setView(checkBox); }*/ final CheckBox checkBoxFinal = checkBox; - builder.setPositiveButton(R.string.OK, new DialogInterface.OnClickListener() { + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { didSelectResult(dialog_id, false, checkBoxFinal != null && checkBoxFinal.isChecked()); } }); - builder.setNegativeButton(R.string.Cancel, null); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); showAlertDialog(builder); if (checkBox != null) { ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams)checkBox.getLayoutParams(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/NotificationsSettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/NotificationsSettingsActivity.java index ace44bad7..a8f3bfd52 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/NotificationsSettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/NotificationsSettingsActivity.java @@ -77,6 +77,7 @@ public class NotificationsSettingsActivity extends BaseFragment implements Notif private int inappSoundRow; private int inappVibrateRow; private int inappPreviewRow; + private int inchatSoundRow; private int inappPriorityRow; private int eventsSectionRow2; private int eventsSectionRow; @@ -125,6 +126,7 @@ public class NotificationsSettingsActivity extends BaseFragment implements Notif inappSoundRow = rowCount++; inappVibrateRow = rowCount++; inappPreviewRow = rowCount++; + inchatSoundRow = rowCount++; if (Build.VERSION.SDK_INT >= 21) { inappPriorityRow = rowCount++; } else { @@ -154,381 +156,385 @@ public class NotificationsSettingsActivity extends BaseFragment implements Notif } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - actionBar.setTitle(LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + actionBar.setTitle(LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds)); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); } - }); + } + }); - fragmentView = new FrameLayout(getParentActivity()); - FrameLayout frameLayout = (FrameLayout) fragmentView; + fragmentView = new FrameLayout(context); + FrameLayout frameLayout = (FrameLayout) fragmentView; - listView = new ListView(getParentActivity()); - listView.setDivider(null); - listView.setDividerHeight(0); - listView.setVerticalScrollBarEnabled(false); - frameLayout.addView(listView); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - listView.setLayoutParams(layoutParams); - listView.setAdapter(new ListAdapter(getParentActivity())); - listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, final int i, long l) { - boolean enabled = false; - if (i == messageAlertRow || i == groupAlertRow) { + listView = new ListView(context); + listView.setDivider(null); + listView.setDividerHeight(0); + listView.setVerticalScrollBarEnabled(false); + frameLayout.addView(listView); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + listView.setLayoutParams(layoutParams); + listView.setAdapter(new ListAdapter(context)); + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, final int i, long l) { + boolean enabled = false; + if (i == messageAlertRow || i == groupAlertRow) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + if (i == messageAlertRow) { + enabled = preferences.getBoolean("EnableAll", true); + editor.putBoolean("EnableAll", !enabled); + } else if (i == groupAlertRow) { + enabled = preferences.getBoolean("EnableGroup", true); + editor.putBoolean("EnableGroup", !enabled); + } + editor.commit(); + updateServerNotificationsSettings(i == groupAlertRow); + } else if (i == messagePreviewRow || i == groupPreviewRow) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + if (i == messagePreviewRow) { + enabled = preferences.getBoolean("EnablePreviewAll", true); + editor.putBoolean("EnablePreviewAll", !enabled); + } else if (i == groupPreviewRow) { + enabled = preferences.getBoolean("EnablePreviewGroup", true); + editor.putBoolean("EnablePreviewGroup", !enabled); + } + editor.commit(); + updateServerNotificationsSettings(i == groupPreviewRow); + } else if (i == messageSoundRow || i == groupSoundRow) { + try { SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - if (i == messageAlertRow) { - enabled = preferences.getBoolean("EnableAll", true); - editor.putBoolean("EnableAll", !enabled); - } else if (i == groupAlertRow) { - enabled = preferences.getBoolean("EnableGroup", true); - editor.putBoolean("EnableGroup", !enabled); - } - editor.commit(); - updateServerNotificationsSettings(i == groupAlertRow); - } else if (i == messagePreviewRow || i == groupPreviewRow) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - if (i == messagePreviewRow) { - enabled = preferences.getBoolean("EnablePreviewAll", true); - editor.putBoolean("EnablePreviewAll", !enabled); - } else if (i == groupPreviewRow) { - enabled = preferences.getBoolean("EnablePreviewGroup", true); - editor.putBoolean("EnablePreviewGroup", !enabled); - } - editor.commit(); - updateServerNotificationsSettings(i == groupPreviewRow); - } else if (i == messageSoundRow || i == groupSoundRow) { - try { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - Intent tmpIntent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER); - tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION); - tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true); - tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)); - Uri currentSound = null; + Intent tmpIntent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER); + tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION); + tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true); + tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)); + Uri currentSound = null; - String defaultPath = null; - Uri defaultUri = Settings.System.DEFAULT_NOTIFICATION_URI; - if (defaultUri != null) { - defaultPath = defaultUri.getPath(); - } + String defaultPath = null; + Uri defaultUri = Settings.System.DEFAULT_NOTIFICATION_URI; + if (defaultUri != null) { + defaultPath = defaultUri.getPath(); + } - if (i == messageSoundRow) { - String path = preferences.getString("GlobalSoundPath", defaultPath); - if (path != null && !path.equals("NoSound")) { - if (path.equals(defaultPath)) { - currentSound = defaultUri; - } else { - currentSound = Uri.parse(path); - } - } - } else if (i == groupSoundRow) { - String path = preferences.getString("GroupSoundPath", defaultPath); - if (path != null && !path.equals("NoSound")) { - if (path.equals(defaultPath)) { - currentSound = defaultUri; - } else { - currentSound = Uri.parse(path); - } + if (i == messageSoundRow) { + String path = preferences.getString("GlobalSoundPath", defaultPath); + if (path != null && !path.equals("NoSound")) { + if (path.equals(defaultPath)) { + currentSound = defaultUri; + } else { + currentSound = Uri.parse(path); } } - tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, currentSound); - startActivityForResult(tmpIntent, i); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } else if (i == resetNotificationsRow) { - if (reseting) { - return; - } - reseting = true; - TLRPC.TL_account_resetNotifySettings req = new TLRPC.TL_account_resetNotifySettings(); - ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { - @Override - public void run(TLObject response, TLRPC.TL_error error) { - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - MessagesController.getInstance().enableJoined = true; - reseting = false; - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - editor.clear(); - editor.commit(); - if (listView != null) { - listView.invalidateViews(); - } - if (getParentActivity() != null) { - Toast toast = Toast.makeText(getParentActivity(), LocaleController.getString("ResetNotificationsText", R.string.ResetNotificationsText), Toast.LENGTH_SHORT); - toast.show(); - } - } - }); + } else if (i == groupSoundRow) { + String path = preferences.getString("GroupSoundPath", defaultPath); + if (path != null && !path.equals("NoSound")) { + if (path.equals(defaultPath)) { + currentSound = defaultUri; + } else { + currentSound = Uri.parse(path); + } } - }); - } else if (i == inappSoundRow) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - enabled = preferences.getBoolean("EnableInAppSounds", true); - editor.putBoolean("EnableInAppSounds", !enabled); - editor.commit(); - } else if (i == inappVibrateRow) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - enabled = preferences.getBoolean("EnableInAppVibrate", true); - editor.putBoolean("EnableInAppVibrate", !enabled); - editor.commit(); - } else if (i == inappPreviewRow) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - enabled = preferences.getBoolean("EnableInAppPreview", true); - editor.putBoolean("EnableInAppPreview", !enabled); - editor.commit(); - } else if (i == inappPriorityRow) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - enabled = preferences.getBoolean("EnableInAppPriority", false); - editor.putBoolean("EnableInAppPriority", !enabled); - editor.commit(); - } else if (i == contactJoinedRow) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - enabled = preferences.getBoolean("EnableContactJoined", true); - MessagesController.getInstance().enableJoined = !enabled; - editor.putBoolean("EnableContactJoined", !enabled); - editor.commit(); - } else if (i == pebbleAlertRow) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - enabled = preferences.getBoolean("EnablePebbleNotifications", false); - editor.putBoolean("EnablePebbleNotifications", !enabled); - editor.commit(); - } else if (i == badgeNumberRow) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - enabled = preferences.getBoolean("badgeNumber", true); - editor.putBoolean("badgeNumber", !enabled); - editor.commit(); - NotificationsController.getInstance().setBadgeEnabled(!enabled); - } else if (i == notificationsServiceRow) { - final SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - enabled = preferences.getBoolean("pushService", true); - if (!enabled) { - final SharedPreferences.Editor editor = preferences.edit(); - editor.putBoolean("pushService", !enabled); - editor.commit(); - ApplicationLoader.startPushService(); - } else { - if (getParentActivity() == null) { - return; - } - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setMessage(LocaleController.getString("NotificationsServiceDisableInfo", R.string.NotificationsServiceDisableInfo)); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + } + tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, currentSound); + startActivityForResult(tmpIntent, i); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } else if (i == resetNotificationsRow) { + if (reseting) { + return; + } + reseting = true; + TLRPC.TL_account_resetNotifySettings req = new TLRPC.TL_account_resetNotifySettings(); + ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, TLRPC.TL_error error) { + AndroidUtilities.runOnUIThread(new Runnable() { @Override - public void onClick(DialogInterface dialogInterface, int i) { - ApplicationLoader.stopPushService(); - final SharedPreferences.Editor editor = preferences.edit(); - editor.putBoolean("pushService", false); + public void run() { + MessagesController.getInstance().enableJoined = true; + reseting = false; + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.clear(); editor.commit(); - listView.invalidateViews(); + if (listView != null) { + listView.invalidateViews(); + } + if (getParentActivity() != null) { + Toast toast = Toast.makeText(getParentActivity(), LocaleController.getString("ResetNotificationsText", R.string.ResetNotificationsText), Toast.LENGTH_SHORT); + toast.show(); + } } }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); } - } else if (i == messageLedRow || i == groupLedRow) { + }); + } else if (i == inappSoundRow) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + enabled = preferences.getBoolean("EnableInAppSounds", true); + editor.putBoolean("EnableInAppSounds", !enabled); + editor.commit(); + } else if (i == inappVibrateRow) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + enabled = preferences.getBoolean("EnableInAppVibrate", true); + editor.putBoolean("EnableInAppVibrate", !enabled); + editor.commit(); + } else if (i == inappPreviewRow) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + enabled = preferences.getBoolean("EnableInAppPreview", true); + editor.putBoolean("EnableInAppPreview", !enabled); + editor.commit(); + } else if (i == inchatSoundRow) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + enabled = preferences.getBoolean("EnableInChatSound", true); + editor.putBoolean("EnableInChatSound", !enabled); + editor.commit(); + NotificationsController.getInstance().setInChatSoundEnabled(!enabled); + } else if (i == inappPriorityRow) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + enabled = preferences.getBoolean("EnableInAppPriority", false); + editor.putBoolean("EnableInAppPriority", !enabled); + editor.commit(); + } else if (i == contactJoinedRow) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + enabled = preferences.getBoolean("EnableContactJoined", true); + MessagesController.getInstance().enableJoined = !enabled; + editor.putBoolean("EnableContactJoined", !enabled); + editor.commit(); + } else if (i == pebbleAlertRow) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + enabled = preferences.getBoolean("EnablePebbleNotifications", false); + editor.putBoolean("EnablePebbleNotifications", !enabled); + editor.commit(); + } else if (i == badgeNumberRow) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + enabled = preferences.getBoolean("badgeNumber", true); + editor.putBoolean("badgeNumber", !enabled); + editor.commit(); + NotificationsController.getInstance().setBadgeEnabled(!enabled); + } else if (i == notificationsServiceRow) { + final SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + enabled = preferences.getBoolean("pushService", true); + if (!enabled) { + final SharedPreferences.Editor editor = preferences.edit(); + editor.putBoolean("pushService", !enabled); + editor.commit(); + ApplicationLoader.startPushService(); + } else { if (getParentActivity() == null) { return; } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.getString("NotificationsServiceDisableInfo", R.string.NotificationsServiceDisableInfo)); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + ApplicationLoader.stopPushService(); + final SharedPreferences.Editor editor = preferences.edit(); + editor.putBoolean("pushService", false); + editor.commit(); + listView.invalidateViews(); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } + } else if (i == messageLedRow || i == groupLedRow) { + if (getParentActivity() == null) { + return; + } - LayoutInflater li = (LayoutInflater)getParentActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); - view = li.inflate(R.layout.settings_color_dialog_layout, null, false); - final ColorPickerView colorPickerView = (ColorPickerView)view.findViewById(R.id.color_picker); + LayoutInflater li = (LayoutInflater) getParentActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + view = li.inflate(R.layout.settings_color_dialog_layout, null, false); + final ColorPickerView colorPickerView = (ColorPickerView) view.findViewById(R.id.color_picker); - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - if (i == messageLedRow) { - colorPickerView.setOldCenterColor(preferences.getInt("MessagesLed", 0xff00ff00)); - } else if (i == groupLedRow) { - colorPickerView.setOldCenterColor(preferences.getInt("GroupLed", 0xff00ff00)); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + if (i == messageLedRow) { + colorPickerView.setOldCenterColor(preferences.getInt("MessagesLed", 0xff00ff00)); + } else if (i == groupLedRow) { + colorPickerView.setOldCenterColor(preferences.getInt("GroupLed", 0xff00ff00)); + } + + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("LedColor", R.string.LedColor)); + builder.setView(view); + builder.setPositiveButton(LocaleController.getString("Set", R.string.Set), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int which) { + final SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + if (i == messageLedRow) { + editor.putInt("MessagesLed", colorPickerView.getColor()); + } else if (i == groupLedRow) { + editor.putInt("GroupLed", colorPickerView.getColor()); + } + editor.commit(); + listView.invalidateViews(); } - - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("LedColor", R.string.LedColor)); - builder.setView(view); - builder.setPositiveButton(LocaleController.getString("Set", R.string.Set), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int which) { - final SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - if (i == messageLedRow) { - editor.putInt("MessagesLed", colorPickerView.getColor()); - } else if (i == groupLedRow) { - editor.putInt("GroupLed", colorPickerView.getColor()); - } - editor.commit(); + }); + builder.setNeutralButton(LocaleController.getString("LedDisabled", R.string.LedDisabled), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + final SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + if (i == messageLedRow) { + editor.putInt("MessagesLed", 0); + } else if (i == groupLedRow) { + editor.putInt("GroupLed", 0); + } + editor.commit(); + listView.invalidateViews(); + } + }); + showAlertDialog(builder); + } else if (i == messagePopupNotificationRow || i == groupPopupNotificationRow) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("PopupNotification", R.string.PopupNotification)); + builder.setItems(new CharSequence[]{ + LocaleController.getString("NoPopup", R.string.NoPopup), + LocaleController.getString("OnlyWhenScreenOn", R.string.OnlyWhenScreenOn), + LocaleController.getString("OnlyWhenScreenOff", R.string.OnlyWhenScreenOff), + LocaleController.getString("AlwaysShowPopup", R.string.AlwaysShowPopup) + }, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + if (i == messagePopupNotificationRow) { + editor.putInt("popupAll", which); + } else if (i == groupPopupNotificationRow) { + editor.putInt("popupGroup", which); + } + editor.commit(); + if (listView != null) { listView.invalidateViews(); } - }); - builder.setNeutralButton(LocaleController.getString("Disabled", R.string.Disabled), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - final SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - if (i == messageLedRow) { - editor.putInt("MessagesLed", 0); - } else if (i == groupLedRow) { - editor.putInt("GroupLed", 0); - } - editor.commit(); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } else if (i == messageVibrateRow || i == groupVibrateRow) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("Vibrate", R.string.Vibrate)); + builder.setItems(new CharSequence[]{ + LocaleController.getString("VibrationDisabled", R.string.VibrationDisabled), + LocaleController.getString("Default", R.string.Default), + LocaleController.getString("Short", R.string.Short), + LocaleController.getString("Long", R.string.Long), + LocaleController.getString("OnlyIfSilent", R.string.OnlyIfSilent) + }, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + String param = "vibrate_messages"; + if (i == groupVibrateRow) { + param = "vibrate_group"; + } + if (which == 0) { + editor.putInt(param, 2); + } else if (which == 1) { + editor.putInt(param, 0); + } else if (which == 2) { + editor.putInt(param, 1); + } else if (which == 3) { + editor.putInt(param, 3); + } else if (which == 4) { + editor.putInt(param, 4); + } + editor.commit(); + if (listView != null) { listView.invalidateViews(); } - }); - showAlertDialog(builder); - } else if (i == messagePopupNotificationRow || i == groupPopupNotificationRow) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("PopupNotification", R.string.PopupNotification)); - builder.setItems(new CharSequence[] { - LocaleController.getString("NoPopup", R.string.NoPopup), - LocaleController.getString("OnlyWhenScreenOn", R.string.OnlyWhenScreenOn), - LocaleController.getString("OnlyWhenScreenOff", R.string.OnlyWhenScreenOff), - LocaleController.getString("AlwaysShowPopup", R.string.AlwaysShowPopup) - }, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - if (i == messagePopupNotificationRow) { - editor.putInt("popupAll", which); - } else if (i == groupPopupNotificationRow) { - editor.putInt("popupGroup", which); - } - editor.commit(); - if (listView != null) { - listView.invalidateViews(); - } + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } else if (i == messagePriorityRow || i == groupPriorityRow) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("NotificationsPriority", R.string.NotificationsPriority)); + builder.setItems(new CharSequence[]{ + LocaleController.getString("NotificationsPriorityDefault", R.string.NotificationsPriorityDefault), + LocaleController.getString("NotificationsPriorityHigh", R.string.NotificationsPriorityHigh), + LocaleController.getString("NotificationsPriorityMax", R.string.NotificationsPriorityMax) + }, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + if (i == messagePriorityRow) { + preferences.edit().putInt("priority_messages", which).commit(); + } else if (i == groupPriorityRow) { + preferences.edit().putInt("priority_group", which).commit(); } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } else if (i == messageVibrateRow || i == groupVibrateRow) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("Vibrate", R.string.Vibrate)); - builder.setItems(new CharSequence[] { - LocaleController.getString("Disabled", R.string.Disabled), - LocaleController.getString("Default", R.string.Default), - LocaleController.getString("Short", R.string.Short), - LocaleController.getString("Long", R.string.Long) - }, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - String param = "vibrate_messages"; - if (i == groupVibrateRow) { - param = "vibrate_group"; - } - if (which == 0) { - editor.putInt(param, 2); - } else if (which == 1) { - editor.putInt(param, 0); - } else if (which == 2) { - editor.putInt(param, 1); - } else if (which == 3) { - editor.putInt(param, 3); - } - editor.commit(); - if (listView != null) { - listView.invalidateViews(); - } + if (listView != null) { + listView.invalidateViews(); } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } else if (i == messagePriorityRow || i == groupPriorityRow) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("NotificationsPriority", R.string.NotificationsPriority)); - builder.setItems(new CharSequence[] { - LocaleController.getString("NotificationsPriorityDefault", R.string.NotificationsPriorityDefault), - LocaleController.getString("NotificationsPriorityHigh", R.string.NotificationsPriorityHigh), - LocaleController.getString("NotificationsPriorityMax", R.string.NotificationsPriorityMax) - }, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - if (i == messagePriorityRow) { - preferences.edit().putInt("priority_messages", which).commit(); - } else if (i == groupPriorityRow) { - preferences.edit().putInt("priority_group", which).commit(); - } - if (listView != null) { - listView.invalidateViews(); - } + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } else if (i == repeatRow) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("RepeatNotifications", R.string.RepeatNotifications)); + builder.setItems(new CharSequence[]{ + LocaleController.getString("RepeatDisabled", R.string.RepeatDisabled), + LocaleController.formatPluralString("Minutes", 5), + LocaleController.formatPluralString("Minutes", 10), + LocaleController.formatPluralString("Minutes", 30), + LocaleController.formatPluralString("Hours", 1), + LocaleController.formatPluralString("Hours", 2), + LocaleController.formatPluralString("Hours", 4) + }, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + int minutes = 0; + if (which == 1) { + minutes = 5; + } else if (which == 2) { + minutes = 10; + } else if (which == 3) { + minutes = 30; + } else if (which == 4) { + minutes = 60; + } else if (which == 5) { + minutes = 60 * 2; + } else if (which == 6) { + minutes = 60 * 4; } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } else if (i == repeatRow) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("RepeatNotifications", R.string.RepeatNotifications)); - builder.setItems(new CharSequence[] { - LocaleController.getString("ShortMessageLifetimeForever", R.string.ShortMessageLifetimeForever), - LocaleController.formatPluralString("Minutes", 5), - LocaleController.formatPluralString("Minutes", 10), - LocaleController.formatPluralString("Minutes", 30), - LocaleController.formatPluralString("Hours", 1), - LocaleController.formatPluralString("Hours", 2), - LocaleController.formatPluralString("Hours", 4) - }, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - int minutes = 0; - if (which == 1) { - minutes = 5; - } else if (which == 2) { - minutes = 10; - } else if (which == 3) { - minutes = 30; - } else if (which == 4) { - minutes = 60; - } else if (which == 5) { - minutes = 60 * 2; - } else if (which == 6) { - minutes = 60 * 4; - } - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - preferences.edit().putInt("repeat_messages", minutes).commit(); - if (listView != null) { - listView.invalidateViews(); - } + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + preferences.edit().putInt("repeat_messages", minutes).commit(); + if (listView != null) { + listView.invalidateViews(); } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } - if (view instanceof TextCheckCell) { - ((TextCheckCell) view).setChecked(!enabled); - } + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } + if (view instanceof TextCheckCell) { + ((TextCheckCell) view).setChecked(!enabled); } - }); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); } - } + }); + return fragmentView; } @@ -565,7 +571,7 @@ public class NotificationsSettingsActivity extends BaseFragment implements Notif Ringtone rng = RingtoneManager.getRingtone(getParentActivity(), ringtone); if (rng != null) { if(ringtone.equals(Settings.System.DEFAULT_NOTIFICATION_URI)) { - name = LocaleController.getString("Default", R.string.Default); + name = LocaleController.getString("SoundDefault", R.string.SoundDefault); } else { name = rng.getTitle(getParentActivity()); } @@ -696,6 +702,8 @@ public class NotificationsSettingsActivity extends BaseFragment implements Notif checkCell.setTextAndCheck(LocaleController.getString("NotificationsService", R.string.NotificationsService), preferences.getBoolean("pushService", true), false); } else if (i == badgeNumberRow) { checkCell.setTextAndCheck(LocaleController.getString("BadgeNumber", R.string.BadgeNumber), preferences.getBoolean("badgeNumber", true), true); + } else if (i == inchatSoundRow) { + checkCell.setTextAndCheck(LocaleController.getString("InChatSound", R.string.InChatSound), preferences.getBoolean("EnableInChatSound", true), true); } } else if (type == 2) { if (view == null) { @@ -710,9 +718,9 @@ public class NotificationsSettingsActivity extends BaseFragment implements Notif textCell.setMultilineDetail(false); String value = null; if (i == messageSoundRow) { - value = preferences.getString("GlobalSound", LocaleController.getString("Default", R.string.Default)); + value = preferences.getString("GlobalSound", LocaleController.getString("SoundDefault", R.string.SoundDefault)); } else if (i == groupSoundRow) { - value = preferences.getString("GroupSound", LocaleController.getString("Default", R.string.Default)); + value = preferences.getString("GroupSound", LocaleController.getString("SoundDefault", R.string.SoundDefault)); } if (value.equals("NoSound")) { value = LocaleController.getString("NoSound", R.string.NoSound); @@ -753,9 +761,11 @@ public class NotificationsSettingsActivity extends BaseFragment implements Notif } else if (value == 1) { textCell.setTextAndValue(LocaleController.getString("Vibrate", R.string.Vibrate), LocaleController.getString("Short", R.string.Short), true); } else if (value == 2) { - textCell.setTextAndValue(LocaleController.getString("Vibrate", R.string.Vibrate), LocaleController.getString("Disabled", R.string.Disabled), true); + textCell.setTextAndValue(LocaleController.getString("Vibrate", R.string.Vibrate), LocaleController.getString("VibrationDisabled", R.string.VibrationDisabled), true); } else if (value == 3) { textCell.setTextAndValue(LocaleController.getString("Vibrate", R.string.Vibrate), LocaleController.getString("Long", R.string.Long), true); + } else if (value == 4) { + textCell.setTextAndValue(LocaleController.getString("Vibrate", R.string.Vibrate), LocaleController.getString("OnlyIfSilent", R.string.OnlyIfSilent), true); } } else if (i == repeatRow) { textCell.setMultilineDetail(false); @@ -814,7 +824,8 @@ public class NotificationsSettingsActivity extends BaseFragment implements Notif } else if (i == messageAlertRow || i == messagePreviewRow || i == groupAlertRow || i == groupPreviewRow || i == inappSoundRow || i == inappVibrateRow || i == inappPreviewRow || i == contactJoinedRow || i == pebbleAlertRow || - i == notificationsServiceRow || i == badgeNumberRow || i == inappPriorityRow) { + i == notificationsServiceRow || i == badgeNumberRow || i == inappPriorityRow || + i == inchatSoundRow) { return 1; } else if (i == messageLedRow || i == groupLedRow) { return 3; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PasscodeActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PasscodeActivity.java new file mode 100644 index 000000000..f5cad11a8 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/PasscodeActivity.java @@ -0,0 +1,688 @@ +/* + * This is the source code of Telegram for Android v. 2.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-2015. + */ + +package org.telegram.ui; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.res.Configuration; +import android.graphics.Typeface; +import android.os.Build; +import android.os.Vibrator; +import android.text.Editable; +import android.text.InputFilter; +import android.text.InputType; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.text.method.DigitsKeyListener; +import android.text.method.PasswordTransformationMethod; +import android.util.TypedValue; +import android.view.ActionMode; +import android.view.ContextMenu; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.view.inputmethod.EditorInfo; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.Toast; + +import org.telegram.android.AndroidUtilities; +import org.telegram.android.LocaleController; +import org.telegram.android.NotificationCenter; +import org.telegram.messenger.ApplicationLoader; +import org.telegram.messenger.FileLog; +import org.telegram.messenger.R; +import org.telegram.messenger.UserConfig; +import org.telegram.messenger.Utilities; +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.Adapters.BaseFragmentAdapter; +import org.telegram.ui.Cells.TextCheckCell; +import org.telegram.ui.Cells.TextInfoPrivacyCell; +import org.telegram.ui.Cells.TextSettingsCell; +import org.telegram.ui.Components.NumberPicker; + +public class PasscodeActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate { + + private ListAdapter listAdapter; + private ListView listView; + private TextView titleTextView; + private EditText passwordEditText; + private TextView dropDown; + private ActionBarMenuItem dropDownContainer; + + private int type; + private int currentPasswordType = 0; + private String firstPassword; + + private int passcodeRow; + private int changePasscodeRow; + private int passcodeDetailRow; + private int autoLockRow; + private int autoLockDetailRow; + private int rowCount; + + private final static int done_button = 1; + private final static int pin_item = 2; + private final static int password_item = 3; + + public PasscodeActivity(int type) { + super(); + this.type = type; + } + + @Override + public boolean onFragmentCreate() { + super.onFragmentCreate(); + updateRows(); + if (type == 0) { + NotificationCenter.getInstance().addObserver(this, NotificationCenter.didSetPasscode); + } + return true; + } + + @Override + public void onFragmentDestroy() { + super.onFragmentDestroy(); + if (type == 0) { + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.didSetPasscode); + } + } + + @Override + public View createView(Context context, LayoutInflater inflater) { + if (type != 3) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + } + actionBar.setAllowOverlayTitle(false); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } else if (id == done_button) { + if (passwordEditText.getImeOptions() == EditorInfo.IME_ACTION_NEXT) { + processNext(); + } else if (passwordEditText.getImeOptions() == EditorInfo.IME_ACTION_DONE) { + processDone(); + } + } else if (id == pin_item) { + currentPasswordType = 0; + updateDropDownTextView(); + } else if (id == password_item) { + currentPasswordType = 1; + updateDropDownTextView(); + } + } + }); + + fragmentView = new FrameLayout(context); + FrameLayout frameLayout = (FrameLayout) fragmentView; + + if (type != 0) { + ActionBarMenu menu = actionBar.createMenu(); + menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + + titleTextView = new TextView(context); + titleTextView.setTextColor(0xff757575); + if (type == 1) { + if (UserConfig.passcodeHash.length() != 0) { + titleTextView.setText(LocaleController.getString("EnterNewPasscode", R.string.EnterNewPasscode)); + } else { + titleTextView.setText(LocaleController.getString("EnterNewFirstPasscode", R.string.EnterNewFirstPasscode)); + } + } else { + titleTextView.setText(LocaleController.getString("EnterCurrentPasscode", R.string.EnterCurrentPasscode)); + } + titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + titleTextView.setGravity(Gravity.CENTER_HORIZONTAL); + frameLayout.addView(titleTextView); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) titleTextView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.CENTER_HORIZONTAL; + layoutParams.topMargin = AndroidUtilities.dp(38); + titleTextView.setLayoutParams(layoutParams); + + passwordEditText = new EditText(context); + passwordEditText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); + passwordEditText.setTextColor(0xff000000); + passwordEditText.setMaxLines(1); + passwordEditText.setLines(1); + passwordEditText.setGravity(Gravity.CENTER_HORIZONTAL); + passwordEditText.setSingleLine(true); + if (type == 1) { + passwordEditText.setImeOptions(EditorInfo.IME_ACTION_NEXT); + } else { + passwordEditText.setImeOptions(EditorInfo.IME_ACTION_DONE); + } + passwordEditText.setTransformationMethod(PasswordTransformationMethod.getInstance()); + passwordEditText.setTypeface(Typeface.DEFAULT); + AndroidUtilities.clearCursorDrawable(passwordEditText); + frameLayout.addView(passwordEditText); + layoutParams = (FrameLayout.LayoutParams) passwordEditText.getLayoutParams(); + layoutParams.topMargin = AndroidUtilities.dp(90); + layoutParams.height = AndroidUtilities.dp(36); + layoutParams.leftMargin = AndroidUtilities.dp(40); + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + layoutParams.rightMargin = AndroidUtilities.dp(40); + layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT; + passwordEditText.setLayoutParams(layoutParams); + passwordEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { + if (i == EditorInfo.IME_ACTION_NEXT) { + processNext(); + return true; + } else if (i == EditorInfo.IME_ACTION_DONE) { + processDone(); + return true; + } + return false; + } + }); + passwordEditText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + public void afterTextChanged(Editable s) { + if (passwordEditText.length() == 4) { + if (type == 2 && UserConfig.passcodeType == 0) { + processDone(); + } else if (type == 1 && currentPasswordType == 0) { + if (passwordEditText.getImeOptions() == EditorInfo.IME_ACTION_NEXT) { + processNext(); + } else if (passwordEditText.getImeOptions() == EditorInfo.IME_ACTION_DONE) { + processDone(); + } + } + } + } + }); + if (android.os.Build.VERSION.SDK_INT < 11) { + passwordEditText.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() { + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + menu.clear(); + } + }); + } else { + passwordEditText.setCustomSelectionActionModeCallback(new ActionMode.Callback() { + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + return false; + } + + public void onDestroyActionMode(ActionMode mode) { + } + + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + return false; + } + + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + return false; + } + }); + } + + if (type == 1) { + dropDownContainer = new ActionBarMenuItem(context, menu, R.drawable.bar_selector); + dropDownContainer.setSubMenuOpenSide(1); + dropDownContainer.addSubItem(pin_item, LocaleController.getString("PasscodePIN", R.string.PasscodePIN), 0); + dropDownContainer.addSubItem(password_item, LocaleController.getString("PasscodePassword", R.string.PasscodePassword), 0); + actionBar.addView(dropDownContainer); + layoutParams = (FrameLayout.LayoutParams) dropDownContainer.getLayoutParams(); + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.rightMargin = AndroidUtilities.dp(40); + layoutParams.leftMargin = AndroidUtilities.isTablet() ? AndroidUtilities.dp(64) : AndroidUtilities.dp(56); + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + dropDownContainer.setLayoutParams(layoutParams); + dropDownContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + dropDownContainer.toggleSubMenu(); + } + }); + + dropDown = new TextView(context); + dropDown.setGravity(Gravity.LEFT); + dropDown.setSingleLine(true); + dropDown.setLines(1); + dropDown.setMaxLines(1); + dropDown.setEllipsize(TextUtils.TruncateAt.END); + dropDown.setTextColor(0xffffffff); + dropDown.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + dropDown.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_arrow_drop_down, 0); + dropDown.setCompoundDrawablePadding(AndroidUtilities.dp(4)); + dropDown.setPadding(0, 0, AndroidUtilities.dp(10), 0); + dropDownContainer.addView(dropDown); + layoutParams = (FrameLayout.LayoutParams) dropDown.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.leftMargin = AndroidUtilities.dp(16); + layoutParams.gravity = Gravity.CENTER_VERTICAL; + layoutParams.bottomMargin = AndroidUtilities.dp(1); + dropDown.setLayoutParams(layoutParams); + } else { + actionBar.setTitle(LocaleController.getString("Passcode", R.string.Passcode)); + } + + updateDropDownTextView(); + } else { + actionBar.setTitle(LocaleController.getString("Passcode", R.string.Passcode)); + frameLayout.setBackgroundColor(0xfff0f0f0); + listView = new ListView(context); + listView.setDivider(null); + listView.setDividerHeight(0); + listView.setVerticalScrollBarEnabled(false); + listView.setDrawSelectorOnTop(true); + frameLayout.addView(listView); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP; + listView.setLayoutParams(layoutParams); + listView.setAdapter(listAdapter = new ListAdapter(context)); + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, final int i, long l) { + if (i == changePasscodeRow) { + presentFragment(new PasscodeActivity(1)); + } else if (i == passcodeRow) { + TextCheckCell cell = (TextCheckCell) view; + if (UserConfig.passcodeHash.length() != 0) { + UserConfig.passcodeHash = ""; + UserConfig.appLocked = false; + UserConfig.saveConfig(false); + int count = listView.getChildCount(); + for (int a = 0; a < count; a++) { + View child = listView.getChildAt(a); + if (child instanceof TextSettingsCell) { + TextSettingsCell textCell = (TextSettingsCell) child; + textCell.setTextColor(0xffc6c6c6); + break; + } + } + cell.setChecked(UserConfig.passcodeHash.length() != 0); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.didSetPasscode); + } else { + presentFragment(new PasscodeActivity(1)); + } + } else if (i == autoLockRow) { + if (getParentActivity() == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("AutoLock", R.string.AutoLock)); + final NumberPicker numberPicker = new NumberPicker(getParentActivity()); + numberPicker.setMinValue(0); + numberPicker.setMaxValue(4); + if (UserConfig.autoLockIn == 0) { + numberPicker.setValue(0); + } else if (UserConfig.autoLockIn == 60) { + numberPicker.setValue(1); + } else if (UserConfig.autoLockIn == 60 * 5) { + numberPicker.setValue(2); + } else if (UserConfig.autoLockIn == 60 * 60) { + numberPicker.setValue(3); + } else if (UserConfig.autoLockIn == 60 * 60 * 5) { + numberPicker.setValue(4); + } + numberPicker.setFormatter(new NumberPicker.Formatter() { + @Override + public String format(int value) { + if (value == 0) { + return LocaleController.getString("Disabled", R.string.Disabled); + } else if (value == 1) { + return LocaleController.formatString("AutoLockInTime", R.string.AutoLockInTime, LocaleController.formatPluralString("Minutes", 1)); + } else if (value == 2) { + return LocaleController.formatString("AutoLockInTime", R.string.AutoLockInTime, LocaleController.formatPluralString("Minutes", 5)); + } else if (value == 3) { + return LocaleController.formatString("AutoLockInTime", R.string.AutoLockInTime, LocaleController.formatPluralString("Hours", 1)); + } else if (value == 4) { + return LocaleController.formatString("AutoLockInTime", R.string.AutoLockInTime, LocaleController.formatPluralString("Hours", 5)); + } + return ""; + } + }); + builder.setView(numberPicker); + builder.setNegativeButton(LocaleController.getString("Done", R.string.Done), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + which = numberPicker.getValue(); + if (which == 0) { + UserConfig.autoLockIn = 0; + } else if (which == 1) { + UserConfig.autoLockIn = 60; + } else if (which == 2) { + UserConfig.autoLockIn = 60 * 5; + } else if (which == 3) { + UserConfig.autoLockIn = 60 * 60; + } else if (which == 4) { + UserConfig.autoLockIn = 60 * 60 * 5; + } + listView.invalidateViews(); + UserConfig.saveConfig(false); + } + }); + showAlertDialog(builder); + } + } + }); + } + + return fragmentView; + } + + @Override + public void onResume() { + super.onResume(); + if (listAdapter != null) { + listAdapter.notifyDataSetChanged(); + } + if (type != 0) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (passwordEditText != null) { + passwordEditText.requestFocus(); + AndroidUtilities.showKeyboard(passwordEditText); + } + } + }, 200); + } + fixLayoutInternal(); + } + + @Override + public void didReceivedNotification(int id, Object... args) { + if (id == NotificationCenter.didSetPasscode) { + if (type == 0) { + updateRows(); + if (listAdapter != null) { + listAdapter.notifyDataSetChanged(); + } + } + } + } + + private void updateRows() { + rowCount = 0; + passcodeRow = rowCount++; + changePasscodeRow = rowCount++; + passcodeDetailRow = rowCount++; + if (UserConfig.passcodeHash.length() > 0) { + autoLockRow = rowCount++; + autoLockDetailRow = rowCount++; + } else { + autoLockRow = -1; + autoLockDetailRow = -1; + } + } + + @Override + public void onConfigurationChanged(android.content.res.Configuration newConfig) { + super.onConfigurationChanged(newConfig); + if (listView != null) { + ViewTreeObserver obs = listView.getViewTreeObserver(); + obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + listView.getViewTreeObserver().removeOnPreDrawListener(this); + fixLayoutInternal(); + return false; + } + }); + } + } + + @Override + public void onOpenAnimationEnd() { + super.onOpenAnimationEnd(); + if (type != 0) { + AndroidUtilities.showKeyboard(passwordEditText); + } + } + + private void updateDropDownTextView() { + if (dropDown != null) { + if (currentPasswordType == 0) { + dropDown.setText(LocaleController.getString("PasscodePIN", R.string.PasscodePIN)); + } else if (currentPasswordType == 1) { + dropDown.setText(LocaleController.getString("PasscodePassword", R.string.PasscodePassword)); + } + } + if (type == 1 && currentPasswordType == 0 || type == 2 && UserConfig.passcodeType == 0) { + InputFilter[] filterArray = new InputFilter[1]; + filterArray[0] = new InputFilter.LengthFilter(4); + passwordEditText.setFilters(filterArray); + passwordEditText.setInputType(InputType.TYPE_CLASS_PHONE); + passwordEditText.setKeyListener(DigitsKeyListener.getInstance("1234567890")); + } else if (type == 1 && currentPasswordType == 1 || type == 2 && UserConfig.passcodeType == 1) { + passwordEditText.setFilters(new InputFilter[0]); + passwordEditText.setKeyListener(null); + passwordEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); + } + passwordEditText.setTransformationMethod(PasswordTransformationMethod.getInstance()); + } + + private void processNext() { + if (passwordEditText.getText().length() == 0 || currentPasswordType == 0 && passwordEditText.getText().length() != 4) { + onPasscodeError(); + return; + } + if (currentPasswordType == 0) { + actionBar.setTitle(LocaleController.getString("PasscodePIN", R.string.PasscodePIN)); + } else { + actionBar.setTitle(LocaleController.getString("PasscodePassword", R.string.PasscodePassword)); + } + dropDownContainer.setVisibility(View.GONE); + titleTextView.setText(LocaleController.getString("ReEnterYourPasscode", R.string.ReEnterYourPasscode)); + firstPassword = passwordEditText.getText().toString(); + passwordEditText.setText(""); + passwordEditText.setImeOptions(EditorInfo.IME_ACTION_DONE); + } + + private void processDone() { + if (passwordEditText.getText().length() == 0) { + onPasscodeError(); + return; + } + if (type == 1) { + if (!firstPassword.equals(passwordEditText.getText().toString())) { + try { + Toast.makeText(getParentActivity(), LocaleController.getString("PasscodeDoNotMatch", R.string.PasscodeDoNotMatch), Toast.LENGTH_SHORT).show(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + AndroidUtilities.shakeTextView(titleTextView, 2, 0); + passwordEditText.setText(""); + return; + } + UserConfig.passcodeHash = Utilities.MD5(firstPassword); + UserConfig.passcodeType = currentPasswordType; + UserConfig.saveConfig(false); + //TODO show alert + finishFragment(); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.didSetPasscode); + passwordEditText.clearFocus(); + AndroidUtilities.hideKeyboard(passwordEditText); + } else if (type == 2) { + if (!Utilities.MD5(passwordEditText.getText().toString()).equals(UserConfig.passcodeHash)) { + passwordEditText.setText(""); + onPasscodeError(); + return; + } + passwordEditText.clearFocus(); + AndroidUtilities.hideKeyboard(passwordEditText); + presentFragment(new PasscodeActivity(0), true); + } + } + + private void onPasscodeError() { + if (getParentActivity() == null) { + return; + } + Vibrator v = (Vibrator) getParentActivity().getSystemService(Context.VIBRATOR_SERVICE); + if (v != null) { + v.vibrate(200); + } + AndroidUtilities.shakeTextView(titleTextView, 2, 0); + } + + private void fixLayoutInternal() { + if (dropDownContainer != null) { + if (!AndroidUtilities.isTablet()) { + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) dropDownContainer.getLayoutParams(); + layoutParams.topMargin = (Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0); + dropDownContainer.setLayoutParams(layoutParams); + } + if (!AndroidUtilities.isTablet() && ApplicationLoader.applicationContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + dropDown.setTextSize(18); + } else { + dropDown.setTextSize(20); + } + } + } + + private class ListAdapter extends BaseFragmentAdapter { + private Context mContext; + + public ListAdapter(Context context) { + mContext = context; + } + + @Override + public boolean areAllItemsEnabled() { + return false; + } + + @Override + public boolean isEnabled(int i) { + return i == passcodeRow || i == autoLockRow || UserConfig.passcodeHash.length() != 0 && i == changePasscodeRow; + } + + @Override + public int getCount() { + return rowCount; + } + + @Override + public Object getItem(int i) { + return null; + } + + @Override + public long getItemId(int i) { + return i; + } + + @Override + public boolean hasStableIds() { + return false; + } + + @Override + public View getView(int i, View view, ViewGroup viewGroup) { + int viewType = getItemViewType(i); + if (viewType == 0) { + if (view == null) { + view = new TextCheckCell(mContext); + view.setBackgroundColor(0xffffffff); + } + TextCheckCell textCell = (TextCheckCell) view; + + if (i == passcodeRow) { + textCell.setTextAndCheck(LocaleController.getString("Passcode", R.string.Passcode), UserConfig.passcodeHash.length() > 0, true); + } + } else if (viewType == 1) { + if (view == null) { + view = new TextSettingsCell(mContext); + view.setBackgroundColor(0xffffffff); + } + TextSettingsCell textCell = (TextSettingsCell) view; + if (i == changePasscodeRow) { + textCell.setText(LocaleController.getString("ChangePasscode", R.string.ChangePasscode), false); + textCell.setTextColor(UserConfig.passcodeHash.length() == 0 ? 0xffc6c6c6 : 0xff000000); + } else if (i == autoLockRow) { + String val; + if (UserConfig.autoLockIn == 0) { + val = LocaleController.formatString("AutoLockDisabled", R.string.AutoLockDisabled); + } else if (UserConfig.autoLockIn < 60 * 60) { + val = LocaleController.formatString("AutoLockInTime", R.string.AutoLockInTime, LocaleController.formatPluralString("Minutes", UserConfig.autoLockIn / 60)); + } else if (UserConfig.autoLockIn < 60 * 60 * 24) { + val = LocaleController.formatString("AutoLockInTime", R.string.AutoLockInTime, LocaleController.formatPluralString("Hours", (int) Math.ceil(UserConfig.autoLockIn / 60.0f / 60))); + } else { + val = LocaleController.formatString("AutoLockInTime", R.string.AutoLockInTime, LocaleController.formatPluralString("Days", (int) Math.ceil(UserConfig.autoLockIn / 60.0f / 60 / 24))); + } + textCell.setTextAndValue(LocaleController.getString("AutoLock", R.string.AutoLock), val, true); + textCell.setTextColor(0xff000000); + } + } else if (viewType == 2) { + if (view == null) { + view = new TextInfoPrivacyCell(mContext); + } + if (i == passcodeDetailRow) { + ((TextInfoPrivacyCell) view).setText(LocaleController.getString("ChangePasscodeInfo", R.string.ChangePasscodeInfo)); + if (autoLockDetailRow != -1) { + view.setBackgroundResource(R.drawable.greydivider); + } else { + view.setBackgroundResource(R.drawable.greydivider_bottom); + } + } else if (i == autoLockDetailRow) { + ((TextInfoPrivacyCell) view).setText(LocaleController.getString("AutoLockInfo", R.string.AutoLockInfo)); + view.setBackgroundResource(R.drawable.greydivider_bottom); + } + } + return view; + } + + @Override + public int getItemViewType(int i) { + if (i == passcodeRow) { + return 0; + } else if (i == changePasscodeRow || i == autoLockRow) { + return 1; + } else if (i == passcodeDetailRow || i == autoLockDetailRow) { + return 2; + } + return 0; + } + + @Override + public int getViewTypeCount() { + return 3; + } + + @Override + public boolean isEmpty() { + return false; + } + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java index 61646ad1e..fa330b1db 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java @@ -45,10 +45,9 @@ import java.util.HashMap; public class PhotoAlbumPickerActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate { - public static interface PhotoAlbumPickerActivityDelegate { - public abstract void didSelectPhotos(ArrayList photos); - public abstract void didSelectWebPhotos(ArrayList photos); - public abstract void startPhotoSelectActivity(); + public interface PhotoAlbumPickerActivityDelegate { + void didSelectPhotos(ArrayList photos, ArrayList webPhotos); + void startPhotoSelectActivity(); } private ArrayList albumsSorted = null; @@ -67,9 +66,15 @@ public class PhotoAlbumPickerActivity extends BaseFragment implements Notificati private TextView emptyView; private PhotoPickerBottomLayout photoPickerBottomLayout; private boolean sendPressed = false; + private boolean singlePhoto = false; private PhotoAlbumPickerActivityDelegate delegate; + public PhotoAlbumPickerActivity(boolean onlyOnePhoto) { + super(); + singlePhoto = onlyOnePhoto; + } + @Override public boolean onFragmentCreate() { loading = true; @@ -90,129 +95,123 @@ public class PhotoAlbumPickerActivity extends BaseFragment implements Notificati @SuppressWarnings("unchecked") @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackgroundColor(0xff333333); - actionBar.setItemsBackground(R.drawable.bar_selector_picker); - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setTitle(LocaleController.getString("Gallery", R.string.Gallery)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - if (Build.VERSION.SDK_INT < 11) { - listView.setAdapter(null); - listView = null; - listAdapter = null; - } - finishFragment(); - } else if (id == 1) { - if (delegate != null) { - finishFragment(false); - delegate.startPhotoSelectActivity(); - } + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackgroundColor(0xff333333); + actionBar.setItemsBackground(R.drawable.bar_selector_picker); + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setTitle(LocaleController.getString("Gallery", R.string.Gallery)); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + if (Build.VERSION.SDK_INT < 11) { + listView.setAdapter(null); + listView = null; + listAdapter = null; + } + finishFragment(); + } else if (id == 1) { + if (delegate != null) { + finishFragment(false); + delegate.startPhotoSelectActivity(); } } - }); - - ActionBarMenu menu = actionBar.createMenu(); - menu.addItem(1, R.drawable.ic_ab_other); - - fragmentView = new FrameLayout(getParentActivity()); - - FrameLayout frameLayout = (FrameLayout) fragmentView; - frameLayout.setBackgroundColor(0xff000000); - - listView = new ListView(getParentActivity()); - listView.setPadding(AndroidUtilities.dp(4), 0, AndroidUtilities.dp(4), AndroidUtilities.dp(4)); - listView.setClipToPadding(false); - listView.setHorizontalScrollBarEnabled(false); - listView.setVerticalScrollBarEnabled(false); - listView.setSelector(new ColorDrawable(0)); - listView.setDividerHeight(0); - listView.setDivider(null); - listView.setDrawingCacheEnabled(false); - listView.setScrollingCacheEnabled(false); - frameLayout.addView(listView); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.bottomMargin = AndroidUtilities.dp(48); - listView.setLayoutParams(layoutParams); - listView.setAdapter(listAdapter = new ListAdapter(getParentActivity())); - AndroidUtilities.setListViewEdgeEffectColor(listView, 0xff333333); - - emptyView = new TextView(getParentActivity()); - emptyView.setTextColor(0xff808080); - emptyView.setTextSize(20); - emptyView.setGravity(Gravity.CENTER); - emptyView.setVisibility(View.GONE); - emptyView.setText(LocaleController.getString("NoPhotos", R.string.NoPhotos)); - frameLayout.addView(emptyView); - layoutParams = (FrameLayout.LayoutParams) emptyView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.bottomMargin = AndroidUtilities.dp(48); - emptyView.setLayoutParams(layoutParams); - emptyView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return true; - } - }); - - progressView = new FrameLayout(getParentActivity()); - progressView.setVisibility(View.GONE); - frameLayout.addView(progressView); - layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.bottomMargin = AndroidUtilities.dp(48); - progressView.setLayoutParams(layoutParams); - - ProgressBar progressBar = new ProgressBar(getParentActivity()); - progressView.addView(progressBar); - layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.gravity = Gravity.CENTER; - progressView.setLayoutParams(layoutParams); - - photoPickerBottomLayout = new PhotoPickerBottomLayout(getParentActivity()); - frameLayout.addView(photoPickerBottomLayout); - layoutParams = (FrameLayout.LayoutParams) photoPickerBottomLayout.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = AndroidUtilities.dp(48); - layoutParams.gravity = Gravity.BOTTOM; - photoPickerBottomLayout.setLayoutParams(layoutParams); - photoPickerBottomLayout.cancelButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - finishFragment(); - } - }); - photoPickerBottomLayout.doneButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - sendSelectedPhotos(); - finishFragment(); - } - }); - - if (loading && (albumsSorted == null || albumsSorted != null && albumsSorted.isEmpty())) { - progressView.setVisibility(View.VISIBLE); - listView.setEmptyView(null); - } else { - progressView.setVisibility(View.GONE); - listView.setEmptyView(emptyView); } - photoPickerBottomLayout.updateSelectedCount(selectedPhotos.size() + selectedWebPhotos.size(), true); + }); + + ActionBarMenu menu = actionBar.createMenu(); + menu.addItem(1, R.drawable.ic_ab_other); + + fragmentView = new FrameLayout(context); + + FrameLayout frameLayout = (FrameLayout) fragmentView; + frameLayout.setBackgroundColor(0xff000000); + + listView = new ListView(context); + listView.setPadding(AndroidUtilities.dp(4), 0, AndroidUtilities.dp(4), AndroidUtilities.dp(4)); + listView.setClipToPadding(false); + listView.setHorizontalScrollBarEnabled(false); + listView.setVerticalScrollBarEnabled(false); + listView.setSelector(new ColorDrawable(0)); + listView.setDividerHeight(0); + listView.setDivider(null); + listView.setDrawingCacheEnabled(false); + listView.setScrollingCacheEnabled(false); + frameLayout.addView(listView); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.bottomMargin = AndroidUtilities.dp(48); + listView.setLayoutParams(layoutParams); + listView.setAdapter(listAdapter = new ListAdapter(context)); + AndroidUtilities.setListViewEdgeEffectColor(listView, 0xff333333); + + emptyView = new TextView(context); + emptyView.setTextColor(0xff808080); + emptyView.setTextSize(20); + emptyView.setGravity(Gravity.CENTER); + emptyView.setVisibility(View.GONE); + emptyView.setText(LocaleController.getString("NoPhotos", R.string.NoPhotos)); + frameLayout.addView(emptyView); + layoutParams = (FrameLayout.LayoutParams) emptyView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.bottomMargin = AndroidUtilities.dp(48); + emptyView.setLayoutParams(layoutParams); + emptyView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + progressView = new FrameLayout(context); + progressView.setVisibility(View.GONE); + frameLayout.addView(progressView); + layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.bottomMargin = AndroidUtilities.dp(48); + progressView.setLayoutParams(layoutParams); + + ProgressBar progressBar = new ProgressBar(context); + progressView.addView(progressBar); + layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.CENTER; + progressView.setLayoutParams(layoutParams); + + photoPickerBottomLayout = new PhotoPickerBottomLayout(context); + frameLayout.addView(photoPickerBottomLayout); + layoutParams = (FrameLayout.LayoutParams) photoPickerBottomLayout.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = AndroidUtilities.dp(48); + layoutParams.gravity = Gravity.BOTTOM; + photoPickerBottomLayout.setLayoutParams(layoutParams); + photoPickerBottomLayout.cancelButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + finishFragment(); + } + }); + photoPickerBottomLayout.doneButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + sendSelectedPhotos(); + finishFragment(); + } + }); + + if (loading && (albumsSorted == null || albumsSorted != null && albumsSorted.isEmpty())) { + progressView.setVisibility(View.VISIBLE); + listView.setEmptyView(null); } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); - } + progressView.setVisibility(View.GONE); + listView.setEmptyView(emptyView); } + photoPickerBottomLayout.updateSelectedCount(selectedPhotos.size() + selectedWebPhotos.size(), true); + return fragmentView; } @@ -292,7 +291,11 @@ public class PhotoAlbumPickerActivity extends BaseFragment implements Notificati boolean webChange = false; for (HashMap.Entry entry : selectedWebPhotos.entrySet()) { MediaController.SearchImage searchImage = entry.getValue(); - webPhotos.add(searchImage); + if (searchImage.imagePath != null) { + photos.add(searchImage.imagePath); + } else { + webPhotos.add(searchImage); + } searchImage.date = (int) (System.currentTimeMillis() / 1000); if (searchImage.type == 0) { @@ -322,8 +325,7 @@ public class PhotoAlbumPickerActivity extends BaseFragment implements Notificati MessagesStorage.getInstance().putWebRecent(recentGifImages); } - delegate.didSelectPhotos(photos); - delegate.didSelectWebPhotos(webPhotos); + delegate.didSelectPhotos(photos, webPhotos); } private void fixLayout() { @@ -349,7 +351,7 @@ public class PhotoAlbumPickerActivity extends BaseFragment implements Notificati WindowManager manager = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); int rotation = manager.getDefaultDisplay().getRotation(); columnsCount = 2; - if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { + if (!AndroidUtilities.isTablet() && (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90)) { columnsCount = 4; } listAdapter.notifyDataSetChanged(); @@ -364,7 +366,7 @@ public class PhotoAlbumPickerActivity extends BaseFragment implements Notificati recentImages = recentGifImages; } } - PhotoPickerActivity fragment = new PhotoPickerActivity(type, albumEntry, selectedPhotos, selectedWebPhotos, recentImages); + PhotoPickerActivity fragment = new PhotoPickerActivity(type, albumEntry, selectedPhotos, selectedWebPhotos, recentImages, singlePhoto); fragment.setDelegate(new PhotoPickerActivity.PhotoPickerActivityDelegate() { @Override public void selectedPhotosChanged() { @@ -403,6 +405,9 @@ public class PhotoAlbumPickerActivity extends BaseFragment implements Notificati @Override public int getCount() { + if (singlePhoto) { + return albumsSorted != null ? (int) Math.ceil(albumsSorted.size() / (float) columnsCount) : 0; + } return 1 + (albumsSorted != null ? (int) Math.ceil(albumsSorted.size() / (float) columnsCount) : 0); } @@ -440,7 +445,12 @@ public class PhotoAlbumPickerActivity extends BaseFragment implements Notificati } photoPickerAlbumsCell.setAlbumsCount(columnsCount); for (int a = 0; a < columnsCount; a++) { - int index = (i - 1) * columnsCount + a; + int index; + if (singlePhoto) { + index = i * columnsCount + a; + } else { + index = (i - 1) * columnsCount + a; + } if (index < albumsSorted.size()) { MediaController.AlbumEntry albumEntry = albumsSorted.get(index); photoPickerAlbumsCell.setAlbum(a, albumEntry); @@ -448,6 +458,7 @@ public class PhotoAlbumPickerActivity extends BaseFragment implements Notificati photoPickerAlbumsCell.setAlbum(a, null); } } + photoPickerAlbumsCell.requestLayout(); } else if (type == 1) { if (view == null) { view = new PhotoPickerSearchCell(mContext); @@ -464,6 +475,9 @@ public class PhotoAlbumPickerActivity extends BaseFragment implements Notificati @Override public int getItemViewType(int i) { + if (singlePhoto) { + return 0; + } if (i == 0) { return 1; } @@ -472,6 +486,9 @@ public class PhotoAlbumPickerActivity extends BaseFragment implements Notificati @Override public int getViewTypeCount() { + if (singlePhoto) { + return 1; + } return 2; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoCropActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoCropActivity.java index 910b4f444..af94958c1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoCropActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoCropActivity.java @@ -19,7 +19,6 @@ import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; -import android.view.ViewGroup; import android.widget.FrameLayout; import org.telegram.android.AndroidUtilities; @@ -36,7 +35,7 @@ import java.io.File; public class PhotoCropActivity extends BaseFragment { public interface PhotoEditActivityDelegate { - public abstract void didFinishEdit(Bitmap bitmap, Bundle args); + void didFinishEdit(Bitmap bitmap, Bundle args); } private class PhotoCropView extends FrameLayout { @@ -303,6 +302,12 @@ public class PhotoCropActivity extends BaseFragment { int y = (int)(percY * imageToCrop.getHeight()); int sizeX = (int)(percSizeX * imageToCrop.getWidth()); int sizeY = (int)(percSizeY * imageToCrop.getWidth()); + if (x < 0) { + x = 0; + } + if (y < 0) { + y = 0; + } if (x + sizeX > imageToCrop.getWidth()) { sizeX = imageToCrop.getWidth() - x; } @@ -426,44 +431,38 @@ public class PhotoCropActivity extends BaseFragment { } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackgroundColor(0xff333333); - actionBar.setItemsBackground(R.drawable.bar_selector_picker); - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - actionBar.setTitle(LocaleController.getString("CropImage", R.string.CropImage)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } else if (id == done_button) { - if (delegate != null && !doneButtonPressed) { - Bitmap bitmap = view.getBitmap(); - if (bitmap == imageToCrop) { - sameBitmap = true; - } - delegate.didFinishEdit(bitmap, getArguments()); - doneButtonPressed = true; + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackgroundColor(0xff333333); + actionBar.setItemsBackground(R.drawable.bar_selector_picker); + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + actionBar.setTitle(LocaleController.getString("CropImage", R.string.CropImage)); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } else if (id == done_button) { + if (delegate != null && !doneButtonPressed) { + Bitmap bitmap = view.getBitmap(); + if (bitmap == imageToCrop) { + sameBitmap = true; } - finishFragment(); + delegate.didFinishEdit(bitmap, getArguments()); + doneButtonPressed = true; } + finishFragment(); } - }); - - ActionBarMenu menu = actionBar.createMenu(); - menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); - - fragmentView = view = new PhotoCropView(getParentActivity()); - ((PhotoCropView) fragmentView).freeform = getArguments().getBoolean("freeform", false); - fragmentView.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); } - } + }); + + ActionBarMenu menu = actionBar.createMenu(); + menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + + fragmentView = view = new PhotoCropView(context); + ((PhotoCropView) fragmentView).freeform = getArguments().getBoolean("freeform", false); + fragmentView.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); + return fragmentView; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoEditorActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoEditorActivity.java deleted file mode 100644 index 5e0ff8f4e..000000000 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoEditorActivity.java +++ /dev/null @@ -1,1285 +0,0 @@ -/* - * 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.content.Context; -import android.content.res.Configuration; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.net.Uri; -import android.opengl.GLES20; -import android.opengl.GLSurfaceView; -import android.opengl.GLUtils; -import android.os.Build; -import android.os.Bundle; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewTreeObserver; -import android.view.animation.AccelerateDecelerateInterpolator; -import android.view.animation.AccelerateInterpolator; -import android.view.animation.DecelerateInterpolator; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.SeekBar; - -import org.telegram.android.AndroidUtilities; -import org.telegram.android.ImageLoader; -import org.telegram.android.LocaleController; -import org.telegram.messenger.FileLog; -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.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.Cells.PhotoEditToolCell; -import org.telegram.ui.Components.RecyclerListView; - -import java.io.File; -import java.lang.reflect.Field; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; - -import javax.microedition.khronos.opengles.GL10; - -public class PhotoEditorActivity extends BaseFragment { - - private GLSurfaceView glView; - private PhotoCropView cropView; - - private SeekBar valueSeekBar; - private LinearLayout toolsView; - private LinearLayout cropButtonsView; - private ImageView imageView; - private ImageView filtersButton; - private ImageView toolButton; - private AnimatorSetProxy rotationAnimation; - - private ActionBarMenuItem doneButton; - private ActionBarMenuItem sizeButton; - private ActionBarMenuItem rotateButton; - - private boolean sameBitmap = false; - private int currentMode = 0; - private boolean freeformCrop; - private boolean onlyCrop; - - private PhotoCropActivity.PhotoEditActivityDelegate delegate; - - private int selectedTool = 0; - private int rotateDegree = 0; - - private Bitmap bitmapToEdit; - private String bitmapKey; - - private float highlightsValue = 0; //0 100 - private float contrastValue = 0; //-100 100 - private float shadowsValue = 0; //0 100 - private float exposureValue = 0; //-100 100 - private float saturationValue = 0; //-100 100 - private float warmthValue = 0; //-100 100 - private float vignetteValue = 0; //0 100 - private float grainValue = 0; //0 100 - private float width = 0; - private float height = 0; - - private boolean donePressed = false; - - private final static int done_button = 1; - private final static int rotate_button = 2; - private final static int size_button = 3; - - private class PhotoCropView extends FrameLayout { - - private Paint rectPaint; - private Paint circlePaint; - private Paint halfPaint; - private Paint shadowPaint; - private float rectSizeX = 600; - private float rectSizeY = 600; - private int draggingState = 0; - private float oldX = 0, oldY = 0; - private int bitmapWidth = 1, bitmapHeight = 1, bitmapX, bitmapY; - private float rectX = -1, rectY = -1; - - public PhotoCropView(Context context) { - super(context); - - rectPaint = new Paint(); - rectPaint.setColor(0xb2ffffff); - rectPaint.setStrokeWidth(AndroidUtilities.dp(2)); - rectPaint.setStyle(Paint.Style.STROKE); - circlePaint = new Paint(); - circlePaint.setColor(0xffffffff); - halfPaint = new Paint(); - halfPaint.setColor(0x7f000000); - shadowPaint = new Paint(); - shadowPaint.setColor(0x1a000000); - setWillNotDraw(false); - - setOnTouchListener(new OnTouchListener() { - @Override - public boolean onTouch(View view, MotionEvent motionEvent) { - float x = motionEvent.getX(); - float y = motionEvent.getY(); - int cornerSide = AndroidUtilities.dp(20); - if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { - if (rectX - cornerSide < x && rectX + cornerSide > x && rectY - cornerSide < y && rectY + cornerSide > y) { - draggingState = 1; - } else if (rectX - cornerSide + rectSizeX < x && rectX + cornerSide + rectSizeX > x && rectY - cornerSide < y && rectY + cornerSide > y) { - draggingState = 2; - } else if (rectX - cornerSide < x && rectX + cornerSide > x && rectY - cornerSide + rectSizeY < y && rectY + cornerSide + rectSizeY > y) { - draggingState = 3; - } else if (rectX - cornerSide + rectSizeX < x && rectX + cornerSide + rectSizeX > x && rectY - cornerSide + rectSizeY < y && rectY + cornerSide + rectSizeY > y) { - draggingState = 4; - } else if (rectX < x && rectX + rectSizeX > x && rectY < y && rectY + rectSizeY > y) { - draggingState = 5; - } else { - draggingState = 0; - } - if (draggingState != 0) { - PhotoCropView.this.requestDisallowInterceptTouchEvent(true); - } - oldX = x; - oldY = y; - } else if (motionEvent.getAction() == MotionEvent.ACTION_UP) { - draggingState = 0; - } else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE && draggingState != 0) { - float diffX = x - oldX; - float diffY = y - oldY; - if (draggingState == 5) { - rectX += diffX; - rectY += diffY; - - if (rectX < bitmapX) { - rectX = bitmapX; - } else if (rectX + rectSizeX > bitmapX + bitmapWidth) { - rectX = bitmapX + bitmapWidth - rectSizeX; - } - if (rectY < bitmapY) { - rectY = bitmapY; - } else if (rectY + rectSizeY > bitmapY + bitmapHeight) { - rectY = bitmapY + bitmapHeight - rectSizeY; - } - } else { - if (draggingState == 1) { - if (rectSizeX - diffX < 160) { - diffX = rectSizeX - 160; - } - if (rectX + diffX < bitmapX) { - diffX = bitmapX - rectX; - } - if (!freeformCrop) { - if (rectY + diffX < bitmapY) { - diffX = bitmapY - rectY; - } - rectX += diffX; - rectY += diffX; - rectSizeX -= diffX; - rectSizeY -= diffX; - } else { - if (rectSizeY - diffY < 160) { - diffY = rectSizeY - 160; - } - if (rectY + diffY < bitmapY) { - diffY = bitmapY - rectY; - } - rectX += diffX; - rectY += diffY; - rectSizeX -= diffX; - rectSizeY -= diffY; - } - } else if (draggingState == 2) { - if (rectSizeX + diffX < 160) { - diffX = -(rectSizeX - 160); - } - if (rectX + rectSizeX + diffX > bitmapX + bitmapWidth) { - diffX = bitmapX + bitmapWidth - rectX - rectSizeX; - } - if (!freeformCrop) { - if (rectY - diffX < bitmapY) { - diffX = rectY - bitmapY; - } - rectY -= diffX; - rectSizeX += diffX; - rectSizeY += diffX; - } else { - if (rectSizeY - diffY < 160) { - diffY = rectSizeY - 160; - } - if (rectY + diffY < bitmapY) { - diffY = bitmapY - rectY; - } - rectY += diffY; - rectSizeX += diffX; - rectSizeY -= diffY; - } - } else if (draggingState == 3) { - if (rectSizeX - diffX < 160) { - diffX = rectSizeX - 160; - } - if (rectX + diffX < bitmapX) { - diffX = bitmapX - rectX; - } - if (!freeformCrop) { - if (rectY + rectSizeX - diffX > bitmapY + bitmapHeight) { - diffX = rectY + rectSizeX - bitmapY - bitmapHeight; - } - rectX += diffX; - rectSizeX -= diffX; - rectSizeY -= diffX; - } else { - if (rectY + rectSizeY + diffY > bitmapY + bitmapHeight) { - diffY = bitmapY + bitmapHeight - rectY - rectSizeY; - } - rectX += diffX; - rectSizeX -= diffX; - rectSizeY += diffY; - if (rectSizeY < 160) { - rectSizeY = 160; - } - } - } else if (draggingState == 4) { - if (rectX + rectSizeX + diffX > bitmapX + bitmapWidth) { - diffX = bitmapX + bitmapWidth - rectX - rectSizeX; - } - if (!freeformCrop) { - if (rectY + rectSizeX + diffX > bitmapY + bitmapHeight) { - diffX = bitmapY + bitmapHeight - rectY - rectSizeX; - } - rectSizeX += diffX; - rectSizeY += diffX; - } else { - if (rectY + rectSizeY + diffY > bitmapY + bitmapHeight) { - diffY = bitmapY + bitmapHeight - rectY - rectSizeY; - } - rectSizeX += diffX; - rectSizeY += diffY; - } - if (rectSizeX < 160) { - rectSizeX = 160; - } - if (rectSizeY < 160) { - rectSizeY = 160; - } - } - } - - oldX = x; - oldY = y; - invalidate(); - } - return true; - } - }); - } - - public Bitmap getBitmap() { - float percX = (rectX - bitmapX) / bitmapWidth; - float percY = (rectY - bitmapY) / bitmapHeight; - float percSizeX = rectSizeX / bitmapWidth; - float percSizeY = rectSizeY / bitmapWidth; - int x = (int)(percX * bitmapToEdit.getWidth()); - int y = (int)(percY * bitmapToEdit.getHeight()); - int sizeX = (int)(percSizeX * bitmapToEdit.getWidth()); - int sizeY = (int)(percSizeY * bitmapToEdit.getWidth()); - if (x + sizeX > bitmapToEdit.getWidth()) { - sizeX = bitmapToEdit.getWidth() - x; - } - if (y + sizeY > bitmapToEdit.getHeight()) { - sizeY = bitmapToEdit.getHeight() - y; - } - try { - return Bitmap.createBitmap(bitmapToEdit, x, y, sizeX, sizeY); - } catch (Throwable e) { - FileLog.e("tmessags", e); - System.gc(); - try { - return Bitmap.createBitmap(bitmapToEdit, x, y, sizeX, sizeY); - } catch (Throwable e2) { - FileLog.e("tmessages", e2); - } - } - return null; - } - - @Override - protected void onDraw(Canvas canvas) { - canvas.drawRect(bitmapX, bitmapY, bitmapX + bitmapWidth, rectY, halfPaint); - canvas.drawRect(bitmapX, rectY, rectX, rectY + rectSizeY, halfPaint); - canvas.drawRect(rectX + rectSizeX, rectY, bitmapX + bitmapWidth, rectY + rectSizeY, halfPaint); - canvas.drawRect(bitmapX, rectY + rectSizeY, bitmapX + bitmapWidth, bitmapY + bitmapHeight, halfPaint); - - int side = AndroidUtilities.dp(1); - canvas.drawRect(rectX - side * 2, rectY - side * 2, rectX - side * 2 + AndroidUtilities.dp(20), rectY, circlePaint); - canvas.drawRect(rectX - side * 2, rectY - side * 2, rectX, rectY - side * 2 + AndroidUtilities.dp(20), circlePaint); - - canvas.drawRect(rectX + rectSizeX + side * 2 - AndroidUtilities.dp(20), rectY - side * 2, rectX + rectSizeX + side * 2, rectY, circlePaint); - canvas.drawRect(rectX + rectSizeX, rectY - side * 2, rectX + rectSizeX + side * 2, rectY - side * 2 + AndroidUtilities.dp(20), circlePaint); - - canvas.drawRect(rectX - side * 2, rectY + rectSizeY + side * 2 - AndroidUtilities.dp(20), rectX, rectY + rectSizeY + side * 2, circlePaint); - canvas.drawRect(rectX - side * 2, rectY + rectSizeY, rectX - side * 2 + AndroidUtilities.dp(20), rectY + rectSizeY + side * 2, circlePaint); - - canvas.drawRect(rectX + rectSizeX + side * 2 - AndroidUtilities.dp(20), rectY + rectSizeY, rectX + rectSizeX + side * 2, rectY + rectSizeY + side * 2, circlePaint); - canvas.drawRect(rectX + rectSizeX, rectY + rectSizeY + side * 2 - AndroidUtilities.dp(20), rectX + rectSizeX + side * 2, rectY + rectSizeY + side * 2, circlePaint); - - for (int a = 1; a < 3; a++) { - canvas.drawRect(rectX + rectSizeX / 3 * a - side, rectY, rectX + side * 2 + rectSizeX / 3 * a, rectY + rectSizeY, shadowPaint); - canvas.drawRect(rectX, rectY + rectSizeY / 3 * a - side, rectX + rectSizeX, rectY + rectSizeY / 3 * a + side * 2, shadowPaint); - } - - for (int a = 1; a < 3; a++) { - canvas.drawRect(rectX + rectSizeX / 3 * a, rectY, rectX + side + rectSizeX / 3 * a, rectY + rectSizeY, circlePaint); - canvas.drawRect(rectX, rectY + rectSizeY / 3 * a, rectX + rectSizeX, rectY + rectSizeY / 3 * a + side, circlePaint); - } - - canvas.drawRect(rectX, rectY, rectX + rectSizeX, rectY + rectSizeY, rectPaint); - } - } - - class MyGLSurfaceView extends GLSurfaceView { - - public MyGLSurfaceView(Context context){ - super(context); - setEGLContextClientVersion(2); - setRenderer(new MyGLRenderer()); - setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); - } - } - - public class MyGLRenderer implements GLSurfaceView.Renderer { - - private int trivialShaderProgram; - - private int positionHandle; - private int inputTexCoordHandle; - private int photoImageHandle; - private int shadowsHandle; - private int highlightsHandle; - private int exposureHandle; - private int contrastHandle; - private int saturationHandle; - private int warmthHandle; - private int vignetteHandle; - private int grainHandle; - private int grainWidthHandle; - private int grainHeightHandle; - - private int[] textures = new int[1]; - - private FloatBuffer vertexBuffer; - private FloatBuffer textureBuffer; - private FloatBuffer vertexSaveBuffer; - - private static final String trivialVertexShaderCode = - "attribute vec4 position;" + - "attribute vec4 inputTexCoord;" + - "varying vec2 texCoord;" + - "void main() {" + - "gl_Position = position;" + - "texCoord = inputTexCoord.xy;" + - "}"; - - private static final String trivialFragmentShaderCode = - "varying highp vec2 texCoord;" + - "uniform sampler2D photoImage;" + - "uniform lowp float shadows;" + - "uniform highp float width;" + - "uniform highp float height;" + - "const mediump vec3 hsLuminanceWeighting = vec3(0.3, 0.3, 0.3);" + - "uniform lowp float highlights;" + - "uniform highp float exposure;" + - "uniform lowp float contrast;" + - "const mediump vec3 satLuminanceWeighting = vec3(0.2126, 0.7152, 0.0722);" + - "uniform lowp float saturation;" + - "uniform lowp float warmth;" + - "uniform lowp float grain;" + - "const lowp float permTexUnit = 1.0 / 256.0;" + - "const lowp float permTexUnitHalf = 0.5 / 256.0;" + - "const lowp float grainsize = 2.3;" + - "uniform lowp float vignette;" + - "highp float getLuma(highp vec3 rgbP) { return (0.299 * rgbP.r) + (0.587 * rgbP.g) + (0.114 * rgbP.b); }" + - "highp vec3 rgbToYuv(highp vec3 inP) { highp vec3 outP; outP.r = getLuma(inP); outP.g = (1.0 / 1.772) * (inP.b - outP.r); outP.b = (1.0 / 1.402) * (inP.r - outP.r); return outP; }" + - "lowp vec3 yuvToRgb(highp vec3 inP) { highp float y = inP.r; highp float u = inP.g; highp float v = inP.b; lowp vec3 outP; outP.r = 1.402 * v + y; outP.g = (y - (0.299 * 1.402 / 0.587) * v - (0.114 * 1.772 / 0.587) * u); outP.b = 1.772 * u + y; return outP; } " + - "lowp float easeInOutSigmoid(lowp float value, lowp float strength) { lowp float t = 1.0 / (1.0 - strength); if (value > 0.5) { return 1.0 - pow(2.0 - 2.0 * value, t) * 0.5; } else { return pow(2.0 * value, t) * 0.5; } }" + - "highp vec4 rnm(in highp vec2 tc) { highp float noise = sin(dot(tc,vec2(12.9898,78.233))) * 43758.5453; highp float noiseR = fract(noise)*2.0-1.0; highp float noiseG = fract(noise*1.2154)*2.0-1.0; highp float noiseB = fract(noise*1.3453)*2.0-1.0; " + - "highp float noiseA = fract(noise*1.3647)*2.0-1.0; return vec4(noiseR,noiseG,noiseB,noiseA); } highp float fade(in highp float t) { return t*t*t*(t*(t*6.0-15.0)+10.0); } highp float pnoise3D(in highp vec3 p) { highp vec3 pi = permTexUnit*floor(p)+permTexUnitHalf; " + - "highp vec3 pf = fract(p); highp float perm00 = rnm(pi.xy).a ; highp vec3 grad000 = rnm(vec2(perm00, pi.z)).rgb * 4.0 - 1.0; highp float n000 = dot(grad000, pf); highp vec3 grad001 = rnm(vec2(perm00, pi.z + permTexUnit)).rgb * 4.0 - 1.0; " + - "highp float n001 = dot(grad001, pf - vec3(0.0, 0.0, 1.0)); highp float perm01 = rnm(pi.xy + vec2(0.0, permTexUnit)).a ; highp vec3 grad010 = rnm(vec2(perm01, pi.z)).rgb * 4.0 - 1.0; highp float n010 = dot(grad010, pf - vec3(0.0, 1.0, 0.0));" + - "highp vec3 grad011 = rnm(vec2(perm01, pi.z + permTexUnit)).rgb * 4.0 - 1.0; highp float n011 = dot(grad011, pf - vec3(0.0, 1.0, 1.0)); highp float perm10 = rnm(pi.xy + vec2(permTexUnit, 0.0)).a ;" + - "highp vec3 grad100 = rnm(vec2(perm10, pi.z)).rgb * 4.0 - 1.0; highp float n100 = dot(grad100, pf - vec3(1.0, 0.0, 0.0)); highp vec3 grad101 = rnm(vec2(perm10, pi.z + permTexUnit)).rgb * 4.0 - 1.0;" + - "highp float n101 = dot(grad101, pf - vec3(1.0, 0.0, 1.0)); highp float perm11 = rnm(pi.xy + vec2(permTexUnit, permTexUnit)).a ; highp vec3 grad110 = rnm(vec2(perm11, pi.z)).rgb * 4.0 - 1.0; highp float n110 = dot(grad110, pf - vec3(1.0, 1.0, 0.0));" + - "highp vec3 grad111 = rnm(vec2(perm11, pi.z + permTexUnit)).rgb * 4.0 - 1.0; highp float n111 = dot(grad111, pf - vec3(1.0, 1.0, 1.0)); highp vec4 n_x = mix(vec4(n000, n001, n010, n011), vec4(n100, n101, n110, n111), fade(pf.x));" + - "highp vec2 n_xy = mix(n_x.xy, n_x.zw, fade(pf.y)); highp float n_xyz = mix(n_xy.x, n_xy.y, fade(pf.z)); return n_xyz; } lowp vec2 coordRot(in lowp vec2 tc, in lowp float angle) { lowp float rotX = ((tc.x * 2.0 - 1.0) * cos(angle)) - ((tc.y * 2.0 - 1.0) * sin(angle));" + - "lowp float rotY = ((tc.y * 2.0 - 1.0) * cos(angle)) + ((tc.x * 2.0 - 1.0) * sin(angle)); rotX = rotX * 0.5 + 0.5; rotY = rotY * 0.5 + 0.5; return vec2(rotX,rotY); }void main() {lowp vec4 source = texture2D(photoImage, texCoord);lowp vec4 result = source;" + - "const lowp float toolEpsilon = 0.005;mediump float hsLuminance = dot(result.rgb, hsLuminanceWeighting); mediump float shadow = clamp((pow(hsLuminance, 1.0 / (shadows + 1.0)) + (-0.76) * pow(hsLuminance, 2.0 / (shadows + 1.0))) - hsLuminance, 0.0, 1.0);" + - "mediump float highlight = clamp((1.0 - (pow(1.0 - hsLuminance, 1.0 / (2.0 - highlights)) + (-0.8) * pow(1.0 - hsLuminance, 2.0 / (2.0 - highlights)))) - hsLuminance, -1.0, 0.0);" + - "lowp vec3 shresult = vec3(0.0, 0.0, 0.0) + ((hsLuminance + shadow + highlight) - 0.0) * ((result.rgb - vec3(0.0, 0.0, 0.0)) / (hsLuminance - 0.0)); result = vec4(shresult.rgb, result.a);" + - "if (abs(exposure) > toolEpsilon) { mediump float mag = exposure * 1.045; mediump float exppower = 1.0 + abs(mag); if (mag < 0.0) { exppower = 1.0 / exppower; } result.r = 1.0 - pow((1.0 - result.r), exppower);" + - "result.g = 1.0 - pow((1.0 - result.g), exppower); result.b = 1.0 - pow((1.0 - result.b), exppower); }result = vec4(((result.rgb - vec3(0.5)) * contrast + vec3(0.5)), result.a);" + - "lowp float satLuminance = dot(result.rgb, satLuminanceWeighting); lowp vec3 greyScaleColor = vec3(satLuminance); result = vec4(mix(greyScaleColor, result.rgb, saturation), result.a);" + - "if (abs(warmth) > toolEpsilon) { highp vec3 yuvVec; if (warmth > 0.0 ) { yuvVec = vec3(0.1765, -0.1255, 0.0902); } else { yuvVec = -vec3(0.0588, 0.1569, -0.1255); } highp vec3 yuvColor = rgbToYuv(result.rgb); highp float luma = yuvColor.r;" + - "highp float curveScale = sin(luma * 3.14159); yuvColor += 0.375 * warmth * curveScale * yuvVec; result.rgb = yuvToRgb(yuvColor); }if (abs(grain) > toolEpsilon) { highp vec3 rotOffset = vec3(1.425, 3.892, 5.835);" + - "highp vec2 rotCoordsR = coordRot(texCoord, rotOffset.x); highp vec3 noise = vec3(pnoise3D(vec3(rotCoordsR * vec2(width / grainsize, height / grainsize),0.0))); lowp vec3 lumcoeff = vec3(0.299,0.587,0.114);" + - "lowp float luminance = dot(result.rgb, lumcoeff); lowp float lum = smoothstep(0.2, 0.0, luminance); lum += luminance; noise = mix(noise,vec3(0.0),pow(lum,4.0)); result.rgb = result.rgb + noise * grain; }" + - "if (abs(vignette) > toolEpsilon) { const lowp float midpoint = 0.7; const lowp float fuzziness = 0.62; lowp float radDist = length(texCoord - 0.5) / sqrt(0.5);" + - "lowp float mag = easeInOutSigmoid(radDist * midpoint, fuzziness) * vignette * 0.645; result.rgb = mix(pow(result.rgb, vec3(1.0 / (1.0 - mag))), vec3(0.0), mag * mag); }gl_FragColor = result;}"; - - private int loadShader(int type, String shaderCode) { - int shader = GLES20.glCreateShader(type); - GLES20.glShaderSource(shader, shaderCode); - GLES20.glCompileShader(shader); - int[] compileStatus = new int[1]; - GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compileStatus, 0); - if (compileStatus[0] == 0) { - GLES20.glDeleteShader(shader); - shader = 0; - } - return shader; - } - - @Override - public void onSurfaceCreated(GL10 gl, javax.microedition.khronos.egl.EGLConfig config) { - - float squareCoordinates[] = { - -1.0f, 1.0f, - 1.0f, 1.0f, - -1.0f, -1.0f, - 1.0f, -1.0f}; - - ByteBuffer bb = ByteBuffer.allocateDirect(squareCoordinates.length * 4); - bb.order(ByteOrder.nativeOrder()); - vertexBuffer = bb.asFloatBuffer(); - vertexBuffer.put(squareCoordinates); - vertexBuffer.position(0); - - float squareCoordinates2[] = { - -1.0f, -1.0f, - 1.0f, -1.0f, - -1.0f, 1.0f, - 1.0f, 1.0f}; - - bb = ByteBuffer.allocateDirect(squareCoordinates2.length * 4); - bb.order(ByteOrder.nativeOrder()); - vertexSaveBuffer = bb.asFloatBuffer(); - vertexSaveBuffer.put(squareCoordinates2); - vertexSaveBuffer.position(0); - - float textureCoordinates[] = { - 0.0f, 0.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 1.0f, - }; - - bb = ByteBuffer.allocateDirect(textureCoordinates.length * 4); - bb.order(ByteOrder.nativeOrder()); - textureBuffer = bb.asFloatBuffer(); - textureBuffer.put(textureCoordinates); - textureBuffer.position(0); - - GLES20.glGenTextures(1, textures, 0); - gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); - gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); - gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); - GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmapToEdit, 0); - - int trivialVertexShader = loadShader(GLES20.GL_VERTEX_SHADER, trivialVertexShaderCode); - int trivialFragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, trivialFragmentShaderCode); - - if (trivialVertexShader != 0 && trivialFragmentShader != 0) { - trivialShaderProgram = GLES20.glCreateProgram(); - GLES20.glAttachShader(trivialShaderProgram, trivialVertexShader); - GLES20.glAttachShader(trivialShaderProgram, trivialFragmentShader); - GLES20.glBindAttribLocation(trivialShaderProgram, 0, "position"); - GLES20.glBindAttribLocation(trivialShaderProgram, 1, "inputTexCoord"); - - GLES20.glLinkProgram(trivialShaderProgram); - int[] linkStatus = new int[1]; - GLES20.glGetProgramiv(trivialShaderProgram, GLES20.GL_LINK_STATUS, linkStatus, 0); - if (linkStatus[0] == 0) { - GLES20.glDeleteProgram(trivialShaderProgram); - trivialShaderProgram = 0; - } - } - - if (trivialShaderProgram != 0) { - positionHandle = GLES20.glGetAttribLocation(trivialShaderProgram, "position"); - inputTexCoordHandle = GLES20.glGetAttribLocation(trivialShaderProgram, "inputTexCoord"); - photoImageHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "photoImage"); - shadowsHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "shadows"); - highlightsHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "highlights"); - exposureHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "exposure"); - contrastHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "contrast"); - saturationHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "saturation"); - warmthHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "warmth"); - vignetteHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "vignette"); - grainHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "grain"); - grainWidthHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "width"); - grainHeightHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "height"); - GLES20.glUseProgram(trivialShaderProgram); - } - } - - public void onDrawFrame(GL10 unused) { - GLES20.glActiveTexture(GLES20.GL_TEXTURE0); - GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]); - GLES20.glUniform1i(photoImageHandle, 0); - GLES20.glUniform1f(shadowsHandle, getShadowsValue()); - GLES20.glUniform1f(highlightsHandle, getHighlightsValue()); - GLES20.glUniform1f(exposureHandle, getExposureValue()); - GLES20.glUniform1f(contrastHandle, getContrastValue()); - GLES20.glUniform1f(saturationHandle, getSaturationValue()); - GLES20.glUniform1f(warmthHandle, getWarmthValue()); - GLES20.glUniform1f(vignetteHandle, getVignetteValue()); - GLES20.glUniform1f(grainHandle, getGrainValue()); - GLES20.glUniform1f(grainWidthHandle, width); - GLES20.glUniform1f(grainHeightHandle, height); - GLES20.glEnableVertexAttribArray(inputTexCoordHandle); - GLES20.glVertexAttribPointer(inputTexCoordHandle, 2, GLES20.GL_FLOAT, false, 8, textureBuffer); - GLES20.glEnableVertexAttribArray(positionHandle); - if (donePressed) { - GLES20.glVertexAttribPointer(positionHandle, 2, GLES20.GL_FLOAT, false, 8, vertexSaveBuffer); - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - final Bitmap bitmap = saveTexture((int)width, (int)height); - donePressed = false; - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - delegate.didFinishEdit(bitmap, getArguments()); - finishFragment(); - } - }); - } - GLES20.glVertexAttribPointer(positionHandle, 2, GLES20.GL_FLOAT, false, 8, vertexBuffer); - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - } - - public void onSurfaceChanged(GL10 unused, int width, int height) { - GLES20.glViewport(0, 0, width, height); - } - - public Bitmap saveTexture(int width, int height) { - //int[] frame = new int[1]; - //GLES20.glGenFramebuffers(1, frame, 0); - //GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frame[0]); - //GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, texture, 0); - ByteBuffer buffer = ByteBuffer.allocate(width * height * 4); - GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buffer); - Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - bitmap.copyPixelsFromBuffer(buffer); - //GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); - //GLES20.glDeleteFramebuffers(1, frame, 0); - return bitmap; - } - } - - public PhotoEditorActivity(Bundle args, Bitmap bitmap, String key) { - super(args); - bitmapToEdit = bitmap; - bitmapKey = key; - if (bitmapToEdit != null && key != null) { - ImageLoader.getInstance().incrementUseCount(key); - } - } - - private float getShadowsValue() { - return (shadowsValue / 100.0f) * 0.65f; - } - - private float getHighlightsValue() { - return 1 - (highlightsValue / 100.0f); - } - - private float getExposureValue() { - return (exposureValue / 100.0f); - } - - private float getContrastValue() { - return (contrastValue / 100.0f) * 0.3f + 1; - } - - private float getWarmthValue() { - return warmthValue / 100.0f; - } - - private float getVignetteValue() { - return vignetteValue / 100.0f; - } - - private float getGrainValue() { - return grainValue / 100.0f * 0.04f; - } - - private float getSaturationValue() { - float value = (saturationValue / 100.0f); - if (value < 0) { - value *= 0.55f; - } else { - value *= 1.05f; - } - return value + 1; - } - - @Override - public boolean onFragmentCreate() { - swipeBackEnabled = false; - freeformCrop = getArguments().getBoolean("freeformCrop", false); - onlyCrop = getArguments().getBoolean("onlyCrop", false); - if (bitmapToEdit == null) { - String photoPath = getArguments().getString("photoPath"); - Uri photoUri = getArguments().getParcelable("photoUri"); - if (photoPath == null && photoUri == null) { - return false; - } - if (photoPath != null) { - File f = new File(photoPath); - if (!f.exists()) { - return false; - } - } - int size = 0; - if (AndroidUtilities.isTablet()) { - size = AndroidUtilities.dp(520); - } else { - size = Math.max(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y); - } - bitmapToEdit = ImageLoader.loadBitmap(photoPath, photoUri, size, size, true); - if (bitmapToEdit == null) { - return false; - } - } - return super.onFragmentCreate(); - } - - @Override - public void onFragmentDestroy() { - super.onFragmentDestroy(); - if (bitmapKey != null) { - if (ImageLoader.getInstance().decrementUseCount(bitmapKey) && !ImageLoader.getInstance().isInCache(bitmapKey)) { - bitmapKey = null; - } - } - if (bitmapKey == null && bitmapToEdit != null && !sameBitmap) { - bitmapToEdit.recycle(); - bitmapToEdit = null; - } - } - - @Override - public void onPause() { - super.onPause(); - if (glView != null) { - glView.onPause(); - } - } - - @Override - public void onResume() { - super.onResume(); - if (glView != null) { - glView.onResume(); - } - } - - @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackgroundColor(0xff262626); - actionBar.setItemsBackground(R.drawable.bar_selector_picker); - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - actionBar.setTitle(LocaleController.getString("EditImage", R.string.EditImage)); - actionBar.setCastShadows(false); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } else if (id == done_button) { - donePressed = true; - glView.requestRender(); - } else if (id == rotate_button) { - int newRotation = rotateDegree; - newRotation += 90; - fixLayoutInternal(newRotation, true); - } - } - }); - - ActionBarMenu menu = actionBar.createMenu(); - rotateButton = menu.addItemWithWidth(rotate_button, R.drawable.photo_rotate, AndroidUtilities.dp(56)); - sizeButton = menu.addItemWithWidth(size_button, R.drawable.photo_sizes, AndroidUtilities.dp(56)); - doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); - - rotateButton.setVisibility(View.GONE); - sizeButton.setVisibility(View.GONE); - - FrameLayout frameLayout = null; - fragmentView = frameLayout = new FrameLayout(getParentActivity()); - fragmentView.setBackgroundColor(0xff262626); - - imageView = new ImageView(getParentActivity()); - imageView.setScaleType(ImageView.ScaleType.MATRIX); - imageView.setImageBitmap(bitmapToEdit); - frameLayout.addView(imageView); - - cropView = new PhotoCropView(getParentActivity()); - cropView.setVisibility(View.GONE); - frameLayout.addView(cropView); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) cropView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - cropView.setLayoutParams(layoutParams); - - cropButtonsView = new LinearLayout(getParentActivity()); - cropButtonsView.setVisibility(View.GONE); - frameLayout.addView(cropButtonsView); - layoutParams = (FrameLayout.LayoutParams) cropButtonsView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.height = AndroidUtilities.dp(48); - layoutParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; - cropButtonsView.setLayoutParams(layoutParams); - - ImageView button = new ImageView(getParentActivity()); - button.setScaleType(ImageView.ScaleType.CENTER); - button.setImageResource(R.drawable.ic_close_white); - cropButtonsView.addView(button); - LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams) button.getLayoutParams(); - layoutParams1.width = AndroidUtilities.dp(48); - layoutParams1.height = AndroidUtilities.dp(48); - button.setLayoutParams(layoutParams1); - button.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (onlyCrop) { - finishFragment(); - } else { - switchToMode(0, true); - } - } - }); - - button = new ImageView(getParentActivity()); - button.setScaleType(ImageView.ScaleType.CENTER); - button.setImageResource(R.drawable.ic_done); - cropButtonsView.addView(button); - layoutParams1 = (LinearLayout.LayoutParams) button.getLayoutParams(); - layoutParams1.width = AndroidUtilities.dp(48); - layoutParams1.height = AndroidUtilities.dp(48); - layoutParams1.leftMargin = AndroidUtilities.dp(146); - button.setLayoutParams(layoutParams1); - button.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (onlyCrop) { - if (delegate != null && currentMode == 1) { - Bitmap bitmap = cropView.getBitmap(); - if (bitmap == bitmapToEdit) { - sameBitmap = true; - } - delegate.didFinishEdit(bitmap, getArguments()); - currentMode = 0; - finishFragment(); - } - } else { - switchToMode(0, false); - } - } - }); - - if (!onlyCrop) { - toolsView = new LinearLayout(getParentActivity()); - frameLayout.addView(toolsView); - layoutParams = (FrameLayout.LayoutParams) toolsView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.height = AndroidUtilities.dp(48); - layoutParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; - toolsView.setLayoutParams(layoutParams); - - button = new ImageView(getParentActivity()); - button.setScaleType(ImageView.ScaleType.CENTER); - button.setImageResource(R.drawable.photo_crop); - toolsView.addView(button); - layoutParams1 = (LinearLayout.LayoutParams) button.getLayoutParams(); - layoutParams1.width = AndroidUtilities.dp(48); - layoutParams1.height = AndroidUtilities.dp(48); - button.setLayoutParams(layoutParams1); - button.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - switchToMode(1, true); - } - }); - - filtersButton = new ImageView(getParentActivity()); - filtersButton.setScaleType(ImageView.ScaleType.CENTER); - filtersButton.setImageResource(R.drawable.photo_filters); - toolsView.addView(filtersButton); - layoutParams1 = (LinearLayout.LayoutParams) filtersButton.getLayoutParams(); - layoutParams1.width = AndroidUtilities.dp(48); - layoutParams1.height = AndroidUtilities.dp(48); - layoutParams1.leftMargin = AndroidUtilities.dp(54); - filtersButton.setLayoutParams(layoutParams1); - - toolButton = new ImageView(getParentActivity()); - toolButton.setScaleType(ImageView.ScaleType.CENTER); - toolButton.setImageResource(R.drawable.photo_tune); - toolsView.addView(toolButton); - layoutParams1 = (LinearLayout.LayoutParams) toolButton.getLayoutParams(); - layoutParams1.width = AndroidUtilities.dp(48); - layoutParams1.height = AndroidUtilities.dp(48); - layoutParams1.leftMargin = AndroidUtilities.dp(54); - toolButton.setLayoutParams(layoutParams1); - - glView = new MyGLSurfaceView(getParentActivity()); - glView.setVisibility(View.GONE); - frameLayout.addView(glView); - layoutParams = (FrameLayout.LayoutParams) glView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - glView.setLayoutParams(layoutParams); - - RecyclerListView toolsView = new RecyclerListView(getParentActivity()); - LinearLayoutManager layoutManager = new LinearLayoutManager(getParentActivity()); - layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); - toolsView.setLayoutManager(layoutManager); - toolsView.setClipToPadding(false); - if (Build.VERSION.SDK_INT >= 9) { - toolsView.setOverScrollMode(RecyclerListView.OVER_SCROLL_NEVER); - } - toolsView.setAdapter(new ToolsAdapter(getParentActivity())); - toolsView.setVisibility(View.GONE); - frameLayout.addView(toolsView); - layoutParams = (FrameLayout.LayoutParams) toolsView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = AndroidUtilities.dp(60); - layoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM; - layoutParams.bottomMargin = AndroidUtilities.dp(40); - toolsView.setLayoutParams(layoutParams); - toolsView.addOnItemTouchListener(new RecyclerListView.RecyclerListViewItemClickListener(getParentActivity(), new RecyclerListView.OnItemClickListener() { - @Override - public void onItemClick(View view, int i) { - selectedTool = i; - if (i == 0) { - valueSeekBar.setMax(100); - valueSeekBar.setProgress((int) highlightsValue); - } else if (i == 1) { - valueSeekBar.setMax(200); - valueSeekBar.setProgress((int) contrastValue + 100); - } else if (i == 2) { - valueSeekBar.setMax(200); - valueSeekBar.setProgress((int) exposureValue + 100); - } else if (i == 3) { - valueSeekBar.setMax(200); - valueSeekBar.setProgress((int) warmthValue + 100); - } else if (i == 4) { - valueSeekBar.setMax(200); - valueSeekBar.setProgress((int) saturationValue + 100); - } else if (i == 5) { - valueSeekBar.setMax(100); - valueSeekBar.setProgress((int) vignetteValue); - } else if (i == 6) { - valueSeekBar.setMax(100); - valueSeekBar.setProgress((int) shadowsValue); - } else if (i == 7) { - valueSeekBar.setMax(100); - valueSeekBar.setProgress((int) grainValue); - } - } - })); - - valueSeekBar = new SeekBar(getParentActivity()); - valueSeekBar.setVisibility(View.GONE); - valueSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if (!fromUser) { - return; - } - if (selectedTool == 0) { - highlightsValue = progress; - } else if (selectedTool == 1) { - contrastValue = progress - 100; - } else if (selectedTool == 2) { - exposureValue = progress - 100; - } else if (selectedTool == 3) { - warmthValue = progress - 100; - } else if (selectedTool == 4) { - saturationValue = progress - 100; - } else if (selectedTool == 5) { - vignetteValue = progress; - } else if (selectedTool == 6) { - shadowsValue = progress; - } else if (selectedTool == 7) { - grainValue = progress; - } - glView.requestRender(); - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - - } - }); - try { - Field field = ProgressBar.class.getDeclaredField("mMinHeight"); - field.setAccessible(true); - field.setInt(valueSeekBar, AndroidUtilities.dp(40)); - field = ProgressBar.class.getDeclaredField("mMaxHeight"); - field.setAccessible(true); - field.setInt(valueSeekBar, AndroidUtilities.dp(40)); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - frameLayout.addView(valueSeekBar); - layoutParams = (FrameLayout.LayoutParams) valueSeekBar.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = AndroidUtilities.dp(40); - layoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM; - layoutParams.leftMargin = AndroidUtilities.dp(10); - layoutParams.rightMargin = AndroidUtilities.dp(10); - valueSeekBar.setLayoutParams(layoutParams); - } else { - switchToMode(1, false); - } - - fixLayout(); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); - } - } - return fragmentView; - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - fixLayout(); - } - - private void switchToMode(final int mode, final boolean animated) { - if (animated) { - if (currentMode == 0) { - AnimatorSetProxy animatorSet = new AnimatorSetProxy(); - animatorSet.playTogether( - ObjectAnimatorProxy.ofFloat(doneButton, "alpha", 1.0f, 0.0f), - ObjectAnimatorProxy.ofFloat(toolsView, "translationY", 0, AndroidUtilities.dp(48))); - animatorSet.setDuration(150); - animatorSet.setInterpolator(new DecelerateInterpolator()); - animatorSet.addListener(new AnimatorListenerAdapterProxy() { - @Override - public void onAnimationEnd(Object animation) { - processFromMode(currentMode, mode, animated); - } - }); - animatorSet.start(); - } else if (currentMode == 1) { - AnimatorSetProxy animatorSet = new AnimatorSetProxy(); - animatorSet.playTogether( - ObjectAnimatorProxy.ofFloat(cropView, "alpha", 1.0f, 0.0f), - ObjectAnimatorProxy.ofFloat(cropButtonsView, "translationY", 0, AndroidUtilities.dp(48)), - ObjectAnimatorProxy.ofFloat(rotateButton, "alpha", 1.0f, 0.0f), - ObjectAnimatorProxy.ofFloat(sizeButton, "alpha", 1.0f, 0.0f)); - animatorSet.setDuration(150); - animatorSet.setInterpolator(new DecelerateInterpolator()); - animatorSet.addListener(new AnimatorListenerAdapterProxy() { - @Override - public void onAnimationEnd(Object animation) { - processFromMode(currentMode, mode, animated); - } - }); - animatorSet.start(); - } - } else { - processFromMode(currentMode, mode, animated); - } - } - - private void processFromMode(int from, int to, boolean animated) { - if (from == 0) { - doneButton.setVisibility(View.GONE); - if (toolsView != null) { - toolsView.setVisibility(View.GONE); - } - processToMode(to, animated); - } else if (from == 1) { - cropView.setVisibility(View.GONE); - rotateButton.setVisibility(View.GONE); - if (freeformCrop) { - sizeButton.setVisibility(View.GONE); - } - cropButtonsView.setVisibility(View.GONE); - processToMode(to, animated); - } - } - - private void processToMode(int to, boolean animated) { - currentMode = to; - if (currentMode == 0) { - doneButton.setVisibility(View.VISIBLE); - toolsView.setVisibility(View.VISIBLE); - actionBar.setTitle(LocaleController.getString("EditImage", R.string.EditImage)); - if (animated) { - AnimatorSetProxy animatorSet = new AnimatorSetProxy(); - animatorSet.playTogether( - ObjectAnimatorProxy.ofFloat(doneButton, "alpha", 0.0f, 1.0f), - ObjectAnimatorProxy.ofFloat(toolsView, "translationY", AndroidUtilities.dp(48), 0)); - animatorSet.setDuration(150); - animatorSet.setInterpolator(new AccelerateInterpolator()); - animatorSet.start(); - } - } else if (currentMode == 1) { - cropView.setVisibility(View.VISIBLE); - rotateButton.setVisibility(View.VISIBLE); - if (freeformCrop) { - sizeButton.setVisibility(View.VISIBLE); - } - cropButtonsView.setVisibility(View.VISIBLE); - actionBar.setTitle(LocaleController.getString("CropImage", R.string.CropImage)); - if (animated) { - AnimatorSetProxy animatorSet = new AnimatorSetProxy(); - animatorSet.playTogether( - ObjectAnimatorProxy.ofFloat(cropView, "alpha", 0.0f, 1.0f), - ObjectAnimatorProxy.ofFloat(cropButtonsView, "translationY", AndroidUtilities.dp(48), 0), - ObjectAnimatorProxy.ofFloat(rotateButton, "alpha", 0.0f, 1.0f), - ObjectAnimatorProxy.ofFloat(sizeButton, "alpha", 0.0f, 1.0f)); - animatorSet.setDuration(150); - animatorSet.setInterpolator(new AccelerateInterpolator()); - animatorSet.start(); - } - } - } - - private void fixLayoutInternal(int rotation, final boolean animated) { - if (bitmapToEdit == null || fragmentView == null) { - return; - } - - int viewWidth = fragmentView.getWidth() - AndroidUtilities.dp(28); - int viewHeight = fragmentView.getHeight() - AndroidUtilities.dp(28 + 48); - - rotateDegree = rotation; - - if (cropView != null) { - float bitmapWidth = rotation % 180 == 0 ? bitmapToEdit.getWidth() : bitmapToEdit.getHeight(); - float bitmapHeight = rotation % 180 == 0 ? bitmapToEdit.getHeight() : bitmapToEdit.getWidth(); - float scaleX = viewWidth / bitmapWidth; - float scaleY = viewHeight / bitmapHeight; - if (scaleX > scaleY) { - bitmapHeight = viewHeight; - bitmapWidth = (int)Math.ceil(bitmapWidth * scaleY); - } else { - bitmapWidth = viewWidth; - bitmapHeight = (int)Math.ceil(bitmapHeight * scaleX); - } - - float percX = (cropView.rectX - cropView.bitmapX) / cropView.bitmapWidth; - float percY = (cropView.rectY - cropView.bitmapY) / cropView.bitmapHeight; - float percSizeX = cropView.rectSizeX / cropView.bitmapWidth; - float percSizeY = cropView.rectSizeY / cropView.bitmapHeight; - cropView.bitmapWidth = (int) bitmapWidth; - cropView.bitmapHeight = (int) bitmapHeight; - - cropView.bitmapX = (int) Math.ceil((viewWidth - bitmapWidth) / 2 + AndroidUtilities.dp(14)); - cropView.bitmapY = (int) Math.ceil((viewHeight - bitmapHeight) / 2 + AndroidUtilities.dp(14)); - - if (cropView.rectX == -1 && cropView.rectY == -1) { - if (freeformCrop) { - cropView.rectY = cropView.bitmapY; - cropView.rectX = cropView.bitmapX; - cropView.rectSizeX = bitmapWidth; - cropView.rectSizeY = bitmapHeight; - } else { - if (bitmapWidth > bitmapHeight) { - cropView.rectY = cropView.bitmapY; - cropView.rectX = (viewWidth - bitmapHeight) / 2 + AndroidUtilities.dp(14); - cropView.rectSizeX = bitmapHeight; - cropView.rectSizeY = bitmapHeight; - } else { - cropView.rectX = cropView.bitmapX; - cropView.rectY = (viewHeight - bitmapWidth) / 2 + AndroidUtilities.dp(14); - cropView.rectSizeX = bitmapWidth; - cropView.rectSizeY = bitmapWidth; - } - } - } else { - if (rotation % 180 == 0) { - cropView.rectX = percX * bitmapWidth + cropView.bitmapX; - cropView.rectY = percY * bitmapHeight + cropView.bitmapY; - } else { - cropView.rectX = percY * bitmapWidth + cropView.bitmapX; - cropView.rectY = percX * bitmapHeight + cropView.bitmapY; - } - cropView.rectSizeX = percSizeX * bitmapWidth; - cropView.rectSizeY = percSizeY * bitmapHeight; - } - cropView.invalidate(); - } - - float bitmapWidth = bitmapToEdit.getWidth(); - float bitmapHeight = bitmapToEdit.getHeight(); - float scaleX = viewWidth / bitmapWidth; - float scaleY = viewHeight / bitmapHeight; - float scale; - if (scaleX > scaleY) { - bitmapHeight = viewHeight; - bitmapWidth = (int)Math.ceil(bitmapWidth * scaleY); - scale = cropView.bitmapHeight / bitmapWidth; - } else { - bitmapWidth = viewWidth; - bitmapHeight = (int)Math.ceil(bitmapHeight * scaleX); - scale = cropView.bitmapWidth / bitmapHeight; - } - - FrameLayout.LayoutParams layoutParams; - if (imageView != null) { - layoutParams = (FrameLayout.LayoutParams) imageView.getLayoutParams(); - layoutParams.leftMargin = (int) ((viewWidth - bitmapWidth) / 2 + AndroidUtilities.dp(14)); - layoutParams.topMargin = (int) ((viewHeight - bitmapHeight) / 2 + AndroidUtilities.dp(14)); - layoutParams.width = (int) bitmapWidth; - layoutParams.height = (int) bitmapHeight; - imageView.setLayoutParams(layoutParams); - - if (animated) { - ViewProxy.setAlpha(cropView, 0.0f); - rotationAnimation = new AnimatorSetProxy(); - rotationAnimation.playTogether( - ObjectAnimatorProxy.ofFloat(imageView, "scaleX", rotateDegree % 180 != 0 ? scale : 1), - ObjectAnimatorProxy.ofFloat(imageView, "scaleY", rotateDegree % 180 != 0 ? scale : 1), - ObjectAnimatorProxy.ofFloat(imageView, "rotation", rotateDegree)); - rotationAnimation.setDuration(150); - rotationAnimation.setInterpolator(new AccelerateDecelerateInterpolator()); - rotationAnimation.addListener(new AnimatorListenerAdapterProxy() { - @Override - public void onAnimationEnd(Object animation) { - if (rotationAnimation.equals(animation)) { - AnimatorSetProxy animatorSet = new AnimatorSetProxy(); - animatorSet.playTogether(ObjectAnimatorProxy.ofFloat(cropView, "alpha", 1.0f)); - animatorSet.setDuration(150); - animatorSet.setInterpolator(new AccelerateDecelerateInterpolator()); - animatorSet.start(); - rotationAnimation = null; - } - } - }); - rotationAnimation.start(); - } else { - imageView.setScaleX(rotateDegree % 180 != 0 ? scale : 1); - imageView.setScaleY(rotateDegree % 180 != 0 ? scale : 1); - imageView.setRotation(rotateDegree); - } - } - - if (glView != null) { - width = bitmapWidth; - height = bitmapHeight; - layoutParams = (FrameLayout.LayoutParams) glView.getLayoutParams(); - layoutParams.leftMargin = (int) ((viewWidth - bitmapWidth) / 2 + AndroidUtilities.dp(14)); - layoutParams.topMargin = (int) ((viewHeight - bitmapHeight) / 2 + AndroidUtilities.dp(14)); - layoutParams.width = (int) bitmapWidth; - layoutParams.height = (int) bitmapHeight; - glView.setLayoutParams(layoutParams); - glView.requestRender(); - } - } - - private void fixLayout() { - if (fragmentView == null) { - return; - } - fragmentView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { - if (fragmentView != null) { - fixLayoutInternal(rotateDegree, false); - fragmentView.getViewTreeObserver().removeOnPreDrawListener(this); - } - return false; - } - }); - } - - public void setDelegate(PhotoCropActivity.PhotoEditActivityDelegate delegate) { - this.delegate = delegate; - } - - public class ToolsAdapter extends RecyclerView.Adapter { - - private Context mContext; - - private class Holder extends RecyclerView.ViewHolder { - - public Holder(View itemView) { - super(itemView); - } - } - - public ToolsAdapter(Context context) { - mContext = context; - } - - @Override - public int getItemCount() { - return 8; - } - - @Override - public long getItemId(int i) { - return i; - } - - @Override - public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { - PhotoEditToolCell view = new PhotoEditToolCell(mContext); - return new Holder(view); - } - - @Override - public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) { - Holder holder = (Holder) viewHolder; - if (i == 0) { - ((PhotoEditToolCell) holder.itemView).setIconAndText(R.drawable.photo_editor_highlights, "Highlights"); - } else if (i == 1) { - ((PhotoEditToolCell) holder.itemView).setIconAndText(R.drawable.photo_editor_contrast, "Contrast"); - } else if (i == 2) { - ((PhotoEditToolCell) holder.itemView).setIconAndText(R.drawable.photo_editor_exposure, "Exposure"); - } else if (i == 3) { - ((PhotoEditToolCell) holder.itemView).setIconAndText(R.drawable.photo_editor_warmth, "Warmth"); - } else if (i == 4) { - ((PhotoEditToolCell) holder.itemView).setIconAndText(R.drawable.photo_editor_saturation, "Saturation"); - } else if (i == 5) { - ((PhotoEditToolCell) holder.itemView).setIconAndText(R.drawable.photo_editor_vignette, "Vignette"); - } else if (i == 6) { - ((PhotoEditToolCell) holder.itemView).setIconAndText(R.drawable.photo_editor_shadows, "Shadows"); - } else if (i == 7) { - ((PhotoEditToolCell) holder.itemView).setIconAndText(R.drawable.photo_editor_grain, "Grain"); - } - } - } -} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java index 0c573a96c..d58873cad 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java @@ -9,10 +9,11 @@ package org.telegram.ui; import android.app.Activity; +import android.app.AlertDialog; import android.content.Context; +import android.content.DialogInterface; import android.graphics.Bitmap; import android.os.Build; -import android.os.Bundle; import android.util.Base64; import android.view.Gravity; import android.view.LayoutInflater; @@ -33,7 +34,6 @@ import android.widget.TextView; import org.json.JSONArray; import org.json.JSONObject; import org.telegram.android.AndroidUtilities; -import org.telegram.android.ImageLoader; import org.telegram.android.LocaleController; import org.telegram.android.MediaController; import org.telegram.android.MessagesStorage; @@ -47,7 +47,6 @@ import org.telegram.android.volley.toolbox.JsonObjectRequest; import org.telegram.android.volley.toolbox.Volley; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.BuildVars; -import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; @@ -68,11 +67,11 @@ import java.util.HashMap; import java.util.Locale; import java.util.Map; -public class PhotoPickerActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate, PhotoViewer.PhotoViewerProvider, PhotoCropActivity.PhotoEditActivityDelegate { +public class PhotoPickerActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate, PhotoViewer.PhotoViewerProvider { - public static interface PhotoPickerActivityDelegate { - public abstract void selectedPhotosChanged(); - public abstract void actionButtonPressed(boolean canceled); + public interface PhotoPickerActivityDelegate { + void selectedPhotosChanged(); + void actionButtonPressed(boolean canceled); } private RequestQueue requestQueue; @@ -102,16 +101,18 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen private ActionBarMenuItem searchItem; private int itemWidth = 100; private boolean sendPressed; + private boolean singlePhoto; private PhotoPickerActivityDelegate delegate; - public PhotoPickerActivity(int type, MediaController.AlbumEntry selectedAlbum, HashMap selectedPhotos, HashMap selectedWebPhotos, ArrayList recentImages) { + public PhotoPickerActivity(int type, MediaController.AlbumEntry selectedAlbum, HashMap selectedPhotos, HashMap selectedWebPhotos, ArrayList recentImages, boolean onlyOnePhoto) { super(); this.selectedAlbum = selectedAlbum; this.selectedPhotos = selectedPhotos; this.selectedWebPhotos = selectedWebPhotos; this.type = type; this.recentImages = recentImages; + this.singlePhoto = onlyOnePhoto; } @Override @@ -141,244 +142,269 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen @SuppressWarnings("unchecked") @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackgroundColor(0xff333333); - actionBar.setItemsBackground(R.drawable.bar_selector_picker); - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - if (selectedAlbum != null) { - actionBar.setTitle(selectedAlbum.bucketName); - } else if (type == 0) { - actionBar.setTitle(LocaleController.getString("SearchImagesTitle", R.string.SearchImagesTitle)); - } else if (type == 1) { - actionBar.setTitle(LocaleController.getString("SearchGifsTitle", R.string.SearchGifsTitle)); - } - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - if (Build.VERSION.SDK_INT < 11) { - listView.setAdapter(null); - listView = null; - listAdapter = null; - } - finishFragment(); + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackgroundColor(0xff333333); + actionBar.setItemsBackground(R.drawable.bar_selector_picker); + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + if (selectedAlbum != null) { + actionBar.setTitle(selectedAlbum.bucketName); + } else if (type == 0) { + actionBar.setTitle(LocaleController.getString("SearchImagesTitle", R.string.SearchImagesTitle)); + } else if (type == 1) { + actionBar.setTitle(LocaleController.getString("SearchGifsTitle", R.string.SearchGifsTitle)); + } + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + if (Build.VERSION.SDK_INT < 11) { + listView.setAdapter(null); + listView = null; + listAdapter = null; } + finishFragment(); } - }); + } + }); - if (selectedAlbum == null) { - ActionBarMenu menu = actionBar.createMenu(); - searchItem = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true).setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() { - @Override - public void onSearchExpand() { + if (selectedAlbum == null) { + ActionBarMenu menu = actionBar.createMenu(); + searchItem = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true).setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() { + @Override + public void onSearchExpand() { - } + } - @Override - public void onSearchCollapse() { - finishFragment(); - } + @Override + public boolean onSearchCollapse() { + finishFragment(); + return false; + } - @Override - public void onTextChanged(EditText editText) { - if (editText.getText().length() == 0) { - searchResult.clear(); - searchResultKeys.clear(); - lastSearchString = null; - nextSearchBingString = null; - giphySearchEndReached = true; - searching = false; - requestQueue.cancelAll("search"); - if (type == 0) { - emptyView.setText(LocaleController.getString("NoRecentPhotos", R.string.NoRecentPhotos)); - } else if (type == 1) { - emptyView.setText(LocaleController.getString("NoRecentGIFs", R.string.NoRecentGIFs)); - } - updateSearchInterface(); - } - } - - @Override - public void onSearchPressed(EditText editText) { - if (editText.getText().toString().length() == 0) { - return; - } + @Override + public void onTextChanged(EditText editText) { + if (editText.getText().length() == 0) { searchResult.clear(); searchResultKeys.clear(); + lastSearchString = null; nextSearchBingString = null; giphySearchEndReached = true; + searching = false; + requestQueue.cancelAll("search"); if (type == 0) { - searchBingImages(editText.getText().toString(), 0, 53); + emptyView.setText(LocaleController.getString("NoRecentPhotos", R.string.NoRecentPhotos)); } else if (type == 1) { - searchGiphyImages(editText.getText().toString(), 0, 53); - } - lastSearchString = editText.getText().toString(); - if (lastSearchString.length() == 0) { - lastSearchString = null; - if (type == 0) { - emptyView.setText(LocaleController.getString("NoRecentPhotos", R.string.NoRecentPhotos)); - } else if (type == 1) { - emptyView.setText(LocaleController.getString("NoRecentGIFs", R.string.NoRecentGIFs)); - } - } else { - emptyView.setText(LocaleController.getString("NoResult", R.string.NoResult)); + emptyView.setText(LocaleController.getString("NoRecentGIFs", R.string.NoRecentGIFs)); } updateSearchInterface(); } - }); - } - - if (selectedAlbum == null) { - if (type == 0) { - searchItem.getSearchField().setHint(LocaleController.getString("SearchImagesTitle", R.string.SearchImagesTitle)); - } else if (type == 1) { - searchItem.getSearchField().setHint(LocaleController.getString("SearchGifsTitle", R.string.SearchGifsTitle)); } - } - fragmentView = new FrameLayout(getParentActivity()); - - FrameLayout frameLayout = (FrameLayout) fragmentView; - frameLayout.setBackgroundColor(0xff000000); - - listView = new GridView(getParentActivity()); - listView.setPadding(AndroidUtilities.dp(4), AndroidUtilities.dp(4), AndroidUtilities.dp(4), AndroidUtilities.dp(4)); - listView.setClipToPadding(false); - listView.setDrawSelectorOnTop(true); - listView.setStretchMode(GridView.STRETCH_COLUMN_WIDTH); - listView.setHorizontalScrollBarEnabled(false); - listView.setVerticalScrollBarEnabled(false); - listView.setNumColumns(GridView.AUTO_FIT); - listView.setVerticalSpacing(AndroidUtilities.dp(4)); - listView.setHorizontalSpacing(AndroidUtilities.dp(4)); - listView.setSelector(R.drawable.list_selector); - frameLayout.addView(listView); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.bottomMargin = AndroidUtilities.dp(48); - listView.setLayoutParams(layoutParams); - listView.setAdapter(listAdapter = new ListAdapter(getParentActivity())); - AndroidUtilities.setListViewEdgeEffectColor(listView, 0xff333333); - listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override - public void onItemClick(AdapterView adapterView, View view, int i, long l) { - ArrayList arrayList = null; - if (selectedAlbum != null) { - arrayList = (ArrayList) selectedAlbum.photos; - } else { - if (searchResult.isEmpty() && lastSearchString == null) { - arrayList = (ArrayList) recentImages; - } else { - arrayList = (ArrayList) searchResult; - } - } - if (i < 0 || i >= arrayList.size()) { + public void onSearchPressed(EditText editText) { + if (editText.getText().toString().length() == 0) { return; } - PhotoViewer.getInstance().setParentActivity(getParentActivity()); - PhotoViewer.getInstance().openPhotoForSelect(arrayList, i, PhotoPickerActivity.this); - } - }); - - emptyView = new TextView(getParentActivity()); - emptyView.setTextColor(0xff808080); - emptyView.setTextSize(20); - emptyView.setGravity(Gravity.CENTER); - emptyView.setVisibility(View.GONE); - if (selectedAlbum != null) { - emptyView.setText(LocaleController.getString("NoPhotos", R.string.NoPhotos)); - } else { - if (type == 0) { - emptyView.setText(LocaleController.getString("NoRecentPhotos", R.string.NoRecentPhotos)); - } else if (type == 1) { - emptyView.setText(LocaleController.getString("NoRecentGIFs", R.string.NoRecentGIFs)); - } - } - frameLayout.addView(emptyView); - layoutParams = (FrameLayout.LayoutParams) emptyView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.bottomMargin = AndroidUtilities.dp(48); - emptyView.setLayoutParams(layoutParams); - emptyView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return true; - } - }); - - if (selectedAlbum == null) { - listView.setOnScrollListener(new AbsListView.OnScrollListener() { - @Override - public void onScrollStateChanged(AbsListView absListView, int i) { - if (i == SCROLL_STATE_TOUCH_SCROLL) { - AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); - } + searchResult.clear(); + searchResultKeys.clear(); + nextSearchBingString = null; + giphySearchEndReached = true; + if (type == 0) { + searchBingImages(editText.getText().toString(), 0, 53); + } else if (type == 1) { + searchGiphyImages(editText.getText().toString(), 0, 53); } - - @Override - public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - if (visibleItemCount != 0 && firstVisibleItem + visibleItemCount > totalItemCount - 2 && !searching) { - if (type == 0 && nextSearchBingString != null) { - searchBingImages(lastSearchString, searchResult.size(), 54); - } else if (type == 1 && !giphySearchEndReached) { - searchGiphyImages(searchItem.getSearchField().getText().toString(), searchResult.size(), 54); - } + lastSearchString = editText.getText().toString(); + if (lastSearchString.length() == 0) { + lastSearchString = null; + if (type == 0) { + emptyView.setText(LocaleController.getString("NoRecentPhotos", R.string.NoRecentPhotos)); + } else if (type == 1) { + emptyView.setText(LocaleController.getString("NoRecentGIFs", R.string.NoRecentGIFs)); } + } else { + emptyView.setText(LocaleController.getString("NoResult", R.string.NoResult)); } - }); - - progressView = new FrameLayout(getParentActivity()); - progressView.setVisibility(View.GONE); - frameLayout.addView(progressView); - layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.bottomMargin = AndroidUtilities.dp(48); - progressView.setLayoutParams(layoutParams); - - ProgressBar progressBar = new ProgressBar(getParentActivity()); - progressView.addView(progressBar); - layoutParams = (FrameLayout.LayoutParams) progressBar.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.gravity = Gravity.CENTER; - progressBar.setLayoutParams(layoutParams); - - updateSearchInterface(); - } - - photoPickerBottomLayout = new PhotoPickerBottomLayout(getParentActivity()); - frameLayout.addView(photoPickerBottomLayout); - layoutParams = (FrameLayout.LayoutParams) photoPickerBottomLayout.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = AndroidUtilities.dp(48); - layoutParams.gravity = Gravity.BOTTOM; - photoPickerBottomLayout.setLayoutParams(layoutParams); - photoPickerBottomLayout.cancelButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - delegate.actionButtonPressed(true); - finishFragment(); - } - }); - photoPickerBottomLayout.doneButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - sendSelectedPhotos(); + updateSearchInterface(); } }); + } - listView.setEmptyView(emptyView); - photoPickerBottomLayout.updateSelectedCount(selectedPhotos.size() + selectedWebPhotos.size(), true); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); + if (selectedAlbum == null) { + if (type == 0) { + searchItem.getSearchField().setHint(LocaleController.getString("SearchImagesTitle", R.string.SearchImagesTitle)); + } else if (type == 1) { + searchItem.getSearchField().setHint(LocaleController.getString("SearchGifsTitle", R.string.SearchGifsTitle)); } } + + fragmentView = new FrameLayout(context); + + FrameLayout frameLayout = (FrameLayout) fragmentView; + frameLayout.setBackgroundColor(0xff000000); + + listView = new GridView(context); + listView.setPadding(AndroidUtilities.dp(4), AndroidUtilities.dp(4), AndroidUtilities.dp(4), AndroidUtilities.dp(4)); + listView.setClipToPadding(false); + listView.setDrawSelectorOnTop(true); + listView.setStretchMode(GridView.STRETCH_COLUMN_WIDTH); + listView.setHorizontalScrollBarEnabled(false); + listView.setVerticalScrollBarEnabled(false); + listView.setNumColumns(GridView.AUTO_FIT); + listView.setVerticalSpacing(AndroidUtilities.dp(4)); + listView.setHorizontalSpacing(AndroidUtilities.dp(4)); + listView.setSelector(R.drawable.list_selector); + frameLayout.addView(listView); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.bottomMargin = singlePhoto ? 0 : AndroidUtilities.dp(48); + listView.setLayoutParams(layoutParams); + listView.setAdapter(listAdapter = new ListAdapter(context)); + AndroidUtilities.setListViewEdgeEffectColor(listView, 0xff333333); + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, int i, long l) { + ArrayList arrayList = null; + if (selectedAlbum != null) { + arrayList = (ArrayList) selectedAlbum.photos; + } else { + if (searchResult.isEmpty() && lastSearchString == null) { + arrayList = (ArrayList) recentImages; + } else { + arrayList = (ArrayList) searchResult; + } + } + if (i < 0 || i >= arrayList.size()) { + return; + } + PhotoViewer.getInstance().setParentActivity(getParentActivity()); + PhotoViewer.getInstance().openPhotoForSelect(arrayList, i, singlePhoto ? 1 : 0, PhotoPickerActivity.this); + } + }); + + if (selectedAlbum == null) { + listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { + if (searchResult.isEmpty() && lastSearchString == null) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setMessage(LocaleController.getString("ClearSearch", R.string.ClearSearch)); + builder.setPositiveButton(LocaleController.getString("ClearButton", R.string.ClearButton).toUpperCase(), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + recentImages.clear(); + if (listAdapter != null) { + listAdapter.notifyDataSetChanged(); + } + MessagesStorage.getInstance().clearWebRecent(type); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + return true; + } + return false; + } + }); + } + + emptyView = new TextView(context); + emptyView.setTextColor(0xff808080); + emptyView.setTextSize(20); + emptyView.setGravity(Gravity.CENTER); + emptyView.setVisibility(View.GONE); + if (selectedAlbum != null) { + emptyView.setText(LocaleController.getString("NoPhotos", R.string.NoPhotos)); + } else { + if (type == 0) { + emptyView.setText(LocaleController.getString("NoRecentPhotos", R.string.NoRecentPhotos)); + } else if (type == 1) { + emptyView.setText(LocaleController.getString("NoRecentGIFs", R.string.NoRecentGIFs)); + } + } + frameLayout.addView(emptyView); + layoutParams = (FrameLayout.LayoutParams) emptyView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.bottomMargin = singlePhoto ? 0 : AndroidUtilities.dp(48); + emptyView.setLayoutParams(layoutParams); + emptyView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + if (selectedAlbum == null) { + listView.setOnScrollListener(new AbsListView.OnScrollListener() { + @Override + public void onScrollStateChanged(AbsListView absListView, int i) { + if (i == SCROLL_STATE_TOUCH_SCROLL) { + AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); + } + } + + @Override + public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { + if (visibleItemCount != 0 && firstVisibleItem + visibleItemCount > totalItemCount - 2 && !searching) { + if (type == 0 && nextSearchBingString != null) { + searchBingImages(lastSearchString, searchResult.size(), 54); + } else if (type == 1 && !giphySearchEndReached) { + searchGiphyImages(searchItem.getSearchField().getText().toString(), searchResult.size(), 54); + } + } + } + }); + + progressView = new FrameLayout(context); + progressView.setVisibility(View.GONE); + frameLayout.addView(progressView); + layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.bottomMargin = singlePhoto ? 0 : AndroidUtilities.dp(48); + progressView.setLayoutParams(layoutParams); + + ProgressBar progressBar = new ProgressBar(context); + progressView.addView(progressBar); + layoutParams = (FrameLayout.LayoutParams) progressBar.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.CENTER; + progressBar.setLayoutParams(layoutParams); + + updateSearchInterface(); + } + + photoPickerBottomLayout = new PhotoPickerBottomLayout(context); + frameLayout.addView(photoPickerBottomLayout); + layoutParams = (FrameLayout.LayoutParams) photoPickerBottomLayout.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = AndroidUtilities.dp(48); + layoutParams.gravity = Gravity.BOTTOM; + photoPickerBottomLayout.setLayoutParams(layoutParams); + photoPickerBottomLayout.cancelButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + delegate.actionButtonPressed(true); + finishFragment(); + } + }); + photoPickerBottomLayout.doneButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + sendSelectedPhotos(); + } + }); + if (singlePhoto) { + photoPickerBottomLayout.setVisibility(View.GONE); + } + + listView.setEmptyView(emptyView); + photoPickerBottomLayout.updateSelectedCount(selectedPhotos.size() + selectedWebPhotos.size(), true); + return fragmentView; } @@ -456,7 +482,7 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen object.viewX = coords[0]; object.viewY = coords[1] - AndroidUtilities.statusBarHeight; object.parentView = listView; - object.imageReceiver = cell.photoImage.imageReceiver; + object.imageReceiver = cell.photoImage.getImageReceiver(); object.thumb = object.imageReceiver.getBitmap(); cell.checkBox.setVisibility(View.GONE); return object; @@ -464,11 +490,45 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen return null; } + @Override + public void updatePhotoAtIndex(int index) { + PhotoPickerPhotoCell cell = getCellForIndex(index); + if (cell != null) { + if (selectedAlbum != null) { + cell.photoImage.setOrientation(0, true); + MediaController.PhotoEntry photoEntry = selectedAlbum.photos.get(index); + if (photoEntry.thumbPath != null) { + cell.photoImage.setImage(photoEntry.thumbPath, null, cell.getContext().getResources().getDrawable(R.drawable.nophotos)); + } else if (photoEntry.path != null) { + cell.photoImage.setOrientation(photoEntry.orientation, true); + cell.photoImage.setImage("thumb://" + photoEntry.imageId + ":" + photoEntry.path, null, cell.getContext().getResources().getDrawable(R.drawable.nophotos)); + } else { + cell.photoImage.setImageResource(R.drawable.nophotos); + } + } else { + ArrayList array = null; + if (searchResult.isEmpty() && lastSearchString == null) { + array = recentImages; + } else { + array = searchResult; + } + MediaController.SearchImage photoEntry = array.get(index); + if (photoEntry.thumbPath != null) { + cell.photoImage.setImage(photoEntry.thumbPath, null, cell.getContext().getResources().getDrawable(R.drawable.nophotos)); + } else if (photoEntry.thumbUrl != null && photoEntry.thumbUrl.length() > 0) { + cell.photoImage.setImage(photoEntry.thumbUrl, null, cell.getContext().getResources().getDrawable(R.drawable.nophotos)); + } else { + cell.photoImage.setImageResource(R.drawable.nophotos); + } + } + } + } + @Override public Bitmap getThumbForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index) { PhotoPickerPhotoCell cell = getCellForIndex(index); if (cell != null) { - return cell.photoImage.imageReceiver.getBitmap(); + return cell.photoImage.getImageReceiver().getBitmap(); } return null; } @@ -618,20 +678,6 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen } } - @Override - public void didFinishEdit(Bitmap bitmap, Bundle args) { - TLRPC.PhotoSize size = ImageLoader.scaleAndSaveImage(bitmap, AndroidUtilities.getPhotoSize(), AndroidUtilities.getPhotoSize(), 80, false, 101, 101); - if (size != null) { - int id = args.getInt("id"); - MediaController.PhotoEntry entry = selectedAlbum.photosByIds.get(id); - entry.imagePath = FileLoader.getPathToAttach(size, true).toString(); - selectedPhotos.put(entry.imageId, entry); - listAdapter.notifyDataSetChanged(); - photoPickerBottomLayout.updateSelectedCount(selectedPhotos.size() + selectedWebPhotos.size(), true); - delegate.selectedPhotosChanged(); - } - } - private void updateSearchInterface() { if (listAdapter != null) { listAdapter.notifyDataSetChanged(); @@ -654,7 +700,7 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen } try { searching = true; - String url = String.format("https://api.giphy.com/v1/gifs/search?q=%s&offset=%d&limit=%d&api_key=141Wa2KDAfNfxu", URLEncoder.encode(query, "UTF-8"), offset, count); + String url = String.format(Locale.US, "https://api.giphy.com/v1/gifs/search?q=%s&offset=%d&limit=%d&api_key=141Wa2KDAfNfxu", URLEncoder.encode(query, "UTF-8"), offset, count); JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener() { @Override @@ -933,15 +979,17 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen cell.checkFrame.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + int index = (Integer) ((View) v.getParent()).getTag(); if (selectedAlbum != null) { - MediaController.PhotoEntry photoEntry = selectedAlbum.photos.get((Integer) ((View) v.getParent()).getTag()); + MediaController.PhotoEntry photoEntry = selectedAlbum.photos.get(index); if (selectedPhotos.containsKey(photoEntry.imageId)) { selectedPhotos.remove(photoEntry.imageId); photoEntry.imagePath = null; + photoEntry.thumbPath = null; + updatePhotoAtIndex(index); } else { selectedPhotos.put(photoEntry.imageId, photoEntry); } - ((PhotoPickerPhotoCell) v.getParent()).editedImage.setVisibility(photoEntry.imagePath != null ? View.VISIBLE : View.GONE); ((PhotoPickerPhotoCell) v.getParent()).checkBox.setChecked(selectedPhotos.containsKey(photoEntry.imageId), true); } else { AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); @@ -953,32 +1001,38 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen } if (selectedWebPhotos.containsKey(photoEntry.id)) { selectedWebPhotos.remove(photoEntry.id); + photoEntry.imagePath = null; + photoEntry.thumbPath = null; + updatePhotoAtIndex(index); } else { selectedWebPhotos.put(photoEntry.id, photoEntry); } - ((PhotoPickerPhotoCell) v.getParent()).editedImage.setVisibility(View.GONE); ((PhotoPickerPhotoCell) v.getParent()).checkBox.setChecked(selectedWebPhotos.containsKey(photoEntry.id), true); } photoPickerBottomLayout.updateSelectedCount(selectedPhotos.size() + selectedWebPhotos.size(), true); delegate.selectedPhotosChanged(); } }); + cell.checkFrame.setVisibility(singlePhoto ? View.GONE : View.VISIBLE); } cell.itemWidth = itemWidth; BackupImageView imageView = ((PhotoPickerPhotoCell) view).photoImage; imageView.setTag(i); view.setTag(i); boolean showing = false; + imageView.setOrientation(0, true); if (selectedAlbum != null) { MediaController.PhotoEntry photoEntry = selectedAlbum.photos.get(i); - if (photoEntry.path != null) { + if (photoEntry.thumbPath != null) { + imageView.setImage(photoEntry.thumbPath, null, mContext.getResources().getDrawable(R.drawable.nophotos)); + } else if (photoEntry.path != null) { + imageView.setOrientation(photoEntry.orientation, true); imageView.setImage("thumb://" + photoEntry.imageId + ":" + photoEntry.path, null, mContext.getResources().getDrawable(R.drawable.nophotos)); } else { imageView.setImageResource(R.drawable.nophotos); } cell.checkBox.setChecked(selectedPhotos.containsKey(photoEntry.imageId), false); - cell.editedImage.setVisibility(photoEntry.imagePath != null ? View.VISIBLE : View.GONE); showing = PhotoViewer.getInstance().isShowingImage(photoEntry.path); } else { MediaController.SearchImage photoEntry = null; @@ -987,17 +1041,18 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen } else { photoEntry = searchResult.get(i); } - if (photoEntry.thumbUrl != null && photoEntry.thumbUrl.length() > 0) { + if (photoEntry.thumbPath != null) { + imageView.setImage(photoEntry.thumbPath, null, mContext.getResources().getDrawable(R.drawable.nophotos)); + } else if (photoEntry.thumbUrl != null && photoEntry.thumbUrl.length() > 0) { imageView.setImage(photoEntry.thumbUrl, null, mContext.getResources().getDrawable(R.drawable.nophotos)); } else { imageView.setImageResource(R.drawable.nophotos); } cell.checkBox.setChecked(selectedWebPhotos.containsKey(photoEntry.id), false); - cell.editedImage.setVisibility(View.GONE); showing = PhotoViewer.getInstance().isShowingImage(photoEntry.thumbUrl); } - imageView.imageReceiver.setVisible(!showing, false); - cell.checkBox.setVisibility(showing ? View.GONE : View.VISIBLE); + imageView.getImageReceiver().setVisible(!showing, false); + cell.checkBox.setVisibility(singlePhoto || showing ? View.GONE : View.VISIBLE); } else if (viewType == 1) { if (view == null) { LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java index 4def7298d..79bd4d4cb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java @@ -12,6 +12,7 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -23,8 +24,10 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.text.TextUtils; +import android.util.TypedValue; import android.view.GestureDetector; import android.view.Gravity; import android.view.MotionEvent; @@ -69,12 +72,15 @@ import org.telegram.ui.Components.CheckBox; import org.telegram.ui.Components.ClippingImageView; import org.telegram.android.ImageReceiver; import org.telegram.ui.Components.GifDrawable; +import org.telegram.ui.Components.PhotoCropView; +import org.telegram.ui.Components.PhotoFilterView; import org.telegram.ui.Components.PhotoPickerBottomLayout; import java.io.File; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; +import java.util.Date; import java.util.HashMap; import java.util.Locale; @@ -98,17 +104,22 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat private FrameLayout bottomLayout; private TextView nameTextView; private TextView dateTextView; - private ImageView deleteButton; private ActionBarMenuItem menuItem; + private ImageView shareButton; private ColorDrawable backgroundDrawable = new ColorDrawable(0xff000000); private CheckBox checkImageView; private PhotoPickerBottomLayout pickerView; - private ImageView shareButton; + private PhotoPickerBottomLayout editorDoneLayout; private RadialProgressView radialProgressViews[] = new RadialProgressView[3]; private GifDrawable gifDrawable; - private ActionBarMenuItem editItem; + private ActionBarMenuItem cropItem; + private ActionBarMenuItem tuneItem; private AnimatorSetProxy currentActionBarAnimation; + private PhotoCropView photoCropView; + private PhotoFilterView photoFilterView; + private AlertDialog visibleDialog = null; private boolean canShowBottom = true; + private int sendPhotoType = 0; private int animationInProgress = 0; private long transitionAnimationStartTime = 0; @@ -117,6 +128,8 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat private PlaceProviderObject hideAfterAnimation; private boolean disableShowCheck = false; + private int currentEditMode; + private ImageReceiver leftImage = new ImageReceiver(); private ImageReceiver centerImage = new ImageReceiver(); private ImageReceiver rightImage = new ImageReceiver(); @@ -145,8 +158,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat private float animateToX; private float animateToY; private float animateToScale; - private long animationDuration; + private float animationValue; private long animationStartTime; + private AnimatorSetProxy imageMoveAnimation; private GestureDetector gestureDetector; private DecelerateInterpolator interpolator = new DecelerateInterpolator(1.5f); private float pinchStartDistance = 0; @@ -187,7 +201,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat private final static int gallery_menu_save = 1; private final static int gallery_menu_showall = 2; private final static int gallery_menu_send = 3; - private final static int gallery_menu_edit = 4; + private final static int gallery_menu_crop = 4; + private final static int gallery_menu_delete = 6; + private final static int gallery_menu_tune = 7; private final static int PAGE_SPACING = AndroidUtilities.dp(30); @@ -337,24 +353,78 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat public int radius; } - public static interface PhotoViewerProvider { - public PlaceProviderObject getPlaceForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index); + public static class EmptyPhotoViewerProvider implements PhotoViewerProvider { + @Override + public PlaceProviderObject getPlaceForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index) { + return null; + } - public Bitmap getThumbForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index); + @Override + public Bitmap getThumbForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index) { + return null; + } - public void willSwitchFromPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index); + @Override + public void willSwitchFromPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index) { - public void willHidePhotoViewer(); + } - public boolean isPhotoChecked(int index); + @Override + public void willHidePhotoViewer() { - public void setPhotoChecked(int index); + } - public void cancelButtonPressed(); + @Override + public boolean isPhotoChecked(int index) { + return false; + } - public void sendButtonPressed(int index); + @Override + public void setPhotoChecked(int index) { - public int getSelectedCount(); + } + + @Override + public void cancelButtonPressed() { + + } + + @Override + public void sendButtonPressed(int index) { + + } + + @Override + public int getSelectedCount() { + return 0; + } + + @Override + public void updatePhotoAtIndex(int index) { + + } + } + + public interface PhotoViewerProvider { + PlaceProviderObject getPlaceForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index); + + Bitmap getThumbForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index); + + void willSwitchFromPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index); + + void willHidePhotoViewer(); + + boolean isPhotoChecked(int index); + + void setPhotoChecked(int index); + + void cancelButtonPressed(); + + void sendButtonPressed(int index); + + int getSelectedCount(); + + void updatePhotoAtIndex(int index); } private class FrameLayoutTouchListener extends FrameLayout { @@ -448,7 +518,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat imagesArrLocationsSizes.clear(); avatarsArr.clear(); for (TLRPC.Photo photo : photos) { - if (photo instanceof TLRPC.TL_photoEmpty || photo.sizes == null) { + if (photo == null || photo instanceof TLRPC.TL_photoEmpty || photo.sizes == null) { continue; } TLRPC.PhotoSize sizeFull = FileLoader.getClosestPhotoSizeWithSize(photo.sizes, 640); @@ -467,9 +537,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } } if (!avatarsArr.isEmpty()) { - deleteButton.setVisibility(View.VISIBLE); + menuItem.showSubItem(gallery_menu_delete); } else { - deleteButton.setVisibility(View.GONE); + menuItem.hideSubItem(gallery_menu_delete); } needSearchImageInArr = false; currentIndex = -1; @@ -497,7 +567,11 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat loadingMoreImages = true; SharedMediaQuery.loadMedia(currentDialogId, 0, 100, 0, SharedMediaQuery.MEDIA_PHOTOVIDEO, true, classGuid); } else if (!imagesArr.isEmpty()) { - actionBar.setTitle(LocaleController.formatString("Of", R.string.Of, (totalImagesCount - imagesArr.size()) + currentIndex + 1, totalImagesCount)); + if (opennedFromMedia) { + actionBar.setTitle(LocaleController.formatString("Of", R.string.Of, currentIndex + 1, totalImagesCount)); + } else { + actionBar.setTitle(LocaleController.formatString("Of", R.string.Of, (totalImagesCount - imagesArr.size()) + currentIndex + 1, totalImagesCount)); + } } } } else if (id == NotificationCenter.mediaDidLoaded) { @@ -519,12 +593,20 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat int added = 0; for (MessageObject message : arr) { - if (!imagesByIdsTemp.containsKey(message.messageOwner.id)) { - added++; - imagesArrTemp.add(0, message); - imagesByIdsTemp.put(message.messageOwner.id, message); - if (message.messageOwner.id == currentMessage.messageOwner.id) { - foundIndex = arr.size() - added; + if (!imagesByIdsTemp.containsKey(message.getId())) { + imagesByIdsTemp.put(message.getId(), message); + if (opennedFromMedia) { + imagesArrTemp.add(message); + if (message.getId() == currentMessage.getId()) { + foundIndex = added; + } + added++; + } else { + added++; + imagesArrTemp.add(0, message); + if (message.getId() == currentMessage.getId()) { + foundIndex = arr.size() - added; + } } } } @@ -548,27 +630,41 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } else { if (!cacheEndReached || !arr.isEmpty() && added != 0) { loadingMoreImages = true; - SharedMediaQuery.loadMedia(currentDialogId, 0, 100, imagesArrTemp.get(0).messageOwner.id, SharedMediaQuery.MEDIA_PHOTOVIDEO, true, classGuid); + if (opennedFromMedia) { + SharedMediaQuery.loadMedia(currentDialogId, 0, 100, imagesArrTemp.get(imagesArrTemp.size() - 1).getId(), SharedMediaQuery.MEDIA_PHOTOVIDEO, true, classGuid); + } else { + SharedMediaQuery.loadMedia(currentDialogId, 0, 100, imagesArrTemp.get(0).getId(), SharedMediaQuery.MEDIA_PHOTOVIDEO, true, classGuid); + } } } } else { int added = 0; for (MessageObject message : arr) { - if (!imagesByIds.containsKey(message.messageOwner.id)) { + if (!imagesByIds.containsKey(message.getId())) { added++; - imagesArr.add(0, message); - imagesByIds.put(message.messageOwner.id, message); + if (opennedFromMedia) { + imagesArr.add(message); + } else { + imagesArr.add(0, message); + } + imagesByIds.put(message.getId(), message); } } if (arr.isEmpty() && !fromCache) { totalImagesCount = arr.size(); } - if (added != 0) { - int index = currentIndex; - currentIndex = -1; - setImageIndex(index + added, true); + if (opennedFromMedia) { + if (added == 0) { + totalImagesCount = imagesArr.size(); + } } else { - totalImagesCount = imagesArr.size(); + if (added != 0) { + int index = currentIndex; + currentIndex = -1; + setImageIndex(index + added, true); + } else { + totalImagesCount = imagesArr.size(); + } } } } @@ -630,7 +726,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat @Override public void onItemClick(int id) { if (id == -1) { - closePhoto(true); + closePhoto(true, false); } else if (id == gallery_menu_save) { File f = null; if (currentMessageObject != null) { @@ -644,16 +740,16 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } else { AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity); builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(R.string.OK, null); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null); builder.setMessage(LocaleController.getString("PleaseDownload", R.string.PleaseDownload)); - builder.show().setCanceledOnTouchOutside(true); + showAlertDialog(builder); } } else if (id == gallery_menu_showall) { if (opennedFromMedia) { - closePhoto(true); + closePhoto(true, false); } else if (currentDialogId != 0) { disableShowCheck = true; - closePhoto(false); + closePhoto(false, false); Bundle args2 = new Bundle(); args2.putLong("dialog_id", currentDialogId); ((LaunchActivity) parentActivity).presentFragment(new MediaActivity(args2), false, true); @@ -691,21 +787,94 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } } }*/ - } else if (id == gallery_menu_edit) { - Bundle args = new Bundle(); - Bitmap bitmap = centerImage.getBitmap(); - String key = centerImage.getKey(); - if (bitmap == null) { - args.putString("photoPath", currentPathObject); + } else if (id == gallery_menu_crop) { + switchToEditMode(1); + } else if (id == gallery_menu_tune) { + switchToEditMode(2); + } else if (id == gallery_menu_delete) { + if (parentActivity == null) { + return; } - MediaController.PhotoEntry object = (MediaController.PhotoEntry) imagesArrLocals.get(currentIndex); - args.putInt("id", object.imageId); - args.putBoolean("freeformCrop", true); - args.putBoolean("onlyCrop", true); - PhotoEditorActivity fragment = new PhotoEditorActivity(args, bitmap, key); - fragment.setDelegate((PhotoCropActivity.PhotoEditActivityDelegate) placeProvider); - ((LaunchActivity) parentActivity).presentFragment(fragment, false, true); - closePhoto(false); + AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity); + if (currentFileNames[0] != null && currentFileNames[0].endsWith("mp4")) { + builder.setMessage(LocaleController.formatString("AreYouSureDeleteVideo", R.string.AreYouSureDeleteVideo)); + } else { + builder.setMessage(LocaleController.formatString("AreYouSureDeletePhoto", R.string.AreYouSureDeletePhoto)); + } + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + if (!imagesArr.isEmpty()) { + if (currentIndex < 0 || currentIndex >= imagesArr.size()) { + return; + } + MessageObject obj = imagesArr.get(currentIndex); + if (obj.isSent()) { + ArrayList arr = new ArrayList<>(); + arr.add(obj.getId()); + + ArrayList random_ids = null; + TLRPC.EncryptedChat encryptedChat = null; + if ((int) obj.getDialogId() == 0 && obj.messageOwner.random_id != 0) { + random_ids = new ArrayList<>(); + random_ids.add(obj.messageOwner.random_id); + encryptedChat = MessagesController.getInstance().getEncryptedChat((int) (obj.getDialogId() >> 32)); + } + + MessagesController.getInstance().deleteMessages(arr, random_ids, encryptedChat); + closePhoto(false, false); + } + } else if (!avatarsArr.isEmpty()) { + if (currentIndex < 0 || currentIndex >= avatarsArr.size()) { + return; + } + TLRPC.Photo photo = avatarsArr.get(currentIndex); + TLRPC.FileLocation currentLocation = imagesArrLocations.get(currentIndex); + if (photo instanceof TLRPC.TL_photoEmpty) { + photo = null; + } + boolean current = false; + if (currentUserAvatarLocation != null) { + if (photo != null) { + for (TLRPC.PhotoSize size : photo.sizes) { + if (size.location.local_id == currentUserAvatarLocation.local_id && size.location.volume_id == currentUserAvatarLocation.volume_id) { + current = true; + break; + } + } + } else if (currentLocation.local_id == currentUserAvatarLocation.local_id && currentLocation.volume_id == currentUserAvatarLocation.volume_id) { + current = true; + } + } + if (current) { + MessagesController.getInstance().deleteUserPhoto(null); + closePhoto(false, false); + } else if (photo != null) { + TLRPC.TL_inputPhoto inputPhoto = new TLRPC.TL_inputPhoto(); + inputPhoto.id = photo.id; + inputPhoto.access_hash = photo.access_hash; + MessagesController.getInstance().deleteUserPhoto(inputPhoto); + MessagesStorage.getInstance().clearUserPhoto(avatarsUserId, photo.id); + imagesArrLocations.remove(currentIndex); + imagesArrLocationsSizes.remove(currentIndex); + avatarsArr.remove(currentIndex); + if (imagesArrLocations.isEmpty()) { + closePhoto(false, false); + } else { + int index = currentIndex; + if (index >= avatarsArr.size()) { + index = avatarsArr.size() - 1; + } + currentIndex = -1; + setImageIndex(index, true); + } + } + } + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); } } @@ -727,12 +896,15 @@ 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); + menuItem.addSubItem(gallery_menu_save, LocaleController.getString("SaveToGallery", R.string.SaveToGallery), 0); + menuItem.addSubItem(gallery_menu_delete, LocaleController.getString("Delete", R.string.Delete), 0); - editItem = menu.addItemWithWidth(gallery_menu_edit, R.drawable.photo_edit, AndroidUtilities.dp(56)); + cropItem = menu.addItemWithWidth(gallery_menu_crop, R.drawable.photo_crop, AndroidUtilities.dp(56)); + tuneItem = menu.addItemWithWidth(gallery_menu_tune, R.drawable.tune, AndroidUtilities.dp(56)); bottomLayout = new FrameLayout(containerView.getContext()); containerView.addView(bottomLayout); @@ -741,7 +913,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat layoutParams.height = AndroidUtilities.dp(48); layoutParams.gravity = Gravity.BOTTOM | Gravity.LEFT; bottomLayout.setLayoutParams(layoutParams); - bottomLayout.setBackgroundColor(0x7F000000); + bottomLayout.setBackgroundColor(0x7f000000); radialProgressViews[0] = new RadialProgressView(containerView.getContext(), containerView); radialProgressViews[0].setBackgroundState(0, false); @@ -751,13 +923,14 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat radialProgressViews[2].setBackgroundState(0, false); shareButton = new ImageView(containerView.getContext()); - shareButton.setImageResource(R.drawable.ic_ab_share_white); + shareButton.setImageResource(R.drawable.share); shareButton.setScaleType(ImageView.ScaleType.CENTER); shareButton.setBackgroundResource(R.drawable.bar_selector_white); bottomLayout.addView(shareButton); layoutParams = (FrameLayout.LayoutParams) shareButton.getLayoutParams(); layoutParams.width = AndroidUtilities.dp(50); layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP | Gravity.RIGHT; shareButton.setLayoutParams(layoutParams); shareButton.setOnClickListener(new View.OnClickListener() { @Override @@ -783,13 +956,13 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(f)); - parentActivity.startActivity(Intent.createChooser(intent, "")); + parentActivity.startActivityForResult(Intent.createChooser(intent, LocaleController.getString("ShareFile", R.string.ShareFile)), 500); } else { AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity); builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(R.string.OK, null); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null); builder.setMessage(LocaleController.getString("PleaseDownload", R.string.PleaseDownload)); - builder.show().setCanceledOnTouchOutside(true); + showAlertDialog(builder); } } catch (Exception e) { FileLog.e("tmessages", e); @@ -797,131 +970,56 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } }); - deleteButton = new ImageView(containerView.getContext()); - deleteButton.setImageResource(R.drawable.ic_ab_delete_white); - deleteButton.setScaleType(ImageView.ScaleType.CENTER); - deleteButton.setBackgroundResource(R.drawable.bar_selector_white); - bottomLayout.addView(deleteButton); - layoutParams = (FrameLayout.LayoutParams) deleteButton.getLayoutParams(); - layoutParams.width = AndroidUtilities.dp(50); - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.gravity = Gravity.RIGHT; - deleteButton.setLayoutParams(layoutParams); - deleteButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (!imagesArr.isEmpty()) { - if (currentIndex < 0 || currentIndex >= imagesArr.size()) { - return; - } - MessageObject obj = imagesArr.get(currentIndex); - if (obj.isSent()) { - ArrayList arr = new ArrayList<>(); - arr.add(obj.messageOwner.id); - - ArrayList random_ids = null; - TLRPC.EncryptedChat encryptedChat = null; - if ((int) obj.getDialogId() == 0 && obj.messageOwner.random_id != 0) { - random_ids = new ArrayList<>(); - random_ids.add(obj.messageOwner.random_id); - encryptedChat = MessagesController.getInstance().getEncryptedChat((int) (obj.getDialogId() >> 32)); - } - - MessagesController.getInstance().deleteMessages(arr, random_ids, encryptedChat); - closePhoto(false); - } - } else if (!avatarsArr.isEmpty()) { - if (currentIndex < 0 || currentIndex >= avatarsArr.size()) { - return; - } - TLRPC.Photo photo = avatarsArr.get(currentIndex); - TLRPC.FileLocation currentLocation = imagesArrLocations.get(currentIndex); - if (photo instanceof TLRPC.TL_photoEmpty) { - photo = null; - } - boolean current = false; - if (currentUserAvatarLocation != null) { - if (photo != null) { - for (TLRPC.PhotoSize size : photo.sizes) { - if (size.location.local_id == currentUserAvatarLocation.local_id && size.location.volume_id == currentUserAvatarLocation.volume_id) { - current = true; - break; - } - } - } else if (currentLocation.local_id == currentUserAvatarLocation.local_id && currentLocation.volume_id == currentUserAvatarLocation.volume_id) { - current = true; - } - } - if (current) { - MessagesController.getInstance().deleteUserPhoto(null); - closePhoto(false); - } else if (photo != null) { - TLRPC.TL_inputPhoto inputPhoto = new TLRPC.TL_inputPhoto(); - inputPhoto.id = photo.id; - inputPhoto.access_hash = photo.access_hash; - MessagesController.getInstance().deleteUserPhoto(inputPhoto); - MessagesStorage.getInstance().clearUserPhoto(avatarsUserId, photo.id); - imagesArrLocations.remove(currentIndex); - imagesArrLocationsSizes.remove(currentIndex); - avatarsArr.remove(currentIndex); - if (imagesArrLocations.isEmpty()) { - closePhoto(false); - } else { - int index = currentIndex; - if (index >= avatarsArr.size()) { - index = avatarsArr.size() - 1; - } - currentIndex = -1; - setImageIndex(index, true); - } - } - } - } - }); - nameTextView = new TextView(containerView.getContext()); - nameTextView.setTextSize(17); + nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); nameTextView.setSingleLine(true); nameTextView.setMaxLines(1); nameTextView.setEllipsize(TextUtils.TruncateAt.END); nameTextView.setTextColor(0xffffffff); - nameTextView.setGravity(Gravity.CENTER); + nameTextView.setGravity(Gravity.LEFT); bottomLayout.addView(nameTextView); layoutParams = (FrameLayout.LayoutParams) nameTextView.getLayoutParams(); layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.gravity = Gravity.TOP; - layoutParams.leftMargin = AndroidUtilities.dp(60); - layoutParams.rightMargin = AndroidUtilities.dp(60); - layoutParams.topMargin = AndroidUtilities.dp(2); + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + layoutParams.leftMargin = AndroidUtilities.dp(16); + layoutParams.rightMargin = AndroidUtilities.dp(50); + layoutParams.topMargin = AndroidUtilities.dp(5); nameTextView.setLayoutParams(layoutParams); dateTextView = new TextView(containerView.getContext()); - dateTextView.setTextSize(14); + dateTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13); dateTextView.setSingleLine(true); dateTextView.setMaxLines(1); dateTextView.setEllipsize(TextUtils.TruncateAt.END); - dateTextView.setTextColor(0xffb8bdbe); - dateTextView.setGravity(Gravity.CENTER); + dateTextView.setTextColor(0xffffffff); + dateTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + dateTextView.setGravity(Gravity.LEFT); bottomLayout.addView(dateTextView); layoutParams = (FrameLayout.LayoutParams) dateTextView.getLayoutParams(); layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.gravity = Gravity.TOP; - layoutParams.leftMargin = AndroidUtilities.dp(60); - layoutParams.rightMargin = AndroidUtilities.dp(60); - layoutParams.topMargin = AndroidUtilities.dp(26); + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; + layoutParams.leftMargin = AndroidUtilities.dp(16); + layoutParams.rightMargin = AndroidUtilities.dp(50); + layoutParams.topMargin = AndroidUtilities.dp(25); dateTextView.setLayoutParams(layoutParams); pickerView = new PhotoPickerBottomLayout(parentActivity); pickerView.setBackgroundColor(0x7f000000); containerView.addView(pickerView); + layoutParams = (FrameLayout.LayoutParams) pickerView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = AndroidUtilities.dp(48); + layoutParams.gravity = Gravity.BOTTOM; + pickerView.setLayoutParams(layoutParams); pickerView.cancelButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (placeProvider != null) { placeProvider.cancelButtonPressed(); - closePhoto(false); + closePhoto(false, false); } } }); @@ -930,16 +1028,40 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat public void onClick(View view) { if (placeProvider != null) { placeProvider.sendButtonPressed(currentIndex); - closePhoto(false); + closePhoto(false, false); } } }); - layoutParams = (FrameLayout.LayoutParams) pickerView.getLayoutParams(); + editorDoneLayout = new PhotoPickerBottomLayout(parentActivity); + editorDoneLayout.setBackgroundColor(0x7f000000); + editorDoneLayout.updateSelectedCount(0, false); + editorDoneLayout.setVisibility(View.GONE); + containerView.addView(editorDoneLayout); + layoutParams = (FrameLayout.LayoutParams) editorDoneLayout.getLayoutParams(); layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; layoutParams.height = AndroidUtilities.dp(48); layoutParams.gravity = Gravity.BOTTOM; - pickerView.setLayoutParams(layoutParams); + editorDoneLayout.setLayoutParams(layoutParams); + editorDoneLayout.cancelButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (currentEditMode == 1) { + photoCropView.cancelAnimationRunnable(); + } + switchToEditMode(0); + } + }); + editorDoneLayout.doneButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (currentEditMode == 1) { + photoCropView.cancelAnimationRunnable(); + } + applyCurrentEditMode(); + switchToEditMode(0); + } + }); gestureDetector = new GestureDetector(containerView.getContext(), this); gestureDetector.setOnDoubleTapListener(this); @@ -980,12 +1102,427 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat }); } + private void showAlertDialog(AlertDialog.Builder builder) { + if (parentActivity == null) { + return; + } + try { + if (visibleDialog != null) { + visibleDialog.dismiss(); + visibleDialog = null; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + try { + visibleDialog = builder.show(); + visibleDialog.setCanceledOnTouchOutside(true); + visibleDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + visibleDialog = null; + } + }); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + + private void applyCurrentEditMode() { + Bitmap bitmap = null; + if (currentEditMode == 1) { + bitmap = photoCropView.getBitmap(); + } else if (currentEditMode == 2) { + bitmap = photoFilterView.getBitmap(); + } + if (bitmap != null) { + TLRPC.PhotoSize size = ImageLoader.scaleAndSaveImage(bitmap, AndroidUtilities.getPhotoSize(), AndroidUtilities.getPhotoSize(), 80, false, 101, 101); + if (size != null) { + Object object = imagesArrLocals.get(currentIndex); + if (object instanceof MediaController.PhotoEntry) { + MediaController.PhotoEntry entry = (MediaController.PhotoEntry) object; + entry.imagePath = FileLoader.getPathToAttach(size, true).toString(); + size = ImageLoader.scaleAndSaveImage(bitmap, AndroidUtilities.dp(120), AndroidUtilities.dp(120), 70, false, 101, 101); + if (size != null) { + entry.thumbPath = FileLoader.getPathToAttach(size, true).toString(); + } + } else if (object instanceof MediaController.SearchImage) { + MediaController.SearchImage entry = (MediaController.SearchImage) object; + entry.imagePath = FileLoader.getPathToAttach(size, true).toString(); + size = ImageLoader.scaleAndSaveImage(bitmap, AndroidUtilities.dp(120), AndroidUtilities.dp(120), 70, false, 101, 101); + if (size != null) { + entry.thumbPath = FileLoader.getPathToAttach(size, true).toString(); + } + } + if (sendPhotoType == 0 && placeProvider != null) { + placeProvider.updatePhotoAtIndex(currentIndex); + if (!placeProvider.isPhotoChecked(currentIndex)) { + placeProvider.setPhotoChecked(currentIndex); + checkImageView.setChecked(placeProvider.isPhotoChecked(currentIndex), true); + updateSelectedCount(); + } + } + if (currentEditMode == 1) { + float scaleX = photoCropView.getRectSizeX() / (float) getContainerViewWidth(); + float scaleY = photoCropView.getRectSizeY() / (float) getContainerViewHeight(); + scale = scaleX > scaleY ? scaleX : scaleY; + translationX = photoCropView.getRectX() + photoCropView.getRectSizeX() / 2 - getContainerViewWidth() / 2; + translationY = photoCropView.getRectY() + photoCropView.getRectSizeY() / 2 - getContainerViewHeight() / 2; + zoomAnimation = true; + } + centerImage.setParentView(null); + centerImage.setOrientation(0, true); + centerImage.setImageBitmap(bitmap); + centerImage.setParentView(containerView); + } + } + } + + private void switchToEditMode(final int mode) { + if (currentEditMode == mode || centerImage.getBitmap() == null || imageMoveAnimation != null || radialProgressViews[0].backgroundState != -1) { + return; + } + if (mode == 0) { + if (currentEditMode == 2) { + if (photoFilterView.getToolsView().getVisibility() != View.VISIBLE) { + photoFilterView.switchToOrFromEditMode(); + return; + } + } + Bitmap bitmap = centerImage.getBitmap(); + if (bitmap != null) { + int bitmapWidth = centerImage.getBitmapWidth(); + int bitmapHeight = centerImage.getBitmapHeight(); + + float scaleX = (float) getContainerViewWidth() / (float) bitmapWidth; + float scaleY = (float) getContainerViewHeight() / (float) bitmapHeight; + float newScaleX = (float) getContainerViewWidth(0) / (float) bitmapWidth; + float newScaleY = (float) getContainerViewHeight(0) / (float) bitmapHeight; + float scale = scaleX > scaleY ? scaleY : scaleX; + float newScale = newScaleX > newScaleY ? newScaleY : newScaleX; + int width = (int) (bitmapWidth * scale); + int height = (int) (bitmapHeight * scale); + + animateToScale = newScale / scale; + animateToX = 0; + if (currentEditMode == 1) { + animateToY = AndroidUtilities.dp(24); + } else if (currentEditMode == 2) { + animateToY = AndroidUtilities.dp(62); + } + animationStartTime = System.currentTimeMillis(); + zoomAnimation = true; + } + + imageMoveAnimation = new AnimatorSetProxy(); + if (currentEditMode == 1) { + imageMoveAnimation.playTogether( + ObjectAnimatorProxy.ofFloat(editorDoneLayout, "translationY", AndroidUtilities.dp(48)), + ObjectAnimatorProxy.ofFloat(PhotoViewer.this, "animationValue", 0, 1), + ObjectAnimatorProxy.ofFloat(photoCropView, "alpha", 0) + ); + } else if (currentEditMode == 2) { + photoFilterView.shutdown(); + imageMoveAnimation.playTogether( + ObjectAnimatorProxy.ofFloat(photoFilterView.getToolsView(), "translationY", AndroidUtilities.dp(126)), + ObjectAnimatorProxy.ofFloat(PhotoViewer.this, "animationValue", 0, 1) + ); + } + imageMoveAnimation.setDuration(200); + imageMoveAnimation.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + if (currentEditMode == 1) { + photoCropView.clearAnimation(); + editorDoneLayout.clearAnimation(); + editorDoneLayout.setVisibility(View.GONE); + photoCropView.setVisibility(View.GONE); + } else if (currentEditMode == 2) { + photoFilterView.getToolsView().clearAnimation(); + containerView.removeView(photoFilterView); + photoFilterView = null; + } + imageMoveAnimation = null; + currentEditMode = mode; + animateToScale = 1; + animateToX = 0; + animateToY = 0; + scale = 1; + updateMinMax(scale); + containerView.invalidate(); + + AnimatorSetProxy animatorSet = new AnimatorSetProxy(); + ArrayList arrayList = new ArrayList<>(); + arrayList.add(ObjectAnimatorProxy.ofFloat(pickerView, "translationY", 0)); + arrayList.add(ObjectAnimatorProxy.ofFloat(actionBar, "translationY", 0)); + if (sendPhotoType == 0) { + arrayList.add(ObjectAnimatorProxy.ofFloat(checkImageView, "alpha", 1)); + } + animatorSet.playTogether(arrayList); + animatorSet.setDuration(200); + animatorSet.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationStart(Object animation) { + pickerView.setVisibility(View.VISIBLE); + actionBar.setVisibility(View.VISIBLE); + if (sendPhotoType == 0) { + checkImageView.setVisibility(View.VISIBLE); + } + } + + @Override + public void onAnimationEnd(Object animation) { + pickerView.clearAnimation(); + actionBar.clearAnimation(); + if (sendPhotoType == 0) { + checkImageView.clearAnimation(); + } + } + }); + animatorSet.start(); + } + }); + imageMoveAnimation.start(); + } else if (mode == 1) { + if (photoCropView == null) { + photoCropView = new PhotoCropView(parentActivity); + photoCropView.setVisibility(View.GONE); + containerView.addView(photoCropView); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) photoCropView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.bottomMargin = AndroidUtilities.dp(48); + photoCropView.setLayoutParams(layoutParams); + photoCropView.setDelegate(new PhotoCropView.PhotoCropViewDelegate() { + @Override + public void needMoveImageTo(float x, float y, float s, boolean animated) { + if (animated) { + animateTo(s, x, y, true); + } else { + translationX = x; + translationY = y; + scale = s; + containerView.invalidate(); + } + } + }); + } + + editorDoneLayout.doneButtonTextView.setText(LocaleController.getString("Crop", R.string.Crop)); + AnimatorSetProxy animatorSet = new AnimatorSetProxy(); + ArrayList arrayList = new ArrayList<>(); + arrayList.add(ObjectAnimatorProxy.ofFloat(pickerView, "translationY", 0, AndroidUtilities.dp(48))); + arrayList.add(ObjectAnimatorProxy.ofFloat(actionBar, "translationY", 0, -actionBar.getHeight())); + if (sendPhotoType == 0) { + arrayList.add(ObjectAnimatorProxy.ofFloat(checkImageView, "alpha", 1, 0)); + } + animatorSet.playTogether(arrayList); + animatorSet.setDuration(200); + animatorSet.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + pickerView.clearAnimation(); + actionBar.clearAnimation(); + pickerView.setVisibility(View.GONE); + actionBar.setVisibility(View.GONE); + if (sendPhotoType == 0) { + checkImageView.clearAnimation(); + checkImageView.setVisibility(View.GONE); + } + + Bitmap bitmap = centerImage.getBitmap(); + if (bitmap != null) { + photoCropView.setBitmap(bitmap, centerImage.getOrientation(), sendPhotoType != 1); + int bitmapWidth = centerImage.getBitmapWidth(); + int bitmapHeight = centerImage.getBitmapHeight(); + + float scaleX = (float) getContainerViewWidth() / (float) bitmapWidth; + float scaleY = (float) getContainerViewHeight() / (float) bitmapHeight; + float newScaleX = (float) getContainerViewWidth(1) / (float) bitmapWidth; + float newScaleY = (float) getContainerViewHeight(1) / (float) bitmapHeight; + float scale = scaleX > scaleY ? scaleY : scaleX; + float newScale = newScaleX > newScaleY ? newScaleY : newScaleX; + int width = (int) (bitmapWidth * scale); + int height = (int) (bitmapHeight * scale); + + animateToScale = newScale / scale; + animateToX = 0; + animateToY = -AndroidUtilities.dp(24); + animationStartTime = System.currentTimeMillis(); + zoomAnimation = true; + } + + imageMoveAnimation = new AnimatorSetProxy(); + imageMoveAnimation.playTogether( + ObjectAnimatorProxy.ofFloat(editorDoneLayout, "translationY", AndroidUtilities.dp(48), 0), + ObjectAnimatorProxy.ofFloat(PhotoViewer.this, "animationValue", 0, 1), + ObjectAnimatorProxy.ofFloat(photoCropView, "alpha", 0, 1) + ); + imageMoveAnimation.setDuration(200); + imageMoveAnimation.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationStart(Object animation) { + editorDoneLayout.setVisibility(View.VISIBLE); + photoCropView.setVisibility(View.VISIBLE); + } + + @Override + public void onAnimationEnd(Object animation) { + imageMoveAnimation = null; + currentEditMode = mode; + animateToScale = 1; + animateToX = 0; + animateToY = 0; + scale = 1; + updateMinMax(scale); + containerView.invalidate(); + editorDoneLayout.clearAnimation(); + photoCropView.clearAnimation(); + } + }); + imageMoveAnimation.start(); + } + }); + animatorSet.start(); + } else if (mode == 2) { + if (photoFilterView == null) { + photoFilterView = new PhotoFilterView(parentActivity, centerImage.getBitmap(), centerImage.getOrientation()); + containerView.addView(photoFilterView); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) photoFilterView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + photoFilterView.setLayoutParams(layoutParams); + photoFilterView.getDoneTextView().setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + applyCurrentEditMode(); + switchToEditMode(0); + } + }); + photoFilterView.getCancelTextView().setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (photoFilterView.hasChanges()) { + if (parentActivity == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity); + builder.setMessage(LocaleController.getString("DiscardChanges", R.string.DiscardChanges)); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + switchToEditMode(0); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } else { + switchToEditMode(0); + } + } + }); + //photoFilterView.setEditViewFirst(); + ViewProxy.setTranslationY(photoFilterView.getToolsView(), AndroidUtilities.dp(126)); + } + + AnimatorSetProxy animatorSet = new AnimatorSetProxy(); + ArrayList arrayList = new ArrayList<>(); + arrayList.add(ObjectAnimatorProxy.ofFloat(pickerView, "translationY", 0, AndroidUtilities.dp(48))); + arrayList.add(ObjectAnimatorProxy.ofFloat(actionBar, "translationY", 0, -actionBar.getHeight())); + if (sendPhotoType == 0) { + arrayList.add(ObjectAnimatorProxy.ofFloat(checkImageView, "alpha", 1, 0)); + } + animatorSet.playTogether(arrayList); + animatorSet.setDuration(200); + animatorSet.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + pickerView.clearAnimation(); + actionBar.clearAnimation(); + pickerView.setVisibility(View.GONE); + actionBar.setVisibility(View.GONE); + if (sendPhotoType == 0) { + checkImageView.clearAnimation(); + checkImageView.setVisibility(View.GONE); + } + + Bitmap bitmap = centerImage.getBitmap(); + if (bitmap != null) { + int bitmapWidth = centerImage.getBitmapWidth(); + int bitmapHeight = centerImage.getBitmapHeight(); + + float scaleX = (float) getContainerViewWidth() / (float) bitmapWidth; + float scaleY = (float) getContainerViewHeight() / (float) bitmapHeight; + float newScaleX = (float) getContainerViewWidth(2) / (float) bitmapWidth; + float newScaleY = (float) getContainerViewHeight(2) / (float) bitmapHeight; + float scale = scaleX > scaleY ? scaleY : scaleX; + float newScale = newScaleX > newScaleY ? newScaleY : newScaleX; + int width = (int) (bitmapWidth * scale); + int height = (int) (bitmapHeight * scale); + + animateToScale = newScale / scale; + animateToX = 0; + animateToY = -AndroidUtilities.dp(62); + animationStartTime = System.currentTimeMillis(); + zoomAnimation = true; + } + + imageMoveAnimation = new AnimatorSetProxy(); + imageMoveAnimation.playTogether( + ObjectAnimatorProxy.ofFloat(PhotoViewer.this, "animationValue", 0, 1), + ObjectAnimatorProxy.ofFloat(photoFilterView.getToolsView(), "translationY", AndroidUtilities.dp(126), 0) + ); + imageMoveAnimation.setDuration(200); + imageMoveAnimation.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationStart(Object animation) { + + } + + @Override + public void onAnimationEnd(Object animation) { + photoFilterView.init(); + imageMoveAnimation = null; + currentEditMode = mode; + animateToScale = 1; + animateToX = 0; + animateToY = 0; + scale = 1; + updateMinMax(scale); + containerView.invalidate(); + photoFilterView.getToolsView().clearAnimation(); + } + }); + imageMoveAnimation.start(); + } + }); + animatorSet.start(); + } + /*Bundle args = new Bundle(); + Bitmap bitmap = centerImage.getBitmap(); + String key = centerImage.getKey(); + if (bitmap == null) { + args.putString("photoPath", currentPathObject); + } + MediaController.PhotoEntry object = + args.putInt("id", object.imageId); + args.putBoolean("freeformCrop", true); + args.putBoolean("onlyCrop", true); + PhotoEditorActivity fragment = new PhotoEditorActivity(args, bitmap, key); + fragment.setDelegate((PhotoCropActivity.PhotoEditActivityDelegate) placeProvider); + ((LaunchActivity) parentActivity).presentFragment(fragment, false, true); + closePhoto(false);*/ + } + private void toggleCheckImageView(boolean show) { AnimatorSetProxy animatorSet = new AnimatorSetProxy(); - animatorSet.playTogether( - ObjectAnimatorProxy.ofFloat(checkImageView, "alpha", show ? 1.0f : 0.0f), - ObjectAnimatorProxy.ofFloat(pickerView, "alpha", show ? 1.0f : 0.0f) - ); + ArrayList arrayList = new ArrayList<>(); + arrayList.add(ObjectAnimatorProxy.ofFloat(pickerView, "alpha", show ? 1.0f : 0.0f)); + if (sendPhotoType == 0) { + arrayList.add(ObjectAnimatorProxy.ofFloat(checkImageView, "alpha", show ? 1.0f : 0.0f)); + } + animatorSet.playTogether(arrayList); animatorSet.setDuration(200); animatorSet.start(); } @@ -1014,6 +1551,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (currentActionBarAnimation.equals(animation)) { actionBar.setVisibility(View.GONE); if (canShowBottom) { + bottomLayout.clearAnimation(); bottomLayout.setVisibility(View.GONE); } currentActionBarAnimation = null; @@ -1030,6 +1568,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (!show) { actionBar.setVisibility(View.GONE); if (canShowBottom) { + bottomLayout.clearAnimation(); bottomLayout.setVisibility(View.GONE); } } @@ -1211,6 +1750,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat avatarsUserId = 0; currentDialogId = 0; totalImagesCount = 0; + currentEditMode = 0; isFirstLoading = true; needSearchImageInArr = false; loadingMoreImages = false; @@ -1226,16 +1766,32 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat imagesArrTemp.clear(); imagesByIdsTemp.clear(); currentUserAvatarLocation = null; - currentThumb = object.thumb; + currentThumb = object != null ? object.thumb : null; menuItem.setVisibility(View.VISIBLE); bottomLayout.setVisibility(View.VISIBLE); + shareButton.setVisibility(View.GONE); + menuItem.hideSubItem(gallery_menu_showall); + ViewProxy.setTranslationY(actionBar, 0); + ViewProxy.setTranslationY(pickerView, 0); ViewProxy.setAlpha(checkImageView, 1.0f); ViewProxy.setAlpha(pickerView, 1.0f); checkImageView.clearAnimation(); pickerView.clearAnimation(); + editorDoneLayout.clearAnimation(); checkImageView.setVisibility(View.GONE); pickerView.setVisibility(View.GONE); - editItem.setVisibility(View.GONE); + cropItem.setVisibility(View.GONE); + tuneItem.setVisibility(View.GONE); + editorDoneLayout.setVisibility(View.GONE); + if (photoCropView != null) { + photoCropView.clearAnimation(); + photoCropView.setVisibility(View.GONE); + } + if (photoFilterView != null) { + photoFilterView.clearAnimation(); + photoFilterView.setVisibility(View.GONE); + } + for (int a = 0; a < 3; a++) { if (radialProgressViews[a] != null) { radialProgressViews[a].setBackgroundState(-1, false); @@ -1246,7 +1802,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat imagesArr.add(messageObject); if (messageObject.messageOwner.action == null || messageObject.messageOwner.action instanceof TLRPC.TL_messageActionEmpty) { needSearchImageInArr = true; - imagesByIds.put(messageObject.messageOwner.id, messageObject); + imagesByIds.put(messageObject.getId(), messageObject); if (messageObject.messageOwner.dialog_id != 0) { currentDialogId = messageObject.messageOwner.dialog_id; } else { @@ -1270,24 +1826,28 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat imagesArrLocations.add(fileLocation); imagesArrLocationsSizes.add(object.size); avatarsArr.add(new TLRPC.TL_photoEmpty()); - bottomLayout.setVisibility(View.GONE); + bottomLayout.clearAnimation(); shareButton.setVisibility(View.VISIBLE); menuItem.hideSubItem(gallery_menu_showall); setImageIndex(0, true); currentUserAvatarLocation = fileLocation; } else if (messages != null) { + menuItem.showSubItem(gallery_menu_showall); + opennedFromMedia = true; imagesArr.addAll(messages); - Collections.reverse(imagesArr); - for (MessageObject message : imagesArr) { - imagesByIds.put(message.messageOwner.id, message); + if (!opennedFromMedia) { + Collections.reverse(imagesArr); + index = imagesArr.size() - index - 1; + } + for (MessageObject message : imagesArr) { + imagesByIds.put(message.getId(), message); } - index = imagesArr.size() - index - 1; if (messageObject.messageOwner.dialog_id != 0) { currentDialogId = messageObject.messageOwner.dialog_id; } else { if (messageObject.messageOwner.to_id == null) { - closePhoto(false); + closePhoto(false, false); return; } if (messageObject.messageOwner.to_id.chat_id != 0) { @@ -1300,18 +1860,23 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } } } - opennedFromMedia = true; setImageIndex(index, true); } else if (photos != null) { - checkImageView.setVisibility(View.VISIBLE); + if (sendPhotoType == 0) { + checkImageView.setVisibility(View.VISIBLE); + } menuItem.setVisibility(View.GONE); imagesArrLocals.addAll(photos); setImageIndex(index, true); pickerView.setVisibility(View.VISIBLE); + bottomLayout.clearAnimation(); bottomLayout.setVisibility(View.GONE); - shareButton.setVisibility(View.VISIBLE); canShowBottom = false; - //editItem.setVisibility(imagesArrLocals.get(index) instanceof MediaController.PhotoEntry ? View.VISIBLE : View.GONE); + Object obj = imagesArrLocals.get(index); + cropItem.setVisibility(obj instanceof MediaController.PhotoEntry || obj instanceof MediaController.SearchImage && ((MediaController.SearchImage) obj).type == 0 ? View.VISIBLE : View.GONE); + if (Build.VERSION.SDK_INT >= 16) { + tuneItem.setVisibility(cropItem.getVisibility()); + } updateSelectedCount(); } @@ -1347,9 +1912,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat boolean sameImage = false; if (!imagesArr.isEmpty()) { - deleteButton.setVisibility(View.VISIBLE); + menuItem.showSubItem(gallery_menu_delete); if (currentIndex < 0 || currentIndex >= imagesArr.size()) { - closePhoto(false); + closePhoto(false, false); return; } currentMessageObject = imagesArr.get(currentIndex); @@ -1359,19 +1924,30 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } else { nameTextView.setText(""); } + long date = (long) currentMessageObject.messageOwner.date * 1000; + String dateString = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, LocaleController.formatterYear.format(new Date(date)), LocaleController.formatterDay.format(new Date(date))); if (currentFileNames[0] != null && currentFileNames[0].endsWith("mp4")) { - dateTextView.setText(String.format("%s (%s)", LocaleController.formatterYearMax.format(((long) currentMessageObject.messageOwner.date) * 1000), Utilities.formatFileSize(currentMessageObject.messageOwner.media.video.size))); + dateTextView.setText(String.format("%s (%s)", dateString, Utilities.formatFileSize(currentMessageObject.messageOwner.media.video.size))); } else { - dateTextView.setText(LocaleController.formatterYearMax.format(((long) currentMessageObject.messageOwner.date) * 1000)); + dateTextView.setText(dateString); } if (totalImagesCount != 0 && !needSearchImageInArr) { - if (imagesArr.size() < totalImagesCount && !loadingMoreImages && currentIndex < 5) { - MessageObject lastMessage = imagesArr.get(0); - SharedMediaQuery.loadMedia(currentDialogId, 0, 100, lastMessage.messageOwner.id, SharedMediaQuery.MEDIA_PHOTOVIDEO, !cacheEndReached, classGuid); - loadingMoreImages = true; + if (opennedFromMedia) { + if (imagesArr.size() < totalImagesCount && !loadingMoreImages && currentIndex > imagesArr.size() - 5) { + MessageObject lastMessage = imagesArr.get(imagesArr.size() - 1); + SharedMediaQuery.loadMedia(currentDialogId, 0, 100, lastMessage.getId(), SharedMediaQuery.MEDIA_PHOTOVIDEO, !cacheEndReached, classGuid); + loadingMoreImages = true; + } + actionBar.setTitle(LocaleController.formatString("Of", R.string.Of, currentIndex + 1, totalImagesCount)); + } else { + if (imagesArr.size() < totalImagesCount && !loadingMoreImages && currentIndex < 5) { + MessageObject lastMessage = imagesArr.get(0); + SharedMediaQuery.loadMedia(currentDialogId, 0, 100, lastMessage.getId(), SharedMediaQuery.MEDIA_PHOTOVIDEO, !cacheEndReached, classGuid); + loadingMoreImages = true; + } + actionBar.setTitle(LocaleController.formatString("Of", R.string.Of, (totalImagesCount - imagesArr.size()) + currentIndex + 1, totalImagesCount)); } - actionBar.setTitle(LocaleController.formatString("Of", R.string.Of, (totalImagesCount - imagesArr.size()) + currentIndex + 1, totalImagesCount)); } if (currentMessageObject.messageOwner.ttl != 0) { menuItem.hideSubItem(gallery_menu_save); @@ -1384,13 +1960,13 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat nameTextView.setText(""); dateTextView.setText(""); if (avatarsUserId == UserConfig.getClientUserId() && !avatarsArr.isEmpty()) { - deleteButton.setVisibility(View.VISIBLE); + menuItem.showSubItem(gallery_menu_delete); } else { - deleteButton.setVisibility(View.GONE); + menuItem.hideSubItem(gallery_menu_delete); } TLRPC.FileLocation old = currentFileLocation; if (index < 0 || index >= imagesArrLocations.size()) { - closePhoto(false); + closePhoto(false, false); return; } currentFileLocation = imagesArrLocations.get(index); @@ -1403,16 +1979,24 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } else if (!imagesArrLocals.isEmpty()) { Object object = imagesArrLocals.get(index); if (index < 0 || index >= imagesArrLocals.size()) { - closePhoto(false); + closePhoto(false, false); return; } + boolean fromCamera = false; if (object instanceof MediaController.PhotoEntry) { currentPathObject = ((MediaController.PhotoEntry) object).path; + fromCamera = ((MediaController.PhotoEntry) object).bucketId == 0 && ((MediaController.PhotoEntry) object).dateTaken == 0 && imagesArrLocals.size() == 1; } else if (object instanceof MediaController.SearchImage) { currentPathObject = ((MediaController.SearchImage) object).imageUrl; } - actionBar.setTitle(LocaleController.formatString("Of", R.string.Of, currentIndex + 1, imagesArrLocals.size())); - checkImageView.setChecked(placeProvider.isPhotoChecked(currentIndex), false); + if (fromCamera) { + actionBar.setTitle(LocaleController.getString("AttachPhoto", R.string.AttachPhoto)); + } else { + actionBar.setTitle(LocaleController.formatString("Of", R.string.Of, currentIndex + 1, imagesArrLocals.size())); + } + if (sendPhotoType == 0) { + checkImageView.setChecked(placeProvider.isPhotoChecked(currentIndex), false); + } } @@ -1440,8 +2024,8 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat animateToX = 0; animateToY = 0; animateToScale = 1; - animationDuration = 0; animationStartTime = 0; + imageMoveAnimation = null; pinchStartDistance = 0; pinchStartScale = 1; @@ -1586,6 +2170,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } private void setIndexToImage(ImageReceiver imageReceiver, int index) { + imageReceiver.setOrientation(0, false); if (!imagesArrLocals.isEmpty()) { imageReceiver.setParentMessageObject(null); if (index >= 0 && index < imagesArrLocals.size()) { @@ -1601,10 +2186,21 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat String path = null; int imageSize = 0; if (object instanceof MediaController.PhotoEntry) { - path = ((MediaController.PhotoEntry) object).path; + MediaController.PhotoEntry photoEntry = (MediaController.PhotoEntry) object; + if (photoEntry.imagePath != null) { + path = photoEntry.imagePath; + } else { + imageReceiver.setOrientation(photoEntry.orientation, false); + path = photoEntry.path; + } } else if (object instanceof MediaController.SearchImage) { - path = ((MediaController.SearchImage) object).imageUrl; - imageSize = ((MediaController.SearchImage) object).size; + MediaController.SearchImage photoEntry = (MediaController.SearchImage) object; + if (photoEntry.imagePath != null) { + path = photoEntry.imagePath; + } else { + path = photoEntry.imageUrl; + imageSize = ((MediaController.SearchImage) object).size; + } } imageReceiver.setImage(path, String.format(Locale.US, "%d_%d", size, size), placeHolder != null ? new BitmapDrawable(null, placeHolder) : null, imageSize); } else { @@ -1661,7 +2257,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } public boolean isShowingImage(MessageObject object) { - return isVisible && !disableShowCheck && object != null && currentMessageObject != null && currentMessageObject.messageOwner.id == object.messageOwner.id; + return isVisible && !disableShowCheck && object != null && currentMessageObject != null && currentMessageObject.getId() == object.getId(); } public boolean isShowingImage(TLRPC.FileLocation object) { @@ -1684,7 +2280,11 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat openPhoto(messages.get(index), null, messages, null, index, provider); } - public void openPhotoForSelect(final ArrayList photos, final int index, final PhotoViewerProvider provider) { + public void openPhotoForSelect(final ArrayList photos, final int index, int type, final PhotoViewerProvider provider) { + sendPhotoType = type; + if (pickerView != null) { + pickerView.doneButtonTextView.setText(sendPhotoType == 1 ? LocaleController.getString("Set", R.string.Set).toUpperCase() : LocaleController.getString("Send", R.string.Send).toUpperCase()); + } openPhoto(null, null, null, photos, index, provider); } @@ -1702,24 +2302,22 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } public void openPhoto(final MessageObject messageObject, final TLRPC.FileLocation fileLocation, final ArrayList messages, final ArrayList photos, final int index, final PhotoViewerProvider provider) { - if (parentActivity == null || isVisible || provider == null || checkAnimation() || messageObject == null && fileLocation == null && messages == null && photos == null) { + if (parentActivity == null || isVisible || provider == null && checkAnimation() || messageObject == null && fileLocation == null && messages == null && photos == null) { return; } + final PlaceProviderObject object = provider.getPlaceForPhoto(messageObject, fileLocation, index); - if (object == null) { + if (object == null && photos == null) { return; } try { - if (windowView.getParent() != null) { - WindowManager wm = (WindowManager) parentActivity.getSystemService(Context.WINDOW_SERVICE); - wm.removeView(windowView); - } + WindowManager wm = (WindowManager) parentActivity.getSystemService(Context.WINDOW_SERVICE); + wm.removeView(windowView); } catch (Exception e) { - FileLog.e("tmessages", e); + //don't promt } - WindowManager wm = (WindowManager) parentActivity.getSystemService(Context.WINDOW_SERVICE); try { wm.addView(windowView, windowLayoutParams); @@ -1742,126 +2340,162 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat velocityTracker = VelocityTracker.obtain(); } - disableShowCheck = true; - animationInProgress = 1; - onPhotoShow(messageObject, fileLocation, messages, photos, index, object); isVisible = true; backgroundDrawable.setAlpha(255); toggleActionBar(true, false); - AndroidUtilities.lockOrientation(parentActivity); + if (object != null) { + disableShowCheck = true; + animationInProgress = 1; + onPhotoShow(messageObject, fileLocation, messages, photos, index, object); - final Rect drawRegion = object.imageReceiver.getDrawRegion(); + AndroidUtilities.lockOrientation(parentActivity); - animatingImageView.setVisibility(View.VISIBLE); - animatingImageView.setRadius(object.radius); - animatingImageView.setNeedRadius(object.radius != 0); - animatingImageView.setImageBitmap(object.thumb); + final Rect drawRegion = object.imageReceiver.getDrawRegion(); + int orientation = object.imageReceiver.getOrientation(); - ViewProxy.setAlpha(animatingImageView, 1.0f); - ViewProxy.setPivotX(animatingImageView, 0.0f); - ViewProxy.setPivotY(animatingImageView, 0.0f); - ViewProxy.setScaleX(animatingImageView, 1.0f); - ViewProxy.setScaleY(animatingImageView, 1.0f); - ViewProxy.setTranslationX(animatingImageView, object.viewX + drawRegion.left); - ViewProxy.setTranslationY(animatingImageView, object.viewY + drawRegion.top); - final ViewGroup.LayoutParams layoutParams = animatingImageView.getLayoutParams(); - layoutParams.width = drawRegion.right - drawRegion.left; - layoutParams.height = drawRegion.bottom - drawRegion.top; - animatingImageView.setLayoutParams(layoutParams); + animatingImageView.setVisibility(View.VISIBLE); + animatingImageView.setRadius(object.radius); + animatingImageView.setOrientation(orientation); + animatingImageView.setNeedRadius(object.radius != 0); + animatingImageView.setImageBitmap(object.thumb); - containerView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { - containerView.getViewTreeObserver().removeOnPreDrawListener(this); + ViewProxy.setAlpha(animatingImageView, 1.0f); + ViewProxy.setPivotX(animatingImageView, 0.0f); + ViewProxy.setPivotY(animatingImageView, 0.0f); + ViewProxy.setScaleX(animatingImageView, 1.0f); + ViewProxy.setScaleY(animatingImageView, 1.0f); + ViewProxy.setTranslationX(animatingImageView, object.viewX + drawRegion.left); + ViewProxy.setTranslationY(animatingImageView, object.viewY + drawRegion.top); + final ViewGroup.LayoutParams layoutParams = animatingImageView.getLayoutParams(); + layoutParams.width = drawRegion.right - drawRegion.left; + layoutParams.height = drawRegion.bottom - drawRegion.top; + animatingImageView.setLayoutParams(layoutParams); - float scaleX = (float) AndroidUtilities.displaySize.x / layoutParams.width; - float scaleY = (float) (AndroidUtilities.displaySize.y - AndroidUtilities.statusBarHeight) / layoutParams.height; - float scale = scaleX > scaleY ? scaleY : scaleX; - float width = layoutParams.width * scale; - float height = layoutParams.height * scale; - float xPos = (AndroidUtilities.displaySize.x - width) / 2.0f; - float yPos = (AndroidUtilities.displaySize.y - AndroidUtilities.statusBarHeight - height) / 2.0f; - int clipHorizontal = Math.abs(drawRegion.left - object.imageReceiver.getImageX()); - int clipVertical = Math.abs(drawRegion.top - object.imageReceiver.getImageY()); + containerView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + containerView.getViewTreeObserver().removeOnPreDrawListener(this); - int coords2[] = new int[2]; - object.parentView.getLocationInWindow(coords2); - int clipTop = coords2[1] - AndroidUtilities.statusBarHeight - (object.viewY + drawRegion.top); - if (clipTop < 0) { - clipTop = 0; + float scaleX = (float) AndroidUtilities.displaySize.x / layoutParams.width; + float scaleY = (float) (AndroidUtilities.displaySize.y - AndroidUtilities.statusBarHeight) / layoutParams.height; + float scale = scaleX > scaleY ? scaleY : scaleX; + float width = layoutParams.width * scale; + float height = layoutParams.height * scale; + float xPos = (AndroidUtilities.displaySize.x - width) / 2.0f; + float yPos = (AndroidUtilities.displaySize.y - AndroidUtilities.statusBarHeight - height) / 2.0f; + int clipHorizontal = Math.abs(drawRegion.left - object.imageReceiver.getImageX()); + int clipVertical = Math.abs(drawRegion.top - object.imageReceiver.getImageY()); + + int coords2[] = new int[2]; + object.parentView.getLocationInWindow(coords2); + int clipTop = coords2[1] - AndroidUtilities.statusBarHeight - (object.viewY + drawRegion.top); + if (clipTop < 0) { + clipTop = 0; + } + int clipBottom = (object.viewY + drawRegion.top + layoutParams.height) - (coords2[1] + object.parentView.getHeight() - AndroidUtilities.statusBarHeight); + if (clipBottom < 0) { + clipBottom = 0; + } + clipTop = Math.max(clipTop, clipVertical); + clipBottom = Math.max(clipBottom, clipVertical); + + AnimatorSetProxy animatorSet = new AnimatorSetProxy(); + animatorSet.playTogether( + ObjectAnimatorProxy.ofFloat(animatingImageView, "scaleX", scale), + ObjectAnimatorProxy.ofFloat(animatingImageView, "scaleY", scale), + ObjectAnimatorProxy.ofFloat(animatingImageView, "translationX", xPos), + ObjectAnimatorProxy.ofFloat(animatingImageView, "translationY", yPos), + ObjectAnimatorProxy.ofInt(backgroundDrawable, "alpha", 0, 255), + ObjectAnimatorProxy.ofInt(animatingImageView, "clipHorizontal", clipHorizontal, 0), + ObjectAnimatorProxy.ofInt(animatingImageView, "clipTop", clipTop, 0), + ObjectAnimatorProxy.ofInt(animatingImageView, "clipBottom", clipBottom, 0), + ObjectAnimatorProxy.ofInt(animatingImageView, "radius", 0), + ObjectAnimatorProxy.ofFloat(containerView, "alpha", 0.0f, 1.0f) + ); + + animationEndRunnable = new Runnable() { + @Override + public void run() { + animationInProgress = 0; + setImages(); + transitionAnimationStartTime = 0; + containerView.invalidate(); + animatingImageView.setVisibility(View.GONE); + AndroidUtilities.unlockOrientation(parentActivity); + if (showAfterAnimation != null) { + showAfterAnimation.imageReceiver.setVisible(true, true); + } + if (hideAfterAnimation != null) { + hideAfterAnimation.imageReceiver.setVisible(false, true); + } + } + }; + + animatorSet.setDuration(200); + animatorSet.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + if (animationEndRunnable != null) { + animationEndRunnable.run(); + animationEndRunnable = null; + } + } + + @Override + public void onAnimationCancel(Object animation) { + onAnimationEnd(animation); + } + }); + transitionAnimationStartTime = System.currentTimeMillis(); + animatorSet.start(); + + animatingImageView.setOnDrawListener(new ClippingImageView.onDrawListener() { + @Override + public void onDraw() { + disableShowCheck = false; + animatingImageView.setOnDrawListener(null); + object.imageReceiver.setVisible(false, true); + } + }); + return true; } - int clipBottom = (object.viewY + drawRegion.top + layoutParams.height) - (coords2[1] + object.parentView.getHeight() - AndroidUtilities.statusBarHeight); - if (clipBottom < 0) { - clipBottom = 0; - } - clipTop = Math.max(clipTop, clipVertical); - clipBottom = Math.max(clipBottom, clipVertical); - - AnimatorSetProxy animatorSet = new AnimatorSetProxy(); - animatorSet.playTogether( - ObjectAnimatorProxy.ofFloat(animatingImageView, "scaleX", scale), - ObjectAnimatorProxy.ofFloat(animatingImageView, "scaleY", scale), - ObjectAnimatorProxy.ofFloat(animatingImageView, "translationX", xPos), - ObjectAnimatorProxy.ofFloat(animatingImageView, "translationY", yPos), - ObjectAnimatorProxy.ofInt(backgroundDrawable, "alpha", 0, 255), - ObjectAnimatorProxy.ofInt(animatingImageView, "clipHorizontal", clipHorizontal, 0), - ObjectAnimatorProxy.ofInt(animatingImageView, "clipTop", clipTop, 0), - ObjectAnimatorProxy.ofInt(animatingImageView, "clipBottom", clipBottom, 0), - ObjectAnimatorProxy.ofInt(animatingImageView, "radius", 0), - ObjectAnimatorProxy.ofFloat(containerView, "alpha", 0.0f, 1.0f) - ); - - animationEndRunnable = new Runnable() { - @Override - public void run() { - animationInProgress = 0; - setImages(); - transitionAnimationStartTime = 0; - containerView.invalidate(); - animatingImageView.setVisibility(View.GONE); - AndroidUtilities.unlockOrientation(parentActivity); - if (showAfterAnimation != null) { - showAfterAnimation.imageReceiver.setVisible(true, true); - } - if (hideAfterAnimation != null) { - hideAfterAnimation.imageReceiver.setVisible(false, true); - } - } - }; - - animatorSet.setDuration(200); - animatorSet.addListener(new AnimatorListenerAdapterProxy() { - @Override - public void onAnimationEnd(Object animation) { - if (animationEndRunnable != null) { - animationEndRunnable.run(); - animationEndRunnable = null; - } - } - - @Override - public void onAnimationCancel(Object animation) { - onAnimationEnd(animation); - } - }); - transitionAnimationStartTime = System.currentTimeMillis(); - animatorSet.start(); - - animatingImageView.setOnDrawListener(new ClippingImageView.onDrawListener() { - @Override - public void onDraw() { - disableShowCheck = false; - animatingImageView.setOnDrawListener(null); - object.imageReceiver.setVisible(false, true); - } - }); - return true; - } - }); + }); + } else { + ViewProxy.setAlpha(containerView, 1.0f); + onPhotoShow(messageObject, fileLocation, messages, photos, index, object); + } } - public void closePhoto(boolean animated) { + public void closePhoto(boolean animated, boolean fromEditMode) { + if (!fromEditMode && currentEditMode != 0) { + if (currentEditMode == 1) { + photoCropView.cancelAnimationRunnable(); + } + switchToEditMode(0); + return; + } + try { + if (visibleDialog != null) { + visibleDialog.dismiss(); + visibleDialog = null; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + + if (currentEditMode != 0) { + if (currentEditMode == 2) { + photoFilterView.shutdown(); + containerView.removeView(photoFilterView); + photoFilterView = null; + } else if (currentEditMode == 1) { + editorDoneLayout.setVisibility(View.GONE); + photoCropView.setVisibility(View.GONE); + } + currentEditMode = 0; + } + if (parentActivity == null || !isVisible || checkAnimation() || placeProvider == null) { return; } @@ -1896,6 +2530,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat final ViewGroup.LayoutParams layoutParams = animatingImageView.getLayoutParams(); Rect drawRegion = null; + animatingImageView.setOrientation(centerImage.getOrientation()); if (object != null) { animatingImageView.setNeedRadius(object.radius != 0); drawRegion = object.imageReceiver.getDrawRegion(); @@ -2086,8 +2721,8 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } private void updateMinMax(float scale) { - int maxW = (int) (centerImage.getImageWidth() * scale - containerView.getWidth()) / 2; - int maxH = (int) (centerImage.getImageHeight() * scale - containerView.getHeight()) / 2; + int maxW = (int) (centerImage.getImageWidth() * scale - getContainerViewWidth()) / 2; + int maxH = (int) (centerImage.getImageHeight() * scale - getContainerViewHeight()) / 2; if (maxW > 0) { minX = -maxW; maxX = maxW; @@ -2100,6 +2735,52 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } else { minY = maxY = 0; } + if (currentEditMode == 1) { + maxX += photoCropView.getLimitX(); + maxY += photoCropView.getLimitY(); + minX -= photoCropView.getLimitWidth(); + minY -= photoCropView.getLimitHeight(); + } + } + + private int getAdditionX() { + if (currentEditMode != 0) { + return AndroidUtilities.dp(14); + } + return 0; + } + + private int getAdditionY() { + if (currentEditMode != 0) { + return AndroidUtilities.dp(14); + } + return 0; + } + + private int getContainerViewWidth() { + return getContainerViewWidth(currentEditMode); + } + + private int getContainerViewWidth(int mode) { + int width = containerView.getWidth(); + if (mode != 0) { + width -= AndroidUtilities.dp(28); + } + return width; + } + + private int getContainerViewHeight() { + return getContainerViewHeight(currentEditMode); + } + + private int getContainerViewHeight(int mode) { + int height = containerView.getHeight(); + if (mode == 1) { + height -= AndroidUtilities.dp(76); + } else if (mode == 2) { + height -= AndroidUtilities.dp(154); + } + return height; } private boolean onTouchEvent(MotionEvent ev) { @@ -2110,7 +2791,23 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat return false; } - if (ev.getPointerCount() == 1 && gestureDetector.onTouchEvent(ev)) { + if (currentEditMode == 2) { + photoFilterView.onTouch(ev); + return true; + } + + if (currentEditMode == 1) { + if (ev.getPointerCount() == 1) { + if (photoCropView.onTouch(ev)) { + updateMinMax(scale); + return true; + } + } else { + photoCropView.onTouch(null); + } + } + + if (currentEditMode == 0 && ev.getPointerCount() == 1 && gestureDetector.onTouchEvent(ev)) { if (doubleTap) { doubleTap = false; moving = false; @@ -2121,6 +2818,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } if (ev.getActionMasked() == MotionEvent.ACTION_DOWN || ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) { + if (currentEditMode == 1) { + photoCropView.cancelAnimationRunnable(); + } discardTap = false; if (!scroller.isFinished()) { scroller.abortAnimation(); @@ -2150,11 +2850,14 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } } } else if (ev.getActionMasked() == MotionEvent.ACTION_MOVE) { + if (currentEditMode == 1) { + photoCropView.cancelAnimationRunnable(); + } if (canZoom && ev.getPointerCount() == 2 && !draggingDown && zooming && !changingPage) { discardTap = true; scale = (float) Math.hypot(ev.getX(1) - ev.getX(0), ev.getY(1) - ev.getY(0)) / pinchStartDistance * pinchStartScale; - translationX = (pinchCenterX - containerView.getWidth() / 2) - ((pinchCenterX - containerView.getWidth() / 2) - pinchStartX) * (scale / pinchStartScale); - translationY = (pinchCenterY - containerView.getHeight() / 2) - ((pinchCenterY - containerView.getHeight() / 2) - pinchStartY) * (scale / pinchStartScale); + translationX = (pinchCenterX - getContainerViewWidth() / 2) - ((pinchCenterX - getContainerViewWidth() / 2) - pinchStartX) * (scale / pinchStartScale); + translationY = (pinchCenterY - getContainerViewHeight() / 2) - ((pinchCenterY - getContainerViewHeight() / 2) - pinchStartY) * (scale / pinchStartScale); updateMinMax(scale); containerView.invalidate(); } else if (ev.getPointerCount() == 1) { @@ -2166,13 +2869,13 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (dx > AndroidUtilities.dp(3) || dy > AndroidUtilities.dp(3)) { discardTap = true; } - if (canDragDown && !draggingDown && scale == 1 && dy >= AndroidUtilities.dp(30) && dy / 2 > dx) { + if (!(placeProvider instanceof EmptyPhotoViewerProvider) && currentEditMode == 0 && canDragDown && !draggingDown && scale == 1 && dy >= AndroidUtilities.dp(30) && dy / 2 > dx) { draggingDown = true; moving = false; dragY = ev.getY(); if (isActionBarVisible && canShowBottom) { toggleActionBar(false, true); - } else if (checkImageView.getVisibility() == View.VISIBLE) { + } else if (pickerView.getVisibility() == View.VISIBLE) { toggleActionBar(false, true); toggleCheckImageView(false); } @@ -2183,7 +2886,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } else if (!invalidCoords && animationStartTime == 0) { float moveDx = moveStartX - ev.getX(); float moveDy = moveStartY - ev.getY(); - if (moving || scale == 1 && Math.abs(moveDy) + AndroidUtilities.dp(12) < Math.abs(moveDx) || scale != 1) { + if (moving || currentEditMode != 0 || scale == 1 && Math.abs(moveDy) + AndroidUtilities.dp(12) < Math.abs(moveDx) || scale != 1) { if (!moving) { moveDx = 0; moveDy = 0; @@ -2194,10 +2897,10 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat moveStartX = ev.getX(); moveStartY = ev.getY(); updateMinMax(scale); - if (translationX < minX && !rightImage.hasImage() || translationX > maxX && !leftImage.hasImage()) { + if (translationX < minX && (currentEditMode != 0 || !rightImage.hasImage()) || translationX > maxX && (currentEditMode != 0 || !leftImage.hasImage())) { moveDx /= 3.0f; } - if (maxY == 0 && minY == 0) { + if (maxY == 0 && minY == 0 && currentEditMode == 0) { if (translationY - moveDy < minY) { translationY = minY; moveDy = 0; @@ -2212,7 +2915,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } translationX -= moveDx; - if (scale != 1) { + if (scale != 1 || currentEditMode != 0) { translationY -= moveDy; } @@ -2225,14 +2928,17 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } } } else if (ev.getActionMasked() == MotionEvent.ACTION_CANCEL || ev.getActionMasked() == MotionEvent.ACTION_UP || ev.getActionMasked() == MotionEvent.ACTION_POINTER_UP) { + if (currentEditMode == 1) { + photoCropView.startAnimationRunnable(); + } if (zooming) { invalidCoords = true; if (scale < 1.0f) { updateMinMax(1.0f); animateTo(1.0f, 0, 0, true); } else if (scale > 3.0f) { - float atx = (pinchCenterX - containerView.getWidth() / 2) - ((pinchCenterX - containerView.getWidth() / 2) - pinchStartX) * (3.0f / pinchStartScale); - float aty = (pinchCenterY - containerView.getHeight() / 2) - ((pinchCenterY - containerView.getHeight() / 2) - pinchStartY) * (3.0f / pinchStartScale); + float atx = (pinchCenterX - getContainerViewWidth() / 2) - ((pinchCenterX - getContainerViewWidth() / 2) - pinchStartX) * (3.0f / pinchStartScale); + float aty = (pinchCenterY - getContainerViewHeight() / 2) - ((pinchCenterY - getContainerViewHeight() / 2) - pinchStartY) * (3.0f / pinchStartScale); updateMinMax(3.0f); if (atx < minX) { atx = minX; @@ -2250,14 +2956,14 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } zooming = false; } else if (draggingDown) { - if (Math.abs(dragY - ev.getY()) > containerView.getHeight() / 6.0f) { - closePhoto(true); + if (Math.abs(dragY - ev.getY()) > getContainerViewHeight() / 6.0f) { + closePhoto(true, false); } else { - if (checkImageView.getVisibility() == View.VISIBLE) { + if (pickerView.getVisibility() == View.VISIBLE) { toggleActionBar(true, true); toggleCheckImageView(true); } - animateTo(1, 0, 0); + animateTo(1, 0, 0, false); } draggingDown = false; } else if (moving) { @@ -2272,13 +2978,15 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat velocity = velocityTracker.getXVelocity(); } - if ((translationX < minX - containerView.getWidth() / 3 || velocity < -AndroidUtilities.dp(650)) && rightImage.hasImage()) { - goToNext(); - return true; - } - if ((translationX > maxX + containerView.getWidth() / 3 || velocity > AndroidUtilities.dp(650)) && leftImage.hasImage()) { - goToPrev(); - return true; + if (currentEditMode == 0) { + if ((translationX < minX - getContainerViewWidth() / 3 || velocity < -AndroidUtilities.dp(650)) && rightImage.hasImage()) { + goToNext(); + return true; + } + if ((translationX > maxX + getContainerViewWidth() / 3 || velocity > AndroidUtilities.dp(650)) && leftImage.hasImage()) { + goToPrev(); + return true; + } } if (translationX < minX) { @@ -2291,7 +2999,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } else if (translationY > maxY) { moveToY = maxY; } - animateTo(scale, moveToX, moveToY); + animateTo(scale, moveToX, moveToY, false); } else { AndroidUtilities.unlockOrientation(parentActivity); } @@ -2319,26 +3027,26 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat private void goToNext() { float extra = 0; if (scale != 1) { - extra = (containerView.getWidth() - centerImage.getImageWidth()) / 2 * scale; + extra = (getContainerViewWidth() - centerImage.getImageWidth()) / 2 * scale; } switchImageAfterAnimation = 1; - animateTo(scale, minX - containerView.getWidth() - extra - PAGE_SPACING / 2, translationY); + animateTo(scale, minX - getContainerViewWidth() - extra - PAGE_SPACING / 2, translationY, false); } private void goToPrev() { float extra = 0; if (scale != 1) { - extra = (containerView.getWidth() - centerImage.getImageWidth()) / 2 * scale; + extra = (getContainerViewWidth() - centerImage.getImageWidth()) / 2 * scale; } switchImageAfterAnimation = 2; - animateTo(scale, maxX + containerView.getWidth() + extra + PAGE_SPACING / 2, translationY); - } - - private void animateTo(float newScale, float newTx, float newTy) { - animateTo(newScale, newTx, newTy, false); + animateTo(scale, maxX + getContainerViewWidth() + extra + PAGE_SPACING / 2, translationY, false); } private void animateTo(float newScale, float newTx, float newTy, boolean isZoom) { + animateTo(newScale, newTx, newTy, isZoom, 250); + } + + private void animateTo(float newScale, float newTx, float newTy, boolean isZoom, int duration) { if (scale == newScale && translationX == newTx && translationY == newTy) { AndroidUtilities.unlockOrientation(parentActivity); return; @@ -2348,11 +3056,33 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat animateToX = newTx; animateToY = newTy; animationStartTime = System.currentTimeMillis(); - animationDuration = 250; - containerView.postInvalidate(); + imageMoveAnimation = new AnimatorSetProxy(); + imageMoveAnimation.playTogether( + ObjectAnimatorProxy.ofFloat(this, "animationValue", 0, 1) + ); + imageMoveAnimation.setInterpolator(interpolator); + imageMoveAnimation.setDuration(duration); + imageMoveAnimation.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + imageMoveAnimation = null; + AndroidUtilities.unlockOrientation(parentActivity); + containerView.invalidate(); + } + }); + imageMoveAnimation.start(); AndroidUtilities.lockOrientation(parentActivity); } + public void setAnimationValue(float value) { + animationValue = value; + containerView.invalidate(); + } + + public float getAnimationValue() { + return animationValue; + } + private void onDraw(Canvas canvas) { if (animationInProgress == 1 || !isVisible && animationInProgress != 2) { return; @@ -2362,23 +3092,18 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat float currentTranslationX; float currentScale; float aty = -1; - float ai = -1; - if (System.currentTimeMillis() - animationStartTime < animationDuration) { - ai = interpolator.getInterpolation((float) (System.currentTimeMillis() - animationStartTime) / animationDuration); - if (ai >= 1.0f) { - ai = -1; - } - } - - if (ai != -1) { + if (imageMoveAnimation != null) { if (!scroller.isFinished()) { scroller.abortAnimation(); } - float ts = scale + (animateToScale - scale) * ai; - float tx = translationX + (animateToX - translationX) * ai; - float ty = translationY + (animateToY - translationY) * ai; + float ts = scale + (animateToScale - scale) * animationValue; + float tx = translationX + (animateToX - translationX) * animationValue; + float ty = translationY + (animateToY - translationY) * animationValue; + if (currentEditMode == 1) { + photoCropView.setAnimationProgress(animationValue); + } if (animateToScale == 1 && scale == 1 && translationX == 0) { aty = ty; @@ -2393,6 +3118,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat translationY = animateToY; scale = animateToScale; animationStartTime = 0; + if (currentEditMode == 1) { + photoCropView.setAnimationProgress(1); + } updateMinMax(scale); AndroidUtilities.unlockOrientation(parentActivity); zoomAnimation = false; @@ -2424,8 +3152,8 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } } - if (scale == 1 && aty != -1) { - float maxValue = containerView.getHeight() / 4.0f; + if (currentEditMode == 0 && scale == 1 && aty != -1 && !zoomAnimation) { + float maxValue = getContainerViewHeight() / 4.0f; backgroundDrawable.setAlpha((int) Math.max(127, 255 * (1.0f - (Math.min(Math.abs(aty), maxValue) / maxValue)))); } else { backgroundDrawable.setAlpha(255); @@ -2433,14 +3161,16 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat ImageReceiver sideImage = null; Bitmap bitmap; - if (scale >= 1.0f && !zoomAnimation && !zooming) { - if (currentTranslationX > maxX + AndroidUtilities.dp(5)) { - sideImage = leftImage; - } else if (currentTranslationX < minX - AndroidUtilities.dp(5)) { - sideImage = rightImage; + if (currentEditMode == 0) { + if (scale >= 1.0f && !zoomAnimation && !zooming) { + if (currentTranslationX > maxX + AndroidUtilities.dp(5)) { + sideImage = leftImage; + } else if (currentTranslationX < minX - AndroidUtilities.dp(5)) { + sideImage = rightImage; + } } + changingPage = sideImage != null; } - changingPage = sideImage != null; if (sideImage == rightImage) { float tranlateX = currentTranslationX; @@ -2452,17 +3182,16 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat tranlateX = -canvas.getWidth() - PAGE_SPACING / 2; } - bitmap = sideImage.getBitmap(); - if (bitmap != null) { + if (sideImage.getBitmap() != null) { canvas.save(); - canvas.translate(containerView.getWidth() / 2, containerView.getHeight() / 2); + canvas.translate(getContainerViewWidth() / 2, getContainerViewHeight() / 2); canvas.translate(canvas.getWidth() + PAGE_SPACING / 2 + tranlateX, 0); canvas.scale(1.0f - scaleDiff, 1.0f - scaleDiff); - int bitmapWidth = bitmap.getWidth(); - int bitmapHeight = bitmap.getHeight(); + int bitmapWidth = sideImage.getBitmapWidth(); + int bitmapHeight = sideImage.getBitmapHeight(); - float scaleX = (float) containerView.getWidth() / (float) bitmapWidth; - float scaleY = (float) containerView.getHeight() / (float) bitmapHeight; + float scaleX = (float) getContainerViewWidth() / (float) bitmapWidth; + float scaleY = (float) getContainerViewHeight() / (float) bitmapHeight; float scale = scaleX > scaleY ? scaleY : scaleX; int width = (int) (bitmapWidth * scale); int height = (int) (bitmapHeight * scale); @@ -2485,24 +3214,27 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat float tranlateX = currentTranslationX; float scaleDiff = 0; float alpha = 1; - if (!zoomAnimation && tranlateX > maxX) { + if (!zoomAnimation && tranlateX > maxX && currentEditMode == 0) { alpha = Math.min(1.0f, (tranlateX - maxX) / canvas.getWidth()); scaleDiff = alpha * 0.3f; alpha = 1.0f - alpha; tranlateX = maxX; } - bitmap = centerImage.getBitmap(); - if (bitmap != null) { + if (centerImage.getBitmap() != null) { canvas.save(); - canvas.translate(containerView.getWidth() / 2, containerView.getHeight() / 2); + canvas.translate(getContainerViewWidth() / 2 + getAdditionX(), getContainerViewHeight() / 2 + getAdditionY()); canvas.translate(tranlateX, currentTranslationY); canvas.scale(currentScale - scaleDiff, currentScale - scaleDiff); - int bitmapWidth = bitmap.getWidth(); - int bitmapHeight = bitmap.getHeight(); + if (currentEditMode == 1) { + photoCropView.setBitmapParams(currentScale, tranlateX, currentTranslationY); + } - float scaleX = (float) containerView.getWidth() / (float) bitmapWidth; - float scaleY = (float) containerView.getHeight() / (float) bitmapHeight; + int bitmapWidth = centerImage.getBitmapWidth(); + int bitmapHeight = centerImage.getBitmapHeight(); + + float scaleX = (float) getContainerViewWidth() / (float) bitmapWidth; + float scaleY = (float) getContainerViewHeight() / (float) bitmapHeight; float scale = scaleX > scaleY ? scaleY : scaleX; int width = (int) (bitmapWidth * scale); int height = (int) (bitmapHeight * scale); @@ -2528,16 +3260,15 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat canvas.restore(); if (sideImage == leftImage) { - bitmap = sideImage.getBitmap(); - if (bitmap != null) { + if (sideImage.getBitmap() != null) { canvas.save(); - canvas.translate(containerView.getWidth() / 2, containerView.getHeight() / 2); + canvas.translate(getContainerViewWidth() / 2, getContainerViewHeight() / 2); canvas.translate(-(canvas.getWidth() * (scale + 1) + PAGE_SPACING) / 2 + currentTranslationX, 0); - int bitmapWidth = bitmap.getWidth(); - int bitmapHeight = bitmap.getHeight(); + int bitmapWidth = sideImage.getBitmapWidth(); + int bitmapHeight = sideImage.getBitmapHeight(); - float scaleX = (float) containerView.getWidth() / (float) bitmapWidth; - float scaleY = (float) containerView.getHeight() / (float) bitmapHeight; + float scaleX = (float) getContainerViewWidth() / (float) bitmapWidth; + float scaleY = (float) getContainerViewHeight() / (float) bitmapHeight; float scale = scaleX > scaleY ? scaleY : scaleX; int width = (int) (bitmapWidth * scale); int height = (int) (bitmapHeight * scale); @@ -2597,7 +3328,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (f.exists()) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(f), "video/mp4"); - parentActivity.startActivity(intent); + parentActivity.startActivityForResult(intent, 500); } else { loadFile = true; } @@ -2606,7 +3337,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (cacheFile.exists()) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(cacheFile), "video/mp4"); - parentActivity.startActivity(intent); + parentActivity.startActivityForResult(intent, 500); } else { loadFile = true; } @@ -2666,8 +3397,8 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (state > 0 && state <= 3) { float x = e.getX(); float y = e.getY(); - if (x >= (containerView.getWidth() - AndroidUtilities.dp(64)) / 2.0f && x <= (containerView.getWidth() + AndroidUtilities.dp(64)) / 2.0f && - y >= (containerView.getHeight() - AndroidUtilities.dp(64)) / 2.0f && y <= (containerView.getHeight() + AndroidUtilities.dp(64)) / 2.0f) { + if (x >= (getContainerViewWidth() - AndroidUtilities.dp(64)) / 2.0f && x <= (getContainerViewWidth() + AndroidUtilities.dp(64)) / 2.0f && + y >= (getContainerViewHeight() - AndroidUtilities.dp(64)) / 2.0f && y <= (getContainerViewHeight() + AndroidUtilities.dp(64)) / 2.0f) { onActionClick(); checkProgress(0, true); return true; @@ -2675,7 +3406,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } } toggleActionBar(!isActionBarVisible, true); - } else { + } else if (sendPhotoType == 0) { checkImageView.performClick(); } return true; @@ -2690,8 +3421,8 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat return false; } if (scale == 1.0f) { - float atx = (e.getX() - containerView.getWidth() / 2) - ((e.getX() - containerView.getWidth() / 2) - translationX) * (3.0f / scale); - float aty = (e.getY() - containerView.getHeight() / 2) - ((e.getY() - containerView.getHeight() / 2) - translationY) * (3.0f / scale); + float atx = (e.getX() - getContainerViewWidth() / 2) - ((e.getX() - getContainerViewWidth() / 2) - translationX) * (3.0f / scale); + float aty = (e.getY() - getContainerViewHeight() / 2) - ((e.getY() - getContainerViewHeight() / 2) - translationY) * (3.0f / scale); updateMinMax(3.0f); if (atx < minX) { atx = minX; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java index 5c9dcae8a..b8a8832d8 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java @@ -53,6 +53,7 @@ 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.SizeNotifierRelativeLayout; import org.telegram.ui.Components.TypingDotsDrawable; import java.io.File; @@ -159,23 +160,54 @@ public class PopupNotificationActivity extends Activity implements NotificationC typingDotsDrawable = new TypingDotsDrawable(); - chatActivityEnterView = new ChatActivityEnterView(); + SizeNotifierRelativeLayout contentView = new SizeNotifierRelativeLayout(this); + setContentView(contentView); + contentView.setBackgroundColor(0x99000000); + + RelativeLayout relativeLayout = new RelativeLayout(this); + contentView.addView(relativeLayout); + RelativeLayout.LayoutParams layoutParams3 = (RelativeLayout.LayoutParams) relativeLayout.getLayoutParams(); + layoutParams3.width = RelativeLayout.LayoutParams.MATCH_PARENT; + layoutParams3.height = RelativeLayout.LayoutParams.MATCH_PARENT; + relativeLayout.setLayoutParams(layoutParams3); + + RelativeLayout popupContainer = new RelativeLayout(this); + popupContainer.setBackgroundColor(0xffffffff); + relativeLayout.addView(popupContainer); + layoutParams3 = (RelativeLayout.LayoutParams) popupContainer.getLayoutParams(); + layoutParams3.width = RelativeLayout.LayoutParams.MATCH_PARENT; + layoutParams3.height = AndroidUtilities.dp(240); + layoutParams3.leftMargin = AndroidUtilities.dp(12); + layoutParams3.rightMargin = AndroidUtilities.dp(12); + layoutParams3.addRule(RelativeLayout.CENTER_IN_PARENT); + popupContainer.setLayoutParams(layoutParams3); + + if (chatActivityEnterView != null) { + chatActivityEnterView.onDestroy(); + } + chatActivityEnterView = new ChatActivityEnterView(this, contentView, null, false); + popupContainer.addView(chatActivityEnterView); + layoutParams3 = (RelativeLayout.LayoutParams) chatActivityEnterView.getLayoutParams(); + layoutParams3.width = RelativeLayout.LayoutParams.MATCH_PARENT; + layoutParams3.height = RelativeLayout.LayoutParams.WRAP_CONTENT; + layoutParams3.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); + chatActivityEnterView.setLayoutParams(layoutParams3); chatActivityEnterView.setDelegate(new ChatActivityEnterView.ChatActivityEnterViewDelegate() { @Override - public void onMessageSend() { + public void onMessageSend(String message) { if (currentMessageObject == null) { return; } if (currentMessageNum >= 0 && currentMessageNum < NotificationsController.getInstance().popupMessages.size()) { NotificationsController.getInstance().popupMessages.remove(currentMessageNum); } - MessagesController.getInstance().markDialogAsRead(currentMessageObject.getDialogId(), currentMessageObject.messageOwner.id, Math.max(0, currentMessageObject.messageOwner.id), 0, currentMessageObject.messageOwner.date, true, true); + MessagesController.getInstance().markDialogAsRead(currentMessageObject.getDialogId(), currentMessageObject.getId(), Math.max(0, currentMessageObject.getId()), 0, currentMessageObject.messageOwner.date, true, true); currentMessageObject = null; getNewMessage(); } @Override - public void onTextChanged(CharSequence text) { + public void onTextChanged(CharSequence text, boolean big) { } @@ -202,15 +234,13 @@ public class PopupNotificationActivity extends Activity implements NotificationC } }); - setContentView(R.layout.popup_notification_layout); - RelativeLayout popupContainer = (RelativeLayout) findViewById(R.id.popup_container); messageContainer = new FrameLayoutTouch(this); popupContainer.addView(messageContainer, 0); actionBar = new ActionBar(this); actionBar.setOccupyStatusBar(false); actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setBackgroundResource(R.color.header); + actionBar.setBackgroundColor(0xff54759e); actionBar.setItemsBackground(R.drawable.bar_selector); popupContainer.addView(actionBar); ViewGroup.LayoutParams layoutParams = actionBar.getLayoutParams(); @@ -234,8 +264,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC avatarContainer.setLayoutParams(layoutParams2); avatarImageView = new BackupImageView(this); - avatarImageView.imageReceiver.setRoundRadius(AndroidUtilities.dp(21)); - avatarImageView.processDetach = false; + avatarImageView.setRoundRadius(AndroidUtilities.dp(21)); avatarContainer.addView(avatarImageView); layoutParams2 = (FrameLayout.LayoutParams) avatarImageView.getLayoutParams(); layoutParams2.width = AndroidUtilities.dp(42); @@ -292,8 +321,6 @@ public class PopupNotificationActivity extends Activity implements NotificationC } }); - chatActivityEnterView.setContainerView(this, findViewById(R.id.chat_layout)); - 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); @@ -521,7 +548,7 @@ 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); + imageView.setAspectFit(true); if (messageObject.type == 1) { TLRPC.PhotoSize currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, AndroidUtilities.getPhotoSize()); @@ -774,7 +801,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC boolean found = false; if ((currentMessageNum != 0 || chatActivityEnterView.hasText() || startedMoving) && currentMessageObject != null) { for (int a = 0; a < NotificationsController.getInstance().popupMessages.size(); a++) { - if (NotificationsController.getInstance().popupMessages.get(a).messageOwner.id == currentMessageObject.messageOwner.id) { + if (NotificationsController.getInstance().popupMessages.get(a).getId() == currentMessageObject.getId()) { currentMessageNum = a; found = true; break; @@ -958,6 +985,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC } ConnectionsManager.getInstance().setAppPaused(false, false); fixLayout(); + checkAndUpdateAvatar(); wakeLock.acquire(7000); } @@ -1004,7 +1032,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC View view = messageContainer.getChildAt(a); if ((Integer)view.getTag() == 3) { PopupAudioView cell = (PopupAudioView)view.findViewWithTag(300); - if (cell.getMessageObject() != null && cell.getMessageObject().messageOwner.id == mid) { + if (cell.getMessageObject() != null && cell.getMessageObject().getId() == mid) { cell.updateButtonState(); break; } @@ -1019,7 +1047,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC View view = messageContainer.getChildAt(a); if ((Integer)view.getTag() == 3) { PopupAudioView cell = (PopupAudioView)view.findViewWithTag(300); - if (cell.getMessageObject() != null && cell.getMessageObject().messageOwner.id == mid) { + if (cell.getMessageObject() != null && cell.getMessageObject().getId() == mid) { cell.updateProgress(); break; } @@ -1051,6 +1079,9 @@ public class PopupNotificationActivity extends Activity implements NotificationC if (wakeLock.isHeld()) { wakeLock.release(); } + if (avatarImageView != null) { + avatarImageView.setImageDrawable(null); + } } protected void onFinish() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PrivacySettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PrivacySettingsActivity.java index 5cdc731cc..6f5d0e901 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PrivacySettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PrivacySettingsActivity.java @@ -19,12 +19,10 @@ import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.FrameLayout; import android.widget.ListView; -import android.widget.Toast; import org.telegram.android.AndroidUtilities; import org.telegram.android.ContactsController; import org.telegram.android.LocaleController; -import org.telegram.android.MessagesController; import org.telegram.android.NotificationCenter; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; @@ -51,9 +49,10 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio private int lastSeenRow; private int lastSeenDetailRow; private int securitySectionRow; - private int terminateSessionsRow; + private int sessionsRow; private int passwordRow; - private int terminateSessionsDetailRow; + private int passcodeRow; + private int sessionsDetailRow; private int deleteAccountSectionRow; private int deleteAccountRow; private int deleteAccountDetailRow; @@ -71,12 +70,13 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio lastSeenRow = rowCount++; lastSeenDetailRow = rowCount++; securitySectionRow = rowCount++; - terminateSessionsRow = rowCount++; - terminateSessionsDetailRow = rowCount++; + passcodeRow = rowCount++; + passwordRow = rowCount++; + sessionsRow = rowCount++; + sessionsDetailRow = rowCount++; deleteAccountSectionRow = rowCount++; deleteAccountRow = rowCount++; deleteAccountDetailRow = rowCount++; - passwordRow = -1; NotificationCenter.getInstance().addObserver(this, NotificationCenter.privacyRulesUpdated); @@ -90,152 +90,114 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - actionBar.setTitle(LocaleController.getString("PrivacySettings", R.string.PrivacySettings)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + actionBar.setTitle(LocaleController.getString("PrivacySettings", R.string.PrivacySettings)); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); } - }); - - listAdapter = new ListAdapter(getParentActivity()); - - fragmentView = new FrameLayout(getParentActivity()); - FrameLayout frameLayout = (FrameLayout) fragmentView; - frameLayout.setBackgroundColor(0xfff0f0f0); - - ListView listView = new ListView(getParentActivity()); - listView.setDivider(null); - listView.setDividerHeight(0); - listView.setVerticalScrollBarEnabled(false); - listView.setDrawSelectorOnTop(true); - frameLayout.addView(listView); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.gravity = Gravity.TOP; - listView.setLayoutParams(layoutParams); - listView.setAdapter(listAdapter); - listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, final int i, long l) { - if (i == blockedRow) { - presentFragment(new BlockedUsersActivity()); - } else if (i == terminateSessionsRow) { - if (getParentActivity() == null) { - return; - } - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setMessage(LocaleController.getString("AreYouSureSessions", R.string.AreYouSureSessions)); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - TLRPC.TL_auth_resetAuthorizations req = new TLRPC.TL_auth_resetAuthorizations(); - 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 (getParentActivity() == null) { - return; - } - if (error == null && response instanceof TLRPC.TL_boolTrue) { - Toast toast = Toast.makeText(getParentActivity(), LocaleController.getString("TerminateAllSessions", R.string.TerminateAllSessions), Toast.LENGTH_SHORT); - toast.show(); - } else { - Toast toast = Toast.makeText(getParentActivity(), LocaleController.getString("UnknownError", R.string.UnknownError), Toast.LENGTH_SHORT); - toast.show(); - } - } - }); - UserConfig.registeredForPush = false; - UserConfig.registeredForInternalPush = false; - UserConfig.saveConfig(false); - MessagesController.getInstance().registerForPush(UserConfig.pushString); - ConnectionsManager.getInstance().initPushConnection(); - } - }); - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } else if (i == deleteAccountRow) { - if (getParentActivity() == null) { - return; - } - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("DeleteAccountTitle", R.string.DeleteAccountTitle)); - builder.setItems(new CharSequence[] { - LocaleController.formatPluralString("Months", 1), - LocaleController.formatPluralString("Months", 3), - LocaleController.formatPluralString("Months", 6), - LocaleController.formatPluralString("Years", 1) - }, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - int value = 0; - if (which == 0) { - value = 30; - } else if (which == 1) { - value = 90; - } else if (which == 2) { - value = 182; - } else if (which == 3) { - value = 365; - } - final ProgressDialog progressDialog = new ProgressDialog(getParentActivity()); - progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading)); - progressDialog.setCanceledOnTouchOutside(false); - progressDialog.setCancelable(false); - progressDialog.show(); - - final TLRPC.TL_account_setAccountTTL req = new TLRPC.TL_account_setAccountTTL(); - req.ttl = new TLRPC.TL_accountDaysTTL(); - req.ttl.days = value; - 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() { - try { - progressDialog.dismiss(); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - if (response instanceof TLRPC.TL_boolTrue) { - ContactsController.getInstance().setDeleteAccountTTL(req.ttl.days); - listAdapter.notifyDataSetChanged(); - } - } - }); - } - }); - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } else if (i == lastSeenRow) { - presentFragment(new LastSeenActivity()); - } else if (i == passwordRow) { - presentFragment(new AccountPasswordActivity(0)); - } - } - }); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); } - } + }); + + listAdapter = new ListAdapter(context); + + fragmentView = new FrameLayout(context); + FrameLayout frameLayout = (FrameLayout) fragmentView; + frameLayout.setBackgroundColor(0xfff0f0f0); + + ListView listView = new ListView(context); + listView.setDivider(null); + listView.setDividerHeight(0); + listView.setVerticalScrollBarEnabled(false); + listView.setDrawSelectorOnTop(true); + frameLayout.addView(listView); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP; + listView.setLayoutParams(layoutParams); + listView.setAdapter(listAdapter); + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, final int i, long l) { + if (i == blockedRow) { + presentFragment(new BlockedUsersActivity()); + } else if (i == sessionsRow) { + presentFragment(new SessionsActivity()); + } else if (i == deleteAccountRow) { + if (getParentActivity() == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("DeleteAccountTitle", R.string.DeleteAccountTitle)); + builder.setItems(new CharSequence[]{ + LocaleController.formatPluralString("Months", 1), + LocaleController.formatPluralString("Months", 3), + LocaleController.formatPluralString("Months", 6), + LocaleController.formatPluralString("Years", 1) + }, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + int value = 0; + if (which == 0) { + value = 30; + } else if (which == 1) { + value = 90; + } else if (which == 2) { + value = 182; + } else if (which == 3) { + value = 365; + } + final ProgressDialog progressDialog = new ProgressDialog(getParentActivity()); + progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.setCancelable(false); + progressDialog.show(); + + final TLRPC.TL_account_setAccountTTL req = new TLRPC.TL_account_setAccountTTL(); + req.ttl = new TLRPC.TL_accountDaysTTL(); + req.ttl.days = value; + 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() { + try { + progressDialog.dismiss(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + if (response instanceof TLRPC.TL_boolTrue) { + ContactsController.getInstance().setDeleteAccountTTL(req.ttl.days); + listAdapter.notifyDataSetChanged(); + } + } + }); + } + }); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } else if (i == lastSeenRow) { + presentFragment(new LastSeenActivity()); + } else if (i == passwordRow) { + presentFragment(new TwoStepVerificationActivity(0)); + } else if (i == passcodeRow) { + if (UserConfig.passcodeHash.length() > 0) { + presentFragment(new PasscodeActivity(2)); + } else { + presentFragment(new PasscodeActivity(0)); + } + } + } + }); + return fragmentView; } @@ -319,7 +281,7 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio @Override public boolean isEnabled(int i) { - return i == passwordRow || i == blockedRow || i == terminateSessionsRow || i == lastSeenRow && !ContactsController.getInstance().getLoadingLastSeenInfo() || i == deleteAccountRow && !ContactsController.getInstance().getLoadingDeleteInfo(); + return i == passcodeRow || i == passwordRow || i == blockedRow || i == sessionsRow || i == lastSeenRow && !ContactsController.getInstance().getLoadingLastSeenInfo() || i == deleteAccountRow && !ContactsController.getInstance().getLoadingDeleteInfo(); } @Override @@ -353,10 +315,12 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio TextSettingsCell textCell = (TextSettingsCell) view; if (i == blockedRow) { textCell.setText(LocaleController.getString("BlockedUsers", R.string.BlockedUsers), true); - } else if (i == terminateSessionsRow) { - textCell.setText(LocaleController.getString("TerminateAllSessions", R.string.TerminateAllSessions), false); + } else if (i == sessionsRow) { + textCell.setText(LocaleController.getString("SessionsTitle", R.string.SessionsTitle), false); } else if (i == passwordRow) { - textCell.setText(LocaleController.getString("Password", R.string.Password), true); + textCell.setText(LocaleController.getString("TwoStepVerification", R.string.TwoStepVerification), true); + } else if (i == passcodeRow) { + textCell.setText(LocaleController.getString("Passcode", R.string.Passcode), true); } else if (i == lastSeenRow) { String value; if (ContactsController.getInstance().getLoadingLastSeenInfo()) { @@ -391,8 +355,8 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio } else if (i == lastSeenDetailRow) { ((TextInfoPrivacyCell) view).setText(LocaleController.getString("LastSeenHelp", R.string.LastSeenHelp)); view.setBackgroundResource(R.drawable.greydivider); - } else if (i == terminateSessionsDetailRow) { - ((TextInfoPrivacyCell) view).setText(LocaleController.getString("ClearOtherSessionsHelp", R.string.ClearOtherSessionsHelp)); + } else if (i == sessionsDetailRow) { + ((TextInfoPrivacyCell) view).setText(LocaleController.getString("SessionsInfo", R.string.SessionsInfo)); view.setBackgroundResource(R.drawable.greydivider); } } else if (type == 2) { @@ -413,9 +377,9 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio @Override public int getItemViewType(int i) { - if (i == lastSeenRow || i == blockedRow || i == deleteAccountRow || i == terminateSessionsRow || i == passwordRow) { + if (i == lastSeenRow || i == blockedRow || i == deleteAccountRow || i == sessionsRow || i == passwordRow || i == passcodeRow) { return 0; - } else if (i == deleteAccountDetailRow || i == lastSeenDetailRow || i == terminateSessionsDetailRow) { + } else if (i == deleteAccountDetailRow || i == lastSeenDetailRow || i == sessionsDetailRow) { return 1; } else if (i == securitySectionRow || i == deleteAccountSectionRow || i == privacySectionRow) { return 2; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java index fe5284968..99fae5d7e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java @@ -20,7 +20,6 @@ import android.graphics.Outline; import android.net.Uri; import android.os.Build; import android.os.Bundle; -import android.text.Html; import android.text.TextUtils; import android.util.TypedValue; import android.view.Gravity; @@ -224,434 +223,425 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackgroundColor(AvatarDrawable.getProfileBackColorForId(user_id != 0 ? 5 : chat_id)); - actionBar.setItemsBackground(AvatarDrawable.getButtonColorForId(user_id != 0 ? 5 : chat_id)); - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setExtraHeight(AndroidUtilities.dp(88), false); - if (AndroidUtilities.isTablet()) { - actionBar.setOccupyStatusBar(false); + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackgroundColor(AvatarDrawable.getProfileBackColorForId(user_id != 0 ? 5 : chat_id)); + actionBar.setItemsBackground(AvatarDrawable.getButtonColorForId(user_id != 0 ? 5 : chat_id)); + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setExtraHeight(AndroidUtilities.dp(88), false); + if (AndroidUtilities.isTablet()) { + actionBar.setOccupyStatusBar(false); + } + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(final int id) { + if (getParentActivity() == null) { + return; + } + if (id == -1) { + finishFragment(); + } else if (id == block_contact) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + if (!userBlocked) { + builder.setMessage(LocaleController.getString("AreYouSureBlockContact", R.string.AreYouSureBlockContact)); + } else { + builder.setMessage(LocaleController.getString("AreYouSureUnblockContact", R.string.AreYouSureUnblockContact)); + } + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + if (!userBlocked) { + MessagesController.getInstance().blockUser(user_id); + } else { + MessagesController.getInstance().unblockUser(user_id); + } + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } else if (id == add_contact) { + TLRPC.User user = MessagesController.getInstance().getUser(user_id); + Bundle args = new Bundle(); + args.putInt("user_id", user.id); + presentFragment(new ContactAddActivity(args)); + } else if (id == share_contact) { + Bundle args = new Bundle(); + args.putBoolean("onlySelect", true); + args.putBoolean("serverOnly", true); + MessagesActivity fragment = new MessagesActivity(args); + fragment.setDelegate(ProfileActivity.this); + presentFragment(fragment); + } else if (id == edit_contact) { + Bundle args = new Bundle(); + args.putInt("user_id", user_id); + presentFragment(new ContactAddActivity(args)); + } else if (id == delete_contact) { + final TLRPC.User user = MessagesController.getInstance().getUser(user_id); + if (user == null || getParentActivity() == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.getString("AreYouSureDeleteContact", R.string.AreYouSureDeleteContact)); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + ArrayList arrayList = new ArrayList<>(); + arrayList.add(user); + ContactsController.getInstance().deleteContact(arrayList); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } else if (id == add_member) { + Bundle args = new Bundle(); + args.putBoolean("onlyUsers", true); + args.putBoolean("destroyAfterSelect", true); + args.putBoolean("returnAsResult", true); + //args.putBoolean("allowUsernameSearch", false); + if (chat_id > 0) { + args.putString("selectAlertString", LocaleController.getString("AddToTheGroup", R.string.AddToTheGroup)); + } + ContactsActivity fragment = new ContactsActivity(args); + fragment.setDelegate(new ContactsActivity.ContactsActivityDelegate() { + @Override + public void didSelectContact(TLRPC.User user, String param) { + MessagesController.getInstance().addUserToChat(chat_id, user, info, param != null ? Utilities.parseInt(param) : 0); + } + }); + if (info != null) { + HashMap users = new HashMap<>(); + for (TLRPC.TL_chatParticipant p : info.participants) { + users.put(p.user_id, null); + } + fragment.setIgnoreUsers(users); + } + presentFragment(fragment); + } else if (id == leave_group) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.getString("AreYouSureDeleteAndExit", R.string.AreYouSureDeleteAndExit)); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + kickUser(null); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } else if (id == edit_name) { + Bundle args = new Bundle(); + args.putInt("chat_id", chat_id); + presentFragment(new ChangeChatNameActivity(args)); + } } - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(final int id) { + }); + + createActionBarMenu(); + + listAdapter = new ListAdapter(context); + + fragmentView = new FrameLayout(context); + FrameLayout frameLayout = (FrameLayout) fragmentView; + + avatarImage = new BackupImageView(context); + avatarImage.setRoundRadius(AndroidUtilities.dp(30)); + actionBar.addView(avatarImage); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) avatarImage.getLayoutParams(); + layoutParams.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.BOTTOM; + layoutParams.width = AndroidUtilities.dp(60); + layoutParams.height = AndroidUtilities.dp(60); + layoutParams.leftMargin = LocaleController.isRTL ? 0 : AndroidUtilities.dp(17); + layoutParams.rightMargin = LocaleController.isRTL ? AndroidUtilities.dp(17) : 0; + layoutParams.bottomMargin = AndroidUtilities.dp(22); + avatarImage.setLayoutParams(layoutParams); + avatarImage.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (user_id != 0) { + TLRPC.User user = MessagesController.getInstance().getUser(user_id); + if (user.photo != null && user.photo.photo_big != null) { + PhotoViewer.getInstance().setParentActivity(getParentActivity()); + PhotoViewer.getInstance().openPhoto(user.photo.photo_big, ProfileActivity.this); + } + } else if (chat_id != 0) { + TLRPC.Chat chat = MessagesController.getInstance().getChat(chat_id); + if (chat.photo != null && chat.photo.photo_big != null) { + PhotoViewer.getInstance().setParentActivity(getParentActivity()); + PhotoViewer.getInstance().openPhoto(chat.photo.photo_big, ProfileActivity.this); + } + } + } + }); + + nameTextView = new TextView(context); + nameTextView.setTextColor(0xffffffff); + nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); + nameTextView.setLines(1); + nameTextView.setMaxLines(1); + nameTextView.setSingleLine(true); + nameTextView.setEllipsize(TextUtils.TruncateAt.END); + nameTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)); + nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + actionBar.addView(nameTextView); + layoutParams = (FrameLayout.LayoutParams) nameTextView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? 16 : 97); + layoutParams.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? 97 : 16); + layoutParams.bottomMargin = AndroidUtilities.dp(51); + layoutParams.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.BOTTOM; + nameTextView.setLayoutParams(layoutParams); + + onlineTextView = new TextView(context); + onlineTextView.setTextColor(AvatarDrawable.getProfileTextColorForId(user_id != 0 ? 5 : chat_id)); + onlineTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + onlineTextView.setLines(1); + onlineTextView.setMaxLines(1); + onlineTextView.setSingleLine(true); + onlineTextView.setEllipsize(TextUtils.TruncateAt.END); + onlineTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)); + actionBar.addView(onlineTextView); + layoutParams = (FrameLayout.LayoutParams) onlineTextView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? 16 : 97); + layoutParams.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? 97 : 16); + layoutParams.bottomMargin = AndroidUtilities.dp(30); + layoutParams.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.BOTTOM; + onlineTextView.setLayoutParams(layoutParams); + + listView = new ListView(context); + listView.setDivider(null); + listView.setDividerHeight(0); + listView.setVerticalScrollBarEnabled(false); + AndroidUtilities.setListViewEdgeEffectColor(listView, AvatarDrawable.getProfileBackColorForId(user_id != 0 ? 5 : chat_id)); + frameLayout.addView(listView); + layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP; + listView.setLayoutParams(layoutParams); + + listView.setAdapter(listAdapter); + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, final int i, long l) { + if (getParentActivity() == null) { + return; + } + if (i == sharedMediaRow) { + Bundle args = new Bundle(); + if (user_id != 0) { + args.putLong("dialog_id", dialog_id != 0 ? dialog_id : user_id); + } else { + args.putLong("dialog_id", -chat_id); + } + presentFragment(new MediaActivity(args)); + } else if (i == settingsKeyRow) { + Bundle args = new Bundle(); + args.putInt("chat_id", (int) (dialog_id >> 32)); + presentFragment(new IdenticonActivity(args)); + } else if (i == settingsTimerRow) { if (getParentActivity() == null) { return; } - if (id == -1) { - finishFragment(); - } else if (id == block_contact) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - if (!userBlocked) { - builder.setMessage(LocaleController.getString("AreYouSureBlockContact", R.string.AreYouSureBlockContact)); - } else { - builder.setMessage(LocaleController.getString("AreYouSureUnblockContact", R.string.AreYouSureUnblockContact)); + showAlertDialog(AndroidUtilities.buildTTLAlert(getParentActivity(), currentEncryptedChat)); + } else if (i == settingsNotificationsRow) { + Bundle args = new Bundle(); + if (user_id != 0) { + args.putLong("dialog_id", dialog_id == 0 ? user_id : dialog_id); + } else if (chat_id != 0) { + args.putLong("dialog_id", -chat_id); + } + presentFragment(new ProfileNotificationsActivity(args)); + } else if (i == startSecretChatRow) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.getString("AreYouSureSecretChat", R.string.AreYouSureSecretChat)); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + creatingChat = true; + SecretChatHelper.getInstance().startSecretChat(getParentActivity(), MessagesController.getInstance().getUser(user_id)); } - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - if (!userBlocked) { - MessagesController.getInstance().blockUser(user_id); + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } else if (i == phoneRow) { + final TLRPC.User user = MessagesController.getInstance().getUser(user_id); + if (user == null || user.phone == null || user.phone.length() == 0 || getParentActivity() == null) { + return; + } + + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setItems(new CharSequence[]{LocaleController.getString("Call", R.string.Call), LocaleController.getString("Copy", R.string.Copy)}, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + if (i == 0) { + try { + Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:+" + user.phone)); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + getParentActivity().startActivityForResult(intent, 500); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } 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); + clipboard.setText("+" + user.phone); } else { - MessagesController.getInstance().unblockUser(user_id); + android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); + android.content.ClipData clip = android.content.ClipData.newPlainText("label", "+" + user.phone); + clipboard.setPrimaryClip(clip); } } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } else if (id == add_contact) { - TLRPC.User user = MessagesController.getInstance().getUser(user_id); - Bundle args = new Bundle(); - args.putInt("user_id", user.id); - presentFragment(new ContactAddActivity(args)); - } else if (id == share_contact) { - Bundle args = new Bundle(); - args.putBoolean("onlySelect", true); - args.putBoolean("serverOnly", true); - MessagesActivity fragment = new MessagesActivity(args); - fragment.setDelegate(ProfileActivity.this); - presentFragment(fragment); - } else if (id == edit_contact) { - Bundle args = new Bundle(); - args.putInt("user_id", user_id); - presentFragment(new ContactAddActivity(args)); - } else if (id == delete_contact) { - final TLRPC.User user = MessagesController.getInstance().getUser(user_id); - if (user == null || getParentActivity() == null) { - return; } - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setMessage(LocaleController.getString("AreYouSureDeleteContact", R.string.AreYouSureDeleteContact)); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - ArrayList arrayList = new ArrayList<>(); - arrayList.add(user); - ContactsController.getInstance().deleteContact(arrayList); - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } else if (id == add_member) { - Bundle args = new Bundle(); - args.putBoolean("onlyUsers", true); - args.putBoolean("destroyAfterSelect", true); - args.putBoolean("returnAsResult", true); - //args.putBoolean("allowUsernameSearch", false); - if (chat_id > 0) { - args.putString("selectAlertString", LocaleController.getString("AddToTheGroup", R.string.AddToTheGroup)); - } - ContactsActivity fragment = new ContactsActivity(args); - fragment.setDelegate(new ContactsActivity.ContactsActivityDelegate() { - @Override - public void didSelectContact(TLRPC.User user, String param) { - MessagesController.getInstance().addUserToChat(chat_id, user, info, param != null ? Utilities.parseInt(param) : 0); - } - }); - if (info != null) { - HashMap users = new HashMap<>(); - for (TLRPC.TL_chatParticipant p : info.participants) { - users.put(p.user_id, null); - } - fragment.setIgnoreUsers(users); - } - presentFragment(fragment); - } else if (id == leave_group) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setMessage(LocaleController.getString("AreYouSureDeleteAndExit", R.string.AreYouSureDeleteAndExit)); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - kickUser(null); - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } else if (id == edit_name) { - Bundle args = new Bundle(); - args.putInt("chat_id", chat_id); - presentFragment(new ChangeChatNameActivity(args)); - } - } - }); - - createActionBarMenu(); - - listAdapter = new ListAdapter(getParentActivity()); - - fragmentView = new FrameLayout(getParentActivity()); - FrameLayout frameLayout = (FrameLayout) fragmentView; - - avatarImage = new BackupImageView(getParentActivity()); - avatarImage.imageReceiver.setRoundRadius(AndroidUtilities.dp(30)); - avatarImage.processDetach = false; - actionBar.addView(avatarImage); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) avatarImage.getLayoutParams(); - layoutParams.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.BOTTOM; - layoutParams.width = AndroidUtilities.dp(60); - layoutParams.height = AndroidUtilities.dp(60); - layoutParams.leftMargin = LocaleController.isRTL ? 0 : AndroidUtilities.dp(17); - layoutParams.rightMargin = LocaleController.isRTL ? AndroidUtilities.dp(17) : 0; - layoutParams.bottomMargin = AndroidUtilities.dp(22); - avatarImage.setLayoutParams(layoutParams); - avatarImage.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (user_id != 0) { - TLRPC.User user = MessagesController.getInstance().getUser(user_id); - if (user.photo != null && user.photo.photo_big != null) { - PhotoViewer.getInstance().setParentActivity(getParentActivity()); - PhotoViewer.getInstance().openPhoto(user.photo.photo_big, ProfileActivity.this); - } - } else if (chat_id != 0) { - TLRPC.Chat chat = MessagesController.getInstance().getChat(chat_id); - if (chat.photo != null && chat.photo.photo_big != null) { - PhotoViewer.getInstance().setParentActivity(getParentActivity()); - PhotoViewer.getInstance().openPhoto(chat.photo.photo_big, ProfileActivity.this); - } - } - } - }); - - nameTextView = new TextView(getParentActivity()); - nameTextView.setTextColor(0xffffffff); - nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); - nameTextView.setLines(1); - nameTextView.setMaxLines(1); - nameTextView.setSingleLine(true); - nameTextView.setEllipsize(TextUtils.TruncateAt.END); - nameTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)); - nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); - actionBar.addView(nameTextView); - layoutParams = (FrameLayout.LayoutParams) nameTextView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? 16 : 97); - layoutParams.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? 97 : 16); - layoutParams.bottomMargin = AndroidUtilities.dp(51); - layoutParams.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.BOTTOM; - nameTextView.setLayoutParams(layoutParams); - - onlineTextView = new TextView(getParentActivity()); - onlineTextView.setTextColor(AvatarDrawable.getProfileTextColorForId(user_id != 0 ? 5 : chat_id)); - onlineTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); - onlineTextView.setLines(1); - onlineTextView.setMaxLines(1); - onlineTextView.setSingleLine(true); - onlineTextView.setEllipsize(TextUtils.TruncateAt.END); - onlineTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)); - actionBar.addView(onlineTextView); - layoutParams = (FrameLayout.LayoutParams) onlineTextView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? 16 : 97); - layoutParams.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? 97 : 16); - layoutParams.bottomMargin = AndroidUtilities.dp(30); - layoutParams.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.BOTTOM; - onlineTextView.setLayoutParams(layoutParams); - - listView = new ListView(getParentActivity()); - listView.setDivider(null); - listView.setDividerHeight(0); - listView.setVerticalScrollBarEnabled(false); - AndroidUtilities.setListViewEdgeEffectColor(listView, AvatarDrawable.getProfileBackColorForId(user_id != 0 ? 5 : chat_id)); - frameLayout.addView(listView); - layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.gravity = Gravity.TOP; - listView.setLayoutParams(layoutParams); - - listView.setAdapter(listAdapter); - listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, final int i, long l) { - if (getParentActivity() == null) { + }); + showAlertDialog(builder); + } else if (i > emptyRowChat2 && i < membersEndRow) { + int user_id = info.participants.get(sortedUsers.get(i - emptyRowChat2 - 1)).user_id; + if (user_id == UserConfig.getClientUserId()) { return; } - if (i == sharedMediaRow) { - Bundle args = new Bundle(); - if (user_id != 0) { - args.putLong("dialog_id", dialog_id != 0 ? dialog_id : user_id); - } else { - args.putLong("dialog_id", -chat_id); - } - presentFragment(new MediaActivity(args)); - } else if (i == settingsKeyRow) { - Bundle args = new Bundle(); - args.putInt("chat_id", (int)(dialog_id >> 32)); - presentFragment(new IdenticonActivity(args)); - } else if (i == settingsTimerRow) { + Bundle args = new Bundle(); + args.putInt("user_id", user_id); + presentFragment(new ProfileActivity(args)); + } + } + }); + if (chat_id != 0) { + listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView adapterView, View view, int i, long l) { + if (i > emptyRowChat2 && i < membersEndRow) { if (getParentActivity() == null) { - return; - } - showAlertDialog(AndroidUtilities.buildTTLAlert(getParentActivity(), currentEncryptedChat)); - } else if (i == settingsNotificationsRow) { - Bundle args = new Bundle(); - if (user_id != 0) { - args.putLong("dialog_id", dialog_id == 0 ? user_id : dialog_id); - } else if (chat_id != 0) { - args.putLong("dialog_id", -chat_id); - } - presentFragment(new ProfileNotificationsActivity(args)); - } else if (i == startSecretChatRow) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setMessage(LocaleController.getString("AreYouSureSecretChat", R.string.AreYouSureSecretChat)); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - creatingChat = true; - SecretChatHelper.getInstance().startSecretChat(getParentActivity(), MessagesController.getInstance().getUser(user_id)); - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } else if (i == phoneRow) { - final TLRPC.User user = MessagesController.getInstance().getUser(user_id); - if (user == null || user.phone == null || user.phone.length() == 0 || getParentActivity() == null) { - return; + return false; } + TLRPC.TL_chatParticipant user = info.participants.get(sortedUsers.get(i - emptyRowChat2 - 1)); + if (user.user_id == UserConfig.getClientUserId()) { + return false; + } + if (info.admin_id != UserConfig.getClientUserId() && user.inviter_id != UserConfig.getClientUserId()) { + return false; + } + selectedUser = user; + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setItems(new CharSequence[] {LocaleController.getString("Call", R.string.Call), LocaleController.getString("Copy", R.string.Copy)}, new DialogInterface.OnClickListener() { + CharSequence[] items = new CharSequence[]{chat_id > 0 ? LocaleController.getString("KickFromGroup", R.string.KickFromGroup) : LocaleController.getString("KickFromBroadcast", R.string.KickFromBroadcast)}; + + builder.setItems(items, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { if (i == 0) { - try { - Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:+" + user.phone)); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - getParentActivity().startActivity(intent); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } 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); - clipboard.setText("+" + user.phone); - } else { - android.content.ClipboardManager clipboard = (android.content.ClipboardManager)ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); - android.content.ClipData clip = android.content.ClipData.newPlainText("label", "+" + user.phone); - clipboard.setPrimaryClip(clip); - } + kickUser(selectedUser); } } }); showAlertDialog(builder); - } else if (i > emptyRowChat2 && i < membersEndRow) { - int user_id = info.participants.get(sortedUsers.get(i - emptyRowChat2 - 1)).user_id; - if (user_id == UserConfig.getClientUserId()) { + + return true; + } + return false; + } + }); + } + if (dialog_id != 0) { + SharedMediaQuery.getMediaCount(dialog_id, SharedMediaQuery.MEDIA_PHOTOVIDEO, classGuid, true); + } else { + SharedMediaQuery.getMediaCount(user_id, SharedMediaQuery.MEDIA_PHOTOVIDEO, classGuid, true); + } + + frameLayout.addView(actionBar); + + if (user_id != 0 || chat_id >= 0 && !currentChat.left) { + writeButton = new ImageView(context); + writeButton.setBackgroundResource(R.drawable.floating_user_states); + writeButton.setScaleType(ImageView.ScaleType.CENTER); + if (user_id != 0) { + writeButton.setImageResource(R.drawable.floating_message); + writeButton.setPadding(0, AndroidUtilities.dp(3), 0, 0); + } else if (chat_id != 0) { + writeButton.setImageResource(R.drawable.floating_camera); + } + frameLayout.addView(writeButton); + if (Build.VERSION.SDK_INT >= 21) { + StateListAnimator animator = new StateListAnimator(); + animator.addState(new int[]{android.R.attr.state_pressed}, ObjectAnimator.ofFloat(writeButton, "translationZ", AndroidUtilities.dp(2), AndroidUtilities.dp(4)).setDuration(200)); + animator.addState(new int[]{}, ObjectAnimator.ofFloat(writeButton, "translationZ", AndroidUtilities.dp(4), AndroidUtilities.dp(2)).setDuration(200)); + writeButton.setStateListAnimator(animator); + writeButton.setOutlineProvider(new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + outline.setOval(0, 0, AndroidUtilities.dp(56), AndroidUtilities.dp(56)); + } + }); + } + layoutParams = (FrameLayout.LayoutParams) writeButton.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? 16 : 0); + layoutParams.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? 0 : 16); + layoutParams.gravity = (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT); + writeButton.setLayoutParams(layoutParams); + writeButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (getParentActivity() == null) { + return; + } + if (user_id != 0) { + TLRPC.User user = MessagesController.getInstance().getUser(user_id); + if (user == null || user instanceof TLRPC.TL_userEmpty) { return; } + NotificationCenter.getInstance().removeObserver(ProfileActivity.this, NotificationCenter.closeChats); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); Bundle args = new Bundle(); args.putInt("user_id", user_id); - presentFragment(new ProfileActivity(args)); + presentFragment(new ChatActivity(args), true); + } else if (chat_id != 0) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + CharSequence[] items; + TLRPC.Chat chat = MessagesController.getInstance().getChat(chat_id); + if (chat.photo == null || chat.photo.photo_big == null || chat.photo instanceof TLRPC.TL_chatPhotoEmpty) { + items = new CharSequence[]{LocaleController.getString("FromCamera", R.string.FromCamera), LocaleController.getString("FromGalley", R.string.FromGalley)}; + } else { + items = new CharSequence[]{LocaleController.getString("FromCamera", R.string.FromCamera), LocaleController.getString("FromGalley", R.string.FromGalley), LocaleController.getString("DeletePhoto", R.string.DeletePhoto)}; + } + + builder.setItems(items, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + int action = 0; + if (i == 0) { + avatarUpdater.openCamera(); + } else if (i == 1) { + avatarUpdater.openGallery(); + } else if (i == 2) { + MessagesController.getInstance().changeChatAvatar(chat_id, null); + } + } + }); + showAlertDialog(builder); } } }); - if (chat_id != 0) { - listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { - @Override - public boolean onItemLongClick(AdapterView adapterView, View view, int i, long l) { - if (i > emptyRowChat2 && i < membersEndRow) { - if (getParentActivity() == null) { - return false; - } - - TLRPC.TL_chatParticipant user = info.participants.get(sortedUsers.get(i - emptyRowChat2 - 1)); - if (user.user_id == UserConfig.getClientUserId()) { - return false; - } - if (info.admin_id != UserConfig.getClientUserId() && user.inviter_id != UserConfig.getClientUserId()) { - return false; - } - selectedUser = user; - - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - CharSequence[] items = new CharSequence[]{chat_id > 0 ? LocaleController.getString("KickFromGroup", R.string.KickFromGroup) : LocaleController.getString("KickFromBroadcast", R.string.KickFromBroadcast)}; - - builder.setItems(items, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - if (i == 0) { - kickUser(selectedUser); - } - } - }); - showAlertDialog(builder); - - return true; - } - return false; - } - }); - } - if (dialog_id != 0) { - SharedMediaQuery.getMediaCount(dialog_id, SharedMediaQuery.MEDIA_PHOTOVIDEO, classGuid, true); - } else { - SharedMediaQuery.getMediaCount(user_id, SharedMediaQuery.MEDIA_PHOTOVIDEO, classGuid, true); - } - - frameLayout.addView(actionBar); - - if (user_id != 0 || chat_id >= 0 && !currentChat.left) { - writeButton = new ImageView(getParentActivity()); - writeButton.setBackgroundResource(R.drawable.floating_user_states); - writeButton.setScaleType(ImageView.ScaleType.CENTER); - if (user_id != 0) { - writeButton.setImageResource(R.drawable.floating_message); - writeButton.setPadding(0, AndroidUtilities.dp(3), 0, 0); - } else if (chat_id != 0) { - writeButton.setImageResource(R.drawable.floating_camera); - } - frameLayout.addView(writeButton); - if (Build.VERSION.SDK_INT >= 21) { - StateListAnimator animator = new StateListAnimator(); - animator.addState(new int[] {android.R.attr.state_pressed}, ObjectAnimator.ofFloat(writeButton, "translationZ", AndroidUtilities.dp(2), AndroidUtilities.dp(4)).setDuration(200)); - animator.addState(new int[] {}, ObjectAnimator.ofFloat(writeButton, "translationZ", AndroidUtilities.dp(4), AndroidUtilities.dp(2)).setDuration(200)); - writeButton.setStateListAnimator(animator); - writeButton.setOutlineProvider(new ViewOutlineProvider() { - @Override - public void getOutline(View view, Outline outline) { - outline.setOval(0, 0, AndroidUtilities.dp(56), AndroidUtilities.dp(56)); - } - }); - } - layoutParams = (FrameLayout.LayoutParams) writeButton.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? 16 : 0); - layoutParams.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? 0 : 16); - layoutParams.gravity = (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT); - writeButton.setLayoutParams(layoutParams); - writeButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (getParentActivity() == null) { - return; - } - if (user_id != 0) { - TLRPC.User user = MessagesController.getInstance().getUser(user_id); - if (user == null || user instanceof TLRPC.TL_userEmpty) { - return; - } - NotificationCenter.getInstance().removeObserver(ProfileActivity.this, NotificationCenter.closeChats); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); - Bundle args = new Bundle(); - args.putInt("user_id", user_id); - presentFragment(new ChatActivity(args), true); - } else if (chat_id != 0) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - CharSequence[] items; - TLRPC.Chat chat = MessagesController.getInstance().getChat(chat_id); - if (chat.photo == null || chat.photo.photo_big == null || chat.photo instanceof TLRPC.TL_chatPhotoEmpty) { - items = new CharSequence[]{LocaleController.getString("FromCamera", R.string.FromCamera), LocaleController.getString("FromGalley", R.string.FromGalley)}; - } else { - items = new CharSequence[]{LocaleController.getString("FromCamera", R.string.FromCamera), LocaleController.getString("FromGalley", R.string.FromGalley), LocaleController.getString("DeletePhoto", R.string.DeletePhoto)}; - } - - builder.setItems(items, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - int action = 0; - if (i == 0) { - avatarUpdater.openCamera(); - } else if (i == 1) { - avatarUpdater.openGallery(); - } else if (i == 2) { - MessagesController.getInstance().changeChatAvatar(chat_id, null); - } - } - }); - showAlertDialog(builder); - } - } - }); - } - - listView.setOnScrollListener(new AbsListView.OnScrollListener() { - @Override - public void onScrollStateChanged(AbsListView view, int scrollState) { - - } - - @Override - public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - checkListViewScroll(); - } - }); - - updateProfileData(); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); - } } + + listView.setOnScrollListener(new AbsListView.OnScrollListener() { + @Override + public void onScrollStateChanged(AbsListView view, int scrollState) { + + } + + @Override + public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { + checkListViewScroll(); + } + }); + return fragmentView; } @@ -715,9 +705,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. int avatarY = AndroidUtilities.dp(22) - (int)((AndroidUtilities.dp(22) - (AndroidUtilities.getCurrentActionBarHeight() - AndroidUtilities.dp(42)) / 2) * (1.0f - diff)); int nameX = 97 + (int)(21 * diffm); int nameEndX = 16 + (int)(32 * diffm); - float nameFontSize = 20 - 2 * diffm; int nameY = avatarY + AndroidUtilities.dp(29 - 10 * diffm); int statusY = avatarY + AndroidUtilities.dp(8 - 7 * diffm); + float scale = 1.0f - 0.12f * diffm; if (writeButton != null) { layoutParams = (FrameLayout.LayoutParams) writeButton.getLayoutParams(); @@ -730,7 +720,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } } - avatarImage.imageReceiver.setRoundRadius(AndroidUtilities.dp(avatarSize / 2)); + avatarImage.setRoundRadius(AndroidUtilities.dp(avatarSize / 2)); layoutParams = (FrameLayout.LayoutParams) avatarImage.getLayoutParams(); layoutParams.width = AndroidUtilities.dp(avatarSize); layoutParams.height = AndroidUtilities.dp(avatarSize); @@ -739,7 +729,10 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. layoutParams.bottomMargin = avatarY; avatarImage.setLayoutParams(layoutParams); - nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, nameFontSize); + ViewProxy.setPivotX(nameTextView, 0); + ViewProxy.setPivotY(nameTextView, 0); + ViewProxy.setScaleX(nameTextView, scale); + ViewProxy.setScaleY(nameTextView, scale); layoutParams = (FrameLayout.LayoutParams) nameTextView.getLayoutParams(); layoutParams.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? nameEndX : nameX); layoutParams.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? nameX : nameEndX); @@ -800,11 +793,13 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. updateProfileData(); } if ((mask & MessagesController.UPDATE_MASK_AVATAR) != 0 || (mask & MessagesController.UPDATE_MASK_NAME) != 0 || (mask & MessagesController.UPDATE_MASK_STATUS) != 0) { - int count = listView.getChildCount(); - for (int a = 0; a < count; a++) { - View child = listView.getChildAt(a); - if (child instanceof UserCell) { - ((UserCell) child).update(mask); + if (listView != null) { + int count = listView.getChildCount(); + for (int a = 0; a < count; a++) { + View child = listView.getChildAt(a); + if (child instanceof UserCell) { + ((UserCell) child).update(mask); + } } } } @@ -881,9 +876,15 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } + updateProfileData(); fixLayout(); } + @Override + public void updatePhotoAtIndex(int index) { + + } + @Override public PhotoViewer.PlaceProviderObject getPlaceForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index) { if (fileLocation == null) { @@ -911,11 +912,11 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. object.viewX = coords[0]; object.viewY = coords[1] - AndroidUtilities.statusBarHeight; object.parentView = avatarImage; - object.imageReceiver = avatarImage.imageReceiver; + object.imageReceiver = avatarImage.getImageReceiver(); object.user_id = user_id; object.thumb = object.imageReceiver.getBitmap(); object.size = -1; - object.radius = avatarImage.imageReceiver.getRoundRadius(); + object.radius = avatarImage.getImageReceiver().getRoundRadius(); return object; } return null; @@ -931,7 +932,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. @Override public void willHidePhotoViewer() { - avatarImage.imageReceiver.setVisible(true, true); + avatarImage.getImageReceiver().setVisible(true, true); } @Override @@ -1031,7 +1032,6 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. NotificationCenter.getInstance().removeObserver(this, NotificationCenter.closeChats); NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); MessagesController.getInstance().deleteUserFromChat(chat_id, MessagesController.getInstance().getUser(UserConfig.getClientUserId()), info); - MessagesController.getInstance().deleteDialog(-chat_id, 0, false); finishFragment(); } } @@ -1110,7 +1110,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } onlineTextView.setText(LocaleController.formatUserStatus(user)); - avatarImage.imageReceiver.setVisible(!PhotoViewer.getInstance().isShowingImage(photoBig), false); + avatarImage.getImageReceiver().setVisible(!PhotoViewer.getInstance().isShowingImage(photoBig), false); } else if (chat_id != 0) { TLRPC.Chat chat = MessagesController.getInstance().getChat(chat_id); if (chat != null) { @@ -1124,7 +1124,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } if (count != 0 && onlineCount > 1) { - onlineTextView.setText(Html.fromHtml(String.format("%s, %s", LocaleController.formatPluralString("Members", count), LocaleController.formatPluralString("Online", onlineCount)))); + onlineTextView.setText(String.format("%s, %s", LocaleController.formatPluralString("Members", count), LocaleController.formatPluralString("Online", onlineCount))); } else { onlineTextView.setText(LocaleController.formatPluralString("Members", count)); } @@ -1137,7 +1137,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } avatarImage.setImage(photo, "50_50", new AvatarDrawable(chat, true)); - avatarImage.imageReceiver.setVisible(!PhotoViewer.getInstance().isShowingImage(photoBig), false); + avatarImage.getImageReceiver().setVisible(!PhotoViewer.getInstance().isShowingImage(photoBig), false); } } @@ -1206,7 +1206,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. presentFragment(new ChatActivity(args), true); removeSelfFromStack(); TLRPC.User user = MessagesController.getInstance().getUser(user_id); - SendMessagesHelper.getInstance().sendMessage(user, dialog_id); + SendMessagesHelper.getInstance().sendMessage(user, dialog_id, null); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileNotificationsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileNotificationsActivity.java index 3675c7633..e845fd4de 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileNotificationsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileNotificationsActivity.java @@ -85,220 +85,214 @@ public class ProfileNotificationsActivity extends BaseFragment implements Notifi } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - actionBar.setTitle(LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + actionBar.setTitle(LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds)); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); } - }); - - fragmentView = new FrameLayout(getParentActivity()); - FrameLayout frameLayout = (FrameLayout) fragmentView; - - listView = new ListView(getParentActivity()); - listView.setDivider(null); - listView.setDividerHeight(0); - listView.setVerticalScrollBarEnabled(false); - AndroidUtilities.setListViewEdgeEffectColor(listView, AvatarDrawable.getProfileBackColorForId(5)); - frameLayout.addView(listView); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - listView.setLayoutParams(layoutParams); - listView.setAdapter(new ListAdapter(getParentActivity())); - listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, final int i, long l) { - if (i == settingsVibrateRow) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("Vibrate", R.string.Vibrate)); - builder.setItems(new CharSequence[] { - LocaleController.getString("Disabled", R.string.Disabled), - LocaleController.getString("SettingsDefault", R.string.SettingsDefault), - LocaleController.getString("SystemDefault", R.string.SystemDefault), - LocaleController.getString("Short", R.string.Short), - LocaleController.getString("Long", R.string.Long) - }, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - if (which == 0) { - editor.putInt("vibrate_" + dialog_id, 2); - } else if (which == 1) { - editor.putInt("vibrate_" + dialog_id, 0); - } else if (which == 2) { - editor.putInt("vibrate_" + dialog_id, 4); - } else if (which == 3) { - editor.putInt("vibrate_" + dialog_id, 1); - } else if (which == 4) { - editor.putInt("vibrate_" + dialog_id, 3); - } - editor.commit(); - if (listView != null) { - listView.invalidateViews(); - } - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } else if (i == settingsNotificationsRow) { - if (getParentActivity() == null) { - return; - } - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setItems(new CharSequence[] { - LocaleController.getString("Default", R.string.Default), - LocaleController.getString("Enabled", R.string.Enabled), - LocaleController.getString("Disabled", R.string.Disabled) - }, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface d, int which) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - editor.putInt("notify2_" + dialog_id, which); - MessagesStorage.getInstance().setDialogFlags(dialog_id, which == 2 ? 1 : 0); - editor.commit(); - TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(dialog_id); - if (dialog != null) { - dialog.notify_settings = new TLRPC.TL_peerNotifySettings(); - if (which == 2) { - dialog.notify_settings.mute_until = Integer.MAX_VALUE; - } - } - if (listView != null) { - listView.invalidateViews(); - } - NotificationsController.updateServerNotificationsSettings(dialog_id); - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } else if (i == settingsSoundRow) { - try { - Intent tmpIntent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER); - tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION); - tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true); - tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)); - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - Uri currentSound = null; - - String defaultPath = null; - Uri defaultUri = Settings.System.DEFAULT_NOTIFICATION_URI; - if (defaultUri != null) { - defaultPath = defaultUri.getPath(); - } - - String path = preferences.getString("sound_path_" + dialog_id, defaultPath); - if (path != null && !path.equals("NoSound")) { - if (path.equals(defaultPath)) { - currentSound = defaultUri; - } else { - currentSound = Uri.parse(path); - } - } - - tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, currentSound); - startActivityForResult(tmpIntent, 12); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } else if (i == settingsLedRow) { - if (getParentActivity() == null) { - return; - } - - LayoutInflater li = (LayoutInflater)getParentActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); - view = li.inflate(R.layout.settings_color_dialog_layout, null, false); - final ColorPickerView colorPickerView = (ColorPickerView)view.findViewById(R.id.color_picker); - - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - if (preferences.contains("color_" + dialog_id)) { - colorPickerView.setOldCenterColor(preferences.getInt("color_" + dialog_id, 0xff00ff00)); - } else { - if ((int)dialog_id < 0) { - colorPickerView.setOldCenterColor(preferences.getInt("GroupLed", 0xff00ff00)); - } else { - colorPickerView.setOldCenterColor(preferences.getInt("MessagesLed", 0xff00ff00)); - } - } - - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("LedColor", R.string.LedColor)); - builder.setView(view); - builder.setPositiveButton(LocaleController.getString("Set", R.string.Set), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int which) { - final SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - editor.putInt("color_" + dialog_id, colorPickerView.getColor()); - editor.commit(); - listView.invalidateViews(); - } - }); - builder.setNeutralButton(LocaleController.getString("Disabled", R.string.Disabled), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - final SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - editor.putInt("color_" + dialog_id, 0); - editor.commit(); - listView.invalidateViews(); - } - }); - builder.setNegativeButton(LocaleController.getString("Default", R.string.Default), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - final SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - editor.remove("color_" + dialog_id); - editor.commit(); - listView.invalidateViews(); - } - }); - showAlertDialog(builder); - } else if (i == settingsPriorityRow) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("NotificationsPriority", R.string.NotificationsPriority)); - builder.setItems(new CharSequence[] { - LocaleController.getString("SettingsDefault", R.string.SettingsDefault), - LocaleController.getString("NotificationsPriorityDefault", R.string.NotificationsPriorityDefault), - LocaleController.getString("NotificationsPriorityHigh", R.string.NotificationsPriorityHigh), - LocaleController.getString("NotificationsPriorityMax", R.string.NotificationsPriorityMax) - }, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - if (which == 0) { - which = 3; - } else { - which--; - } - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - preferences.edit().putInt("priority_" + dialog_id, which).commit(); - if (listView != null) { - listView.invalidateViews(); - } - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } - } - }); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); } - } + }); + + fragmentView = new FrameLayout(context); + FrameLayout frameLayout = (FrameLayout) fragmentView; + + listView = new ListView(context); + listView.setDivider(null); + listView.setDividerHeight(0); + listView.setVerticalScrollBarEnabled(false); + AndroidUtilities.setListViewEdgeEffectColor(listView, AvatarDrawable.getProfileBackColorForId(5)); + frameLayout.addView(listView); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + listView.setLayoutParams(layoutParams); + listView.setAdapter(new ListAdapter(context)); + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, final int i, long l) { + if (i == settingsVibrateRow) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("Vibrate", R.string.Vibrate)); + builder.setItems(new CharSequence[]{ + LocaleController.getString("VibrationDisabled", R.string.VibrationDisabled), + LocaleController.getString("SettingsDefault", R.string.SettingsDefault), + LocaleController.getString("SystemDefault", R.string.SystemDefault), + LocaleController.getString("Short", R.string.Short), + LocaleController.getString("Long", R.string.Long) + }, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + if (which == 0) { + editor.putInt("vibrate_" + dialog_id, 2); + } else if (which == 1) { + editor.putInt("vibrate_" + dialog_id, 0); + } else if (which == 2) { + editor.putInt("vibrate_" + dialog_id, 4); + } else if (which == 3) { + editor.putInt("vibrate_" + dialog_id, 1); + } else if (which == 4) { + editor.putInt("vibrate_" + dialog_id, 3); + } + editor.commit(); + if (listView != null) { + listView.invalidateViews(); + } + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } else if (i == settingsNotificationsRow) { + if (getParentActivity() == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setItems(new CharSequence[]{ + LocaleController.getString("Default", R.string.Default), + LocaleController.getString("Enabled", R.string.Enabled), + LocaleController.getString("NotificationsDisabled", R.string.NotificationsDisabled) + }, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface d, int which) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.putInt("notify2_" + dialog_id, which); + MessagesStorage.getInstance().setDialogFlags(dialog_id, which == 2 ? 1 : 0); + editor.commit(); + TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(dialog_id); + if (dialog != null) { + dialog.notify_settings = new TLRPC.TL_peerNotifySettings(); + if (which == 2) { + dialog.notify_settings.mute_until = Integer.MAX_VALUE; + } + } + if (listView != null) { + listView.invalidateViews(); + } + NotificationsController.updateServerNotificationsSettings(dialog_id); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } else if (i == settingsSoundRow) { + try { + Intent tmpIntent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER); + tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION); + tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true); + tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + Uri currentSound = null; + + String defaultPath = null; + Uri defaultUri = Settings.System.DEFAULT_NOTIFICATION_URI; + if (defaultUri != null) { + defaultPath = defaultUri.getPath(); + } + + String path = preferences.getString("sound_path_" + dialog_id, defaultPath); + if (path != null && !path.equals("NoSound")) { + if (path.equals(defaultPath)) { + currentSound = defaultUri; + } else { + currentSound = Uri.parse(path); + } + } + + tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, currentSound); + startActivityForResult(tmpIntent, 12); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } else if (i == settingsLedRow) { + if (getParentActivity() == null) { + return; + } + + LayoutInflater li = (LayoutInflater) getParentActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + view = li.inflate(R.layout.settings_color_dialog_layout, null, false); + final ColorPickerView colorPickerView = (ColorPickerView) view.findViewById(R.id.color_picker); + + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + if (preferences.contains("color_" + dialog_id)) { + colorPickerView.setOldCenterColor(preferences.getInt("color_" + dialog_id, 0xff00ff00)); + } else { + if ((int) dialog_id < 0) { + colorPickerView.setOldCenterColor(preferences.getInt("GroupLed", 0xff00ff00)); + } else { + colorPickerView.setOldCenterColor(preferences.getInt("MessagesLed", 0xff00ff00)); + } + } + + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("LedColor", R.string.LedColor)); + builder.setView(view); + builder.setPositiveButton(LocaleController.getString("Set", R.string.Set), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int which) { + final SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.putInt("color_" + dialog_id, colorPickerView.getColor()); + editor.commit(); + listView.invalidateViews(); + } + }); + builder.setNeutralButton(LocaleController.getString("LedDisabled", R.string.LedDisabled), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + final SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.putInt("color_" + dialog_id, 0); + editor.commit(); + listView.invalidateViews(); + } + }); + builder.setNegativeButton(LocaleController.getString("Default", R.string.Default), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + final SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.remove("color_" + dialog_id); + editor.commit(); + listView.invalidateViews(); + } + }); + showAlertDialog(builder); + } else if (i == settingsPriorityRow) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("NotificationsPriority", R.string.NotificationsPriority)); + builder.setItems(new CharSequence[]{ + LocaleController.getString("SettingsDefault", R.string.SettingsDefault), + LocaleController.getString("NotificationsPriorityDefault", R.string.NotificationsPriorityDefault), + LocaleController.getString("NotificationsPriorityHigh", R.string.NotificationsPriorityHigh), + LocaleController.getString("NotificationsPriorityMax", R.string.NotificationsPriorityMax) + }, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if (which == 0) { + which = 3; + } else { + which--; + } + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + preferences.edit().putInt("priority_" + dialog_id, which).commit(); + if (listView != null) { + listView.invalidateViews(); + } + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } + } + }); + return fragmentView; } @@ -314,7 +308,7 @@ public class ProfileNotificationsActivity extends BaseFragment implements Notifi Ringtone rng = RingtoneManager.getRingtone(ApplicationLoader.applicationContext, ringtone); if (rng != null) { if(ringtone.equals(Settings.System.DEFAULT_NOTIFICATION_URI)) { - name = LocaleController.getString("Default", R.string.Default); + name = LocaleController.getString("SoundDefault", R.string.SoundDefault); } else { name = rng.getTitle(getParentActivity()); } @@ -402,7 +396,7 @@ public class ProfileNotificationsActivity extends BaseFragment implements Notifi } else if (value == 1) { textCell.setTextAndValue(LocaleController.getString("Vibrate", R.string.Vibrate), LocaleController.getString("Short", R.string.Short), true); } else if (value == 2) { - textCell.setTextAndValue(LocaleController.getString("Vibrate", R.string.Vibrate), LocaleController.getString("Disabled", R.string.Disabled), true); + textCell.setTextAndValue(LocaleController.getString("Vibrate", R.string.Vibrate), LocaleController.getString("VibrationDisabled", R.string.VibrationDisabled), true); } else if (value == 3) { textCell.setTextAndValue(LocaleController.getString("Vibrate", R.string.Vibrate), LocaleController.getString("Long", R.string.Long), true); } else if (value == 4) { @@ -415,7 +409,7 @@ public class ProfileNotificationsActivity extends BaseFragment implements Notifi } else if (value == 1) { textCell.setTextAndValue(LocaleController.getString("Notifications", R.string.Notifications), LocaleController.getString("Enabled", R.string.Enabled), true); } else if (value == 2) { - textCell.setTextAndValue(LocaleController.getString("Notifications", R.string.Notifications), LocaleController.getString("Disabled", R.string.Disabled), true); + textCell.setTextAndValue(LocaleController.getString("Notifications", R.string.Notifications), LocaleController.getString("NotificationsDisabled", R.string.NotificationsDisabled), true); } else if (value == 3) { int delta = preferences.getInt("notifyuntil_" + dialog_id, 0) - ConnectionsManager.getInstance().getCurrentTime(); String val; @@ -425,13 +419,19 @@ public class ProfileNotificationsActivity extends BaseFragment implements Notifi val = LocaleController.formatString("WillUnmuteIn", R.string.WillUnmuteIn, LocaleController.formatPluralString("Minutes", delta / 60)); } else if (delta < 60 * 60 * 24) { val = LocaleController.formatString("WillUnmuteIn", R.string.WillUnmuteIn, LocaleController.formatPluralString("Hours", (int) Math.ceil(delta / 60.0f / 60))); - } else { + } else if (delta < 60 * 60 * 24 * 365) { val = LocaleController.formatString("WillUnmuteIn", R.string.WillUnmuteIn, LocaleController.formatPluralString("Days", (int) Math.ceil(delta / 60.0f / 60 / 24))); + } else { + val = null; + } + if (val != null) { + textCell.setTextAndValue(LocaleController.getString("Notifications", R.string.Notifications), val, true); + } else { + textCell.setTextAndValue(LocaleController.getString("Notifications", R.string.Notifications), LocaleController.getString("NotificationsDisabled", R.string.NotificationsDisabled), true); } - textCell.setTextAndValue(LocaleController.getString("Notifications", R.string.Notifications), val, true); } } else if (i == settingsSoundRow) { - String value = preferences.getString("sound_" + dialog_id, LocaleController.getString("Default", R.string.Default)); + String value = preferences.getString("sound_" + dialog_id, LocaleController.getString("SoundDefault", R.string.SoundDefault)); if (value.equals("NoSound")) { value = LocaleController.getString("NoSound", R.string.NoSound); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SecretPhotoViewer.java b/TMessagesProj/src/main/java/org/telegram/ui/SecretPhotoViewer.java index ef77d39e2..ee5928a7e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SecretPhotoViewer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SecretPhotoViewer.java @@ -176,7 +176,7 @@ public class SecretPhotoViewer implements NotificationCenter.NotificationCenterD return; } ArrayList markAsDeletedMessages = (ArrayList)args[0]; - if (markAsDeletedMessages.contains(currentMessageObject.messageOwner.id)) { + if (markAsDeletedMessages.contains(currentMessageObject.getId())) { closePhoto(); } } else if (id == NotificationCenter.didCreatedNewDeleteTask) { @@ -188,7 +188,7 @@ public class SecretPhotoViewer implements NotificationCenter.NotificationCenterD int key = mids.keyAt(i); ArrayList arr = mids.get(key); for (Integer mid : arr) { - if (currentMessageObject.messageOwner.id == mid) { + if (currentMessageObject.getId() == mid) { currentMessageObject.messageOwner.destroyTime = key; secretDeleteTimer.invalidate(); return; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SessionsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/SessionsActivity.java new file mode 100644 index 000000000..fb90c3100 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/SessionsActivity.java @@ -0,0 +1,475 @@ +/* + * This is the source code of Telegram for Android v. 2.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-2015. + */ + +package org.telegram.ui; + +import android.app.AlertDialog; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.os.Build; +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.AbsListView; +import android.widget.AdapterView; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; + +import org.telegram.android.AndroidUtilities; +import org.telegram.android.LocaleController; +import org.telegram.android.MessagesController; +import org.telegram.android.NotificationCenter; +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.BaseFragment; +import org.telegram.ui.Adapters.BaseFragmentAdapter; +import org.telegram.ui.Cells.HeaderCell; +import org.telegram.ui.Cells.SessionCell; +import org.telegram.ui.Cells.TextInfoPrivacyCell; +import org.telegram.ui.Cells.TextSettingsCell; + +import java.util.ArrayList; + +public class SessionsActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate { + + private ListAdapter listAdapter; + private ArrayList sessions = new ArrayList<>(); + private TLRPC.TL_authorization currentSession = null; + private boolean loading; + private LinearLayout emptyLayout; + + private int currentSessionSectionRow; + private int currentSessionRow; + private int terminateAllSessionsRow; + private int terminateAllSessionsDetailRow; + private int otherSessionsSectionRow; + private int otherSessionsStartRow; + private int otherSessionsEndRow; + private int otherSessionsTerminateDetail; + private int noOtherSessionsRow; + private int rowCount; + + @Override + public boolean onFragmentCreate() { + super.onFragmentCreate(); + updateRows(); + loadSessions(false); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.newSessionReceived); + return true; + } + + @Override + public void onFragmentDestroy() { + super.onFragmentDestroy(); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.newSessionReceived); + } + + @Override + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + actionBar.setTitle(LocaleController.getString("SessionsTitle", R.string.SessionsTitle)); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } + } + }); + + listAdapter = new ListAdapter(context); + + fragmentView = new FrameLayout(context); + FrameLayout frameLayout = (FrameLayout) fragmentView; + frameLayout.setBackgroundColor(0xfff0f0f0); + + emptyLayout = new LinearLayout(context); + emptyLayout.setOrientation(LinearLayout.VERTICAL); + emptyLayout.setGravity(Gravity.CENTER); + emptyLayout.setBackgroundResource(R.drawable.greydivider_bottom); + emptyLayout.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, AndroidUtilities.displaySize.y - AndroidUtilities.getCurrentActionBarHeight())); + + ImageView imageView = new ImageView(context); + imageView.setImageResource(R.drawable.devices); + emptyLayout.addView(imageView); + LinearLayout.LayoutParams layoutParams2 = (LinearLayout.LayoutParams) imageView.getLayoutParams(); + layoutParams2.width = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.height = LinearLayout.LayoutParams.WRAP_CONTENT; + imageView.setLayoutParams(layoutParams2); + + TextView textView = new TextView(context); + textView.setTextColor(0xff8a8a8a); + textView.setGravity(Gravity.CENTER); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 17); + textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + textView.setText(LocaleController.getString("NoOtherSessions", R.string.NoOtherSessions)); + emptyLayout.addView(textView); + layoutParams2 = (LinearLayout.LayoutParams) textView.getLayoutParams(); + layoutParams2.topMargin = AndroidUtilities.dp(16); + layoutParams2.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.gravity = Gravity.CENTER; + textView.setLayoutParams(layoutParams2); + + textView = new TextView(context); + textView.setTextColor(0xff8a8a8a); + textView.setGravity(Gravity.CENTER); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 17); + textView.setPadding(AndroidUtilities.dp(20), 0, AndroidUtilities.dp(20), 0); + textView.setText(LocaleController.getString("NoOtherSessionsInfo", R.string.NoOtherSessionsInfo)); + emptyLayout.addView(textView); + layoutParams2 = (LinearLayout.LayoutParams) textView.getLayoutParams(); + layoutParams2.topMargin = AndroidUtilities.dp(14); + layoutParams2.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams2.gravity = Gravity.CENTER; + textView.setLayoutParams(layoutParams2); + + FrameLayout progressView = new FrameLayout(context); + frameLayout.addView(progressView); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + progressView.setLayoutParams(layoutParams); + progressView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + ProgressBar progressBar = new ProgressBar(context); + progressView.addView(progressBar); + layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.CENTER; + progressView.setLayoutParams(layoutParams); + + ListView listView = new ListView(context); + listView.setDivider(null); + listView.setDividerHeight(0); + listView.setVerticalScrollBarEnabled(false); + listView.setDrawSelectorOnTop(true); + listView.setEmptyView(progressView); + frameLayout.addView(listView); + layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP; + listView.setLayoutParams(layoutParams); + listView.setAdapter(listAdapter); + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, final int i, long l) { + if (i == terminateAllSessionsRow) { + if (getParentActivity() == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.getString("AreYouSureSessions", R.string.AreYouSureSessions)); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + TLRPC.TL_auth_resetAuthorizations req = new TLRPC.TL_auth_resetAuthorizations(); + 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 (getParentActivity() == null) { + return; + } + if (error == null && response instanceof TLRPC.TL_boolTrue) { + Toast toast = Toast.makeText(getParentActivity(), LocaleController.getString("TerminateAllSessions", R.string.TerminateAllSessions), Toast.LENGTH_SHORT); + toast.show(); + } else { + Toast toast = Toast.makeText(getParentActivity(), LocaleController.getString("UnknownError", R.string.UnknownError), Toast.LENGTH_SHORT); + toast.show(); + } + finishFragment(); + } + }); + UserConfig.registeredForPush = false; + UserConfig.registeredForInternalPush = false; + UserConfig.saveConfig(false); + MessagesController.getInstance().registerForPush(UserConfig.pushString); + ConnectionsManager.getInstance().initPushConnection(); + } + }); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } else if (i >= otherSessionsStartRow && i < otherSessionsEndRow) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.getString("TerminateSessionQuestion", R.string.TerminateSessionQuestion)); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int option) { + final ProgressDialog progressDialog = new ProgressDialog(getParentActivity()); + progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.setCancelable(false); + progressDialog.show(); + + final TLRPC.TL_authorization authorization = sessions.get(i - otherSessionsStartRow); + TLRPC.TL_account_resetAuthorization req = new TLRPC.TL_account_resetAuthorization(); + req.hash = authorization.hash; + 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() { + try { + progressDialog.dismiss(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + if (error == null) { + sessions.remove(authorization); + updateRows(); + if (listAdapter != null) { + listAdapter.notifyDataSetChanged(); + } + } + } + }); + } + }); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } + } + }); + + return fragmentView; + } + + @Override + public void onResume() { + super.onResume(); + if (listAdapter != null) { + listAdapter.notifyDataSetChanged(); + } + } + + @Override + public void didReceivedNotification(int id, Object... args) { + if (id == NotificationCenter.newSessionReceived) { + loadSessions(true); + } + } + + private void loadSessions(boolean silent) { + if (loading) { + return; + } + if (!silent) { + loading = true; + } + TLRPC.TL_account_getAuthorizations req = new TLRPC.TL_account_getAuthorizations(); + 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() { + loading = false; + if (error == null) { + sessions.clear(); + TLRPC.TL_account_authorizations res = (TLRPC.TL_account_authorizations) response; + for (TLRPC.TL_authorization authorization : res.authorizations) { + if ((authorization.flags & 1) != 0) { + currentSession = authorization; + } else { + sessions.add(authorization); + } + } + updateRows(); + } + if (listAdapter != null) { + listAdapter.notifyDataSetChanged(); + } + } + }); + } + }); + ConnectionsManager.getInstance().bindRequestToGuid(reqId, classGuid); + } + + private void updateRows() { + rowCount = 0; + if (currentSession != null) { + currentSessionSectionRow = rowCount++; + currentSessionRow = rowCount++; + } else { + currentSessionRow = -1; + currentSessionSectionRow = -1; + } + if (sessions.isEmpty()) { + noOtherSessionsRow = -1; + terminateAllSessionsRow = -1; + terminateAllSessionsDetailRow = -1; + otherSessionsSectionRow = -1; + otherSessionsStartRow = -1; + otherSessionsEndRow = -1; + otherSessionsTerminateDetail = -1; + } else { + noOtherSessionsRow = -1; + terminateAllSessionsRow = rowCount++; + terminateAllSessionsDetailRow = rowCount++; + otherSessionsSectionRow = rowCount++; + otherSessionsStartRow = otherSessionsSectionRow + 1; + otherSessionsEndRow = otherSessionsStartRow + sessions.size(); + rowCount += sessions.size(); + otherSessionsTerminateDetail = rowCount++; + } + } + + private class ListAdapter extends BaseFragmentAdapter { + private Context mContext; + + public ListAdapter(Context context) { + mContext = context; + } + + @Override + public boolean areAllItemsEnabled() { + return false; + } + + @Override + public boolean isEnabled(int i) { + return i == terminateAllSessionsRow || i >= otherSessionsStartRow && i < otherSessionsEndRow; + } + + @Override + public int getCount() { + return loading ? 0 : rowCount; + } + + @Override + public Object getItem(int i) { + return null; + } + + @Override + public long getItemId(int i) { + return i; + } + + @Override + public boolean hasStableIds() { + return false; + } + + @Override + public View getView(int i, View view, ViewGroup viewGroup) { + int type = getItemViewType(i); + if (type == 0) { + if (view == null) { + view = new TextSettingsCell(mContext); + view.setBackgroundColor(0xffffffff); + } + TextSettingsCell textCell = (TextSettingsCell) view; + if (i == terminateAllSessionsRow) { + textCell.setTextColor(0xffdb5151); + textCell.setText(LocaleController.getString("TerminateAllSessions", R.string.TerminateAllSessions), false); + } + } else if (type == 1) { + if (view == null) { + view = new TextInfoPrivacyCell(mContext); + } + if (i == terminateAllSessionsDetailRow) { + ((TextInfoPrivacyCell) view).setText(LocaleController.getString("ClearOtherSessionsHelp", R.string.ClearOtherSessionsHelp)); + view.setBackgroundResource(R.drawable.greydivider); + } else if (i == otherSessionsTerminateDetail) { + ((TextInfoPrivacyCell) view).setText(LocaleController.getString("TerminateSessionInfo", R.string.TerminateSessionInfo)); + view.setBackgroundResource(R.drawable.greydivider_bottom); + } + } else if (type == 2) { + if (view == null) { + view = new HeaderCell(mContext); + view.setBackgroundColor(0xffffffff); + } + if (i == currentSessionSectionRow) { + ((HeaderCell) view).setText(LocaleController.getString("CurrentSession", R.string.CurrentSession)); + } else if (i == otherSessionsSectionRow) { + ((HeaderCell) view).setText(LocaleController.getString("OtherSessions", R.string.OtherSessions)); + } + } else if (type == 3) { + ViewGroup.LayoutParams layoutParams = emptyLayout.getLayoutParams(); + if (layoutParams != null) { + layoutParams.height = Math.max(AndroidUtilities.dp(220), AndroidUtilities.displaySize.y - AndroidUtilities.getCurrentActionBarHeight() - AndroidUtilities.dp(128) - (Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0)); + emptyLayout.setLayoutParams(layoutParams); + } + return emptyLayout; + } else if (type == 4) { + if (view == null) { + view = new SessionCell(mContext); + view.setBackgroundColor(0xffffffff); + } + if (i == currentSessionRow) { + ((SessionCell) view).setSession(currentSession, !sessions.isEmpty()); + } else { + ((SessionCell) view).setSession(sessions.get(i - otherSessionsStartRow), i != otherSessionsEndRow - 1); + } + } + return view; + } + + @Override + public int getItemViewType(int i) { + if (i == terminateAllSessionsRow) { + return 0; + } else if (i == terminateAllSessionsDetailRow || i == otherSessionsTerminateDetail) { + return 1; + } else if (i == currentSessionSectionRow || i == otherSessionsSectionRow) { + return 2; + } else if (i == noOtherSessionsRow) { + return 3; + } else if (i == currentSessionRow || i >= otherSessionsStartRow && i < otherSessionsEndRow) { + return 4; + } + return 0; + } + + @Override + public int getViewTypeCount() { + return 5; + } + + @Override + public boolean isEmpty() { + return loading; + } + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java index 31efa3080..f6ac527a5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java @@ -254,6 +254,9 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter @Override public void onFragmentDestroy() { super.onFragmentDestroy(); + if (avatarImage != null) { + avatarImage.setImageDrawable(null); + } MessagesController.getInstance().cancelLoadFullUser(UserConfig.getClientUserId()); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.updateInterfaces); avatarUpdater.clear(); @@ -265,439 +268,430 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackgroundColor(AvatarDrawable.getProfileBackColorForId(5)); - actionBar.setItemsBackground(AvatarDrawable.getButtonColorForId(5)); - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setExtraHeight(AndroidUtilities.dp(88), false); - if (AndroidUtilities.isTablet()) { - actionBar.setOccupyStatusBar(false); + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackgroundColor(AvatarDrawable.getProfileBackColorForId(5)); + actionBar.setItemsBackground(AvatarDrawable.getButtonColorForId(5)); + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setExtraHeight(AndroidUtilities.dp(88), false); + if (AndroidUtilities.isTablet()) { + actionBar.setOccupyStatusBar(false); + } + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } else if (id == edit_name) { + presentFragment(new ChangeNameActivity()); + } else if (id == logout) { + if (getParentActivity() == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.getString("AreYouSureLogout", R.string.AreYouSureLogout)); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.clear().commit(); + MessagesController.getInstance().unregistedPush(); + MessagesController.getInstance().logOut(); + UserConfig.clearConfig(); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.appDidLogout); + MessagesStorage.getInstance().cleanUp(false); + MessagesController.getInstance().cleanUp(); + ContactsController.getInstance().deleteAllAppAccounts(); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } } - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } else if (id == edit_name) { - presentFragment(new ChangeNameActivity()); - } else if (id == logout) { - if (getParentActivity() == null) { - return; - } - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setMessage(LocaleController.getString("AreYouSureLogout", R.string.AreYouSureLogout)); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - editor.clear().commit(); - MessagesController.getInstance().unregistedPush(); - MessagesController.getInstance().logOut(); - UserConfig.clearConfig(); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.appDidLogout); - MessagesStorage.getInstance().cleanUp(false); - MessagesController.getInstance().cleanUp(); - ContactsController.getInstance().deleteAllAppAccounts(); - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } + }); + ActionBarMenu menu = actionBar.createMenu(); + ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_other); + item.addSubItem(edit_name, LocaleController.getString("EditName", R.string.EditName), 0); + item.addSubItem(logout, LocaleController.getString("LogOut", R.string.LogOut), 0); + + listAdapter = new ListAdapter(context); + + fragmentView = new FrameLayout(context); + FrameLayout frameLayout = (FrameLayout) fragmentView; + + avatarImage = new BackupImageView(context); + avatarImage.setRoundRadius(AndroidUtilities.dp(30)); + actionBar.addView(avatarImage); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) avatarImage.getLayoutParams(); + layoutParams.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.BOTTOM; + layoutParams.width = AndroidUtilities.dp(60); + layoutParams.height = AndroidUtilities.dp(60); + layoutParams.leftMargin = LocaleController.isRTL ? 0 : AndroidUtilities.dp(17); + layoutParams.rightMargin = LocaleController.isRTL ? AndroidUtilities.dp(17) : 0; + layoutParams.bottomMargin = AndroidUtilities.dp(22); + avatarImage.setLayoutParams(layoutParams); + avatarImage.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + TLRPC.User user = MessagesController.getInstance().getUser(UserConfig.getClientUserId()); + if (user.photo != null && user.photo.photo_big != null) { + PhotoViewer.getInstance().setParentActivity(getParentActivity()); + PhotoViewer.getInstance().openPhoto(user.photo.photo_big, SettingsActivity.this); } - }); - ActionBarMenu menu = actionBar.createMenu(); - ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_other); - item.addSubItem(edit_name, LocaleController.getString("EditName", R.string.EditName), 0); - item.addSubItem(logout, LocaleController.getString("LogOut", R.string.LogOut), 0); - - listAdapter = new ListAdapter(getParentActivity()); - - fragmentView = new FrameLayout(getParentActivity()); - FrameLayout frameLayout = (FrameLayout) fragmentView; - - avatarImage = new BackupImageView(getParentActivity()); - avatarImage.imageReceiver.setRoundRadius(AndroidUtilities.dp(30)); - avatarImage.processDetach = false; - actionBar.addView(avatarImage); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) avatarImage.getLayoutParams(); - layoutParams.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.BOTTOM; - layoutParams.width = AndroidUtilities.dp(60); - layoutParams.height = AndroidUtilities.dp(60); - layoutParams.leftMargin = LocaleController.isRTL ? 0 : AndroidUtilities.dp(17); - layoutParams.rightMargin = LocaleController.isRTL ? AndroidUtilities.dp(17) : 0; - layoutParams.bottomMargin = AndroidUtilities.dp(22); - avatarImage.setLayoutParams(layoutParams); - avatarImage.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - TLRPC.User user = MessagesController.getInstance().getUser(UserConfig.getClientUserId()); - if (user.photo != null && user.photo.photo_big != null) { - PhotoViewer.getInstance().setParentActivity(getParentActivity()); - PhotoViewer.getInstance().openPhoto(user.photo.photo_big, SettingsActivity.this); - } - } - }); - - nameTextView = new TextView(getParentActivity()); - nameTextView.setTextColor(0xffffffff); - nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); - nameTextView.setLines(1); - nameTextView.setMaxLines(1); - nameTextView.setSingleLine(true); - nameTextView.setEllipsize(TextUtils.TruncateAt.END); - nameTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)); - nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); - actionBar.addView(nameTextView); - layoutParams = (FrameLayout.LayoutParams) nameTextView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? 16 : 97); - layoutParams.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? 97 : 16); - layoutParams.bottomMargin = AndroidUtilities.dp(51); - layoutParams.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.BOTTOM; - nameTextView.setLayoutParams(layoutParams); - - onlineTextView = new TextView(getParentActivity()); - onlineTextView.setTextColor(AvatarDrawable.getProfileTextColorForId(5)); - onlineTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); - onlineTextView.setLines(1); - onlineTextView.setMaxLines(1); - onlineTextView.setSingleLine(true); - onlineTextView.setEllipsize(TextUtils.TruncateAt.END); - onlineTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)); - actionBar.addView(onlineTextView); - layoutParams = (FrameLayout.LayoutParams) onlineTextView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? 16 : 97); - layoutParams.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? 97 : 16); - layoutParams.bottomMargin = AndroidUtilities.dp(30); - layoutParams.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.BOTTOM; - onlineTextView.setLayoutParams(layoutParams); - - listView = new ListView(getParentActivity()); - listView.setDivider(null); - listView.setDividerHeight(0); - listView.setVerticalScrollBarEnabled(false); - AndroidUtilities.setListViewEdgeEffectColor(listView, AvatarDrawable.getProfileBackColorForId(5)); - frameLayout.addView(listView); - layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.gravity = Gravity.TOP; - listView.setLayoutParams(layoutParams); - listView.setAdapter(listAdapter); - listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, final int i, long l) { - if (i == textSizeRow) { - if (getParentActivity() == null) { - return; - } - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("TextSize", R.string.TextSize)); - final NumberPicker numberPicker = new NumberPicker(getParentActivity()); - numberPicker.setMinValue(12); - numberPicker.setMaxValue(30); - numberPicker.setValue(MessagesController.getInstance().fontSize); - builder.setView(numberPicker); - builder.setNegativeButton(LocaleController.getString("Done", R.string.Done), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - editor.putInt("fons_size", numberPicker.getValue()); - MessagesController.getInstance().fontSize = numberPicker.getValue(); - editor.commit(); - if (listView != null) { - listView.invalidateViews(); - } - } - }); - showAlertDialog(builder); - } else if (i == enableAnimationsRow) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); - boolean animations = preferences.getBoolean("view_animations", true); - SharedPreferences.Editor editor = preferences.edit(); - editor.putBoolean("view_animations", !animations); - editor.commit(); - if (view instanceof TextCheckCell) { - ((TextCheckCell) view).setChecked(!animations); - } - } else if (i == notificationRow) { - presentFragment(new NotificationsSettingsActivity()); - } else if (i == backgroundRow) { - presentFragment(new WallpapersActivity()); - } else if (i == askQuestionRow) { - if (getParentActivity() == null) { - return; - } - final TextView message = new TextView(getParentActivity()); - message.setText(Html.fromHtml(LocaleController.getString("AskAQuestionInfo", R.string.AskAQuestionInfo))); - message.setTextSize(18); - message.setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(5), AndroidUtilities.dp(8), AndroidUtilities.dp(6)); - message.setMovementMethod(new LinkMovementMethodMy()); - - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setView(message); - builder.setPositiveButton(LocaleController.getString("AskButton", R.string.AskButton), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - performAskAQuestion(); - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } else if (i == sendLogsRow) { - sendLogs(); - } else if (i == clearLogsRow) { - FileLog.cleanupLogs(); - } else if (i == sendByEnterRow) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); - boolean send = preferences.getBoolean("send_by_enter", false); - SharedPreferences.Editor editor = preferences.edit(); - editor.putBoolean("send_by_enter", !send); - editor.commit(); - if (view instanceof TextCheckCell) { - ((TextCheckCell) view).setChecked(!send); - } - } else if (i == saveToGalleryRow) { - MediaController.getInstance().toggleSaveToGallery(); - if (view instanceof TextCheckCell) { - ((TextCheckCell) view).setChecked(MediaController.getInstance().canSaveToGallery()); - } - } else if (i == privacyRow) { - presentFragment(new PrivacySettingsActivity()); - } else if (i == languageRow) { - presentFragment(new LanguageSelectActivity()); - } else if (i == switchBackendButtonRow) { - if (getParentActivity() == null) { - return; - } - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setMessage(LocaleController.getString("AreYouSure", R.string.AreYouSure)); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - ConnectionsManager.getInstance().switchBackend(); - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } else if (i == telegramFaqRow) { - try { - Intent pickIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(LocaleController.getString("TelegramFaqUrl", R.string.TelegramFaqUrl))); - getParentActivity().startActivity(pickIntent); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } else if (i == contactsReimportRow) { - - } else if (i == contactsSortRow) { - if (getParentActivity() == null) { - return; - } - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("SortBy", R.string.SortBy)); - builder.setItems(new CharSequence[] { - LocaleController.getString("Default", R.string.Default), - LocaleController.getString("SortFirstName", R.string.SortFirstName), - LocaleController.getString("SortLastName", R.string.SortLastName) - }, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - editor.putInt("sortContactsBy", which); - editor.commit(); - if (listView != null) { - listView.invalidateViews(); - } - } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showAlertDialog(builder); - } else if (i == wifiDownloadRow || i == mobileDownloadRow || i == roamingDownloadRow) { - if (getParentActivity() == null) { - return; - } - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - - int mask = 0; - if (i == mobileDownloadRow) { - builder.setTitle(LocaleController.getString("WhenUsingMobileData", R.string.WhenUsingMobileData)); - mask = MediaController.getInstance().mobileDataDownloadMask; - } else if (i == wifiDownloadRow) { - builder.setTitle(LocaleController.getString("WhenConnectedOnWiFi", R.string.WhenConnectedOnWiFi)); - mask = MediaController.getInstance().wifiDownloadMask; - } else if (i == roamingDownloadRow) { - builder.setTitle(LocaleController.getString("WhenRoaming", R.string.WhenRoaming)); - mask = MediaController.getInstance().roamingDownloadMask; - } - builder.setMultiChoiceItems( - new CharSequence[]{LocaleController.getString("AttachPhoto", R.string.AttachPhoto), LocaleController.getString("AttachAudio", R.string.AttachAudio), LocaleController.getString("AttachVideo", R.string.AttachVideo), LocaleController.getString("AttachDocument", R.string.AttachDocument)}, - new boolean[]{(mask & MediaController.AUTODOWNLOAD_MASK_PHOTO) != 0, (mask & MediaController.AUTODOWNLOAD_MASK_AUDIO) != 0, (mask & MediaController.AUTODOWNLOAD_MASK_VIDEO) != 0, (mask & MediaController.AUTODOWNLOAD_MASK_DOCUMENT) != 0}, - new DialogInterface.OnMultiChoiceClickListener() { - @Override - public void onClick(DialogInterface dialog, int which, boolean isChecked) { - int mask = 0; - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - if (i == mobileDownloadRow) { - mask = MediaController.getInstance().mobileDataDownloadMask; - } else if (i == wifiDownloadRow) { - mask = MediaController.getInstance().wifiDownloadMask; - } else if (i == roamingDownloadRow) { - mask = MediaController.getInstance().roamingDownloadMask; - } - - int maskDiff = 0; - if (which == 0) { - maskDiff = MediaController.AUTODOWNLOAD_MASK_PHOTO; - } else if (which == 1) { - maskDiff = MediaController.AUTODOWNLOAD_MASK_AUDIO; - } else if (which == 2) { - maskDiff = MediaController.AUTODOWNLOAD_MASK_VIDEO; - } else if (which == 3) { - maskDiff = MediaController.AUTODOWNLOAD_MASK_DOCUMENT; - } - - if (isChecked) { - mask |= maskDiff; - } else { - mask &= ~maskDiff; - } - - if (i == mobileDownloadRow) { - editor.putInt("mobileDataDownloadMask", mask); - mask = MediaController.getInstance().mobileDataDownloadMask = mask; - } else if (i == wifiDownloadRow) { - editor.putInt("wifiDownloadMask", mask); - MediaController.getInstance().wifiDownloadMask = mask; - } else if (i == roamingDownloadRow) { - editor.putInt("roamingDownloadMask", mask); - MediaController.getInstance().roamingDownloadMask = mask; - } - editor.commit(); - if (listView != null) { - listView.invalidateViews(); - } - } - }); - builder.setNegativeButton(LocaleController.getString("OK", R.string.OK), null); - showAlertDialog(builder); - } else if (i == usernameRow) { - presentFragment(new ChangeUsernameActivity()); - } else if (i == numberRow) { - presentFragment(new ChangePhoneHelpActivity()); - } - } - }); - - frameLayout.addView(actionBar); - - writeButton = new ImageView(getParentActivity()); - writeButton.setBackgroundResource(R.drawable.floating_user_states); - writeButton.setImageResource(R.drawable.floating_camera); - writeButton.setScaleType(ImageView.ScaleType.CENTER); - if (Build.VERSION.SDK_INT >= 21) { - StateListAnimator animator = new StateListAnimator(); - animator.addState(new int[] {android.R.attr.state_pressed}, ObjectAnimator.ofFloat(writeButton, "translationZ", AndroidUtilities.dp(2), AndroidUtilities.dp(4)).setDuration(200)); - animator.addState(new int[] {}, ObjectAnimator.ofFloat(writeButton, "translationZ", AndroidUtilities.dp(4), AndroidUtilities.dp(2)).setDuration(200)); - writeButton.setStateListAnimator(animator); - writeButton.setOutlineProvider(new ViewOutlineProvider() { - @Override - public void getOutline(View view, Outline outline) { - outline.setOval(0, 0, AndroidUtilities.dp(56), AndroidUtilities.dp(56)); - } - }); } - frameLayout.addView(writeButton); - layoutParams = (FrameLayout.LayoutParams) writeButton.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? 16 : 0); - layoutParams.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? 0 : 16); - layoutParams.gravity = (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT); - writeButton.setLayoutParams(layoutParams); - writeButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { + }); + + nameTextView = new TextView(context); + nameTextView.setTextColor(0xffffffff); + nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); + nameTextView.setLines(1); + nameTextView.setMaxLines(1); + nameTextView.setSingleLine(true); + nameTextView.setEllipsize(TextUtils.TruncateAt.END); + nameTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)); + nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + actionBar.addView(nameTextView); + layoutParams = (FrameLayout.LayoutParams) nameTextView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? 16 : 97); + layoutParams.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? 97 : 16); + layoutParams.bottomMargin = AndroidUtilities.dp(51); + layoutParams.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.BOTTOM; + nameTextView.setLayoutParams(layoutParams); + + onlineTextView = new TextView(context); + onlineTextView.setTextColor(AvatarDrawable.getProfileTextColorForId(5)); + onlineTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + onlineTextView.setLines(1); + onlineTextView.setMaxLines(1); + onlineTextView.setSingleLine(true); + onlineTextView.setEllipsize(TextUtils.TruncateAt.END); + onlineTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)); + actionBar.addView(onlineTextView); + layoutParams = (FrameLayout.LayoutParams) onlineTextView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? 16 : 97); + layoutParams.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? 97 : 16); + layoutParams.bottomMargin = AndroidUtilities.dp(30); + layoutParams.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.BOTTOM; + onlineTextView.setLayoutParams(layoutParams); + + listView = new ListView(context); + listView.setDivider(null); + listView.setDividerHeight(0); + listView.setVerticalScrollBarEnabled(false); + AndroidUtilities.setListViewEdgeEffectColor(listView, AvatarDrawable.getProfileBackColorForId(5)); + frameLayout.addView(listView); + layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP; + listView.setLayoutParams(layoutParams); + listView.setAdapter(listAdapter); + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, final int i, long l) { + if (i == textSizeRow) { + if (getParentActivity() == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("TextSize", R.string.TextSize)); + final NumberPicker numberPicker = new NumberPicker(getParentActivity()); + numberPicker.setMinValue(12); + numberPicker.setMaxValue(30); + numberPicker.setValue(MessagesController.getInstance().fontSize); + builder.setView(numberPicker); + builder.setNegativeButton(LocaleController.getString("Done", R.string.Done), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.putInt("fons_size", numberPicker.getValue()); + MessagesController.getInstance().fontSize = numberPicker.getValue(); + editor.commit(); + if (listView != null) { + listView.invalidateViews(); + } + } + }); + showAlertDialog(builder); + } else if (i == enableAnimationsRow) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + boolean animations = preferences.getBoolean("view_animations", true); + SharedPreferences.Editor editor = preferences.edit(); + editor.putBoolean("view_animations", !animations); + editor.commit(); + if (view instanceof TextCheckCell) { + ((TextCheckCell) view).setChecked(!animations); + } + } else if (i == notificationRow) { + presentFragment(new NotificationsSettingsActivity()); + } else if (i == backgroundRow) { + presentFragment(new WallpapersActivity()); + } else if (i == askQuestionRow) { + if (getParentActivity() == null) { + return; + } + final TextView message = new TextView(getParentActivity()); + message.setText(Html.fromHtml(LocaleController.getString("AskAQuestionInfo", R.string.AskAQuestionInfo))); + message.setTextSize(18); + message.setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(5), AndroidUtilities.dp(8), AndroidUtilities.dp(6)); + message.setMovementMethod(new LinkMovementMethodMy()); + + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setView(message); + builder.setPositiveButton(LocaleController.getString("AskButton", R.string.AskButton), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + performAskAQuestion(); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } else if (i == sendLogsRow) { + sendLogs(); + } else if (i == clearLogsRow) { + FileLog.cleanupLogs(); + } else if (i == sendByEnterRow) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + boolean send = preferences.getBoolean("send_by_enter", false); + SharedPreferences.Editor editor = preferences.edit(); + editor.putBoolean("send_by_enter", !send); + editor.commit(); + if (view instanceof TextCheckCell) { + ((TextCheckCell) view).setChecked(!send); + } + } else if (i == saveToGalleryRow) { + MediaController.getInstance().toggleSaveToGallery(); + if (view instanceof TextCheckCell) { + ((TextCheckCell) view).setChecked(MediaController.getInstance().canSaveToGallery()); + } + } else if (i == privacyRow) { + presentFragment(new PrivacySettingsActivity()); + } else if (i == languageRow) { + presentFragment(new LanguageSelectActivity()); + } else if (i == switchBackendButtonRow) { + if (getParentActivity() == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.getString("AreYouSure", R.string.AreYouSure)); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + ConnectionsManager.getInstance().switchBackend(); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } else if (i == telegramFaqRow) { + try { + Intent pickIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(LocaleController.getString("TelegramFaqUrl", R.string.TelegramFaqUrl))); + getParentActivity().startActivityForResult(pickIntent, 500); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } else if (i == contactsReimportRow) { + + } else if (i == contactsSortRow) { + if (getParentActivity() == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(LocaleController.getString("SortBy", R.string.SortBy)); + builder.setItems(new CharSequence[]{ + LocaleController.getString("Default", R.string.Default), + LocaleController.getString("SortFirstName", R.string.SortFirstName), + LocaleController.getString("SortLastName", R.string.SortLastName) + }, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.putInt("sortContactsBy", which); + editor.commit(); + if (listView != null) { + listView.invalidateViews(); + } + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } else if (i == wifiDownloadRow || i == mobileDownloadRow || i == roamingDownloadRow) { if (getParentActivity() == null) { return; } AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - CharSequence[] items; + int mask = 0; + if (i == mobileDownloadRow) { + builder.setTitle(LocaleController.getString("WhenUsingMobileData", R.string.WhenUsingMobileData)); + mask = MediaController.getInstance().mobileDataDownloadMask; + } else if (i == wifiDownloadRow) { + builder.setTitle(LocaleController.getString("WhenConnectedOnWiFi", R.string.WhenConnectedOnWiFi)); + mask = MediaController.getInstance().wifiDownloadMask; + } else if (i == roamingDownloadRow) { + builder.setTitle(LocaleController.getString("WhenRoaming", R.string.WhenRoaming)); + mask = MediaController.getInstance().roamingDownloadMask; + } + builder.setMultiChoiceItems( + new CharSequence[]{LocaleController.getString("AttachPhoto", R.string.AttachPhoto), LocaleController.getString("AttachAudio", R.string.AttachAudio), LocaleController.getString("AttachVideo", R.string.AttachVideo), LocaleController.getString("AttachDocument", R.string.AttachDocument)}, + new boolean[]{(mask & MediaController.AUTODOWNLOAD_MASK_PHOTO) != 0, (mask & MediaController.AUTODOWNLOAD_MASK_AUDIO) != 0, (mask & MediaController.AUTODOWNLOAD_MASK_VIDEO) != 0, (mask & MediaController.AUTODOWNLOAD_MASK_DOCUMENT) != 0}, + new DialogInterface.OnMultiChoiceClickListener() { + @Override + public void onClick(DialogInterface dialog, int which, boolean isChecked) { + int mask = 0; + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + if (i == mobileDownloadRow) { + mask = MediaController.getInstance().mobileDataDownloadMask; + } else if (i == wifiDownloadRow) { + mask = MediaController.getInstance().wifiDownloadMask; + } else if (i == roamingDownloadRow) { + mask = MediaController.getInstance().roamingDownloadMask; + } - TLRPC.User user = MessagesController.getInstance().getUser(UserConfig.getClientUserId()); - if (user == null) { - user = UserConfig.getCurrentUser(); - } - if (user == null) { - return; - } - boolean fullMenu = false; - if (user.photo != null && user.photo.photo_big != null && !(user.photo instanceof TLRPC.TL_userProfilePhotoEmpty)) { - items = new CharSequence[] {LocaleController.getString("FromCamera", R.string.FromCamera), LocaleController.getString("FromGalley", R.string.FromGalley), LocaleController.getString("DeletePhoto", R.string.DeletePhoto)}; - fullMenu = true; - } else { - items = new CharSequence[] {LocaleController.getString("FromCamera", R.string.FromCamera), LocaleController.getString("FromGalley", R.string.FromGalley)}; - } + int maskDiff = 0; + if (which == 0) { + maskDiff = MediaController.AUTODOWNLOAD_MASK_PHOTO; + } else if (which == 1) { + maskDiff = MediaController.AUTODOWNLOAD_MASK_AUDIO; + } else if (which == 2) { + maskDiff = MediaController.AUTODOWNLOAD_MASK_VIDEO; + } else if (which == 3) { + maskDiff = MediaController.AUTODOWNLOAD_MASK_DOCUMENT; + } - final boolean full = fullMenu; - builder.setItems(items, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - if (i == 0) { - avatarUpdater.openCamera(); - } else if (i == 1) { - avatarUpdater.openGallery(); - } else if (i == 2) { - MessagesController.getInstance().deleteUserPhoto(null); - } - } - }); + if (isChecked) { + mask |= maskDiff; + } else { + mask &= ~maskDiff; + } + + if (i == mobileDownloadRow) { + editor.putInt("mobileDataDownloadMask", mask); + mask = MediaController.getInstance().mobileDataDownloadMask = mask; + } else if (i == wifiDownloadRow) { + editor.putInt("wifiDownloadMask", mask); + MediaController.getInstance().wifiDownloadMask = mask; + } else if (i == roamingDownloadRow) { + editor.putInt("roamingDownloadMask", mask); + MediaController.getInstance().roamingDownloadMask = mask; + } + editor.commit(); + if (listView != null) { + listView.invalidateViews(); + } + } + }); + builder.setNegativeButton(LocaleController.getString("OK", R.string.OK), null); showAlertDialog(builder); + } else if (i == usernameRow) { + presentFragment(new ChangeUsernameActivity()); + } else if (i == numberRow) { + presentFragment(new ChangePhoneHelpActivity()); } - }); - - listView.setOnScrollListener(new AbsListView.OnScrollListener() { - @Override - public void onScrollStateChanged(AbsListView view, int scrollState) { - - } - - @Override - public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - if (totalItemCount == 0) { - return; - } - int height = 0; - View child = view.getChildAt(0); - if (child != null) { - if (firstVisibleItem == 0) { - height = AndroidUtilities.dp(88) + (child.getTop() < 0 ? child.getTop() : 0); - } - if (actionBar.getExtraHeight() != height) { - actionBar.setExtraHeight(height, true); - needLayout(); - } - } - } - }); - - updateUserData(); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); } + }); + + frameLayout.addView(actionBar); + + writeButton = new ImageView(context); + writeButton.setBackgroundResource(R.drawable.floating_user_states); + writeButton.setImageResource(R.drawable.floating_camera); + writeButton.setScaleType(ImageView.ScaleType.CENTER); + if (Build.VERSION.SDK_INT >= 21) { + StateListAnimator animator = new StateListAnimator(); + animator.addState(new int[]{android.R.attr.state_pressed}, ObjectAnimator.ofFloat(writeButton, "translationZ", AndroidUtilities.dp(2), AndroidUtilities.dp(4)).setDuration(200)); + animator.addState(new int[]{}, ObjectAnimator.ofFloat(writeButton, "translationZ", AndroidUtilities.dp(4), AndroidUtilities.dp(2)).setDuration(200)); + writeButton.setStateListAnimator(animator); + writeButton.setOutlineProvider(new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + outline.setOval(0, 0, AndroidUtilities.dp(56), AndroidUtilities.dp(56)); + } + }); } + frameLayout.addView(writeButton); + layoutParams = (FrameLayout.LayoutParams) writeButton.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? 16 : 0); + layoutParams.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? 0 : 16); + layoutParams.gravity = (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT); + writeButton.setLayoutParams(layoutParams); + writeButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (getParentActivity() == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + + CharSequence[] items; + + TLRPC.User user = MessagesController.getInstance().getUser(UserConfig.getClientUserId()); + if (user == null) { + user = UserConfig.getCurrentUser(); + } + if (user == null) { + return; + } + boolean fullMenu = false; + if (user.photo != null && user.photo.photo_big != null && !(user.photo instanceof TLRPC.TL_userProfilePhotoEmpty)) { + items = new CharSequence[]{LocaleController.getString("FromCamera", R.string.FromCamera), LocaleController.getString("FromGalley", R.string.FromGalley), LocaleController.getString("DeletePhoto", R.string.DeletePhoto)}; + fullMenu = true; + } else { + items = new CharSequence[]{LocaleController.getString("FromCamera", R.string.FromCamera), LocaleController.getString("FromGalley", R.string.FromGalley)}; + } + + final boolean full = fullMenu; + builder.setItems(items, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + if (i == 0) { + avatarUpdater.openCamera(); + } else if (i == 1) { + avatarUpdater.openGallery(); + } else if (i == 2) { + MessagesController.getInstance().deleteUserPhoto(null); + } + } + }); + showAlertDialog(builder); + } + }); + + listView.setOnScrollListener(new AbsListView.OnScrollListener() { + @Override + public void onScrollStateChanged(AbsListView view, int scrollState) { + + } + + @Override + public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { + if (totalItemCount == 0) { + return; + } + int height = 0; + View child = view.getChildAt(0); + if (child != null) { + if (firstVisibleItem == 0) { + height = AndroidUtilities.dp(88) + (child.getTop() < 0 ? child.getTop() : 0); + } + if (actionBar.getExtraHeight() != height) { + actionBar.setExtraHeight(height, true); + needLayout(); + } + } + } + }); + return fragmentView; } @@ -706,6 +700,11 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter MediaController.getInstance().checkAutodownloadSettings(); } + @Override + public void updatePhotoAtIndex(int index) { + + } + @Override public PhotoViewer.PlaceProviderObject getPlaceForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index) { if (fileLocation == null) { @@ -721,11 +720,11 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter object.viewX = coords[0]; object.viewY = coords[1] - AndroidUtilities.statusBarHeight; object.parentView = avatarImage; - object.imageReceiver = avatarImage.imageReceiver; + object.imageReceiver = avatarImage.getImageReceiver(); object.user_id = UserConfig.getClientUserId(); object.thumb = object.imageReceiver.getBitmap(); object.size = -1; - object.radius = avatarImage.imageReceiver.getRoundRadius(); + object.radius = avatarImage.getImageReceiver().getRoundRadius(); return object; } } @@ -742,7 +741,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter @Override public void willHidePhotoViewer() { - avatarImage.imageReceiver.setVisible(true, true); + avatarImage.getImageReceiver().setVisible(true, true); } @Override @@ -777,6 +776,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter if (supportUser != null && supportUser.id == 333000) { supportUser = null; } + data.cleanup(); } } catch (Exception e) { FileLog.e("tmessages", e); @@ -807,6 +807,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter res.user.serializeToStream(data); editor.putString("support_user", Base64.encodeToString(data.toByteArray(), Base64.DEFAULT)); editor.commit(); + data.cleanup(); try { progressDialog.dismiss(); } catch (Exception e) { @@ -878,6 +879,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } + updateUserData(); fixLayout(); } @@ -904,9 +906,9 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter int avatarY = AndroidUtilities.dp(22) - (int)((AndroidUtilities.dp(22) - (AndroidUtilities.getCurrentActionBarHeight() - AndroidUtilities.dp(42)) / 2) * (1.0f - diff)); int nameX = 97 + (int)(21 * diffm); int nameEndX = 16 + (int)(32 * diffm); - float nameFontSize = 20 - 2 * diffm; - int nameY = avatarY + AndroidUtilities.dp(29 - 10 * diffm); + int nameY = avatarY + AndroidUtilities.dp(29 - 13 * diffm); int statusY = avatarY + AndroidUtilities.dp(8 - 7 * diffm); + float scale = 1.0f - 0.12f * diffm; layoutParams = (FrameLayout.LayoutParams) writeButton.getLayoutParams(); layoutParams.topMargin = (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0) + AndroidUtilities.getCurrentActionBarHeight() + actionBar.getExtraHeight() - AndroidUtilities.dp(29.5f); @@ -917,7 +919,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter writeButton.clearAnimation(); } - avatarImage.imageReceiver.setRoundRadius(AndroidUtilities.dp(avatarSize / 2)); + avatarImage.setRoundRadius(AndroidUtilities.dp(avatarSize / 2)); layoutParams = (FrameLayout.LayoutParams) avatarImage.getLayoutParams(); layoutParams.width = AndroidUtilities.dp(avatarSize); layoutParams.height = AndroidUtilities.dp(avatarSize); @@ -926,7 +928,10 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter layoutParams.bottomMargin = avatarY; avatarImage.setLayoutParams(layoutParams); - nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, nameFontSize); + ViewProxy.setPivotX(nameTextView, 0); + ViewProxy.setPivotY(nameTextView, 0); + ViewProxy.setScaleX(nameTextView, scale); + ViewProxy.setScaleY(nameTextView, scale); layoutParams = (FrameLayout.LayoutParams) nameTextView.getLayoutParams(); layoutParams.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? nameEndX : nameX); layoutParams.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? nameX : nameEndX); @@ -967,13 +972,15 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter } AvatarDrawable avatarDrawable = new AvatarDrawable(user, true); avatarDrawable.setColor(0xff5c98cd); - avatarImage.setImage(photo, "50_50", avatarDrawable); - avatarImage.imageReceiver.setVisible(!PhotoViewer.getInstance().isShowingImage(photoBig), false); + if (avatarImage != null) { + avatarImage.setImage(photo, "50_50", avatarDrawable); + avatarImage.getImageReceiver().setVisible(!PhotoViewer.getInstance().isShowingImage(photoBig), false); - nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name)); - onlineTextView.setText(LocaleController.getString("Online", R.string.Online)); + nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name)); + onlineTextView.setText(LocaleController.getString("Online", R.string.Online)); - avatarImage.imageReceiver.setVisible(!PhotoViewer.getInstance().isShowingImage(photoBig), false); + avatarImage.getImageReceiver().setVisible(!PhotoViewer.getInstance().isShowingImage(photoBig), false); + } } private void sendLogs() { @@ -994,7 +1001,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter i.putExtra(Intent.EXTRA_EMAIL, new String[]{BuildVars.SEND_LOGS_EMAIL}); i.putExtra(Intent.EXTRA_SUBJECT, "last logs"); i.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); - getParentActivity().startActivity(Intent.createChooser(i, "Select email application.")); + getParentActivity().startActivityForResult(Intent.createChooser(i, "Select email application."), 500); } catch (Exception e) { e.printStackTrace(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/TwoStepVerificationActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/TwoStepVerificationActivity.java new file mode 100644 index 000000000..74f7e9de3 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/TwoStepVerificationActivity.java @@ -0,0 +1,1085 @@ +/* + * This is the source code of Telegram for Android v. 2.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-2015. + */ + +package org.telegram.ui; + +import android.app.AlertDialog; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.graphics.Typeface; +import android.os.Vibrator; +import android.text.InputType; +import android.text.method.PasswordTransformationMethod; +import android.util.TypedValue; +import android.view.ActionMode; +import android.view.ContextMenu; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.view.inputmethod.EditorInfo; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.ProgressBar; +import android.widget.ScrollView; +import android.widget.TextView; +import android.widget.Toast; + +import org.telegram.android.AndroidUtilities; +import org.telegram.android.LocaleController; +import org.telegram.android.NotificationCenter; +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.Utilities; +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.Adapters.BaseFragmentAdapter; +import org.telegram.ui.Cells.TextInfoPrivacyCell; +import org.telegram.ui.Cells.TextSettingsCell; + +public class TwoStepVerificationActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate { + + private ListAdapter listAdapter; + private ListView listView; + private TextView titleTextView; + private TextView bottomTextView; + private TextView bottomButton; + private EditText passwordEditText; + private ProgressDialog progressDialog; + private FrameLayout progressView; + private ActionBarMenuItem doneItem; + private ScrollView scrollView; + + private int type; + private int passwordSetState; + private String firstPassword; + private String hint; + private String email; + private boolean emailOnly; + private boolean loading; + private boolean destroyed; + private boolean waitingForEmail; + private TLRPC.account_Password currentPassword; + private boolean passwordEntered = true; + private byte[] currentPasswordHash = new byte[0]; + private Runnable shortPollRunnable; + + private int setPasswordRow; + private int setPasswordDetailRow; + private int changePasswordRow; + private int shadowRow; + private int turnPasswordOffRow; + private int setRecoveryEmailRow; + private int changeRecoveryEmailRow; + private int abortPasswordRow; + private int passwordSetupDetailRow; + private int passwordEnabledDetailRow; + private int passwordEmailVerifyDetailRow; + private int rowCount; + + private final static int done_button = 1; + + public TwoStepVerificationActivity(int type) { + super(); + this.type = type; + if (type == 0) { + loadPasswordInfo(false); + } + } + + @Override + public boolean onFragmentCreate() { + super.onFragmentCreate(); + updateRows(); + if (type == 0) { + NotificationCenter.getInstance().addObserver(this, NotificationCenter.didSetTwoStepPassword); + } + return true; + } + + @Override + public void onFragmentDestroy() { + super.onFragmentDestroy(); + if (type == 0) { + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.didSetTwoStepPassword); + if (shortPollRunnable != null) { + AndroidUtilities.cancelRunOnUIThread(shortPollRunnable); + shortPollRunnable = null; + } + destroyed = true; + } + 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(Context context, LayoutInflater inflater) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(false); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } else if (id == done_button) { + processDone(); + } + } + }); + + fragmentView = new FrameLayout(context); + FrameLayout frameLayout = (FrameLayout) fragmentView; + frameLayout.setBackgroundColor(0xfff0f0f0); + + ActionBarMenu menu = actionBar.createMenu(); + doneItem = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + + scrollView = new ScrollView(context); + scrollView.setFillViewport(true); + frameLayout.addView(scrollView); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) scrollView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + scrollView.setLayoutParams(layoutParams); + + LinearLayout linearLayout = new LinearLayout(context); + linearLayout.setOrientation(LinearLayout.VERTICAL); + scrollView.addView(linearLayout); + ScrollView.LayoutParams layoutParams2 = (ScrollView.LayoutParams) linearLayout.getLayoutParams(); + layoutParams2.width = ScrollView.LayoutParams.MATCH_PARENT; + layoutParams2.height = ScrollView.LayoutParams.WRAP_CONTENT; + linearLayout.setLayoutParams(layoutParams2); + + titleTextView = new TextView(context); + titleTextView.setTextColor(0xff757575); + titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + titleTextView.setGravity(Gravity.CENTER_HORIZONTAL); + linearLayout.addView(titleTextView); + LinearLayout.LayoutParams layoutParams3 = (LinearLayout.LayoutParams) titleTextView.getLayoutParams(); + layoutParams3.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams3.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams3.gravity = Gravity.CENTER_HORIZONTAL; + layoutParams3.topMargin = AndroidUtilities.dp(38); + titleTextView.setLayoutParams(layoutParams3); + + passwordEditText = new EditText(context); + passwordEditText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); + passwordEditText.setTextColor(0xff000000); + passwordEditText.setMaxLines(1); + passwordEditText.setLines(1); + passwordEditText.setGravity(Gravity.CENTER_HORIZONTAL); + passwordEditText.setSingleLine(true); + passwordEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); + passwordEditText.setTransformationMethod(PasswordTransformationMethod.getInstance()); + passwordEditText.setTypeface(Typeface.DEFAULT); + AndroidUtilities.clearCursorDrawable(passwordEditText); + linearLayout.addView(passwordEditText); + layoutParams3 = (LinearLayout.LayoutParams) passwordEditText.getLayoutParams(); + layoutParams3.topMargin = AndroidUtilities.dp(32); + layoutParams3.height = AndroidUtilities.dp(36); + layoutParams3.leftMargin = AndroidUtilities.dp(40); + layoutParams3.rightMargin = AndroidUtilities.dp(40); + layoutParams3.gravity = Gravity.TOP | Gravity.LEFT; + layoutParams3.width = LinearLayout.LayoutParams.MATCH_PARENT; + passwordEditText.setLayoutParams(layoutParams3); + passwordEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { + if (i == EditorInfo.IME_ACTION_NEXT || i == EditorInfo.IME_ACTION_DONE) { + processDone(); + return true; + } + return false; + } + }); + if (android.os.Build.VERSION.SDK_INT < 11) { + passwordEditText.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() { + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + menu.clear(); + } + }); + } else { + passwordEditText.setCustomSelectionActionModeCallback(new ActionMode.Callback() { + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + return false; + } + + public void onDestroyActionMode(ActionMode mode) { + } + + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + return false; + } + + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + return false; + } + }); + } + + bottomTextView = new TextView(context); + bottomTextView.setTextColor(0xff757575); + bottomTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + bottomTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP); + bottomTextView.setText(LocaleController.getString("YourEmailInfo", R.string.YourEmailInfo)); + linearLayout.addView(bottomTextView); + layoutParams3 = (LinearLayout.LayoutParams) bottomTextView.getLayoutParams(); + layoutParams3.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams3.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams3.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP; + layoutParams3.topMargin = AndroidUtilities.dp(30); + layoutParams3.leftMargin = AndroidUtilities.dp(40); + layoutParams3.rightMargin = AndroidUtilities.dp(40); + bottomTextView.setLayoutParams(layoutParams3); + + LinearLayout linearLayout2 = new LinearLayout(context); + linearLayout2.setGravity(Gravity.BOTTOM | Gravity.CENTER_VERTICAL); + linearLayout.addView(linearLayout2); + layoutParams3 = (LinearLayout.LayoutParams) linearLayout2.getLayoutParams(); + layoutParams3.width = LinearLayout.LayoutParams.MATCH_PARENT; + layoutParams3.height = LinearLayout.LayoutParams.MATCH_PARENT; + linearLayout2.setLayoutParams(layoutParams3); + + bottomButton = new TextView(context); + bottomButton.setTextColor(0xff4d83b3); + bottomButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + bottomButton.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.BOTTOM); + bottomButton.setText(LocaleController.getString("YourEmailSkip", R.string.YourEmailSkip)); + bottomButton.setPadding(0, AndroidUtilities.dp(10), 0, 0); + linearLayout2.addView(bottomButton); + layoutParams3 = (LinearLayout.LayoutParams) bottomButton.getLayoutParams(); + layoutParams3.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams3.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams3.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.BOTTOM; + layoutParams3.bottomMargin = AndroidUtilities.dp(14); + layoutParams3.leftMargin = AndroidUtilities.dp(40); + layoutParams3.rightMargin = AndroidUtilities.dp(40); + bottomButton.setLayoutParams(layoutParams3); + bottomButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (type == 0) { + if (currentPassword.has_recovery) { + needShowProgress(); + TLRPC.TL_auth_requestPasswordRecovery req = new TLRPC.TL_auth_requestPasswordRecovery(); + 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(); + if (error == null) { + final TLRPC.TL_auth_passwordRecovery res = (TLRPC.TL_auth_passwordRecovery) response; + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.formatString("RestoreEmailSent", R.string.RestoreEmailSent, res.email_pattern)); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + TwoStepVerificationActivity fragment = new TwoStepVerificationActivity(1); + fragment.currentPassword = currentPassword; + fragment.currentPassword.email_unconfirmed_pattern = res.email_pattern; + fragment.passwordSetState = 4; + presentFragment(fragment); + } + }); + AlertDialog dialog = showAlertDialog(builder); + if (dialog != null) { + dialog.setCanceledOnTouchOutside(false); + dialog.setCancelable(false); + } + } else { + if (error.text.startsWith("FLOOD_WAIT")) { + int time = Utilities.parseInt(error.text); + String timeString; + if (time < 60) { + timeString = LocaleController.formatPluralString("Seconds", time); + } else { + timeString = LocaleController.formatPluralString("Minutes", time / 60); + } + showAlertWithText(LocaleController.getString("AppName", R.string.AppName), LocaleController.formatString("FloodWaitTime", R.string.FloodWaitTime, timeString)); + } else { + showAlertWithText(LocaleController.getString("AppName", R.string.AppName), error.text); + } + } + } + }); + } + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors | RPCRequest.RPCRequestClassWithoutLogin); + } else { + showAlertWithText(LocaleController.getString("RestorePasswordNoEmailTitle", R.string.RestorePasswordNoEmailTitle), LocaleController.getString("RestorePasswordNoEmailText", R.string.RestorePasswordNoEmailText)); + } + } else { + if (passwordSetState == 4) { + showAlertWithText(LocaleController.getString("RestorePasswordNoEmailTitle", R.string.RestorePasswordNoEmailTitle), LocaleController.getString("RestoreEmailTroubleText", R.string.RestoreEmailTroubleText)); + } else { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.getString("YourEmailSkipWarningText", R.string.YourEmailSkipWarningText)); + builder.setTitle(LocaleController.getString("YourEmailSkipWarning", R.string.YourEmailSkipWarning)); + builder.setPositiveButton(LocaleController.getString("YourEmailSkip", R.string.YourEmailSkip), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + email = ""; + setNewPassword(false); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } + } + } + }); + + if (type == 0) { + progressView = new FrameLayout(context); + frameLayout.addView(progressView); + layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + progressView.setLayoutParams(layoutParams); + progressView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + ProgressBar progressBar = new ProgressBar(context); + progressView.addView(progressBar); + layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.CENTER; + progressView.setLayoutParams(layoutParams); + + listView = new ListView(context); + listView.setDivider(null); + listView.setEmptyView(progressView); + listView.setDividerHeight(0); + listView.setVerticalScrollBarEnabled(false); + listView.setDrawSelectorOnTop(true); + frameLayout.addView(listView); + layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.gravity = Gravity.TOP; + listView.setLayoutParams(layoutParams); + listView.setAdapter(listAdapter = new ListAdapter(context)); + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, final int i, long l) { + if (i == setPasswordRow || i == changePasswordRow) { + TwoStepVerificationActivity fragment = new TwoStepVerificationActivity(1); + fragment.currentPasswordHash = currentPasswordHash; + fragment.currentPassword = currentPassword; + presentFragment(fragment); + } else if (i == setRecoveryEmailRow || i == changeRecoveryEmailRow) { + TwoStepVerificationActivity fragment = new TwoStepVerificationActivity(1); + fragment.currentPasswordHash = currentPasswordHash; + fragment.currentPassword = currentPassword; + fragment.emailOnly = true; + fragment.passwordSetState = 3; + presentFragment(fragment); + } else if (i == turnPasswordOffRow || i == abortPasswordRow) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.getString("TurnPasswordOffQuestion", R.string.TurnPasswordOffQuestion)); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + setNewPassword(true); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showAlertDialog(builder); + } + } + }); + + updateRows(); + + actionBar.setTitle(LocaleController.getString("TwoStepVerification", R.string.TwoStepVerification)); + titleTextView.setText(LocaleController.getString("PleaseEnterCurrentPassword", R.string.PleaseEnterCurrentPassword)); + } else if (type == 1) { + setPasswordSetState(passwordSetState); + } + + return fragmentView; + } + + @Override + public void didReceivedNotification(int id, Object... args) { + if (id == NotificationCenter.didSetTwoStepPassword) { + if (args != null && args.length > 0) { + currentPasswordHash = (byte[]) args[0]; + } + loadPasswordInfo(false); + updateRows(); + } + } + + @Override + public void onResume() { + super.onResume(); + if (type == 1) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (passwordEditText != null) { + passwordEditText.requestFocus(); + AndroidUtilities.showKeyboard(passwordEditText); + } + } + }, 200); + } + if (!AndroidUtilities.isTablet()) { + getParentActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + } + } + + @Override + public void onOpenAnimationEnd() { + super.onOpenAnimationEnd(); + if (type == 1) { + AndroidUtilities.showKeyboard(passwordEditText); + } + } + + private void loadPasswordInfo(final boolean silent) { + if (!silent) { + loading = true; + } + TLRPC.TL_account_getPassword req = new TLRPC.TL_account_getPassword(); + 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() { + loading = false; + if (error == null) { + if (!silent) { + passwordEntered = currentPassword != null || currentPassword == null && response instanceof TLRPC.TL_account_noPassword; + } + currentPassword = (TLRPC.account_Password) response; + waitingForEmail = currentPassword.email_unconfirmed_pattern.length() > 0; + byte[] salt = new byte[currentPassword.new_salt.length + 8]; + Utilities.random.nextBytes(salt); + System.arraycopy(currentPassword.new_salt, 0, salt, 0, currentPassword.new_salt.length); + currentPassword.new_salt = salt; + } + if (type == 0 && !destroyed && shortPollRunnable == null) { + shortPollRunnable = new Runnable() { + @Override + public void run() { + if (shortPollRunnable == null) { + return; + } + loadPasswordInfo(true); + shortPollRunnable = null; + } + }; + AndroidUtilities.runOnUIThread(shortPollRunnable, 5000); + } + updateRows(); + } + }); + } + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors | RPCRequest.RPCRequestClassWithoutLogin); + } + + private void setPasswordSetState(int state) { + if (passwordEditText == null) { + return; + } + passwordSetState = state; + if (passwordSetState == 0) { + actionBar.setTitle(LocaleController.getString("YourPassword", R.string.YourPassword)); + if (currentPassword instanceof TLRPC.TL_account_noPassword) { + titleTextView.setText(LocaleController.getString("PleaseEnterFirstPassword", R.string.PleaseEnterFirstPassword)); + } else { + titleTextView.setText(LocaleController.getString("PleaseEnterPassword", R.string.PleaseEnterPassword)); + } + passwordEditText.setImeOptions(EditorInfo.IME_ACTION_NEXT); + passwordEditText.setTransformationMethod(PasswordTransformationMethod.getInstance()); + bottomTextView.setVisibility(View.INVISIBLE); + bottomButton.setVisibility(View.INVISIBLE); + } else if (passwordSetState == 1) { + actionBar.setTitle(LocaleController.getString("YourPassword", R.string.YourPassword)); + titleTextView.setText(LocaleController.getString("PleaseReEnterPassword", R.string.PleaseReEnterPassword)); + passwordEditText.setImeOptions(EditorInfo.IME_ACTION_NEXT); + passwordEditText.setTransformationMethod(PasswordTransformationMethod.getInstance()); + bottomTextView.setVisibility(View.INVISIBLE); + bottomButton.setVisibility(View.INVISIBLE); + } else if (passwordSetState == 2) { + actionBar.setTitle(LocaleController.getString("PasswordHint", R.string.PasswordHint)); + titleTextView.setText(LocaleController.getString("PasswordHintText", R.string.PasswordHintText)); + passwordEditText.setImeOptions(EditorInfo.IME_ACTION_NEXT); + passwordEditText.setTransformationMethod(null); + bottomTextView.setVisibility(View.INVISIBLE); + bottomButton.setVisibility(View.INVISIBLE); + } else if (passwordSetState == 3) { + actionBar.setTitle(LocaleController.getString("RecoveryEmail", R.string.RecoveryEmail)); + titleTextView.setText(LocaleController.getString("YourEmail", R.string.YourEmail)); + passwordEditText.setImeOptions(EditorInfo.IME_ACTION_DONE); + passwordEditText.setTransformationMethod(null); + passwordEditText.setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS); + bottomTextView.setVisibility(View.VISIBLE); + bottomButton.setVisibility(emailOnly ? View.INVISIBLE : View.VISIBLE); + } else if (passwordSetState == 4) { + actionBar.setTitle(LocaleController.getString("PasswordRecovery", R.string.PasswordRecovery)); + titleTextView.setText(LocaleController.getString("PasswordCode", R.string.PasswordCode)); + bottomTextView.setText(LocaleController.getString("RestoreEmailSentInfo", R.string.RestoreEmailSentInfo)); + bottomButton.setText(LocaleController.formatString("RestoreEmailTrouble", R.string.RestoreEmailTrouble, currentPassword.email_unconfirmed_pattern)); + passwordEditText.setImeOptions(EditorInfo.IME_ACTION_DONE); + passwordEditText.setTransformationMethod(null); + passwordEditText.setInputType(InputType.TYPE_CLASS_PHONE); + bottomTextView.setVisibility(View.VISIBLE); + bottomButton.setVisibility(View.VISIBLE); + } + passwordEditText.setText(""); + } + + private void updateRows() { + rowCount = 0; + setPasswordRow = -1; + setPasswordDetailRow = -1; + changePasswordRow = -1; + turnPasswordOffRow = -1; + setRecoveryEmailRow = -1; + changeRecoveryEmailRow = -1; + abortPasswordRow = -1; + passwordSetupDetailRow = -1; + passwordEnabledDetailRow = -1; + passwordEmailVerifyDetailRow = -1; + shadowRow = -1; + if (!loading && currentPassword != null) { + if (currentPassword instanceof TLRPC.TL_account_noPassword) { + if (waitingForEmail) { + passwordSetupDetailRow = rowCount++; + abortPasswordRow = rowCount++; + shadowRow = rowCount++; + } else { + setPasswordRow = rowCount++; + setPasswordDetailRow = rowCount++; + } + } else if (currentPassword instanceof TLRPC.TL_account_password) { + changePasswordRow = rowCount++; + turnPasswordOffRow = rowCount++; + if (currentPassword.has_recovery) { + changeRecoveryEmailRow = rowCount++; + } else { + setRecoveryEmailRow = rowCount++; + } + if (waitingForEmail) { + passwordEmailVerifyDetailRow = rowCount++; + } else { + passwordEnabledDetailRow = rowCount++; + } + } + } + + if (listAdapter != null) { + listAdapter.notifyDataSetChanged(); + } + if (passwordEntered) { + if (listView != null) { + listView.setVisibility(View.VISIBLE); + scrollView.setVisibility(View.INVISIBLE); + progressView.setVisibility(View.VISIBLE); + listView.setEmptyView(progressView); + } + if (passwordEditText != null) { + doneItem.setVisibility(View.GONE); + passwordEditText.setVisibility(View.INVISIBLE); + titleTextView.setVisibility(View.INVISIBLE); + bottomTextView.setVisibility(View.INVISIBLE); + bottomButton.setVisibility(View.INVISIBLE); + } + } else { + if (listView != null) { + listView.setEmptyView(null); + listView.setVisibility(View.INVISIBLE); + scrollView.setVisibility(View.VISIBLE); + progressView.setVisibility(View.INVISIBLE); + } + if (passwordEditText != null) { + doneItem.setVisibility(View.VISIBLE); + passwordEditText.setVisibility(View.VISIBLE); + titleTextView.setVisibility(View.VISIBLE); + bottomButton.setVisibility(View.VISIBLE); + bottomTextView.setVisibility(View.INVISIBLE); + bottomButton.setText(LocaleController.getString("ForgotPassword", R.string.ForgotPassword)); + if (currentPassword.hint != null && currentPassword.hint.length() > 0) { + passwordEditText.setHint(currentPassword.hint); + } else { + passwordEditText.setHint(""); + } + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (passwordEditText != null) { + passwordEditText.requestFocus(); + AndroidUtilities.showKeyboard(passwordEditText); + } + } + }, 200); + } + } + } + + private 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(); + } + + private void needHideProgress() { + if (progressDialog == null) { + return; + } + try { + progressDialog.dismiss(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + progressDialog = null; + } + + private boolean isValidEmail(String text) { + if (text == null || text.length() < 3) { + return false; + } + int dot = text.lastIndexOf("."); + int dog = text.lastIndexOf("@"); + return !(dot < 0 || dog < 0 || dot < dog); + } + + private void showAlertWithText(String title, String text) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null); + builder.setTitle(title); + builder.setMessage(text); + showAlertDialog(builder); + } + + private void setNewPassword(final boolean clear) { + final TLRPC.TL_account_updatePasswordSettings req = new TLRPC.TL_account_updatePasswordSettings(); + req.current_password_hash = currentPasswordHash; + req.new_settings = new TLRPC.TL_account_passwordInputSettings(); + if (clear) { + if (waitingForEmail && currentPassword instanceof TLRPC.TL_account_noPassword) { + req.new_settings.flags = 2; + req.new_settings.email = ""; + } else { + req.new_settings.flags = 3; + req.new_settings.hint = ""; + req.new_settings.new_password_hash = new byte[0]; + req.new_settings.new_salt = new byte[0]; + req.new_settings.email = ""; + } + } else { + if (firstPassword != null && firstPassword.length() > 0) { + byte[] newPasswordBytes = null; + try { + newPasswordBytes = firstPassword.getBytes("UTF-8"); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + + byte[] new_salt = currentPassword.new_salt; + byte[] hash = new byte[new_salt.length * 2 + newPasswordBytes.length]; + System.arraycopy(new_salt, 0, hash, 0, new_salt.length); + System.arraycopy(newPasswordBytes, 0, hash, new_salt.length, newPasswordBytes.length); + System.arraycopy(new_salt, 0, hash, hash.length - new_salt.length, new_salt.length); + req.new_settings.flags |= 1; + req.new_settings.hint = hint; + req.new_settings.new_password_hash = Utilities.computeSHA256(hash, 0, hash.length); + req.new_settings.new_salt = new_salt; + } + if (email.length() > 0) { + req.new_settings.flags |= 2; + req.new_settings.email = email; + } + } + 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(); + if (error == null && response instanceof TLRPC.TL_boolTrue) { + if (clear) { + currentPassword = null; + currentPasswordHash = new byte[0]; + loadPasswordInfo(false); + updateRows(); + } else { + if (getParentActivity() == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.didSetTwoStepPassword, (Object) req.new_settings.new_password_hash); + finishFragment(); + } + }); + builder.setMessage(LocaleController.getString("YourPasswordSuccessText", R.string.YourPasswordSuccessText)); + builder.setTitle(LocaleController.getString("YourPasswordSuccess", R.string.YourPasswordSuccess)); + AlertDialog dialog = showAlertDialog(builder); + if (dialog != null) { + dialog.setCanceledOnTouchOutside(false); + dialog.setCancelable(false); + } + } + } else { + if (error.text.equals("EMAIL_UNCONFIRMED")) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.didSetTwoStepPassword, (Object) req.new_settings.new_password_hash); + finishFragment(); + } + }); + builder.setMessage(LocaleController.getString("YourEmailAlmostThereText", R.string.YourEmailAlmostThereText)); + builder.setTitle(LocaleController.getString("YourEmailAlmostThere", R.string.YourEmailAlmostThere)); + AlertDialog dialog = showAlertDialog(builder); + if (dialog != null) { + dialog.setCanceledOnTouchOutside(false); + dialog.setCancelable(false); + } + } else { + if (error.text.equals("EMAIL_INVALID")) { + showAlertWithText(LocaleController.getString("AppName", R.string.AppName), LocaleController.getString("PasswordEmailInvalid", R.string.PasswordEmailInvalid)); + } else if (error.text.startsWith("FLOOD_WAIT")) { + int time = Utilities.parseInt(error.text); + String timeString; + if (time < 60) { + timeString = LocaleController.formatPluralString("Seconds", time); + } else { + timeString = LocaleController.formatPluralString("Minutes", time / 60); + } + showAlertWithText(LocaleController.getString("AppName", R.string.AppName), LocaleController.formatString("FloodWaitTime", R.string.FloodWaitTime, timeString)); + } else { + showAlertWithText(LocaleController.getString("AppName", R.string.AppName), error.text); + } + } + } + } + }); + } + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors | RPCRequest.RPCRequestClassWithoutLogin); + } + + private void processDone() { + if (type == 0) { + if (!passwordEntered) { + String oldPassword = passwordEditText.getText().toString(); + if (oldPassword.length() == 0) { + onPasscodeError(false); + return; + } + byte[] oldPasswordBytes = null; + try { + oldPasswordBytes = oldPassword.getBytes("UTF-8"); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + + needShowProgress(); + byte[] hash = new byte[currentPassword.current_salt.length * 2 + oldPasswordBytes.length]; + System.arraycopy(currentPassword.current_salt, 0, hash, 0, currentPassword.current_salt.length); + System.arraycopy(oldPasswordBytes, 0, hash, currentPassword.current_salt.length, oldPasswordBytes.length); + System.arraycopy(currentPassword.current_salt, 0, hash, hash.length - currentPassword.current_salt.length, currentPassword.current_salt.length); + + final TLRPC.TL_account_getPasswordSettings req = new TLRPC.TL_account_getPasswordSettings(); + req.current_password_hash = Utilities.computeSHA256(hash, 0, hash.length); + 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(); + if (error == null) { + currentPasswordHash = req.current_password_hash; + passwordEntered = true; + AndroidUtilities.hideKeyboard(passwordEditText); + updateRows(); + } else { + if (error.text.equals("PASSWORD_HASH_INVALID")) { + onPasscodeError(true); + } else if (error.text.startsWith("FLOOD_WAIT")) { + int time = Utilities.parseInt(error.text); + String timeString; + if (time < 60) { + timeString = LocaleController.formatPluralString("Seconds", time); + } else { + timeString = LocaleController.formatPluralString("Minutes", time / 60); + } + showAlertWithText(LocaleController.getString("AppName", R.string.AppName), LocaleController.formatString("FloodWaitTime", R.string.FloodWaitTime, timeString)); + } else { + showAlertWithText(LocaleController.getString("AppName", R.string.AppName), error.text); + } + } + } + }); + } + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors | RPCRequest.RPCRequestClassWithoutLogin); + } + } else if (type == 1) { + if (passwordSetState == 0) { + if (passwordEditText.getText().length() == 0) { + onPasscodeError(false); + return; + } + titleTextView.setText(LocaleController.getString("ReEnterYourPasscode", R.string.ReEnterYourPasscode)); + firstPassword = passwordEditText.getText().toString(); + setPasswordSetState(1); + } else if (passwordSetState == 1) { + if (!firstPassword.equals(passwordEditText.getText().toString())) { + try { + Toast.makeText(getParentActivity(), LocaleController.getString("PasswordDoNotMatch", R.string.PasswordDoNotMatch), Toast.LENGTH_SHORT).show(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + onPasscodeError(true); + return; + } + setPasswordSetState(2); + } else if (passwordSetState == 2) { + hint = passwordEditText.getText().toString(); + if (hint.toLowerCase().equals(firstPassword.toLowerCase())) { + try { + Toast.makeText(getParentActivity(), LocaleController.getString("PasswordAsHintError", R.string.PasswordAsHintError), Toast.LENGTH_SHORT).show(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + onPasscodeError(false); + return; + } + if (!currentPassword.has_recovery) { + setPasswordSetState(3); + } else { + email = ""; + setNewPassword(false); + } + } else if (passwordSetState == 3) { + email = passwordEditText.getText().toString(); + if (!isValidEmail(email)) { + onPasscodeError(false); + return; + } + setNewPassword(false); + } else if (passwordSetState == 4) { + String code = passwordEditText.getText().toString(); + if (code.length() == 0) { + onPasscodeError(false); + return; + } + TLRPC.TL_auth_recoverPassword req = new TLRPC.TL_auth_recoverPassword(); + req.code = code; + ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, final TLRPC.TL_error error) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (error == null) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.didSetTwoStepPassword); + finishFragment(); + } + }); + builder.setMessage(LocaleController.getString("PasswordReset", R.string.PasswordReset)); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + AlertDialog dialog = showAlertDialog(builder); + if (dialog != null) { + dialog.setCanceledOnTouchOutside(false); + dialog.setCancelable(false); + } + } else { + if (error.text.startsWith("CODE_INVALID")) { + onPasscodeError(true); + } else if (error.text.startsWith("FLOOD_WAIT")) { + int time = Utilities.parseInt(error.text); + String timeString; + if (time < 60) { + timeString = LocaleController.formatPluralString("Seconds", time); + } else { + timeString = LocaleController.formatPluralString("Minutes", time / 60); + } + showAlertWithText(LocaleController.getString("AppName", R.string.AppName), LocaleController.formatString("FloodWaitTime", R.string.FloodWaitTime, timeString)); + } else { + showAlertWithText(LocaleController.getString("AppName", R.string.AppName), error.text); + } + } + } + }); + } + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors | RPCRequest.RPCRequestClassWithoutLogin); + } + } + } + + private void onPasscodeError(boolean clear) { + if (getParentActivity() == null) { + return; + } + Vibrator v = (Vibrator) getParentActivity().getSystemService(Context.VIBRATOR_SERVICE); + if (v != null) { + v.vibrate(200); + } + if (clear) { + passwordEditText.setText(""); + } + AndroidUtilities.shakeTextView(titleTextView, 2, 0); + } + + private class ListAdapter extends BaseFragmentAdapter { + private Context mContext; + + public ListAdapter(Context context) { + mContext = context; + } + + @Override + public boolean areAllItemsEnabled() { + return false; + } + + @Override + public boolean isEnabled(int i) { + return i != setPasswordDetailRow && i != shadowRow && i != passwordSetupDetailRow && i != passwordEmailVerifyDetailRow; + } + + @Override + public int getCount() { + return loading || currentPassword == null ? 0 : rowCount; + } + + @Override + public Object getItem(int i) { + return null; + } + + @Override + public long getItemId(int i) { + return i; + } + + @Override + public boolean hasStableIds() { + return false; + } + + @Override + public View getView(int i, View view, ViewGroup viewGroup) { + int viewType = getItemViewType(i); + if (viewType == 0) { + if (view == null) { + view = new TextSettingsCell(mContext); + view.setBackgroundColor(0xffffffff); + } + TextSettingsCell textCell = (TextSettingsCell) view; + textCell.setTextColor(0xff212121); + if (i == changePasswordRow) { + textCell.setText(LocaleController.getString("ChangePassword", R.string.ChangePassword), true); + } else if (i == setPasswordRow) { + textCell.setText(LocaleController.getString("SetAdditionalPassword", R.string.SetAdditionalPassword), true); + } else if (i == turnPasswordOffRow) { + textCell.setText(LocaleController.getString("TurnPasswordOff", R.string.TurnPasswordOff), true); + } else if (i == changeRecoveryEmailRow) { + textCell.setText(LocaleController.getString("ChangeRecoveryEmail", R.string.ChangeRecoveryEmail), abortPasswordRow != -1); + } else if (i == setRecoveryEmailRow) { + textCell.setText(LocaleController.getString("SetRecoveryEmail", R.string.SetRecoveryEmail), false); + } else if (i == abortPasswordRow) { + textCell.setTextColor(0xffd24949); + textCell.setText(LocaleController.getString("AbortPassword", R.string.AbortPassword), false); + } + } else if (viewType == 1) { + if (view == null) { + view = new TextInfoPrivacyCell(mContext); + } + if (i == setPasswordDetailRow) { + ((TextInfoPrivacyCell) view).setText(LocaleController.getString("SetAdditionalPasswordInfo", R.string.SetAdditionalPasswordInfo)); + view.setBackgroundResource(R.drawable.greydivider_bottom); + } else if (i == shadowRow) { + ((TextInfoPrivacyCell) view).setText(""); + view.setBackgroundResource(R.drawable.greydivider_bottom); + } else if (i == passwordSetupDetailRow) { + ((TextInfoPrivacyCell) view).setText(LocaleController.formatString("EmailPasswordConfirmText", R.string.EmailPasswordConfirmText, currentPassword.email_unconfirmed_pattern)); + view.setBackgroundResource(R.drawable.greydivider_top); + } else if (i == passwordEnabledDetailRow) { + ((TextInfoPrivacyCell) view).setText(LocaleController.getString("EnabledPasswordText", R.string.EnabledPasswordText)); + view.setBackgroundResource(R.drawable.greydivider_bottom); + } else if (i == passwordEmailVerifyDetailRow) { + ((TextInfoPrivacyCell) view).setText(LocaleController.formatString("PendingEmailText", R.string.PendingEmailText, currentPassword.email_unconfirmed_pattern)); + view.setBackgroundResource(R.drawable.greydivider_bottom); + } + } + return view; + } + + @Override + public int getItemViewType(int i) { + if (i == setPasswordDetailRow || i == shadowRow || i == passwordSetupDetailRow || i == passwordEnabledDetailRow || i == passwordEmailVerifyDetailRow) { + return 1; + } + return 0; + } + + @Override + public int getViewTypeCount() { + return 2; + } + + @Override + public boolean isEmpty() { + return loading || currentPassword == null; + } + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java index 63d0da9c5..7121d0a42 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java @@ -10,6 +10,7 @@ package org.telegram.ui; import android.annotation.TargetApi; import android.app.Activity; +import android.content.Context; import android.content.SharedPreferences; import android.content.res.Configuration; import android.graphics.SurfaceTexture; @@ -22,7 +23,6 @@ import android.view.LayoutInflater; import android.view.Surface; import android.view.TextureView; import android.view.View; -import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.widget.CheckBox; import android.widget.CompoundButton; @@ -43,6 +43,7 @@ import com.googlecode.mp4parser.util.Path; 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.FileLog; import org.telegram.messenger.R; @@ -57,7 +58,7 @@ import java.io.File; import java.util.List; @TargetApi(16) -public class VideoEditorActivity extends BaseFragment implements TextureView.SurfaceTextureListener { +public class VideoEditorActivity extends BaseFragment implements TextureView.SurfaceTextureListener, NotificationCenter.NotificationCenterDelegate { private boolean created = false; private MediaPlayer videoPlayer = null; @@ -97,7 +98,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur private long originalSize = 0; public interface VideoEditorActivityDelegate { - public abstract void didFinishEditVideo(String videoPath, long startTime, long endTime, int resultWidth, int resultHeight, int rotationValue, int originalWidth, int originalHeight, int bitrate, long estimatedSize, long estimatedDuration); + void didFinishEditVideo(String videoPath, long startTime, long endTime, int resultWidth, int resultHeight, int rotationValue, int originalWidth, int originalHeight, int bitrate, long estimatedSize, long estimatedDuration); } private Runnable progressRunnable = new Runnable() { @@ -198,6 +199,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur return false; } + NotificationCenter.getInstance().addObserver(this, NotificationCenter.closeChats); created = true; return super.onFragmentCreate(); @@ -217,196 +219,198 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur FileLog.e("tmessages", e); } } + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.closeChats); super.onFragmentDestroy(); } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackgroundColor(0xff333333); - actionBar.setItemsBackground(R.drawable.bar_selector_white); - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setTitle(LocaleController.getString("EditVideo", R.string.EditVideo)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } else if (id == 1) { - synchronized (sync) { - if (videoPlayer != null) { - try { - videoPlayer.stop(); - videoPlayer.release(); - videoPlayer = null; - } catch (Exception e) { - FileLog.e("tmessages", e); - } + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackgroundColor(0xff333333); + actionBar.setItemsBackground(R.drawable.bar_selector_white); + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setTitle(LocaleController.getString("EditVideo", R.string.EditVideo)); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } else if (id == 1) { + synchronized (sync) { + if (videoPlayer != null) { + try { + videoPlayer.stop(); + videoPlayer.release(); + videoPlayer = null; + } catch (Exception e) { + FileLog.e("tmessages", e); } } - if (delegate != null) { - if (compressVideo.getVisibility() == View.GONE || compressVideo.getVisibility() == View.VISIBLE && !compressVideo.isChecked()) { - delegate.didFinishEditVideo(videoPath, startTime, endTime, originalWidth, originalHeight, rotationValue, originalWidth, originalHeight, bitrate, estimatedSize, esimatedDuration); - } else { - delegate.didFinishEditVideo(videoPath, startTime, endTime, resultWidth, resultHeight, rotationValue, originalWidth, originalHeight, bitrate, estimatedSize, esimatedDuration); - } - } - finishFragment(); } + if (delegate != null) { + if (compressVideo.getVisibility() == View.GONE || compressVideo.getVisibility() == View.VISIBLE && !compressVideo.isChecked()) { + delegate.didFinishEditVideo(videoPath, startTime, endTime, originalWidth, originalHeight, rotationValue, originalWidth, originalHeight, bitrate, estimatedSize, esimatedDuration); + } else { + delegate.didFinishEditVideo(videoPath, startTime, endTime, resultWidth, resultHeight, rotationValue, originalWidth, originalHeight, bitrate, estimatedSize, esimatedDuration); + } + } + finishFragment(); } - }); + } + }); - ActionBarMenu menu = actionBar.createMenu(); - menu.addItemWithWidth(1, R.drawable.ic_done, AndroidUtilities.dp(56)); + ActionBarMenu menu = actionBar.createMenu(); + menu.addItemWithWidth(1, R.drawable.ic_done, AndroidUtilities.dp(56)); - fragmentView = inflater.inflate(R.layout.video_editor_layout, container, false); - originalSizeTextView = (TextView) fragmentView.findViewById(R.id.original_size); - editedSizeTextView = (TextView) fragmentView.findViewById(R.id.edited_size); - videoContainerView = fragmentView.findViewById(R.id.video_container); - textContainerView = fragmentView.findViewById(R.id.info_container); - controlView = fragmentView.findViewById(R.id.control_layout); - compressVideo = (CheckBox) fragmentView.findViewById(R.id.compress_video); - compressVideo.setText(LocaleController.getString("CompressVideo", R.string.CompressVideo)); - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); - compressVideo.setVisibility(originalHeight != resultHeight || originalWidth != resultWidth ? View.VISIBLE : View.GONE); - compressVideo.setChecked(preferences.getBoolean("compress_video", true)); - compressVideo.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - editor.putBoolean("compress_video", isChecked); - editor.commit(); - updateVideoEditedInfo(); - } - }); + fragmentView = inflater.inflate(R.layout.video_editor_layout, null, false); + originalSizeTextView = (TextView) fragmentView.findViewById(R.id.original_size); + editedSizeTextView = (TextView) fragmentView.findViewById(R.id.edited_size); + videoContainerView = fragmentView.findViewById(R.id.video_container); + textContainerView = fragmentView.findViewById(R.id.info_container); + controlView = fragmentView.findViewById(R.id.control_layout); + compressVideo = (CheckBox) fragmentView.findViewById(R.id.compress_video); + compressVideo.setText(LocaleController.getString("CompressVideo", R.string.CompressVideo)); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + compressVideo.setVisibility(originalHeight != resultHeight || originalWidth != resultWidth ? View.VISIBLE : View.GONE); + compressVideo.setChecked(preferences.getBoolean("compress_video", true)); + compressVideo.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.putBoolean("compress_video", isChecked); + editor.commit(); + updateVideoEditedInfo(); + } + }); - if (Build.VERSION.SDK_INT < 18) { - try { - MediaCodecInfo codecInfo = MediaController.selectCodec(MediaController.MIME_TYPE); - if (codecInfo == null) { + if (Build.VERSION.SDK_INT < 18) { + try { + MediaCodecInfo codecInfo = MediaController.selectCodec(MediaController.MIME_TYPE); + if (codecInfo == null) { + compressVideo.setVisibility(View.GONE); + } else { + String name = codecInfo.getName(); + if (name.equals("OMX.google.h264.encoder") || + name.equals("OMX.ST.VFM.H264Enc") || + name.equals("OMX.Exynos.avc.enc") || + name.equals("OMX.MARVELL.VIDEO.HW.CODA7542ENCODER") || + name.equals("OMX.MARVELL.VIDEO.H264ENCODER") || + name.equals("OMX.k3.video.encoder.avc") || //fix this later + name.equals("OMX.TI.DUCATI1.VIDEO.H264E")) { //fix this later compressVideo.setVisibility(View.GONE); } else { - String name = codecInfo.getName(); - if (name.equals("OMX.google.h264.encoder") || - name.equals("OMX.ST.VFM.H264Enc") || - name.equals("OMX.Exynos.avc.enc") || - name.equals("OMX.MARVELL.VIDEO.HW.CODA7542ENCODER") || - name.equals("OMX.MARVELL.VIDEO.H264ENCODER") || - name.equals("OMX.k3.video.encoder.avc") || //fix this later - name.equals("OMX.TI.DUCATI1.VIDEO.H264E")) { //fix this later + if (MediaController.selectColorFormat(codecInfo, MediaController.MIME_TYPE) == 0) { compressVideo.setVisibility(View.GONE); - } else { - if (MediaController.selectColorFormat(codecInfo, MediaController.MIME_TYPE) == 0) { - compressVideo.setVisibility(View.GONE); - } } } - } catch (Exception e) { - compressVideo.setVisibility(View.GONE); - FileLog.e("tmessages", e); } - } - - TextView titleTextView = (TextView) fragmentView.findViewById(R.id.original_title); - titleTextView.setText(LocaleController.getString("OriginalVideo", R.string.OriginalVideo)); - titleTextView = (TextView) fragmentView.findViewById(R.id.edited_title); - titleTextView.setText(LocaleController.getString("EditedVideo", R.string.EditedVideo)); - - videoTimelineView = (VideoTimelineView) fragmentView.findViewById(R.id.video_timeline_view); - videoTimelineView.setVideoPath(videoPath); - videoTimelineView.setDelegate(new VideoTimelineView.VideoTimelineViewDelegate() { - @Override - public void onLeftProgressChanged(float progress) { - if (videoPlayer == null || !playerPrepared) { - return; - } - try { - if (videoPlayer.isPlaying()) { - videoPlayer.pause(); - playButton.setImageResource(R.drawable.video_play); - } - videoPlayer.setOnSeekCompleteListener(null); - videoPlayer.seekTo((int) (videoDuration * progress)); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - needSeek = true; - videoSeekBarView.setProgress(videoTimelineView.getLeftProgress()); - updateVideoEditedInfo(); - } - - @Override - public void onRifhtProgressChanged(float progress) { - if (videoPlayer == null || !playerPrepared) { - return; - } - try { - if (videoPlayer.isPlaying()) { - videoPlayer.pause(); - playButton.setImageResource(R.drawable.video_play); - } - videoPlayer.setOnSeekCompleteListener(null); - videoPlayer.seekTo((int) (videoDuration * progress)); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - needSeek = true; - videoSeekBarView.setProgress(videoTimelineView.getLeftProgress()); - updateVideoEditedInfo(); - } - }); - - videoSeekBarView = (VideoSeekBarView) fragmentView.findViewById(R.id.video_seekbar); - videoSeekBarView.delegate = new VideoSeekBarView.SeekBarDelegate() { - @Override - public void onSeekBarDrag(float progress) { - if (progress < videoTimelineView.getLeftProgress()) { - progress = videoTimelineView.getLeftProgress(); - videoSeekBarView.setProgress(progress); - } else if (progress > videoTimelineView.getRightProgress()) { - progress = videoTimelineView.getRightProgress(); - videoSeekBarView.setProgress(progress); - } - if (videoPlayer == null || !playerPrepared) { - return; - } - if (videoPlayer.isPlaying()) { - try { - videoPlayer.seekTo((int) (videoDuration * progress)); - lastProgress = progress; - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } else { - lastProgress = progress; - needSeek = true; - } - } - }; - - playButton = (ImageView) fragmentView.findViewById(R.id.play_button); - playButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - play(); - } - }); - - textureView = (TextureView) fragmentView.findViewById(R.id.video_view); - textureView.setSurfaceTextureListener(this); - - updateVideoOriginalInfo(); - updateVideoEditedInfo(); - } else { - ViewGroup parent = (ViewGroup) fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); + } catch (Exception e) { + compressVideo.setVisibility(View.GONE); + FileLog.e("tmessages", e); } } + + TextView titleTextView = (TextView) fragmentView.findViewById(R.id.original_title); + titleTextView.setText(LocaleController.getString("OriginalVideo", R.string.OriginalVideo)); + titleTextView = (TextView) fragmentView.findViewById(R.id.edited_title); + titleTextView.setText(LocaleController.getString("EditedVideo", R.string.EditedVideo)); + + videoTimelineView = (VideoTimelineView) fragmentView.findViewById(R.id.video_timeline_view); + videoTimelineView.setVideoPath(videoPath); + videoTimelineView.setDelegate(new VideoTimelineView.VideoTimelineViewDelegate() { + @Override + public void onLeftProgressChanged(float progress) { + if (videoPlayer == null || !playerPrepared) { + return; + } + try { + if (videoPlayer.isPlaying()) { + videoPlayer.pause(); + playButton.setImageResource(R.drawable.video_play); + } + videoPlayer.setOnSeekCompleteListener(null); + videoPlayer.seekTo((int) (videoDuration * progress)); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + needSeek = true; + videoSeekBarView.setProgress(videoTimelineView.getLeftProgress()); + updateVideoEditedInfo(); + } + + @Override + public void onRifhtProgressChanged(float progress) { + if (videoPlayer == null || !playerPrepared) { + return; + } + try { + if (videoPlayer.isPlaying()) { + videoPlayer.pause(); + playButton.setImageResource(R.drawable.video_play); + } + videoPlayer.setOnSeekCompleteListener(null); + videoPlayer.seekTo((int) (videoDuration * progress)); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + needSeek = true; + videoSeekBarView.setProgress(videoTimelineView.getLeftProgress()); + updateVideoEditedInfo(); + } + }); + + videoSeekBarView = (VideoSeekBarView) fragmentView.findViewById(R.id.video_seekbar); + videoSeekBarView.delegate = new VideoSeekBarView.SeekBarDelegate() { + @Override + public void onSeekBarDrag(float progress) { + if (progress < videoTimelineView.getLeftProgress()) { + progress = videoTimelineView.getLeftProgress(); + videoSeekBarView.setProgress(progress); + } else if (progress > videoTimelineView.getRightProgress()) { + progress = videoTimelineView.getRightProgress(); + videoSeekBarView.setProgress(progress); + } + if (videoPlayer == null || !playerPrepared) { + return; + } + if (videoPlayer.isPlaying()) { + try { + videoPlayer.seekTo((int) (videoDuration * progress)); + lastProgress = progress; + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } else { + lastProgress = progress; + needSeek = true; + } + } + }; + + playButton = (ImageView) fragmentView.findViewById(R.id.play_button); + playButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + play(); + } + }); + + textureView = (TextureView) fragmentView.findViewById(R.id.video_view); + textureView.setSurfaceTextureListener(this); + + updateVideoOriginalInfo(); + updateVideoEditedInfo(); + return fragmentView; } + @Override + public void didReceivedNotification(int id, Object... args) { + if (id == NotificationCenter.closeChats) { + removeSelfFromStack(); + } + } + private void setPlayerSurface() { if (textureView == null || !textureView.isAvailable() || videoPlayer == null) { return; @@ -578,6 +582,9 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur } private void fixLayoutInternal() { + if (getParentActivity() == null) { + return; + } if (!AndroidUtilities.isTablet() && getParentActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) videoContainerView.getLayoutParams(); layoutParams.topMargin = AndroidUtilities.dp(16); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/WallpapersActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/WallpapersActivity.java index 5b428a431..ab3380f21 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/WallpapersActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/WallpapersActivity.java @@ -63,8 +63,8 @@ public class WallpapersActivity extends BaseFragment implements NotificationCent private ProgressBar progressBar; private int selectedBackground; private int selectedColor; - private ArrayList wallPapers = new ArrayList(); - private HashMap wallpappersByIds = new HashMap(); + private ArrayList wallPapers = new ArrayList<>(); + private HashMap wallpappersByIds = new HashMap<>(); private View doneButton; private String loadingFile = null; private File loadingFileObject = null; @@ -101,120 +101,114 @@ public class WallpapersActivity extends BaseFragment implements NotificationCent } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - actionBar.setTitle(LocaleController.getString("ChatBackground", R.string.ChatBackground)); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } else if (id == done_button) { - boolean done; - TLRPC.WallPaper wallPaper = wallpappersByIds.get(selectedBackground); - if (wallPaper != null && wallPaper.id != 1000001 && wallPaper instanceof TLRPC.TL_wallPaper) { - int width = AndroidUtilities.displaySize.x; - int height = AndroidUtilities.displaySize.y; - if (width > height) { - int temp = width; - width = height; - height = temp; - } - TLRPC.PhotoSize size = FileLoader.getClosestPhotoSizeWithSize(wallPaper.sizes, Math.min(width, height)); - String fileName = size.location.volume_id + "_" + size.location.local_id + ".jpg"; - File f = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName); + public View createView(Context context, LayoutInflater inflater) { + actionBar.setBackButtonImage(R.drawable.ic_ab_back); + actionBar.setAllowOverlayTitle(true); + actionBar.setTitle(LocaleController.getString("ChatBackground", R.string.ChatBackground)); + actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { + @Override + public void onItemClick(int id) { + if (id == -1) { + finishFragment(); + } else if (id == done_button) { + boolean done; + TLRPC.WallPaper wallPaper = wallpappersByIds.get(selectedBackground); + if (wallPaper != null && wallPaper.id != 1000001 && wallPaper instanceof TLRPC.TL_wallPaper) { + int width = AndroidUtilities.displaySize.x; + int height = AndroidUtilities.displaySize.y; + if (width > height) { + int temp = width; + width = height; + height = temp; + } + TLRPC.PhotoSize size = FileLoader.getClosestPhotoSizeWithSize(wallPaper.sizes, Math.min(width, height)); + String fileName = size.location.volume_id + "_" + size.location.local_id + ".jpg"; + File f = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName); + File toFile = new File(ApplicationLoader.applicationContext.getFilesDir(), "wallpaper.jpg"); + try { + done = Utilities.copyFile(f, toFile); + } catch (Exception e) { + done = false; + FileLog.e("tmessages", e); + } + } else { + if (selectedBackground == -1) { + File fromFile = new File(ApplicationLoader.applicationContext.getFilesDir(), "wallpaper-temp.jpg"); File toFile = new File(ApplicationLoader.applicationContext.getFilesDir(), "wallpaper.jpg"); + done = fromFile.renameTo(toFile); + } else { + done = true; + } + } + + if (done) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.putInt("selectedBackground", selectedBackground); + editor.putInt("selectedColor", selectedColor); + editor.commit(); + ApplicationLoader.reloadWallpaper(); + } + finishFragment(); + } + } + }); + + ActionBarMenu menu = actionBar.createMenu(); + doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); + + fragmentView = inflater.inflate(R.layout.settings_wallpapers_layout, null, false); + listAdapter = new ListAdapter(context); + + progressBar = (ProgressBar) fragmentView.findViewById(R.id.action_progress); + backgroundImage = (ImageView) fragmentView.findViewById(R.id.background_image); + listView = (HorizontalListView) fragmentView.findViewById(R.id.listView); + listView.setAdapter(listAdapter); + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, int i, long l) { + if (i == 0) { + if (getParentActivity() == null) { + return; + } + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + + CharSequence[] items = new CharSequence[]{LocaleController.getString("FromCamera", R.string.FromCamera), LocaleController.getString("FromGalley", R.string.FromGalley), LocaleController.getString("Cancel", R.string.Cancel)}; + + builder.setItems(items, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { try { - done = Utilities.copyFile(f, toFile); + if (i == 0) { + Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + File image = Utilities.generatePicturePath(); + if (image != null) { + takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image)); + currentPicturePath = image.getAbsolutePath(); + } + startActivityForResult(takePictureIntent, 10); + } else if (i == 1) { + Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); + photoPickerIntent.setType("image/*"); + startActivityForResult(photoPickerIntent, 11); + } } catch (Exception e) { - done = false; FileLog.e("tmessages", e); } - } else { - if (selectedBackground == -1) { - File fromFile = new File(ApplicationLoader.applicationContext.getFilesDir(), "wallpaper-temp.jpg"); - File toFile = new File(ApplicationLoader.applicationContext.getFilesDir(), "wallpaper.jpg"); - done = fromFile.renameTo(toFile); - } else { - done = true; - } } - - if (done) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - editor.putInt("selectedBackground", selectedBackground); - editor.putInt("selectedColor", selectedColor); - editor.commit(); - ApplicationLoader.cachedWallpaper = null; - } - finishFragment(); - } + }); + showAlertDialog(builder); + } else { + TLRPC.WallPaper wallPaper = wallPapers.get(i - 1); + selectedBackground = wallPaper.id; + listAdapter.notifyDataSetChanged(); + processSelectedBackground(); } - }); - - ActionBarMenu menu = actionBar.createMenu(); - doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); - - fragmentView = inflater.inflate(R.layout.settings_wallpapers_layout, container, false); - listAdapter = new ListAdapter(getParentActivity()); - - progressBar = (ProgressBar)fragmentView.findViewById(R.id.action_progress); - backgroundImage = (ImageView)fragmentView.findViewById(R.id.background_image); - listView = (HorizontalListView)fragmentView.findViewById(R.id.listView); - listView.setAdapter(listAdapter); - listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, int i, long l) { - if (i == 0) { - if (getParentActivity() == null) { - return; - } - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - - CharSequence[] items = new CharSequence[] {LocaleController.getString("FromCamera", R.string.FromCamera), LocaleController.getString("FromGalley", R.string.FromGalley), LocaleController.getString("Cancel", R.string.Cancel)}; - - builder.setItems(items, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - try { - if (i == 0) { - Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - File image = Utilities.generatePicturePath(); - if (image != null) { - takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image)); - currentPicturePath = image.getAbsolutePath(); - } - startActivityForResult(takePictureIntent, 10); - } else if (i == 1) { - Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); - photoPickerIntent.setType("image/*"); - startActivityForResult(photoPickerIntent, 11); - } - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } - }); - showAlertDialog(builder); - } else { - TLRPC.WallPaper wallPaper = wallPapers.get(i - 1); - selectedBackground = wallPaper.id; - listAdapter.notifyDataSetChanged(); - processSelectedBackground(); - } - } - }); - - processSelectedBackground(); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); } - } + }); + + processSelectedBackground(); + return fragmentView; } @@ -223,17 +217,26 @@ public class WallpapersActivity extends BaseFragment implements NotificationCent if (resultCode == Activity.RESULT_OK) { if (requestCode == 10) { Utilities.addMediaToGallery(currentPicturePath); + FileOutputStream stream = null; try { Point screenSize = AndroidUtilities.getRealScreenSize(); Bitmap bitmap = ImageLoader.loadBitmap(currentPicturePath, null, screenSize.x, screenSize.y, true); File toFile = new File(ApplicationLoader.applicationContext.getFilesDir(), "wallpaper-temp.jpg"); - FileOutputStream stream = new FileOutputStream(toFile); + stream = new FileOutputStream(toFile); bitmap.compress(Bitmap.CompressFormat.JPEG, 87, stream); selectedBackground = -1; selectedColor = 0; backgroundImage.setImageBitmap(bitmap); } catch (Exception e) { FileLog.e("tmessages", e); + } finally { + try { + if (stream != null) { + stream.close(); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } } currentPicturePath = null; } else if (requestCode == 11) { @@ -419,7 +422,9 @@ public class WallpapersActivity extends BaseFragment implements NotificationCent wallPapers.add((TLRPC.WallPaper)obj); wallpappersByIds.put(((TLRPC.WallPaper)obj).id, (TLRPC.WallPaper)obj); } - listAdapter.notifyDataSetChanged(); + if (listAdapter != null) { + listAdapter.notifyDataSetChanged(); + } if (backgroundImage != null) { processSelectedBackground(); } diff --git a/TMessagesProj/src/main/res/drawable-hdpi/blur_linear.png b/TMessagesProj/src/main/res/drawable-hdpi/blur_linear.png new file mode 100755 index 000000000..7d255cf57 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/blur_linear.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/blur_linear_active.png b/TMessagesProj/src/main/res/drawable-hdpi/blur_linear_active.png new file mode 100755 index 000000000..9103cc6c2 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/blur_linear_active.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/blur_off.png b/TMessagesProj/src/main/res/drawable-hdpi/blur_off.png new file mode 100755 index 000000000..172256dca Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/blur_off.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/blur_off_active.png b/TMessagesProj/src/main/res/drawable-hdpi/blur_off_active.png new file mode 100755 index 000000000..22124bcf4 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/blur_off_active.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/blur_radial.png b/TMessagesProj/src/main/res/drawable-hdpi/blur_radial.png new file mode 100755 index 000000000..0e4d1b76e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/blur_radial.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/blur_radial_active.png b/TMessagesProj/src/main/res/drawable-hdpi/blur_radial_active.png new file mode 100755 index 000000000..73725eea9 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/blur_radial_active.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/bottom_shadow.png b/TMessagesProj/src/main/res/drawable-hdpi/bottom_shadow.png new file mode 100755 index 000000000..5dc9ed10a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/bottom_shadow.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/boxshadow.9.png b/TMessagesProj/src/main/res/drawable-hdpi/boxshadow.9.png index a4559eb2c..9c4c66110 100644 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/boxshadow.9.png and b/TMessagesProj/src/main/res/drawable-hdpi/boxshadow.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/delete_reply.png b/TMessagesProj/src/main/res/drawable-hdpi/delete_reply.png new file mode 100755 index 000000000..213ff5b50 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/delete_reply.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/devices.png b/TMessagesProj/src/main/res/drawable-hdpi/devices.png new file mode 100755 index 000000000..768704968 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/devices.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/doc_actions_g.png b/TMessagesProj/src/main/res/drawable-hdpi/doc_actions_g.png index c33a4c2fc..09dea5d2a 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/doc_actions_g.png and b/TMessagesProj/src/main/res/drawable-hdpi/doc_actions_g.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/edit_cancel.png b/TMessagesProj/src/main/res/drawable-hdpi/edit_cancel.png new file mode 100755 index 000000000..8fb629d04 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/edit_cancel.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/edit_doneblue.png b/TMessagesProj/src/main/res/drawable-hdpi/edit_doneblue.png new file mode 100755 index 000000000..ad5f280d1 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/edit_doneblue.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/forward_blue.png b/TMessagesProj/src/main/res/drawable-hdpi/forward_blue.png new file mode 100644 index 000000000..36d5c85d6 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/forward_blue.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/gif_search.png b/TMessagesProj/src/main/res/drawable-hdpi/gif_search.png deleted file mode 100644 index ab687dad9..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/gif_search.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/greydivider_top.9.png b/TMessagesProj/src/main/res/drawable-hdpi/greydivider_top.9.png new file mode 100644 index 000000000..4523e953c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/greydivider_top.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_delete_white.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_delete_white.png deleted file mode 100644 index f3273d774..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_delete_white.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_fwd_forward.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_fwd_forward.png index cfa12ce25..bbe96ec85 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_fwd_forward.png and b/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_fwd_forward.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_reply.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_reply.png new file mode 100755 index 000000000..2d78652e7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_reply.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_share_white.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_share_white.png deleted file mode 100644 index 2b9baf7ca..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_share_white.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/igvideo.png b/TMessagesProj/src/main/res/drawable-hdpi/igvideo.png new file mode 100644 index 000000000..92c22481f Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/igvideo.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/link.png b/TMessagesProj/src/main/res/drawable-hdpi/link.png new file mode 100644 index 000000000..5ad1fcb8f Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/link.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/lock_close.png b/TMessagesProj/src/main/res/drawable-hdpi/lock_close.png new file mode 100644 index 000000000..f9b9072cd Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/lock_close.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/lock_open.png b/TMessagesProj/src/main/res/drawable-hdpi/lock_open.png new file mode 100644 index 000000000..b7cc48642 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/lock_open.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_check.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_check.png index 7d63d9115..80e7278e6 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/msg_check.png and b/TMessagesProj/src/main/res/drawable-hdpi/msg_check.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_check_w.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_check_w.png index a35fc7a4f..be83f2bf2 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/msg_check_w.png and b/TMessagesProj/src/main/res/drawable-hdpi/msg_check_w.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_halfcheck.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_halfcheck.png index 0676d17d4..f568503fd 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/msg_halfcheck.png and b/TMessagesProj/src/main/res/drawable-hdpi/msg_halfcheck.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_halfcheck_w.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_halfcheck_w.png index 950d5f251..1cb636875 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/msg_halfcheck_w.png and b/TMessagesProj/src/main/res/drawable-hdpi/msg_halfcheck_w.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_out.9.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_out.9.png index 81cd229e7..08fd35b4c 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/msg_out.9.png and b/TMessagesProj/src/main/res/drawable-hdpi/msg_out.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo.9.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo.9.png index ccfdbaa27..f8f07f7fb 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo.9.png and b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo_selected.9.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo_selected.9.png index 6b4885485..3d5b1f9fa 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo_selected.9.png and b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_out_selected.9.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_selected.9.png index b73ee8be8..5e01d8fe3 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/msg_out_selected.9.png and b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/passcode_check.png b/TMessagesProj/src/main/res/drawable-hdpi/passcode_check.png new file mode 100644 index 000000000..d9b4dc28d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/passcode_check.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/passcode_delete.png b/TMessagesProj/src/main/res/drawable-hdpi/passcode_delete.png new file mode 100644 index 000000000..317c52c5c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/passcode_delete.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/passcode_logo.png b/TMessagesProj/src/main/res/drawable-hdpi/passcode_logo.png new file mode 100644 index 000000000..a004ca95c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/passcode_logo.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/photo_filters.png b/TMessagesProj/src/main/res/drawable-hdpi/photo_filters.png deleted file mode 100644 index 2bd619df2..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/photo_filters.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/photo_filters_active.png b/TMessagesProj/src/main/res/drawable-hdpi/photo_filters_active.png deleted file mode 100644 index e9ad643a6..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/photo_filters_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/photo_rotate.png b/TMessagesProj/src/main/res/drawable-hdpi/photo_rotate.png deleted file mode 100644 index 31e097a2e..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/photo_rotate.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/photo_sizes.png b/TMessagesProj/src/main/res/drawable-hdpi/photo_sizes.png deleted file mode 100644 index ac8c78186..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/photo_sizes.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/photo_tune.png b/TMessagesProj/src/main/res/drawable-hdpi/photo_tune.png deleted file mode 100644 index dc365663d..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/photo_tune.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/photo_tune_active.png b/TMessagesProj/src/main/res/drawable-hdpi/photo_tune_active.png deleted file mode 100644 index 1a30ec1d4..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/photo_tune_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/reply.png b/TMessagesProj/src/main/res/drawable-hdpi/reply.png new file mode 100755 index 000000000..98db79e65 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/reply.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/search_gif.png b/TMessagesProj/src/main/res/drawable-hdpi/search_gif.png new file mode 100755 index 000000000..3be94584a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/search_gif.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/search_web.png b/TMessagesProj/src/main/res/drawable-hdpi/search_web.png new file mode 100755 index 000000000..900a5303b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/search_web.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/selectphoto_small.png b/TMessagesProj/src/main/res/drawable-hdpi/selectphoto_small.png deleted file mode 100755 index 7a023ec07..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/selectphoto_small.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/selectphoto_small_active.png b/TMessagesProj/src/main/res/drawable-hdpi/selectphoto_small_active.png deleted file mode 100755 index 7a023ec07..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/selectphoto_small_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/selectphoto_small_grey.png b/TMessagesProj/src/main/res/drawable-hdpi/selectphoto_small_grey.png deleted file mode 100755 index 6cf4bcda9..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/selectphoto_small_grey.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/share.png b/TMessagesProj/src/main/res/drawable-hdpi/share.png new file mode 100755 index 000000000..8b853cf2d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/share.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/sharedmedia.png b/TMessagesProj/src/main/res/drawable-hdpi/sharedmedia.png new file mode 100755 index 000000000..532e67de0 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/sharedmedia.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/system_blue.9.png b/TMessagesProj/src/main/res/drawable-hdpi/system_blue.9.png old mode 100644 new mode 100755 index 9612e61aa..65ad2140d Binary files a/TMessagesProj/src/main/res/drawable-hdpi/system_blue.9.png and b/TMessagesProj/src/main/res/drawable-hdpi/system_blue.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_blur.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_blur.png new file mode 100755 index 000000000..c8614ecb9 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_blur.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_brightness.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_brightness.png new file mode 100755 index 000000000..fe2ae0640 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_brightness.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_contrast.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_contrast.png new file mode 100755 index 000000000..21a65034b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_contrast.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_details.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_details.png new file mode 100755 index 000000000..85549500b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_details.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_enhance.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_enhance.png new file mode 100755 index 000000000..a365ce793 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_enhance.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_grain.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_grain.png new file mode 100755 index 000000000..39a73a1f7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_grain.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_highlights.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_highlights.png new file mode 100755 index 000000000..5530def4b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_highlights.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_saturation.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_saturation.png new file mode 100755 index 000000000..5d79e93f1 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_saturation.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_shadows.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_shadows.png new file mode 100755 index 000000000..0dc33aa00 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_shadows.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_vignette.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_vignette.png new file mode 100755 index 000000000..a6ac05878 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_vignette.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_warmth.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_warmth.png new file mode 100755 index 000000000..2392e7389 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_warmth.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tune.png b/TMessagesProj/src/main/res/drawable-hdpi/tune.png new file mode 100755 index 000000000..ab404e6a5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tune.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/web_search.png b/TMessagesProj/src/main/res/drawable-hdpi/web_search.png deleted file mode 100644 index a73acd91c..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/web_search.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/blur_linear.png b/TMessagesProj/src/main/res/drawable-mdpi/blur_linear.png new file mode 100755 index 000000000..06d029c46 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/blur_linear.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/blur_linear_active.png b/TMessagesProj/src/main/res/drawable-mdpi/blur_linear_active.png new file mode 100755 index 000000000..c3ffe1bef Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/blur_linear_active.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/blur_off.png b/TMessagesProj/src/main/res/drawable-mdpi/blur_off.png new file mode 100755 index 000000000..424aaa5b4 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/blur_off.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/blur_off_active.png b/TMessagesProj/src/main/res/drawable-mdpi/blur_off_active.png new file mode 100755 index 000000000..5dfc12a2b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/blur_off_active.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/blur_radial.png b/TMessagesProj/src/main/res/drawable-mdpi/blur_radial.png new file mode 100755 index 000000000..a30d6619b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/blur_radial.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/blur_radial_active.png b/TMessagesProj/src/main/res/drawable-mdpi/blur_radial_active.png new file mode 100755 index 000000000..a385ca60a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/blur_radial_active.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/bottom_shadow.png b/TMessagesProj/src/main/res/drawable-mdpi/bottom_shadow.png new file mode 100755 index 000000000..3e170fda5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/bottom_shadow.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/boxshadow.9.png b/TMessagesProj/src/main/res/drawable-mdpi/boxshadow.9.png index e0ed0f591..c63d9ff95 100644 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/boxshadow.9.png and b/TMessagesProj/src/main/res/drawable-mdpi/boxshadow.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/delete_reply.png b/TMessagesProj/src/main/res/drawable-mdpi/delete_reply.png new file mode 100755 index 000000000..2fd1c1ac9 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/delete_reply.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/devices.png b/TMessagesProj/src/main/res/drawable-mdpi/devices.png new file mode 100755 index 000000000..b6bd7a72c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/devices.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/doc_actions_g.png b/TMessagesProj/src/main/res/drawable-mdpi/doc_actions_g.png index 069ff82af..1c1921a82 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/doc_actions_g.png and b/TMessagesProj/src/main/res/drawable-mdpi/doc_actions_g.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/edit_cancel.png b/TMessagesProj/src/main/res/drawable-mdpi/edit_cancel.png new file mode 100755 index 000000000..5dd045bca Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/edit_cancel.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/edit_doneblue.png b/TMessagesProj/src/main/res/drawable-mdpi/edit_doneblue.png new file mode 100755 index 000000000..494f4f85a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/edit_doneblue.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/forward_blue.png b/TMessagesProj/src/main/res/drawable-mdpi/forward_blue.png new file mode 100644 index 000000000..7f4ec885e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/forward_blue.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/gif_search.png b/TMessagesProj/src/main/res/drawable-mdpi/gif_search.png deleted file mode 100644 index bf910aaa5..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/gif_search.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/photo_sizes.png b/TMessagesProj/src/main/res/drawable-mdpi/greydivider_top.9.png similarity index 51% rename from TMessagesProj/src/main/res/drawable-mdpi/photo_sizes.png rename to TMessagesProj/src/main/res/drawable-mdpi/greydivider_top.9.png index 34d1d2ba1..1faeb2636 100644 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/photo_sizes.png and b/TMessagesProj/src/main/res/drawable-mdpi/greydivider_top.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_delete_white.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_delete_white.png deleted file mode 100644 index 49f05043b..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_delete_white.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_fwd_forward.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_fwd_forward.png index fe943423e..5a0f86d73 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_fwd_forward.png and b/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_fwd_forward.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_reply.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_reply.png new file mode 100755 index 000000000..a8d829411 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_reply.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_share_white.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_share_white.png deleted file mode 100644 index eee5acefa..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_share_white.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/igvideo.png b/TMessagesProj/src/main/res/drawable-mdpi/igvideo.png new file mode 100644 index 000000000..e7b93b3b7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/igvideo.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/link.png b/TMessagesProj/src/main/res/drawable-mdpi/link.png new file mode 100644 index 000000000..24125b57e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/link.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/lock_close.png b/TMessagesProj/src/main/res/drawable-mdpi/lock_close.png new file mode 100644 index 000000000..47b4dd80a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/lock_close.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/lock_open.png b/TMessagesProj/src/main/res/drawable-mdpi/lock_open.png new file mode 100644 index 000000000..689f1901e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/lock_open.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_check.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_check.png index 6f92478e4..2fdad7a38 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/msg_check.png and b/TMessagesProj/src/main/res/drawable-mdpi/msg_check.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_check_w.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_check_w.png index ab1c1ba59..f2448a0a5 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/msg_check_w.png and b/TMessagesProj/src/main/res/drawable-mdpi/msg_check_w.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_halfcheck.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_halfcheck.png index 2df5738e6..010da7c52 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/msg_halfcheck.png and b/TMessagesProj/src/main/res/drawable-mdpi/msg_halfcheck.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_halfcheck_w.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_halfcheck_w.png index b1ef529ff..d5c1888a9 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/msg_halfcheck_w.png and b/TMessagesProj/src/main/res/drawable-mdpi/msg_halfcheck_w.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_out.9.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_out.9.png index f8496cd47..f22c541f7 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/msg_out.9.png and b/TMessagesProj/src/main/res/drawable-mdpi/msg_out.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo.9.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo.9.png index d144e3552..ad4ad9ce2 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo.9.png and b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo_selected.9.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo_selected.9.png index d38cf29db..734f94360 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo_selected.9.png and b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_out_selected.9.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_selected.9.png index 06f6fe053..7e29c8128 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/msg_out_selected.9.png and b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/passcode_check.png b/TMessagesProj/src/main/res/drawable-mdpi/passcode_check.png new file mode 100644 index 000000000..1a39754e0 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/passcode_check.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/passcode_delete.png b/TMessagesProj/src/main/res/drawable-mdpi/passcode_delete.png new file mode 100644 index 000000000..c1ccb443b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/passcode_delete.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/passcode_logo.png b/TMessagesProj/src/main/res/drawable-mdpi/passcode_logo.png new file mode 100644 index 000000000..865cb4c97 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/passcode_logo.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/photo_filters.png b/TMessagesProj/src/main/res/drawable-mdpi/photo_filters.png deleted file mode 100644 index 890d61d5d..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/photo_filters.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/photo_filters_active.png b/TMessagesProj/src/main/res/drawable-mdpi/photo_filters_active.png deleted file mode 100644 index 62cfe9ab5..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/photo_filters_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/photo_rotate.png b/TMessagesProj/src/main/res/drawable-mdpi/photo_rotate.png deleted file mode 100644 index cdfc85301..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/photo_rotate.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/photo_tune.png b/TMessagesProj/src/main/res/drawable-mdpi/photo_tune.png deleted file mode 100644 index 9db5621e4..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/photo_tune.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/photo_tune_active.png b/TMessagesProj/src/main/res/drawable-mdpi/photo_tune_active.png deleted file mode 100644 index 61eab0c57..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/photo_tune_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/reply.png b/TMessagesProj/src/main/res/drawable-mdpi/reply.png new file mode 100755 index 000000000..7d71990f7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/reply.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/search_gif.png b/TMessagesProj/src/main/res/drawable-mdpi/search_gif.png new file mode 100755 index 000000000..5e8873fa7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/search_gif.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/search_web.png b/TMessagesProj/src/main/res/drawable-mdpi/search_web.png new file mode 100755 index 000000000..bab8acf03 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/search_web.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/selectphoto_small.png b/TMessagesProj/src/main/res/drawable-mdpi/selectphoto_small.png deleted file mode 100755 index 051f23a6f..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/selectphoto_small.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/selectphoto_small_active.png b/TMessagesProj/src/main/res/drawable-mdpi/selectphoto_small_active.png deleted file mode 100755 index 051f23a6f..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/selectphoto_small_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/selectphoto_small_grey.png b/TMessagesProj/src/main/res/drawable-mdpi/selectphoto_small_grey.png deleted file mode 100755 index 0dcf76705..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/selectphoto_small_grey.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/share.png b/TMessagesProj/src/main/res/drawable-mdpi/share.png new file mode 100755 index 000000000..48a9439cb Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/share.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/sharedmedia.png b/TMessagesProj/src/main/res/drawable-mdpi/sharedmedia.png new file mode 100755 index 000000000..cc21392b4 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/sharedmedia.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/system_blue.9.png b/TMessagesProj/src/main/res/drawable-mdpi/system_blue.9.png old mode 100644 new mode 100755 index 40f8cc607..c1ce3b4f6 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/system_blue.9.png and b/TMessagesProj/src/main/res/drawable-mdpi/system_blue.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_blur.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_blur.png new file mode 100755 index 000000000..9c0592331 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_blur.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_brightness.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_brightness.png new file mode 100755 index 000000000..bc83f7365 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_brightness.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_contrast.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_contrast.png new file mode 100755 index 000000000..ff596a32d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_contrast.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_details.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_details.png new file mode 100755 index 000000000..758b1be91 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_details.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_enhance.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_enhance.png new file mode 100755 index 000000000..caf3478b3 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_enhance.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_grain.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_grain.png new file mode 100755 index 000000000..abf87a45e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_grain.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_highlights.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_highlights.png new file mode 100755 index 000000000..ed936c7d6 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_highlights.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_saturation.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_saturation.png new file mode 100755 index 000000000..297178d03 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_saturation.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_shadows.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_shadows.png new file mode 100755 index 000000000..62adb55d0 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_shadows.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_vignette.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_vignette.png new file mode 100755 index 000000000..fd9972ceb Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_vignette.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_warmth.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_warmth.png new file mode 100755 index 000000000..6f3d4d9fa Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_warmth.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tune.png b/TMessagesProj/src/main/res/drawable-mdpi/tune.png new file mode 100755 index 000000000..633d4b02d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tune.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/web_search.png b/TMessagesProj/src/main/res/drawable-mdpi/web_search.png deleted file mode 100644 index be9464961..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/web_search.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-v21/bar_selector_lock.xml b/TMessagesProj/src/main/res/drawable-v21/bar_selector_lock.xml new file mode 100644 index 000000000..d48dd0a10 --- /dev/null +++ b/TMessagesProj/src/main/res/drawable-v21/bar_selector_lock.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/blur_linear.png b/TMessagesProj/src/main/res/drawable-xhdpi/blur_linear.png new file mode 100755 index 000000000..94ab2c803 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/blur_linear.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/blur_linear_active.png b/TMessagesProj/src/main/res/drawable-xhdpi/blur_linear_active.png new file mode 100755 index 000000000..a7d39b91c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/blur_linear_active.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/blur_off.png b/TMessagesProj/src/main/res/drawable-xhdpi/blur_off.png new file mode 100755 index 000000000..06001a130 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/blur_off.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/blur_off_active.png b/TMessagesProj/src/main/res/drawable-xhdpi/blur_off_active.png new file mode 100755 index 000000000..c37ef8d8e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/blur_off_active.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/blur_radial.png b/TMessagesProj/src/main/res/drawable-xhdpi/blur_radial.png new file mode 100755 index 000000000..10caa4fa4 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/blur_radial.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/blur_radial_active.png b/TMessagesProj/src/main/res/drawable-xhdpi/blur_radial_active.png new file mode 100755 index 000000000..86585c39a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/blur_radial_active.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/bottom_shadow.png b/TMessagesProj/src/main/res/drawable-xhdpi/bottom_shadow.png new file mode 100755 index 000000000..eeb3c8374 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/bottom_shadow.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/boxshadow.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/boxshadow.9.png index ac112f7c5..6d5cbad08 100644 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/boxshadow.9.png and b/TMessagesProj/src/main/res/drawable-xhdpi/boxshadow.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/delete_reply.png b/TMessagesProj/src/main/res/drawable-xhdpi/delete_reply.png new file mode 100755 index 000000000..ce9fd147b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/delete_reply.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/devices.png b/TMessagesProj/src/main/res/drawable-xhdpi/devices.png new file mode 100755 index 000000000..9b5663ff9 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/devices.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/doc_actions_g.png b/TMessagesProj/src/main/res/drawable-xhdpi/doc_actions_g.png index 37e756fae..bc4b1d285 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/doc_actions_g.png and b/TMessagesProj/src/main/res/drawable-xhdpi/doc_actions_g.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/edit_cancel.png b/TMessagesProj/src/main/res/drawable-xhdpi/edit_cancel.png new file mode 100755 index 000000000..bfea63bc6 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/edit_cancel.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/edit_doneblue.png b/TMessagesProj/src/main/res/drawable-xhdpi/edit_doneblue.png new file mode 100755 index 000000000..301434f89 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/edit_doneblue.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/forward_blue.png b/TMessagesProj/src/main/res/drawable-xhdpi/forward_blue.png new file mode 100644 index 000000000..40af0d3dc Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/forward_blue.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/gif_search.png b/TMessagesProj/src/main/res/drawable-xhdpi/gif_search.png deleted file mode 100644 index c4a1eb82f..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/gif_search.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/greydivider_top.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/greydivider_top.9.png new file mode 100644 index 000000000..aeb9cc803 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/greydivider_top.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_delete_white.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_delete_white.png deleted file mode 100644 index 15752143c..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_delete_white.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_fwd_forward.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_fwd_forward.png index 0957f01c9..519de969b 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_fwd_forward.png and b/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_fwd_forward.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_reply.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_reply.png new file mode 100755 index 000000000..1b6cbc5b4 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_reply.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_share_white.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_share_white.png deleted file mode 100644 index 03b1ac32f..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_share_white.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/igvideo.png b/TMessagesProj/src/main/res/drawable-xhdpi/igvideo.png new file mode 100644 index 000000000..bad393640 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/igvideo.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/link.png b/TMessagesProj/src/main/res/drawable-xhdpi/link.png new file mode 100644 index 000000000..ba82f35b9 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/link.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/lock_close.png b/TMessagesProj/src/main/res/drawable-xhdpi/lock_close.png new file mode 100644 index 000000000..9ea564016 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/lock_close.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/lock_open.png b/TMessagesProj/src/main/res/drawable-xhdpi/lock_open.png new file mode 100644 index 000000000..c85e140b1 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/lock_open.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_check.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_check.png index f507eaf88..d214b0240 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/msg_check.png and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_check.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_check_w.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_check_w.png index be9518710..9e797a5c3 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/msg_check_w.png and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_check_w.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_halfcheck.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_halfcheck.png index 0fcf42042..7ae6e79c7 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/msg_halfcheck.png and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_halfcheck.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_halfcheck_w.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_halfcheck_w.png index 1882a27c8..dd2891607 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/msg_halfcheck_w.png and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_halfcheck_w.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_out.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out.9.png index f4e0afa5f..d7c2816f1 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/msg_out.9.png and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo.9.png index 63274aed4..c452372f3 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo.9.png and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo_selected.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo_selected.9.png index 3dd5cb9be..faa2daa55 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo_selected.9.png and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_selected.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_selected.9.png index 5097bdcf8..65e00a868 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_selected.9.png and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/passcode_check.png b/TMessagesProj/src/main/res/drawable-xhdpi/passcode_check.png new file mode 100644 index 000000000..f407719d7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/passcode_check.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/passcode_delete.png b/TMessagesProj/src/main/res/drawable-xhdpi/passcode_delete.png new file mode 100644 index 000000000..57af5956d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/passcode_delete.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/passcode_logo.png b/TMessagesProj/src/main/res/drawable-xhdpi/passcode_logo.png new file mode 100644 index 000000000..92c5f2d5b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/passcode_logo.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/photo_filters.png b/TMessagesProj/src/main/res/drawable-xhdpi/photo_filters.png deleted file mode 100644 index 611021022..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/photo_filters.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/photo_filters_active.png b/TMessagesProj/src/main/res/drawable-xhdpi/photo_filters_active.png deleted file mode 100644 index 6a3090755..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/photo_filters_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/photo_rotate.png b/TMessagesProj/src/main/res/drawable-xhdpi/photo_rotate.png deleted file mode 100644 index 968e91dcd..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/photo_rotate.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/photo_sizes.png b/TMessagesProj/src/main/res/drawable-xhdpi/photo_sizes.png deleted file mode 100644 index 01f3176f5..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/photo_sizes.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/photo_tune.png b/TMessagesProj/src/main/res/drawable-xhdpi/photo_tune.png deleted file mode 100644 index 38edad85d..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/photo_tune.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/photo_tune_active.png b/TMessagesProj/src/main/res/drawable-xhdpi/photo_tune_active.png deleted file mode 100644 index e65b80362..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/photo_tune_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/reply.png b/TMessagesProj/src/main/res/drawable-xhdpi/reply.png new file mode 100755 index 000000000..ee23fc6b6 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/reply.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/search_gif.png b/TMessagesProj/src/main/res/drawable-xhdpi/search_gif.png new file mode 100755 index 000000000..5cd150ba3 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/search_gif.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/search_web.png b/TMessagesProj/src/main/res/drawable-xhdpi/search_web.png new file mode 100755 index 000000000..44532e089 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/search_web.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/selectphoto_small.png b/TMessagesProj/src/main/res/drawable-xhdpi/selectphoto_small.png deleted file mode 100755 index 5b817801c..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/selectphoto_small.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/selectphoto_small_active.png b/TMessagesProj/src/main/res/drawable-xhdpi/selectphoto_small_active.png deleted file mode 100755 index 95d818a44..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/selectphoto_small_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/selectphoto_small_grey.png b/TMessagesProj/src/main/res/drawable-xhdpi/selectphoto_small_grey.png deleted file mode 100755 index 598676b91..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/selectphoto_small_grey.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/share.png b/TMessagesProj/src/main/res/drawable-xhdpi/share.png new file mode 100755 index 000000000..d554570d9 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/share.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/sharedmedia.png b/TMessagesProj/src/main/res/drawable-xhdpi/sharedmedia.png new file mode 100755 index 000000000..ad1203f6d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/sharedmedia.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/system_blue.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/system_blue.9.png old mode 100644 new mode 100755 index 0ff46944a..68c398416 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/system_blue.9.png and b/TMessagesProj/src/main/res/drawable-xhdpi/system_blue.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_blur.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_blur.png new file mode 100755 index 000000000..81511a35a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_blur.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_brightness.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_brightness.png new file mode 100755 index 000000000..1d1269e01 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_brightness.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_contrast.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_contrast.png new file mode 100755 index 000000000..52ca3c908 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_contrast.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_details.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_details.png new file mode 100755 index 000000000..db56a7a9f Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_details.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_enhance.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_enhance.png new file mode 100755 index 000000000..c0e3627a9 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_enhance.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_grain.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_grain.png new file mode 100755 index 000000000..e811faeaa Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_grain.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_highlights.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_highlights.png new file mode 100755 index 000000000..38cae4551 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_highlights.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_saturation.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_saturation.png new file mode 100755 index 000000000..92f8d6c75 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_saturation.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_shadows.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_shadows.png new file mode 100755 index 000000000..99cc7f7b5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_shadows.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_vignette.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_vignette.png new file mode 100755 index 000000000..c9ae138cf Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_vignette.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_warmth.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_warmth.png new file mode 100755 index 000000000..aca145d12 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_warmth.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tune.png b/TMessagesProj/src/main/res/drawable-xhdpi/tune.png new file mode 100755 index 000000000..c6d6b9c7f Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tune.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/web_search.png b/TMessagesProj/src/main/res/drawable-xhdpi/web_search.png deleted file mode 100644 index 345a04629..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/web_search.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/blur_linear.png b/TMessagesProj/src/main/res/drawable-xxhdpi/blur_linear.png new file mode 100755 index 000000000..7a9a7d59d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/blur_linear.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/blur_linear_active.png b/TMessagesProj/src/main/res/drawable-xxhdpi/blur_linear_active.png new file mode 100755 index 000000000..d6802f74b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/blur_linear_active.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/blur_off.png b/TMessagesProj/src/main/res/drawable-xxhdpi/blur_off.png new file mode 100755 index 000000000..954cd8ac5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/blur_off.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/blur_off_active.png b/TMessagesProj/src/main/res/drawable-xxhdpi/blur_off_active.png new file mode 100755 index 000000000..539299f2d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/blur_off_active.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/blur_radial.png b/TMessagesProj/src/main/res/drawable-xxhdpi/blur_radial.png new file mode 100755 index 000000000..d7d8bc1b8 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/blur_radial.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/blur_radial_active.png b/TMessagesProj/src/main/res/drawable-xxhdpi/blur_radial_active.png new file mode 100755 index 000000000..137912f15 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/blur_radial_active.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/bottom_shadow.png b/TMessagesProj/src/main/res/drawable-xxhdpi/bottom_shadow.png new file mode 100755 index 000000000..cf81b6c14 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/bottom_shadow.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/boxshadow.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/boxshadow.9.png index 25232d9c3..8226d849e 100644 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/boxshadow.9.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/boxshadow.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/delete_reply.png b/TMessagesProj/src/main/res/drawable-xxhdpi/delete_reply.png new file mode 100755 index 000000000..3cfc6883e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/delete_reply.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/devices.png b/TMessagesProj/src/main/res/drawable-xxhdpi/devices.png new file mode 100755 index 000000000..3afa7788d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/devices.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/doc_actions_g.png b/TMessagesProj/src/main/res/drawable-xxhdpi/doc_actions_g.png index 5445d4e10..109c13fd7 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/doc_actions_g.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/doc_actions_g.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/edit_cancel.png b/TMessagesProj/src/main/res/drawable-xxhdpi/edit_cancel.png new file mode 100755 index 000000000..d050523b7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/edit_cancel.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/edit_doneblue.png b/TMessagesProj/src/main/res/drawable-xxhdpi/edit_doneblue.png new file mode 100755 index 000000000..643fa3c6e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/edit_doneblue.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/forward_blue.png b/TMessagesProj/src/main/res/drawable-xxhdpi/forward_blue.png new file mode 100644 index 000000000..075a4f7f7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/forward_blue.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/gif_search.png b/TMessagesProj/src/main/res/drawable-xxhdpi/gif_search.png deleted file mode 100644 index e71905cb8..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/gif_search.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/greydivider_top.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/greydivider_top.9.png new file mode 100644 index 000000000..4c3d0b316 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/greydivider_top.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_delete_white.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_delete_white.png deleted file mode 100644 index 4335e31da..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_delete_white.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_fwd_forward.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_fwd_forward.png index f3c8fd6d8..3861355bf 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_fwd_forward.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_fwd_forward.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_reply.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_reply.png new file mode 100755 index 000000000..2af3db4e5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_reply.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_share_white.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_share_white.png deleted file mode 100644 index 890d00aed..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_share_white.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/igvideo.png b/TMessagesProj/src/main/res/drawable-xxhdpi/igvideo.png new file mode 100644 index 000000000..d13eab929 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/igvideo.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/link.png b/TMessagesProj/src/main/res/drawable-xxhdpi/link.png new file mode 100644 index 000000000..655dc9e9a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/link.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/lock_close.png b/TMessagesProj/src/main/res/drawable-xxhdpi/lock_close.png new file mode 100644 index 000000000..716b83b66 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/lock_close.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/lock_open.png b/TMessagesProj/src/main/res/drawable-xxhdpi/lock_open.png new file mode 100644 index 000000000..3cb15715f Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/lock_open.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_check.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_check.png index 467e62be6..5a38cea3e 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_check.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_check.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_check_w.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_check_w.png index 7d2019745..7a6da6cc5 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_check_w.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_check_w.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_halfcheck.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_halfcheck.png index 73bf80ba7..4dbbf75b8 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_halfcheck.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_halfcheck.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_halfcheck_w.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_halfcheck_w.png index 03177ed49..841c77bcc 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_halfcheck_w.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_halfcheck_w.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out.9.png index 10eac9cce..b7aa02377 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out.9.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo.9.png index 1c56a391f..02e3ad804 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo.9.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo_selected.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo_selected.9.png index 7855d66fa..67713607b 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo_selected.9.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_selected.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_selected.9.png index ad929cc4b..6ce8fda0e 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_selected.9.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/passcode_check.png b/TMessagesProj/src/main/res/drawable-xxhdpi/passcode_check.png new file mode 100644 index 000000000..a831f4bb1 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/passcode_check.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/passcode_delete.png b/TMessagesProj/src/main/res/drawable-xxhdpi/passcode_delete.png new file mode 100644 index 000000000..cdd6dce68 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/passcode_delete.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/passcode_logo.png b/TMessagesProj/src/main/res/drawable-xxhdpi/passcode_logo.png new file mode 100644 index 000000000..af2428a20 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/passcode_logo.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_contrast.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_contrast.png deleted file mode 100644 index 78aa2b414..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_contrast.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_exposure.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_exposure.png deleted file mode 100644 index 5feb667ab..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_exposure.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_grain.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_grain.png deleted file mode 100644 index 297bc2dc9..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_grain.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_highlights.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_highlights.png deleted file mode 100644 index ce156a02a..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_highlights.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_saturation.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_saturation.png deleted file mode 100644 index c1a14fa75..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_saturation.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_shadows.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_shadows.png deleted file mode 100644 index f3ead5324..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_shadows.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_sharpen.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_sharpen.png deleted file mode 100644 index 4d6687ba8..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_sharpen.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_vignette.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_vignette.png deleted file mode 100644 index e72d3d71c..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_vignette.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_warmth.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_warmth.png deleted file mode 100644 index 9b9a258ed..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_warmth.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_filters.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_filters.png deleted file mode 100644 index 29abc7eda..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_filters.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_filters_active.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_filters_active.png deleted file mode 100644 index a5bb25e5c..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_filters_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_rotate.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_rotate.png deleted file mode 100644 index 0c1a9c772..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_rotate.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_sizes.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_sizes.png deleted file mode 100644 index 40a564e6a..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_sizes.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_tune.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_tune.png deleted file mode 100644 index 254d18c76..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_tune.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_tune_active.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_tune_active.png deleted file mode 100644 index 3c4e05873..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_tune_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/reply.png b/TMessagesProj/src/main/res/drawable-xxhdpi/reply.png new file mode 100755 index 000000000..d08e72b82 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/reply.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/search_gif.png b/TMessagesProj/src/main/res/drawable-xxhdpi/search_gif.png new file mode 100755 index 000000000..d9e7195be Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/search_gif.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/search_web.png b/TMessagesProj/src/main/res/drawable-xxhdpi/search_web.png new file mode 100755 index 000000000..193208c52 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/search_web.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/selectphoto_small.png b/TMessagesProj/src/main/res/drawable-xxhdpi/selectphoto_small.png deleted file mode 100755 index 7620f457e..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/selectphoto_small.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/selectphoto_small_active.png b/TMessagesProj/src/main/res/drawable-xxhdpi/selectphoto_small_active.png deleted file mode 100755 index 11ac540b6..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/selectphoto_small_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/selectphoto_small_grey.png b/TMessagesProj/src/main/res/drawable-xxhdpi/selectphoto_small_grey.png deleted file mode 100755 index 935604b4d..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/selectphoto_small_grey.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/share.png b/TMessagesProj/src/main/res/drawable-xxhdpi/share.png new file mode 100755 index 000000000..b72403da1 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/share.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/sharedmedia.png b/TMessagesProj/src/main/res/drawable-xxhdpi/sharedmedia.png new file mode 100755 index 000000000..80dfc3838 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/sharedmedia.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/system_blue.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/system_blue.9.png old mode 100644 new mode 100755 index d47327132..1321d3c15 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/system_blue.9.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/system_blue.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_blur.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_blur.png new file mode 100755 index 000000000..b935f2f74 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_blur.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_brightness.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_brightness.png new file mode 100755 index 000000000..fca4f193c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_brightness.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_contrast.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_contrast.png new file mode 100755 index 000000000..b7f4ea77c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_contrast.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_details.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_details.png new file mode 100755 index 000000000..92e5078a5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_details.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_enhance.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_enhance.png new file mode 100755 index 000000000..d3f893339 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_enhance.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_grain.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_grain.png new file mode 100755 index 000000000..fd194574e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_grain.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_highlights.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_highlights.png new file mode 100755 index 000000000..f9b3e0b14 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_highlights.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_saturation.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_saturation.png new file mode 100755 index 000000000..9918b34d4 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_saturation.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_shadows.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_shadows.png new file mode 100755 index 000000000..ba854d4b5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_shadows.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_vignette.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_vignette.png new file mode 100755 index 000000000..ba153fd42 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_vignette.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_warmth.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_warmth.png new file mode 100755 index 000000000..cfbf0d516 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_warmth.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tune.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tune.png new file mode 100755 index 000000000..eda3e5a32 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tune.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/web_search.png b/TMessagesProj/src/main/res/drawable-xxhdpi/web_search.png deleted file mode 100644 index 1fc70c4b1..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/web_search.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable/bar_selector_lock.xml b/TMessagesProj/src/main/res/drawable/bar_selector_lock.xml new file mode 100644 index 000000000..ad45bba68 --- /dev/null +++ b/TMessagesProj/src/main/res/drawable/bar_selector_lock.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout-ar/encrypted_chat_placeholder.xml b/TMessagesProj/src/main/res/layout-ar/encrypted_chat_placeholder.xml deleted file mode 100644 index c265685e2..000000000 --- a/TMessagesProj/src/main/res/layout-ar/encrypted_chat_placeholder.xml +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/chat_layout.xml b/TMessagesProj/src/main/res/layout/chat_layout.xml deleted file mode 100644 index 214bb3d69..000000000 --- a/TMessagesProj/src/main/res/layout/chat_layout.xml +++ /dev/null @@ -1,299 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/encrypted_chat_placeholder.xml b/TMessagesProj/src/main/res/layout/encrypted_chat_placeholder.xml deleted file mode 100644 index 6df0e8915..000000000 --- a/TMessagesProj/src/main/res/layout/encrypted_chat_placeholder.xml +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/media_photo_layout.xml b/TMessagesProj/src/main/res/layout/media_photo_layout.xml deleted file mode 100644 index 918626671..000000000 --- a/TMessagesProj/src/main/res/layout/media_photo_layout.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/media_video_layout.xml b/TMessagesProj/src/main/res/layout/media_video_layout.xml deleted file mode 100644 index 17de40a58..000000000 --- a/TMessagesProj/src/main/res/layout/media_video_layout.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/messages_list.xml b/TMessagesProj/src/main/res/layout/messages_list.xml index 7e685fb8a..6f6381a86 100644 --- a/TMessagesProj/src/main/res/layout/messages_list.xml +++ b/TMessagesProj/src/main/res/layout/messages_list.xml @@ -61,6 +61,8 @@ android:gravity="center" android:textSize="15dp" android:paddingTop="6dp" + android:paddingLeft="8dp" + android:paddingRight="8dp" android:lineSpacingExtra="2dp" android:id="@+id/list_empty_view_text2"/> diff --git a/TMessagesProj/src/main/res/layout/popup_notification_layout.xml b/TMessagesProj/src/main/res/layout/popup_notification_layout.xml deleted file mode 100644 index 3286d13b5..000000000 --- a/TMessagesProj/src/main/res/layout/popup_notification_layout.xml +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/raw/sound_in.wav b/TMessagesProj/src/main/res/raw/sound_in.wav new file mode 100644 index 000000000..262201668 Binary files /dev/null and b/TMessagesProj/src/main/res/raw/sound_in.wav differ diff --git a/TMessagesProj/src/main/res/raw/sound_out.wav b/TMessagesProj/src/main/res/raw/sound_out.wav new file mode 100644 index 000000000..ccfa86963 Binary files /dev/null and b/TMessagesProj/src/main/res/raw/sound_out.wav differ diff --git a/TMessagesProj/src/main/res/values-ar/strings.xml b/TMessagesProj/src/main/res/values-ar/strings.xml index bf476db35..743678431 100644 --- a/TMessagesProj/src/main/res/values-ar/strings.xml +++ b/TMessagesProj/src/main/res/values-ar/strings.xml @@ -57,6 +57,8 @@ ضعه على الصامت لمدة %1$s إزالة كتم الصوت خلال %1$s + تعطيل + الأوسمة رسالة جماعية جديدة أدخل اسم القائمة @@ -83,6 +85,10 @@ جاري الكتابة… يكتب… يكتبون… + %1$s يقوم بإرسال مقطع صوتي... + %1$s يقوم بإرسال صورة... + %1$s يقوم بإرسال مقطع مرئي... + %1$s يقوم بإرسال ملف... هل يوجد لديك سؤال\nحول تيليجرام؟ التقط صورة صورة @@ -115,6 +121,7 @@ المرفق غير مدعوم عداد التدمير الذاتي إشعارات الخدمة + جاري جلب معلومات الرابط... %1$s قام بتعيين عداد التدمير الذاتي إلى to %2$s لقد قمت بتعيين التدمير الذاتي إلى %1$s @@ -143,11 +150,12 @@ %1$s قام بتعديل اسم المجموعة %2$s %1$s قام بتغيير صورة المجموعة %2$s %1$s قام بدعوة %3$s للمجموعة %2$s + %1$s عاد إلى المجموعة %2$s %1$s قام بإخراج %3$s من المجموعة %2$s %1$s قام بإخراجك من المجموعة %2$s %1$s قام بمغادرة المجموعة %2$s %1$s قام بالتسجيل في تيليجرام! - %1$s,\nتم تسجيل الدخول لحسابك من جهاز جديد يوم %2$s\n\nالجهاز: %3$s\nالموقع: %4$s\n\nإذا لم يكن أنت من سجل الدخول، يمكنك الذهاب للإعدادات ثم تسجيل الخروج من كافة الأجهزة الأخرى.\n\nشكرًا,\nفريق عمل تيليجرام + %1$s,\nتم تسجيل الدخول لحسابك من جهاز جديد يوم %2$s\n\nالجهاز: %3$s\nالموقع: %4$s\n\nإذا لم يكن أنت من سجل الدخول، يمكنك الذهاب للإعدادات ثم تسجيل الخروج من كافة الأجهزة الأخرى. كما يمكنك تفعيل التحقق بخطوتين إذا رغبت بذلك عن طريق إعدادات الخصوصية.\n\nشكرًا,\nفريق عمل تيليجرام %1$s قام بتغيير صورته الشخصية الرد الرد على %1$s @@ -242,6 +250,7 @@ لا يوجد صوت افتراضي الدعم + فقط في وضع الصامت خلفية الدردشة الرسائل أرسل بزر الإدخال @@ -296,9 +305,44 @@ سيتم إرسال رسالة قصيرة تحتوي على رمز التفعيل الخاص إلى رقمك الجديد. الرقم %1$s لديه حساب تيليجرام مسبقًا. يرجى حذف هذا الحساب قبل محاولة تغيير رقمك. آخر + تعطيل + تعطيل + تعطيل + إيقاف + الأصوات داخل المحادثات + افتراضي + + الأجهزة المسجّل دخول منها + الجهاز الحالي + لا يوجد أجهزة مسجّل دخول منها أخرى + يمكنك تسجيل الدخول لحسابك في تيليجرام من جوال آخر، جهاز لوحي، أو أجهزة الكمبيوتر، باستخدام نفس رقم الهاتف. تيليجرام سيقوم بمزامنة كافة بياناتك بشكل لحظي. + الأجهزة المسجّل دخول منها + قم بالتحكم بالأجهزة المسجل دخول منها. + اضغط على الجهاز لتسجيل الخروج منه. + هل ترغب في تسجيل الخروج من هذا الجهاز؟ + تطبيق غير رسمي + + قفل رمز المرور + غيًر رمز المرور + عندما تختار رمز مرور، ستظهر علامة قفل في صفحة المحادثات. اضغط عليها لقفل أو فتح تيليجرام.\n\nملاحظة: إذا نسيت رمز المرور، ستحتاج لحذف وإعادة تنزيل التطبيق. وستخسر كافة محادثاتك السرية وستعود المحادثات العادية فور إعادة تسجيل الدخول. + سوف ترى الآن أيقونة قفل في صفحة المحادثات. اضغط عليها لقفل تطبيق تيليجرام برمز المرور الجديد الخاص بك. + الرمز + كلمة المرور + قم بإدخال رمز المرور الخاص بك الحالي + قم بإدخال رمز مرور + قم بإدخال رمز المرور الخاص بك الجديد + قم بإدخال رمز المرور الخاص بك + قم بإعادة إدخال رمز المرور الخاص بك الجديدة + رمز مرور غير صحيح + رموز المرور غير متطابقة + قفل تلقائي + اطلب رمز المرور إذا غبت فترة محددة من الزمن. + خلال %1$s + معطّل شارك المقاطع المرئية والصور في هذه المحادثة لتستطيع الوصول إليها من أية جهاز من أجهزتك ملفات + الوسائط المشتركة شارك الملفات والمستندات في هذه المحادثة لتستطيع الوصول إليها من أية جهاز من أجهزتك الخريطة @@ -318,36 +362,82 @@ فضلًا، قم بتنزيل الوسائط أولًا لا توجد صور حديثة لا يوجد صور متحركة حديثة - البحث على الإنترنت - البحث عن صور متحركة + ابحث عن صور + البحث على الإنترنت + ابحث عن صور متحركة البحث على الإنترنت البحث عن صور متحركة قص الصورة تعديل الصورة + تحسين + التفتيح + التباين + التعريض + الدفء + التشبع + النقش + الظل + الحبوب + زيادة الحدة + الطمس + إيقاف + طولي + قطري + هل أنت متأكد من رغبتك في حذف هذه الصورة؟ + هل أنت متأكد من رغبتك في حذف هذا المقطع المرئي؟ + تجاهل التغييرات؟ + هل ترغب في مسح سجل البحث؟ + مسح - Password - Change password - Old password - Enter old password - New password - Enter new password - Verify new password - Enter your password - Hint - Enter hint - Important: you will lose all your chats, messages and media in the case of a forgotten password. - Passwords do not match - Incorrect old password - Incorrect password - Incorrect new password - Hint shouldn\'t contain password - Enter password - Important: you will lose all your chats, messages and media. - Delete account - Delete my account - Hint: %1$s - Are you sure you want to delete your account? - We deeply clarify you that you will lose all your chats, messages and media. Are you really sure? + التحقق بخطوتين + تعيين كلمة مرور إضافية + يمكنك تعيين كلمة مرور يتم طلبها عند محاولة تسجيل الدخول من جهاز جديد بالإضافة إلى الرمز الذي يأتيك في رسالة قصيرة. + كلمة المرور الخاصة بك + يرجى إعادة إدخال كلمة المرور الخاصة بك: + قم بإدخال كلمة مرور + يرجى إدخال كلمة المرور الجديدة الخاصة بك: + يرجى إعادة إدخال كلمة المرور الخاصة بك: + بريد إسترداد الحساب + بريدك الإلكتروني + فضلًا أضف بريد إلكتروني صحيح. هذه هي الطريقة الوحيدة لإستعادة كلمة المرور بعد نسيانها. + تخطّي + تحذير + الموضوع جدّيّ.\n\nإذا نسيت كلمة المرور الخاصة بك، لن تستطيع الدخول على حساب تيليجرام الخاص بك. لن يكون هناك طريقة لإستعادته. + تقريبًا انتهينا! + يرجى الذهاب لبريدك الإلكتروني والضغط على رابط التأكيد لإنهاء إعدادات التحقق بخطوتين. تأكد من الإطّلاع على مجلد الرسائل الغير مرغوب بها أيضًا. + تم بنجاح! + تم تفعيل كلمة المرور الخاصة بالتحقق بخطوتين. + تغيير كلة المرور + إيقاف كلمة المرور + اختر بريد إلكتروني لإسترداد الحساب + غيّر البريد الإلكتروني لإسترداد الحساب + هل أنت متأكد من رغبتك في تعطيل كلمة المرور؟ + تلميحة كلمة المرور + فضلًا اختر تلميحة لكلمة المرور الخاصة بك: + كلمتي المرور غير متطابقة + إنهاء عملية إعداد التحقق بخطوتين + فضلًا اتّبع هذه الخطوات لإكمال إعدادات التحقق بخطوتين:\n\n١. قم بالإطلاع على بريدة الإلكتروني بما فيه مجلد الرسائل الغير مرغوب بها\n%1$s\n\n٢. اضغط على رابط التأكيد + التلميحة يجب أن تكون مختلفة عن كلمة المرور ذاتها + بريد إلكتروني غير صحيح + عذرًا + لم تقم بإضافة بريد إلكتروني لإستعادة كلمة المرور عند اختيارها، لذلك خياراتك المتبقية هي تذكّر كلمة المرور أو إعادة تعيين حسابك. + لقد قمنا بإرسال رمز الإستعادة إلى بريدك الإلكتروني الذي اخترته مسبقًا:\n\n%1$s + يرجى الإطلاع على بريدك الإلكتروني وإدخال الرمز المكون من ٦ أرقام الذي قمنا بإرساله هنا. + هل تواجه صعوبات في الدخول على بريدك الإلكتروني %1$s؟ + إذا لم تستطع الدخول على بريد الإسترداد الخاص بك، خياراتك المتبقية هي تذكّر كلمة المرور أو إعادة تعيين حسابك. + إعادة تعيين حسابي + إذا قمت بإعادة تعيين حسابك، ستفقد كافّة محادثاتك ورسائلك، بالإضافة إلى الوسائط والملفات التي تمت مشاركتها. + تحذير + لا يمكن الرجوع عن هذا الخيار.\n\nإذا قمت بإعادة تعيين حسابك، كافة رسائلك ومحادثاتك سيتم حذفها. + إعادة تعيين + كلمة المرور + تم تفعيل التحقق بخطوتين، لذلك حسابك محميّ بكلمة مرور إضافية. + هل نسيت كلمة المرور؟ + كلمة مرور الإسترداد + الرمز + تم تعطيل كلمة المرور + لقد قمت بتفعيل التحقق بخطوتين.\nعند محاولة تسجيل الدخول على حساب تيليجرام الخاص بك من جهاز جديد، سيتم طلب كلمة المرور التي اخترتها هنا منك. + البريد الإلكتروني لإسترداد الحساب %1$s غير فعّال بعد ويلزم تفعيله الخصوصية والأمان الخصوصية @@ -405,6 +495,7 @@ حذف الصورة تعيين موافق + قطع un1 أزال un2 غادر المجموعة العضو un1 @@ -422,6 +513,7 @@ لقد قمت بإنشاء المجموعة un1 قام بإخراجك un1 قام بإضافتك + un1 عاد إلى المجموعة نسخة تيليجرام الموجودة لديك لا تدعم هذه الرسالة. الرجاء التحديث لأحدث نسخة: http://telegram.org/update صورة مقطع مرئي @@ -437,12 +529,13 @@ رقم الهاتف غير صحيح انتهت صلاحية الرمز الخاص بك، يرجى تسجيل الدخول مرة أخرى محاولات كثيرة خاطئة، نرجو المحاولة لاحقًا + محاولات كثيرة خاطئة، يرجى المحاولة خلال %1$s الرمز غير صحيح الاسم الأول غير صحيح اسم العائلة غير صحيح جاري التحميل ... ليس لديك أي مشغل مقاطع مرئية، يرجى تنزيل أية مشغل - يرجى إرسال رسالة بواسطة البريد الإلكتروني إلى sms@telegram.org لتخبرنا عن مشكلتك. + يرجى إرسال رسالة بواسطة البريد الإلكتروني إلى sms@stel.com لتخبرنا عن مشكلتك. لا يوجد لديك تطبيق يمكنه فتح \'%1$s\'، يرجى تنزيل تطبيق مناسب للإستمرار هذا المستخدم ليس لديه تيليجرام بعد ، هل ترغب في دعوته الآن؟ هل أنت متأكد؟ @@ -511,18 +604,18 @@ %1$d رسائل %1$d رسالة %1$d رسالة - لا يوجد ملفات - %1$d ملف - %1$d ملفان - %1$d ملفات - %1$d ملف - %1$d ملف - ليس من جهة اتصال - من %1$d جهة اتصال - من %1$d جهتان اتصال - من %1$d جهات اتصال - من %1$d جهة اتصال - من %1$d جهة اتصال + لا يوجد ملفات + %1$d ملف + %1$d ملف + %1$d ملفات + %1$d ملف + %1$d ملف + من ولا محادثة + من %1$d محادثة + من %1$d محادثة + من %1$d محادثات + من %1$d محادثة + من %1$d محادثة %1$d ثانية %1$d ثانية %1$d ثانيتان @@ -571,7 +664,63 @@ %1$d مستخدمون %1$d مستخدم %1$d مستخدم + + %1$d رسالة معاد توجيهها + الرسالة المعاد توجيهها + %1$d رسالة معاد توجيهها + %1$d رسالة معاد توجيهها + %1$d رسالة معاد توجيهها + %1$d رسالة معاد توجيهها + %1$d ملف معاد توجيهه + ملف معاد توجيهه + %1$d ملف معاد توجيهه + %1$d ملف معاد توجيهه + %1$d ملف معاد توجيهه + %1$d ملف معاد توجيهه + %1$d صورة معاد توجيهها + صورة معاد توجيهها + %1$d صورة معاد توجيهها + %1$d صورة معاد توجيهها + %1$d صورة معاد توجيهها + %1$d صورة معاد توجيهها + %1$d مقطع مرئي معاد توجيهه + مقطع مرئي معاد توجيهه + %1$d مقطع مرئي معاد توجيهه + %1$d مقطع مرئي معاد توجيهه + %1$d مقطع مرئي معاد توجيهه + %1$d مقطع مرئي معاد توجيهه + %1$d مقطع صوتي معاد توجيهه + مقطع صوتي معاد توجيهه + %1$d مقطع صوتي معاد توجيهه + %1$d مقطع صوتي معاد توجيهه + %1$d مقطع صوتي معاد توجيهه + %1$d مقطع صوتي معاد توجيهه + %1$d موقع معاد توجيهه + موقع معاد توجيهه + %1$d موقع معاد توجيهه + %1$d موقع معاد توجيهه + %1$d موقع معاد توجيهه + %1$d موقع معاد توجيهه + %1$d جهة اتصال معاد توجيهها + جهة اتصال معاد توجيهها + %1$d جهة اتصال معاد توجيهها + %1$d جهة اتصال معاد توجيهها + %1$d جهة اتصال معاد توجيهها + %1$d جهة اتصال معاد توجيهها + %1$d ملصق معاد توجيهها + ملصق معاد توجيهه + %1$d ملصق معاد توجيهه + %1$d ملصق معاد توجيهه + %1$d ملصق معاد توجيهه + %1$d ملصق معاد توجيهه + و %1$d غيرهم + و %1$d غيره + و %1$d غيرهم + و %1$d غيرهم + و %1$d غيرهم + و %1$d غيرهم + MMMM yyyy MMM dd dd.MM.yy dd.MM.yyyy diff --git a/TMessagesProj/src/main/res/values-de/strings.xml b/TMessagesProj/src/main/res/values-de/strings.xml index 8fe9a5dcf..fd4c0035a 100644 --- a/TMessagesProj/src/main/res/values-de/strings.xml +++ b/TMessagesProj/src/main/res/values-de/strings.xml @@ -34,13 +34,13 @@ gestern Keine Ergebnisse Noch keine Chats… - Tippe unten auf den Sift für deine erste\nChatnachricht oder auf den Menüknopf\num die restlichen Optionen zu öffnen. + Tippe unten auf den Stift für deine erste\nChatnachricht oder auf den Menüknopf\num die restlichen Optionen zu öffnen. Warte auf Netzwerk... Verbinde… Aktualisiere… Neuer Geheimer Chat Warte, bis %s online geht… - Geheimen Chat abgebrochen + Geheimen Chat beendet Tausche Schlüssel aus… %s ist deinem geheimen Chat beigetreten. Du bist dem geheimen Chat beigetreten. @@ -57,6 +57,8 @@ Stumm für %1$s Stumm aus In %1$s + Stumm aus + HASHTAGS Neue Broadcast Liste Listenname @@ -83,6 +85,10 @@ schreibt… schreibt... tippen… + %1$s nimmt etwas auf... + %1$s schickt Bild... + %1$s schickt Video... + %1$s schickt Datei... Hast du eine Frage\nzu Telegram? Foto aufnehmen Galerie @@ -115,6 +121,7 @@ Nicht unterstützte Datei Selbstzerstörungs-Timer setzen Servicemeldungen + Lade Linkvorschau... %1$s hat den Selbstzerstörungs-Timer auf %2$s gesetzt Du hast den Selbstzerstörungs-Timer auf %1$s gesetzt @@ -143,13 +150,14 @@ %1$s hat den Namen der Gruppe %2$s geändert %1$s hat das Bild der Gruppe %2$s geändert %1$s hat %3$s in die Gruppe %2$s eingeladen + %1$s ist in die Gruppe %2$s zurückgekehrt %1$s hat %3$s aus der Gruppe %2$s entfernt %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,\nDein 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\nBeachte unsere zweistufige Bestätigung, welche du in den Telegram Einstellungen unter Privatsphäre und Sicherheit optional aktivieren kannst.\n\nDein Telegram Team %1$s hat das Profilbild geändert - Beantworten + Antworten %1$s antworten %1$s antworten %1$s %2$s @@ -242,16 +250,17 @@ Kein Ton Standard Support + Wenn lautlos Chat-Hintergrundbild Nachrichten Mit Enter senden - Alle anderen Sitzungen beenden + Alle anderen Geräte abmelden Ereignisse Kontakt ist Telegram beigetreten PEBBLE Sprache Bedenke bitte, dass der Telegram Support von einem ehrenamtlichen Team betreut wird. Wir versuchen so schnell wie möglich zu antworten, dies kann jedoch manchmal ein bisschen dauern.
]]>Bitte schau auch in den Fragen und Antworten ]]> nach. Dort findest du Antworten auf die meisten Fragen und wichtige Tipps zur Problembehandlung]]>.
- Frage einen Freiwilligen + Eine Frage stellen Fragen und Antworten https://telegram.org/faq/de Lokalisierung löschen? @@ -296,10 +305,45 @@ 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 + Deaktiviert + Deaktiviert + Deaktiviert + Aus + In-Chat Töne + Standard + + Sitzungen + Aktuelle Sitzung + Keine anderen Geräte + Du kannst dich von jedem Handy, Tablet und Computer bei Telegram mit derselben Telefonnummer anmelden. Alles wird immer sofort synchronisiert. + Andere Geräte + Überprüfe alle deine angemeldeten Geräte. + Tippe auf eine Sitzung um sie zu beenden. + Dieses Gerät abmelden? + inoffizielle Version + + Pincode-Sperre + Pincode ändern + Wenn du die Code-Sperre aktivierst, erscheint ein Schloss ganz oben über der Chatliste. Tippe auf das Schloss, um deine Chats zu sperren und zu entsperren.\n\nÜbrigens: Wenn du den Pincode vergisst, musst du Telegram löschen und neu installieren. Dadurch verlierst du alle Geheimen Chats. + Du wirst nun ein Schloss über der Chatliste sehen. Tippe darauf um deine Chats mit dem neuen Pincode zu sperren. + Pincode + Kennwort + Aktuellen Pincode eingeben + Pincode eingeben + Neuen Pincode eingeben + Deinen Pincode eingeben + Neuen Pincode erneut eingben + Ungültiger Pincode + Pincode falsch + Auto-Sperre + Benötigt Pincode wenn lange inaktiv. + in %1$s + Deaktiviert Die hier geteilten Bilder und Videos kannst du von jedem deiner Geräte aufrufen. Dateien - Die hier geteilten Bilder und Videos kannst du von jedem deiner Geräte aufrufen. + Geteilte Medien + Die hier geteilten Dateien kannst du von jedem deiner Geräte aufrufen. Karte Satellit @@ -319,35 +363,81 @@ Suchverlauf Suchverlauf BILDERSUCHE + BILDERSUCHE GIF-SUCHE Suche Bilder Suche GIFs Bild zuschneiden Bild bearbeiten + Verbessern + Highlights + Kontrast + Belichtung + Wärme + Sättigung + Vignette + Schatten + Körnung + Schärfe + Unschärfe + Aus + Linear + Radial + Möchtest du wirklich dieses Bild löschen? + Möchtest du wirklich dieses Video löschen? + Änderungen verwerfen? + Suchverlauf löschen? + Löschen - Password - Change password - Old password - Enter old password - New password - Enter new password - Verify new password - Enter your password - Hint - Enter hint - Important: you will lose all your chats, messages and media in the case of a forgotten password. - Passwords do not match - Incorrect old password - Incorrect password - Incorrect new password - Hint shouldn\'t contain password - Enter password - Important: you will lose all your chats, messages and media. - Delete account - Delete my account - Hint: %1$s - Are you sure you want to delete your account? - We deeply clarify you that you will lose all your chats, messages and media. Are you really sure? + Zweistufige Bestätigung + Zusätzliches Kennwort festlegen + Du kannst ein eigenes Kennwort festlegen, um dich an einem neuen Gerät anzumelden, zusätzlich zum SMS-Code. + Dein Kennwort + Bitte aktuelles Kennwort eingeben + Kennwort eingeben + Bitte neues Kennwort eingeben + Bitte erneut dein Kennwort eingeben + Wiederherstellung + Deine E-Mail + Falls du dein Kennwort vergisst, benötigen wir deine richtige Email Adresse. + Überspringen + Warnung + Keine gute Idee.\n\nWenn du dein Passwort vergisst, verlierst du den Zugang zu deinem Telegram Konto. Für immer, ohne Ausnahme. + Fast geschafft! + Bitte überprüfe deine Mails (auch den Spam-Ordner) um die zweistufige Bestätigung abzuschließen. + Geschafft! + Dein Kennwort für die zweistufige Bestätigung ist jetzt aktiv. + Kennwort ändern + Kennwort deaktivieren + E-Mailadresse festlegen + E‑Mail-Adresse zur Wiederherstellung ändern + Sicher, dass du dein Kennwort deaktivieren willst? + Kennwort-Erinnerung + Bitte Hinweis auf dein Kennwort eingeben + Kennwörter stimmen nicht überein + Einrichten abbrechen + Bitte folge diesen Schritten um die zweistufige Bestätigung abzuschließen:\n\n1. Überprüfe deine Mails (auch den Spam-Ordner)\n%1$s\n\n2. Auf den Link klicken. + Der Hinweis darf nicht das Kennwort sein. + Ungültige E-Mail + Tut uns leid + Da du für diesen Fall keine Email Adresse hinterlegt hast, kannst du nur noch hoffen, dass dir dein Kennwort wieder einfällt oder du musst dein Telegram Konto zurückzusetzen. + Wir haben den Wiederherstellungscode an diese Adresse geschickt:\n\n%1$s + Überprüfe deine Mails und gib den 6-stelligen Code aus userer Email ein. + Du hast keinen Zugang zu deiner Adresse %1$s? + Wenn du nicht in deine Emails kommst, kannst du nur hoffen, dass dir dein Kennwort wieder einfällt oder du musst dein Telegram Konto zurückzusetzen. + KONTO ZURÜCKSETZEN + Wenn du dein Konto zurücksetzt, verlierst du alle Chats und Nachrichten, ebenso deine geteilten Bilder und Videos. + Warnung + Dies kann nicht rückgängig gemacht werden.\n\nWenn du dein Konto zurücksetzt, sind alle Chats gelöscht. + Zurücksetzen + Kennwort + Du hast die zweistufige Bestätigung aktiviert. Dein Konto ist mit einem zusätzlichem Kennwort geschützt. + Kennwort vergessen? + Kennwort zurücksetzen + Code + Kennwort deaktiviert + Du hast die zweistufige Bestätigung aktiviert.\nWenn du dich bei Telegram anmeldest, brauchst du dein Kennwort. + Deine E-Mail Adresse %1$s wurde noch verifiziert und ist daher noch nicht aktiv. Privatsphäre und Sicherheit Privatsphäre @@ -405,6 +495,7 @@ Foto löschen Wählen OK + SCHNEIDEN un1 hat un2 aus der Gruppe entfernt un1 hat die Gruppe verlassen @@ -422,6 +513,7 @@ Du hast die Gruppe erstellt un1 hat dich aus der Gruppe entfernt un1 hat dich hinzugefügt + un1 ist in die Gruppe zurückgekehrt Diese Nachricht wird von deiner Telegram-Version nicht unterstützt. Bitte aktualisiere die App um sie zu sehen: http://telegram.org/update Foto Video @@ -437,12 +529,13 @@ Ungültige Telefonnummer Code ist abgelaufen, bitte melde dich erneut an Zu viele Versuche in zu kurzer Zeit, versuche es bitte später erneut. + Zu viele Versuche, bitte erneut in %1$s versuchen Ungültiger Code Ungültiger Vorname Ungültiger Nachname Lädt… Du hast keinen Videoplayer. Bitte installiere einen um fortzufahren. - Bitte sende uns eine Email an sms@telegram.org mit einer Beschreibung des Problems. + Bitte sende eine Email an sms@stel.com mit einer Beschreibung des Problems. Du hast keine Applikationen, die den Dateityp \'%1$s\' öffnen könnten. Bitte installiere eine entsprechende Anwendung um fortzufahren. Dieser Benutzer hat noch kein Telegram. Möchtest du ihn einladen? Bist du sicher? @@ -511,18 +604,18 @@ %1$d Nachrichten %1$d Nachrichten %1$d Nachrichten - keine Dateien - %1$d Datei - %1$d Dateien - %1$d Dateien - %1$d Dateien - %1$d Dateien - von keinem Kontakt - von %1$d Kontakt - von %1$d Kontakten - von %1$d Kontakten - von %1$d Kontakten - von %1$d Kontakten + keine Objekte + %1$d Objekt + %1$d Objekte + %1$d Objekte + %1$d Objekte + %1$d Objekte + von keinen Chats + von %1$d Chat + von %1$d Chats + von %1$d Chats + von %1$d Chats + von %1$d Chats %1$d Sekunden %1$d Sekunde %1$d Sekunden @@ -571,7 +664,63 @@ %1$d Nutzer %1$d Nutzer %1$d Nutzer + + %1$d angehängten Nachrichten + Angehängte Nachricht + %1$d angehängte Nachrichten + %1$d angehängte Nachrichten + %1$d angehängte Nachrichten + %1$d angehängte Nachrichten + %1$d angehängten Dateien + Angehängte Datei + %1$d angehängte Dateien + %1$d angehängte Dateien + %1$d angehängte Dateien + %1$d angehängte Dateien + %1$d angehängten Bilder + Angehängtes Bild + %1$d angehängte Bilder + %1$d angehängte Bilder + %1$d angehängte Bilder + %1$d angehängte Bilder + %1$d angehängten Videos + Angehängtes Video + %1$d angehängte Videos + %1$d angehängte Videos + %1$d angehängte Videos + %1$d angehängte Videos + %1$d angehängten Audios + Angehängtes Audio + %1$d angehängte Audios + %1$d angehängte Audios + %1$d angehängte Audios + %1$d angehängte Audios + %1$d weitergeleiteten Standorte + Angehängter Standort + %1$d angehängte Standorte + %1$d angehängte Standorte + %1$d angehängte Standorte + %1$d angehängte Standorte + %1$d weitergeleiteten Kontakt + Angehängter Kontakt + %1$d angehängte Kontakte + %1$d angehängte Kontakte + %1$d angehängte Kontakte + %1$d angehängte Kontakte + %1$d angehängten Sticker + Angehängter Sticker + %1$d angehängte Sticker + %1$d angehängte Sticker + %1$d angehängte Sticker + %1$d angehängte Sticker + und %1$d andere + und %1$d anderer + und %1$d andere + und %1$d andere + und %1$d andere + und %1$d andere + MMMM yyyy dd MMM dd.MM.yy dd.MM.yyyy diff --git a/TMessagesProj/src/main/res/values-es/strings.xml b/TMessagesProj/src/main/res/values-es/strings.xml index c59b5b3ed..b2b2f7b37 100644 --- a/TMessagesProj/src/main/res/values-es/strings.xml +++ b/TMessagesProj/src/main/res/values-es/strings.xml @@ -57,6 +57,8 @@ Silenciar %1$s No silenciar En %1$s + Desactivar + HASHTAGS Nueva difusión Nombre de la lista @@ -83,6 +85,10 @@ escribiendo... está escribiendo... están escribiendo... + %1$s está grabando un audio... + %1$s está enviando una foto... + %1$s está enviando un vídeo... + %1$s está enviando un archivo... ¿Tienes preguntas\nsobre Telegram? Hacer foto Galería @@ -115,6 +121,7 @@ Adjunto no soportado Establecer autodestrucción Servicio de notificaciones + Obteniendo información... %1$s activó la autodestrucción en %2$s Activaste la autodestrucción en %1$s @@ -143,11 +150,12 @@ %1$s cambió el nombre del grupo %2$s %1$s cambió la foto del grupo %2$s %1$s invitó a %3$s al grupo %2$s + %1$s volvió al grupo %2$s %1$s expulsó a %3$s del grupo %2$s %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 - Privacidad y seguirdad - 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 seguridad - Cerrar todas las otras sesiones.\n\nSi crees que alguien ha iniciado la sesión sin tu consentimiento, puedes activar la verificación en dos pasos, en los ajustes de privacidad y seguridad.\n\nAtentamente,\nEl equipo de Telegram %1$s actualizó su foto de perfil Responder Responder a %1$s @@ -242,6 +250,7 @@ Sin sonido Por defecto Soporte + Sólo si está silenciado Fondo de chat Mensajes Enviar con \'Intro\' @@ -296,9 +305,44 @@ 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 + Desactivadas + Desactivadas + Desactivado + Apagado + Sonidos en el chat + Por defecto + + Sesiones activas + Sesión actual + Sin otras sesiones activas + Puedes iniciar sesión en Telegram desde otro móvil, tablet o computador, usando el mismo número de teléfono. Todos tus datos se sincronizarán al instante. + Sesiones activas + Controla tus sesiones en otros dispositivos. + Pulsa una sesión para cerrarla. + ¿Cerrar esta sesión? + aplicación no oficial + + Código de acceso + Cambiar código de acceso + Cuando configuras un código, aparece un candado en la pantalla de chats. Toca sobre él para bloquear y desbloquear la aplicación.\n\nNota: si olvidas el código, tendrás que eliminar y reinstalar la aplicación. Perderás todos los chats secretos. + Ahora verás un candado en la pantalla de chats. Púlsalo para bloquear tu Telegram con tu nuevo código. + PIN + Contraseña + Pon tu código de acceso actual + Pon un código de acceso + Pon tu nuevo código de acceso + Pon tu código de acceso + Pon, otra vez, tu nuevo código + Código de acceso inválido + Los códigos de acceso no coinciden + Bloqueo automático + El bloqueo se activará transcurrido este tiempo. + en %1$s + Desactivado Comparte fotos y vídeos en este chat y accede a ellos desde cualquier dispositivo. Archivos + Multimedia Comparte archivos en este chat y accede a ellos desde cualquier dispositivo. Mapa @@ -307,9 +351,9 @@ m de distancia km de distancia Enviar ubicación - Compartir ubicación + Ubicación - Ir a Fotos y vídeos + Ir a Multimedia Guardar en galería %1$d de %2$d Galería @@ -318,36 +362,82 @@ Por favor, primero descarga la multimedia No hay fotos recientes No hay GIF recientes - BUSCAR FOTO - BUSCAR GIF + BUSCA FOTOS + BÚSQUEDA WEB + BUSCA GIF Buscar foto Buscar GIF - Cortar imagen + Recortar imagen Editar imagen + Realzar + Iluminación + Contraste + Exposición + Temperatura + Saturación + Viñeta + Sombras + Grano + Nitidez + Desenfoque + Apagado + Lineal + Radial + ¿Quieres eliminar esta foto? + ¿Quieres eliminar este vídeo? + ¿Descartar cambios? + ¿Quieres borrar el historial de búsqueda? + Borrar - Password - Change password - Old password - Enter old password - New password - Enter new password - Verify new password - Enter your password - Hint - Enter hint - Important: you will lose all your chats, messages and media in the case of a forgotten password. - Passwords do not match - Incorrect old password - Incorrect password - Incorrect new password - Hint shouldn\'t contain password - Enter password - Important: you will lose all your chats, messages and media. - Delete account - Delete my account - Hint: %1$s - Are you sure you want to delete your account? - We deeply clarify you that you will lose all your chats, messages and media. Are you really sure? + Verificación en dos pasos + Poner contraseña adicional + Puedes poner una contraseña, que será requerida cuando inicies sesión en un nuevo dispositivo, además del código que recibes vía SMS. + Tu contraseña + Por favor, pon tu contraseña + Pon una contraseña + Por favor, pon tu nueva contraseña + Pon, otra vez, tu contraseña + E-mail de recuperación + Tu e-mail + Por favor, añade un e-mail válido. Es la única forma de recuperar una contraseña olvidada. + Omitir + Advertencia + En serio.\n\nSi olvidas tu contraseña, perderás el acceso a tu cuenta de Telegram. No habrá manera de recuperarla. + ¡Ya casi! + Por favor, revisa tu e-mail (no olvides la carpeta de spam) para completar la configuración de la verificación en dos pasos. + ¡Listo! + Tu contraseña para la verificación en dos pasos está activada. + Cambiar contraseña + Desactivar la contraseña + Poner e-mail de recuperación + Cambiar e-mail de recuperación + ¿Quieres desactivar tu contraseña? + Pista para la contraseña + Por favor, crea una pista para tu contraseña + Las contraseñas no coinciden + Anular la configuración de la verificación en dos pasos + Por favor, sigue estos pasos para completar la configuración de la verificación en dos pasos:\n\n1. Revisa tu e-mail (no olvides la carpeta de spam).\n%1$s\n\n2. Haz click en el enlace de validación. + La pista debe ser diferente de tu contraseña + E-mail inválido + Lo sentimos + Como no estableciste un e-mail de recuperación cuando configuraste tu contraseña, las opciones restantes son recordar tu contraseña o restablecer tu cuenta. + Enviamos un código de recuperación al e-mail que nos diste:\n\n%1$s + Por favor, revisa tu e-mail y pon el código de 6 dígitos que te enviamos ahí. + ¿Tienes problemas para acceder a tu e-mail %1$s? + Si no puedes acceder a tu e-mail, las opciones restantes son recordar tu contraseña o restablecer tu cuenta. + RESTABLECER MI CUENTA + Si continúas con el reinicio de tu cuenta, perderás todos tus chats y mensajes, junto con toda la multimedia y archivos que compartiste. + Advertencia + Esta acción no puede deshacerse.\n\nSi reinicias tu cuenta, todos tus mensajes y chats se eliminarán. + Restablecer + Contraseña + Activaste la verificación en dos pasos, así que tu cuenta está protegida con una contraseña adicional. + ¿Olvidaste la contraseña? + Recuperar contraseña + Código + Contraseña desactivada + Tienes activada la verificación en dos pasos.\nNecesitarás la contraseña que configuraste para iniciar tu sesión en Telegram. + Tu e-mail de recuperación %1$s aún no está activo y su confirmación está pendiente. Privacidad y seguridad Privacidad @@ -405,6 +495,7 @@ Eliminar foto Establecer OK + RECORTAR un1 expulsó a un2 un1 dejó el grupo @@ -422,6 +513,7 @@ Creaste el grupo un1 te expulsó un1 te añadió + un1 volvió al grupo Este mensaje no lo admite tu versión de Telegram. Actualiza la app para verlo: http://telegram.org/update Foto Vídeo @@ -437,12 +529,13 @@ Número de teléfono inválido Código expirado. Por favor, vuelve a iniciar sesión. Muchos intentos. Por favor, prueba de nuevo más tarde. + Demasiados intentos. Por favor, reinténtalo en %1$s Código inválido Nombre inválido Apellidos inválidos Cargando... No tienes reproductor de vídeo. Por favor, instala uno para continuar. - Por favor, envíanos un correo electrónico a sms@telegram.org y cuéntanos tu problema. + Por favor, envía un correo electrónico a sms@stel.com y cuéntanos tu problema. No tienes aplicaciones que puedan manejar el tipo de archivo \'%1$s\'. Por favor, instala una para continuar. Este usuario no tiene Telegram aún. ¿Enviarle una invitación? ¿Quieres hacerlo? @@ -511,18 +604,18 @@ %1$d mensajes %1$d mensajes %1$d mensajes - sin archivos - %1$d archivo - %1$d archivos - %1$d archivos - %1$d archivos - %1$d archivos - unused - de %1$d contacto - de %1$d contactos - de %1$d contactos - de %1$d contactos - de %1$d contactos + Sin ítems + %1$d ítem + %1$d ítems + %1$d ítems + %1$d ítems + %1$d ítems + desde ningún chat + desde %1$d chat + desde %1$d chats + desde %1$d chats + desde %1$d chats + desde %1$d chats %1$d segundos %1$d segundo %1$d segundos @@ -571,7 +664,63 @@ %1$d usuarios %1$d usuarios %1$d usuarios + + %1$d mensajes adjuntos + Mensaje adjunto + %1$d mensajes adjuntos + %1$d mensajes adjuntos + %1$d mensajes adjuntos + %1$d mensajes adjuntos + %1$d archivos adjuntos + Archivo adjunto + %1$d archivos adjuntos + %1$d archivos adjuntos + %1$d archivos adjuntos + %1$d archivos adjuntos + %1$d fotos adjuntas + Foto adjunta + %1$d fotos adjuntas + %1$d fotos adjuntas + %1$d fotos adjuntas + %1$d fotos adjuntas + %1$d vídeos adjuntos + Vídeo adjunto + %1$d vídeos adjuntos + %1$d vídeos adjuntos + %1$d vídeos adjuntos + %1$d vídeos adjuntos + %1$d audios adjuntos + Audio adjunto + %1$d audios adjuntos + %1$d audios adjuntos + %1$d audios adjuntos + %1$d audios adjuntos + %1$d ubicaciones adjuntas + Ubicación adjunta + %1$d ubicaciones adjuntas + %1$d ubicaciones adjuntas + %1$d ubicaciones adjuntas + %1$d ubicaciones adjuntas + %1$d contactos adjuntos + Contacto adjunto + %1$d contactos adjuntos + %1$d contactos adjuntos + %1$d contactos adjuntos + %1$d contactos adjuntos + %1$d stickers adjuntos + Sticker adjunto + %1$d stickers adjuntos + %1$d stickers adjuntos + %1$d stickers adjuntos + %1$d stickers adjuntos + y %1$d otros + and %1$d más + y otros %1$d + y otros %1$d + y otros %1$d + y otros %1$d + MMMM \'de\' yyyy dd \'de\' MMM dd.MM.yy dd.MM.yyyy diff --git a/TMessagesProj/src/main/res/values-it/strings.xml b/TMessagesProj/src/main/res/values-it/strings.xml index 2a2f3da83..8d827737c 100644 --- a/TMessagesProj/src/main/res/values-it/strings.xml +++ b/TMessagesProj/src/main/res/values-it/strings.xml @@ -36,8 +36,8 @@ Ancora nessuna chat… Inizia a scrivere premendo il tasto\nnuovo messaggio nell\'angolo in basso a destra\no apri il menu per avere più opzioni. Attendo la rete... - Connessione in corso… - Aggiornamento in corso… + Connessione… + Aggiornamento… Nuova chat segreta In attesa che %s si colleghi… Chat segreta annullata @@ -57,6 +57,8 @@ Silenzia per %1$s Suona Tra %1$s + Disabilita + HASHTAG Nuova lista broadcast Immetti il nome della lista @@ -83,6 +85,10 @@ sta scrivendo… sta scrivendo… stanno scrivendo… + %1$s sta registrando un audio... + %1$s sta inviando una foto... + %1$s sta inviando un video... + %1$s sta inviando un file... Hai una domanda\nsu Telegram? Scatta una foto Galleria @@ -111,10 +117,11 @@ ANNULLA Salva in download Condividi - Applica file di localizzazione + Applica traduzione Allegato non supportato Timer di autodistruzione Notifiche di servizio + Recupero le info del link... %1$s ha impostato il timer di autodistruzione a %2$s Hai impostato il timer di autodistruzione a %1$s @@ -143,11 +150,12 @@ %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 è rientrato nel 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 - Privacy e Sicurezza - Termina tutte le sessioni.\n\nGrazie,\nil team di Telegram + %1$s,\nAbbiamo rilevato un accesso al tuo account da un nuovo dispositivo il %2$s\n\nDispositivo: %3$s\nPosizione: %4$s\n\nSe non sei stato tu, puoi andare su Impostazioni - Privacy e Sicurezza - Sessioni - Termina tutte le sessioni.\n\nSe pensi che qualcuno si sia collegato al tuo account contro il tuo volere, ti raccomandiamo di attivare la verifica in due passaggi nelle impostazioni di Privacy e Sicurezza.\n\nGrazie,\nil team di Telegram %1$s ha aggiornato la foto del profilo Rispondi Rispondi a %1$s @@ -227,7 +235,7 @@ Avviso Anteprima messaggio Notifiche di gruppo - Suoni + Suono Notifiche in-app Suoni in-app Vibrazione in-app @@ -240,12 +248,13 @@ Utenti bloccati Disconnetti Nessun suono - Predefinito + Predefinita Supporto + Solo se silenzioso Sfondo chat Messaggi Spedisci con Invio - Chiudi tutte le altre sessioni + Termina le altre sessioni Eventi Un contatto ha iniziato a usare Telegram PEBBLE @@ -254,10 +263,10 @@ Chiedi a un volontario FAQ di Telegram https://telegram.org/faq/it - Eliminare la localizzazione? - File della localizzazione non valido - Abilitato - Disabilitato + Eliminare la traduzione? + File di traduzione non valido + Abilitate + Disabilitata Servizio notifiche Se i servizi di Google Play sono sufficienti per ricevere le notifiche, è possibile disabilitare il Servizio notifiche. Ti raccomandiamo comunque di lasciarlo abilitato per lasciare l\'app attiva in background e ricevere le notifiche istantanee. Ordina per @@ -272,7 +281,7 @@ Mostra sempre i popup Contatore Badge Breve - Lungo + Lunga Predefinito di sistema Impostazioni predefinite Download automatico media @@ -283,7 +292,7 @@ Salva nella galleria Modifica nome Priorità - Default + Predefinita Bassa Alta Massima @@ -296,9 +305,44 @@ 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 + Disabilitate + Disabilitata + Disabilitato + No + Suoni in-chat + Predefinito + + Sessioni attive + Sessione corrente + Nessun\'altra sessione attiva + Ti puoi connettere a Telegram da altri dispositivi mobili, tablet e desktop usando lo stesso numero. Tutti i tuoi dati saranno sincronizzati istantaneamente. + Sessioni attive + Controlla le tue sessioni sugli altri dispositivi. + Premi su una sessione per terminarla. + Terminare questa sessione? + app non ufficiale + + Blocco con codice + Cambia codice + Quando imposti un codice, un\'icona col lucchetto apparirà nella pagina delle chat. Premi su di essa per bloccare e sbloccare l\'app.\n\nNota: se ti dimentichi il codice, dovrai disinstallare e reinstallare l\'app. Tutte le chat segrete verranno perse. + Ora visualizzerai un\'icona col lucchetto nella pagina delle chat. Premi su di essa per bloccare la tua app Telegram con il codice. + PIN + Password + Inserisci il tuo codice + Inserisci un codice + Inserisci il nuovo codice + Inserisci il tuo codice + Reinserisci il nuovo codice + Codice non valido + I codici non corrispondono + Blocco automatico + Richiede il codice se lontano per del tempo. + tra %1$s + Disabilitato Condividi foto e video in questa chat e accedi ad essi da ogni tuo dispositivo. File + Media condivisi Condividi file e documenti in questa chat e accedi ad essi da ogni tuo dispositivo. Mappa @@ -318,36 +362,82 @@ Scarica prima il file Nessuna foto recente Nessuna GIF recente - RICERCA WEB - RICERCA GIF + CERCA IMMAGINI + RICERCA WEB + CERCA GIF Cerca su web Cerca GIF Ritaglia immagine Modifica immagine + Migliora + Alte luci + Contrasto + Esposizione + Calore + Saturazione + Vignettatura + Ombre + Grana + Nitidezza + Sfocatura + No + Lineare + Radiale + Sei sicuro di voler eliminare questa foto? + Sei sicuro di voler eliminare questo video? + Annullare le modifiche? + Cancellare la cronologia di ricerca? + Pulisci - Password - Change password - Old password - Enter old password - New password - Enter new password - Verify new password - Enter your password - Hint - Enter hint - Important: you will lose all your chats, messages and media in the case of a forgotten password. - Passwords do not match - Incorrect old password - Incorrect password - Incorrect new password - Hint shouldn\'t contain password - Enter password - Important: you will lose all your chats, messages and media. - Delete account - Delete my account - Hint: %1$s - Are you sure you want to delete your account? - We deeply clarify you that you will lose all your chats, messages and media. Are you really sure? + Verifica in due passaggi + Imposta password aggiuntiva + Puoi impostare una password che ti verrà richiesta quando ti connetti da un nuovo dispositivo in aggiunta al codice che riceverai via SMS. + La tua password + Inserisci la tua password + Inserisci una password + Inserisci la tua nuova password + Reinserisci la tua password + E-mail di recupero + La tua e-mail + Per favore inserisci un\'e-mail valida. È l\'unico modo di recuperare una password dimenticata. + Salta + Attenzione + No, seriamente.\n\nSe dimentichi la tua password, perderai l\'accesso al tuo account Telegram. Non ci sarà modo di ripristinarlo. + Ci siamo quasi! + Per favore controlla la tua e-mail (anche lo spam) per completare la configurazione della verifica in due passaggi. + Fatto! + La password per la verifica in due passaggi è ora attiva. + Cambia password + Disattiva password + Imposta e-mail di recupero + Cambia e-mail di recupero + Sei sicuro di voler disabilitare la tua password? + Suggerimento password + Per favore crea un suggerimento per la tua password + Le password non corrispondono + Annulla configurazione della verifica in due passaggi + Per favore segui questi step per completare la configurazione della verifica in due passaggi:\n\n1. Controlla la tua e-mail (anche lo spam)\n%1$s\n\n2. Clicca sul link di conferma. + Il suggerimento deve essere diverso dalla password + E-mail non valida + Scusa + Siccome non hai fornito un\'email di recupero quando hai impostato la tua password, non ti resta che ricordarti la password o ripristinare il tuo account. + Abbiamo inviato un codice di ripristino alla e-mail che ci hai fornito:\n\n%1$s + Per favore controlla la tua e-mail e inserisci il codice a 6 cifre che ti abbiamo inviato. + Hai problemi ad accedere alla tua e-mail %1$s? + Se non puoi ripristinare l\'accesso alla tua e-mail, non ti resta che ricordarti la password o ripristinare il tuo account. + RIPRISTINA IL MIO ACCOUNT + Perderai tutte le chat e i messaggi, insieme ai media e ai file condivisi, se procederai a ripristinare il tuo account. + Attenzione + Questa azione non può essere annullata.\n\n Se ripristini il tuo account, tutti i tuoi messaggi e chat saranno eliminati. + Ripristina + Password + Hai attivato la verifica in due passaggi, così il tuo account è protetto con una password aggiuntiva. + Password dimenticata? + Recupero password + Codice + Password disattivata + Hai attivato la verifica in due passaggi.\nAvrai bisogno della password che hai impostato per accedere al tuo account Telegram. + La tua e-mail di recupero %1$s non è ancora attiva e attende la conferma. Privacy e Sicurezza Privacy @@ -405,6 +495,7 @@ Elimina foto Imposta OK + RITAGLIA un1 ha espulso un2 un1 ha lasciato il gruppo @@ -422,6 +513,7 @@ Hai creato il gruppo un1 ti ha espulso un1 ti ha aggiunto + un1 è ritentrato nel gruppo Questo messaggio non è supportato sulla tua versione di Telegram. Aggiorna l\'applicazione per visualizzarlo: http://telegram.org/update Foto Video @@ -437,12 +529,13 @@ Numero di telefono non valido Codice scaduto, effettua di nuovo l\'accesso Troppi tentativi, riprova più tardi + Troppi tentativi, per favore riprova di nuova tra %1$s Codice non valido Nome non valido Cognome non valido Caricamento… Non hai un lettore video, per favore installane uno per continuare - Invia un’email a sms@telegram.org spiegandoci il problema. + Invia un’email a sms@stel.com spiegandoci il problema. Non hai nessuna applicazione che può gestire il tipo di file \'%1$s\': installane una per proseguire Questo utente non ha ancora Telegram, vuoi invitarlo? Sei sicuro? @@ -450,7 +543,7 @@ Vuoi inoltrare i messaggi a %1$s? Inviare i messaggi a %1$s? Sei sicuro di volerti disconnettere?\n\nRicorda che puoi usare Telegram su tutti i tuoi device insieme.\n\nRicorda, disconnettersi elimina tutte le Chat Segrete. - Chiudere tutte le altre sessioni? + Terminare tutte le altre sessioni? Eliminare il gruppo e uscire da esso? Eliminare questa chat? Condividere le informazioni del proprio contatto? @@ -511,18 +604,18 @@ %1$d messaggi %1$d messaggi %1$d messaggi - nessun file - %1$d file - %1$d file - %1$d file - %1$d file - %1$d file - da nessun contatto - da %1$d contatto - da %1$d contatti - da %1$d contatti - da %1$d contatti - da %1$d contatti + nessun oggetto + %1$d oggetto + %1$d oggetti + %1$d oggetti + %1$d oggetti + %1$d oggetti + in nessuna chat + in %1$d chat + in %1$d chat + in %1$d chat + in %1$d chat + in %1$d chat %1$d secondi %1$d secondo %1$d secondi @@ -571,7 +664,63 @@ %1$d utenti %1$d utenti %1$d utenti + + %1$d messaggi inoltrati + Messaggio inoltrato + %1$d messaggi inoltrati + %1$d messaggi inoltrati + %1$d messaggi inoltrati + %1$d messaggi inoltrati + %1$d file inoltrati + FIle inoltrato + %1$d file inoltrati + %1$d file inoltrati + %1$d file inoltrati + %1$d file inoltrati + %1$d foto inoltrate + Foto inoltrata + %1$d foto inoltrate + %1$d foto inoltrate + %1$d foto inoltrate + %1$d foto inoltrate + %1$d video inoltrati + Video inoltrato + %1$d video inoltrati + %1$d video inoltrati + %1$d video inoltrati + %1$d video inoltrati + %1$d audio inoltrati + Audio inoltrato + %1$d audio inoltrati + %1$d audio inoltrati + %1$d audio inoltrati + %1$d audio inoltrati + %1$d posizioni inoltrate + Posizione inoltrata + %1$d posizione inoltrate + %1$d posizione inoltrate + %1$d posizione inoltrate + %1$d posizione inoltrate + %1$d contatti inoltrati + Contatto inoltrato + %1$d contatti inoltrati + %1$d contatti inoltrati + %1$d contatti inoltrati + %1$d contatti inoltrati + %1$d sticker inoltrati + Sticker inoltrato + %1$d sticker inoltrati + %1$d sticker inoltrati + %1$d sticker inoltrati + %1$d sticker inoltrati + e altri %1$d + e %1$d altro + e altri %1$d + e altri %1$d + e altri %1$d + e altri %1$d + MMMM yyyy dd MMM dd.MM.yy dd.MM.yyyy diff --git a/TMessagesProj/src/main/res/values-ko/strings.xml b/TMessagesProj/src/main/res/values-ko/strings.xml index 08923ac6d..e4c80afb8 100644 --- a/TMessagesProj/src/main/res/values-ko/strings.xml +++ b/TMessagesProj/src/main/res/values-ko/strings.xml @@ -57,6 +57,8 @@ %1$s 동안 음소거 음소거 해제 %1$s 후 + 비활성화 + 해시태그 새 단체 메시지 리스트 리스트 이름을 입력하세요 @@ -83,6 +85,10 @@ 입력 중... 님이 입력 중... 님이 입력 중... + %1$s님이 녹음 중... + %1$s님이 사진 보내는 중... + %1$s님이 동영상 보내는 중... + %1$s님이 파일 보내는 중... 텔레그램에 관해\n궁금한 사항이 있나요? 사진 촬영 앨범 @@ -115,6 +121,7 @@ 지원하지 않는 형식입니다 자동삭제 타이머 설정 서비스 알림 + 링크 정보를 가져오는 중... %1$s님이 자동삭제를 %2$s 후로 설정했습니다 자동삭제를 %1$s 후로 설정했습니다 @@ -143,11 +150,12 @@ %1$s님이 그룹 이름을 %2$s 그룹으로 변경했습니다 %1$s님이 %2$s 그룹 사진을 변경했습니다 %1$s님이 %3$s님을 %2$s 그룹에 초대했습니다 + %1$s 님이 %2$s 그룹으로 되돌아왔습니다 %1$s님이 %3$s님을 %2$s 그룹에서 추방했습니다 %1$s님이 %2$s 그룹에서 추방했습니다 %1$s님이 %2$s 그룹을 떠났습니다 %1$s님이 텔레그램에 가입했습니다! - %1$s님,\n%2$s에 새 기기에서 회원님의 계정에 로그인하였습니다.\n\n기기: %3$s\n위치: %4$s\n\n본인의 접속이 아니라면 \'설정\'으로 가서 \'다른 모든 세션 종료\'를 실행하세요.\n\n감사합니다.\n텔레그램 팀 드림 + %1$s님,\n%2$s에 새 기기에서 회원님의 계정 로그인이 감지되었습니다. \n\n기기: %3$s\n위치: %4$s\n\n본인의 접속이 아니라면 \'설정\' 창에서 \'모든 세션 종료\' 기능을 실행하세요.\n\n만약 강제접속 의심이 되신다면 2단계 인증을 설정 - 개인정보 및 보안에서 설정할 수 있습니다.\n\n감사합니다.\n텔레그램 팀 %1$s님이 프로필 사진을 변경했습니다 답장 %1$s 그룹에 답장하기 @@ -242,6 +250,7 @@ 알림음 없음 기본값 지원 + 음소거일 중에만 채팅방 배경화면 메시지 엔터키로 메시지 전송 @@ -296,9 +305,44 @@ 인증코드 메시지를 새 번호로 전송하겠습니다. 그 번호는 이미 텔레그램 계정에 연결되어 있습니다. 새 번호로 이동하기 전에 %1$s 계정에서 탈퇴해 주세요. 기타 + 비활성화됨 + 비활성화됨 + 비활성화됨 + + 채팅중 소리 설정 + 기본값 + + 활성화된 세션 + 현재 세션 + 활성화된 세션이 없음 + 동일한 휴대번호로 다른 휴대기기,태블릿과 데스크탑에서 텔레그램 로그인이 가능합니다. 모든 데이터는 즉시 동기화 됩니다. + 활성화된 세션 + 다른 기기 세션 관리 + 탭하여 세션 종료 + 해당 세션을 종료하시겠습니까? + 비공식앱 + + 잠금코드 잠금 + 잠금번호 변경 + 잠금코드를 설정하셨을 경우, 대화방에 잠금 아이콘이 표시됩니다. 해당 아이콘을 클릭하여 텔레그램 잠금 설정을 할 수 있습니다.\n\n주의: 잠금코드를 잊어버렸을 경우 앱 삭제후 재설치를 해주셔야합니다. 이 경우 비밀대화 내용은 삭제가 됩니다. + 대화방에 잠금아이콘이 표시가 됩니다. 해당 아이콘을 클릭하여 새로운 잠금코드를 설정하여 텔레그램을 잠글수 있습니다. + 핀코드 + 잠금번호 + 현재 잠금코드 입력 + 잠금코드 입력 + 새로운 잠금코드 입력 + 잠금코드를 입력해주세요 + 잠금코드 재입력 + 올바르지 않은 잠금코드 + 잠금코드가 정확하지 않습니다 + 자동 잠금 + 일정 시간 후에 잠금코드 활성화 + %1$s 후에 + 비활성화됨 이 채팅방에서 사진이나 동영상을 공유하면 다른 기기에서도 보실 수 있습니다. 파일 + 공유된 미디어 이 채팅방에서 파일이나 문서를 공유하면 다른 기기에서도 보실 수 있습니다. 지도 @@ -318,36 +362,82 @@ 사진/동영상을 먼저 다운로드하세요 최근 사진 없음 최근에 검색한 GIF - 웹 검색 + 이미지 검색 + 웹 검색 GIF 검색 웹 검색 GIF 검색 사진 자르기 이미지 편집 + 향상 + 하이라이트 + 대비 + 노출 + 온기 + 채도 + 비네팅 + 그림자 + 그레인 + 선명 + 흐림 + + 선형 + 방사형 + 이 사진을 삭제하시겠습니까? + 이 동영상을 삭제하시겠습니까? + 변경을 취소하시겠습니까? + 검색기록을 지우시겠습니까? + 지우기 - Password - Change password - Old password - Enter old password - New password - Enter new password - Verify new password - Enter your password - Hint - Enter hint - Important: you will lose all your chats, messages and media in the case of a forgotten password. - Passwords do not match - Incorrect old password - Incorrect password - Incorrect new password - Hint shouldn\'t contain password - Enter password - Important: you will lose all your chats, messages and media. - Delete account - Delete my account - Hint: %1$s - Are you sure you want to delete your account? - We deeply clarify you that you will lose all your chats, messages and media. Are you really sure? + 2단계 인증 + 개별 비밀번호 설정 + 새로운 기기에 로그인시 수신되는 SMS와는 별도로 개별 비밀번호를 설정 할 수 있습니다. + 비밀번호 + 비밀번호를 입력해주세요 + 비밀번호 입력 + 새로운 비밀번호 입력 + 비밀번호 재입력 + 복구 이메일 + 이메일 + 올바른 이메일을 입력해주세요. 비밀번호 분실시 유일하게 복구가 가능한 수단입니다. + 건너뛱 + 경고 + 비밀번호 분실시\n\n텔레그램에 대한 모든 접속 권한을 상실하시게 됩니다.\n비밀번호 분실시 복구는 불가능 합니다. + 거의 마무리 되었습니다! + 2단계 인증을 완료하시려면 이메일(스팸 폴더도 확인)을 확인해주세요. + 성공! + 2단계 인증 비밀번호가 활성화 되었습니다. + 비밀번호 변경 + 비밀번호 끄기 + 복구 이메일 설정 + 복구 이메일 변경 + 비밀번호를 정말로 삭제하시겠습니까? + 비밀번호 힌트 + 비밀번호 힌트를 생성해주세요 + 비밀번호가 정확하지 않습니다. + 2단계 인증 설정 끝내기 + 2단계 인증 설정을 완료하시려면 아래의 절차대로 진행해주세요:\n\n1.이메일 확인(스팸 폴더 확인)\n%1$s\n\n2.인증 링크 클릭 + 힌트는 비밀번호와 다르게 설정해주세요. + 올바르지 않은 이메일 + 죄송합니다. + 비밀번호 복구 이메일을 설정하지 않았기때문에, 비밀번호를 기억해내시거나 계정 초기화를 진행해주셔야합니다. + 다음 복구 이메일 주소로 복구 코드를 전송하였습니다:\n\n%1$s + 이메일을 확인하여 수신받은 6자리 코드를 입력해주세요. + 이메일 %1$s 접근에 문제가 있으신가요? + 이메일 접근을 하실 수 없을 경우, 비밀번호를 기억해내시거나 계정 초기화를 진행해주셔야 합니다. + 계정 초기화 + 계정 초기화 진행시 모든 대화,메시지 및 공유받은 미디어와 파일이 삭제가 됩니다. + 경고 + 진행하실 경우 취소가 불가능합니다.\n\n계정 초기화 진행시 모든 대화 및 메시지가 삭제됩니다. + 초기화 + 비밀번호 + 2단계 인증이 활성화되어 회원님 계정이 개별 비밀번호로 보안됩니다. + 비밀번호를 잊어버리셨나요? + 비밀번호 복구 + 코드 + 비밀번호 비활성화 + 2단계 인증을 활성화 하였습니다.\n설정된 개별 비밀번호를 사용하여 텔레그램 계정에 로그인 할 수 있습니다. + 복구 이메일 %1$s 이 아직 활성화 되지 않았으며 미승인 상태입니다. 개인정보 및 보안 개인정보 @@ -405,6 +495,7 @@ 사진 삭제 설정 확인 + 자르기 un1님이 un2님을 추방했습니다 un1님이 퇴장했습니다 @@ -422,6 +513,7 @@ 그룹을 만들었습니다 un1님이 추방했습니다 un1님이 그룹에 초대했습니다 + un1 님께서 그룹에 돌아오셨습니다 이 메시지는 사용 중인 텔레그램의 버전이 낮아 지원하지 않습니다. 앱을 업데이트 하세요: http://telegram.org/update 사진 동영상 @@ -437,12 +529,13 @@ 올바른 전화번호를 입력해 주세요 코드가 만료되었습니다. 다시 로그인하세요 너무 많이 시도하셨습니다. 나중에 다시 시도하세요 + 너무 많이 시도하셨습니다. %1$s 초 후에 다시 시도하세요. 올바른 코드를 입력해 주세요 올바른 이름을 입력해 주세요 올바른 성을 입력해 주세요 불러오는 중... 동영상 재생 앱이 없습니다. 계속하려면 앱을 설치해 주세요. - sms@telegram.org 이메일 주소로 이 문제를 보내주세요. + 발생한 문제에 대하여 sms@stel.com 주소로 이메일을 보내주세요. \'%1$s\' 파일 형식을 처리할 앱이 없습니다. 계속하려면 앱을 설치해 주세요. 친구가 아직 텔레그램을 사용하지 않네요. 초대해 보세요! 확실합니까? @@ -511,18 +604,18 @@ 메시지 %1$d건 메시지 %1$d건 메시지 %1$d건 - 파일 없음 - 파일 %1$d개 - 파일 %1$d개 - 파일 %1$d개 - 파일 %1$d개 - 파일 %1$d개 - 보낸곳 없음 - - 채팅방 %1$d개에서 - 채팅방 %1$d개에서 - 채팅방 %1$d개에서 - 채팅방 %1$d개에서 - 채팅방 %1$d개에서 + 아이템이 없습니다. + %1$d개 아이템 + %1$d개 아이템 + %1$d개 아이템 + %1$d개 아이템 + %1$d개 아이템 + 받은 대화 없음 + %1$d개의 대화로부터 받음 + %1$d개의 대화로부터 받음 + %1$d개의 대화로부터 받음 + %1$d개의 대화로부터 받음 + %1$d개의 대화로부터 받음 %1$d초 %1$d초 %1$d초 @@ -571,7 +664,63 @@ %1$d명의 대화상대 %1$d명의 대화상대 %1$d명의 대화상대 + + %1$d 개의 전달된 메시지 + 전달된 메시지 + %1$d 개의 전달된 메시지 + %1$d 개의 전달된 메시지 + %1$d 개의 전달된 메시지 + %1$d 개의 전달된 메시지 + %1$d 개의 전달된 파일 + 전달된 파일 + %1$d 개의 전달된 파일 + %1$d 개의 전달된 파일 + %1$d 개의 전달된 파일 + %1$d 개의 전달된 파일 + %1$d 개의 전달된 사진 + 전달된 사진 + %1$d 개의 전달된 사진 + %1$d 개의 전달된 사진 + %1$d 개의 전달된 사진 + %1$d 개의 전달된 사진 + %1$d 개의 전달된 사진 + 전달된 비디오 + %1$d 개의 전달된 비디오 + %1$d 개의 전달된 비디오 + %1$d 개의 전달된 비디오 + %1$d 개의 전달된 비디오 + %1$d 개의 전달된 오디오 + 전달된 오디오 + %1$d 개의 전달된 오디오 + %1$d 개의 전달된 오디오 + %1$d 개의 전달된 오디오 + %1$d 개의 전달된 오디오 + %1$d 개의 전달된 위치 + 전달된 위치 + %1$d 개의 전달된 위치 + %1$d 개의 전달된 위치 + %1$d 개의 전달된 위치 + %1$d 개의 전달된 위치 + %1$d 개의 전달된 연락처 + 전달된 연락처 + %1$d 개의 전달된 연락처 + %1$d 개의 전달된 연락처 + %1$d 개의 전달된 연락처 + %1$d 개의 전달된 연락처 + %1$d 개의 전달된 스티커 + 전달된 스티커 + %1$d 개의 전달된 스티커 + %1$d 개의 전달된 스티커 + %1$d 개의 전달된 스티커 + %1$d 개의 전달된 스티커 + 및 %1$d 개 + 및 %1$d 개 + 및 %1$d 개 + 및 %1$d 개 + 및 %1$d 개 + 및 %1$d 개 + MMMM yyyy M\'월\' d\'일\' yyyy.MM.dd. yyyy. MM. dd. diff --git a/TMessagesProj/src/main/res/values-nl/strings.xml b/TMessagesProj/src/main/res/values-nl/strings.xml index 945b90a44..d652346b1 100644 --- a/TMessagesProj/src/main/res/values-nl/strings.xml +++ b/TMessagesProj/src/main/res/values-nl/strings.xml @@ -57,6 +57,8 @@ %1$s stil Stil uitschakelen Over %1$s + Uitschakelen + HASHTAGS Nieuwe verzendlijst Naam van lijst @@ -83,6 +85,10 @@ aan het typen is aan het typen zijn aan het typen + %1$s neemt geluid op + %1$s verstuurt een foto + %1$s verstuurt een video + %1$s verstuurt een bestand Heb je een vraag\nover Telegram? Foto maken Galerij @@ -115,6 +121,7 @@ Bestandstype niet ondersteund Zelfvernietigingstimer instellen Servicemeldingen + Link-preview ophalen... %1$s heeft de zelfvernietigingstimer ingesteld op %2$s Je hebt de zelfvernietigingstimer ingesteld op %1$s @@ -143,11 +150,12 @@ %1$s heeft de naam van de groep %2$s gewijzigd %1$s heeft de afbeelding van de groep %2$s gewijzigd %1$s heeft %3$s uitgenodigd voor de groep %2$s + %1$s is terug in de groep %2$s %1$s heeft %3$s verwijderd uit de groep %2$s %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 - Privacy en veiligheid - 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 die sessie beëindigen via Instellingen - Privacy en veiligheid - Sessies.\n\nAls je dat denkt dat iemand anders zonder jouw toestemming is ingelogd kun je twee-staps-verificatie activeren via instellingen - privacy en veiligheid .\n\nBedankt,\nHet Telegram-team %1$s heeft zijn/haar profielfoto gewijzigd Antwoord Antwoord op %1$s @@ -221,7 +229,7 @@ Een vraag stellen Animaties Deblokkeer - Houd een gebruiker ingedrukt om hem/haar te deblokkeren. + Gebruiker vasthouden om te deblokkeren. Geen geblokkeerde gebruikers Berichtmeldingen Waarschuwing @@ -242,6 +250,7 @@ Geen geluid Standaard Ondersteuning + Alleen indien stil Achtergrond kiezen Berichten Versturen met Enter @@ -296,9 +305,44 @@ 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 + Uitgeschakeld + Uitgeschakeld + Uitgeschakeld + Uit + Chatgeluiden + Standaard + + Actieve sessies + Huidige sessie + Geen andere actieve sessies + Je kunt in Telegram inloggen vanaf andere apparaten (mobiel,tablet,desktop) met hetzelfde telefoonnummer. Al je data zal direct worden gesynchroniseerd. + Actieve sessies + Beheer je sessies van andere apparaten. + Tik op een sessie om deze te beëindigen. + Deze sessie beëindigen? + onofficiële app + + Toegangscode-vergrendeling + Toegangscode wijzigen + Als je een toegangscode instelt verschijnt er een slotje op de chatspagina. Tik erop om Telegram te vergrendelen of te ontgrendelen.\n\nLet op: vergeet je de toegangscode dan zul je de app moeten verwijderen en herinstalleren. Alle geheime chats gaan daarbij verloren. + Je zult nu een slotje op de chatspagina zien. Tik erop om Telegram te vergrendelen met je nieuwe toegangscode. + PIN + Wachtwoord + Huidige toegangscode invoeren + Toegangscode invoeren + Nieuwe toegangscode invoeren + Toegangscode invoeren + Toegangscode opnieuw invoeren + Ongeldige toegangscode + Toegangscodes komen niet overeen + Automatisch vergrendelen + Vraag om toegangscode indien afwezig + over %1$s + Uitgeschakeld Deel foto\'s en video\'s in deze chat om ze op al je apparaten te kunnen benaderen. Bestanden + Gedeelde media Deel bestanden en documenten in deze chat om ze op al je apparaten te kunnen benaderen. Kaart @@ -319,35 +363,81 @@ Niets recents Niets recents ONLINE ZOEKEN - GIF\'S ZOEKEN + ZOEK OP HET WEB + GIF\'S ZOEKEN Online zoeken GIF\'s zoeken Foto bijsnijden Foto bewerken + Verbeteren + Accent + Contrast + Belichting + Warmte + Verzadiging + Vignet + Schaduwen + Korrel + Scherper + Vager + Uit + Lineair + Radiaal + Foto echt verwijderen? + Video echt verwijderen? + Wijzigingen negeren? + Zoekgeschiedenis wissen? + Wissen - Password - Change password - Old password - Enter old password - New password - Enter new password - Verify new password - Enter your password - Hint - Enter hint - Important: you will lose all your chats, messages and media in the case of a forgotten password. - Passwords do not match - Incorrect old password - Incorrect password - Incorrect new password - Hint shouldn\'t contain password - Enter password - Important: you will lose all your chats, messages and media. - Delete account - Delete my account - Hint: %1$s - Are you sure you want to delete your account? - We deeply clarify you that you will lose all your chats, messages and media. Are you really sure? + Twee-staps-verificatie + Extra wachtwoord instellen + Naast de code die je per SMS ontvangt kun je een extra wachtwoord instellen voor als je inlogt op een nieuw apparaat. + Je wachtwoord + Wachtwoord invoeren + Wachtwoord invoeren + Nieuw wachtwoord invoeren + Wachtwoord opnieuw invoeren + Herstel-e-mailadres + Je e-mailadres + Voeg je geldige e-mailadres toe. Het is de enige manier om je wachtwoord te herstellen. + Overslaan + Waarschuwing + Let op:\n\nAls je je wachtwoord vergeet verlies je toegang tot je Telegram-account. Er is geen optie om dit te herstellen. + Bijna klaar! + Controleer je e-mail en klik op de bevestigingslink om de twee-staps-verificatie in te schakelen. Kijk voor de zekerheid ook in de ongewenste post. + Gelukt! + Je wachtwoord voor twee-staps-verificatie is nu actief. + Wachtwoord wijzigen + Wachtwoord uitschakelen + Herstel-e-mailadres instellen + Herstel-e-mailadres wijzigen + Weet je zeker dat je je wachtwoord wilt uitschakelen? + Wachtwoordhint + Stel een hint voor je wachtwoord in + Wachtwoorden komen niet overeen + Twee-staps-verificatie annuleren + Volg deze stappen om twee-staps-verificatie in te schakelen:\n\n1.Controleer je e-mail (kijk voor de zekerheid ook in de ongewenste post)\n%1$s\n\n2.n klik op de bevestigingslink. + De hint moet anders zijn dan je wachtwoord + Ongeldig e-mailadres + Sorry + Omdat je geen herstel-e-mailadres hebt opgegeven voor je wachtwoord zul je bij verlies van je wachtwoord je account moeten resetten. + We hebben een herstelcode naar je opgegeven e-mailadres gestuurd:\n\n%1$s + Controleer je e-mail en geef de 6-cijferige code in die we je hebben gestuurd. + Kun je je e-mail niet benaderen %1$s? + Bij verlies van je wachtwoord zul je je account moeten resetten. + ACCOUNT RESETTEN + Al je chats, berichten en alle andere data gaan verloren als je verder gaat met de account-reset. + Waarschuwing + Deze actie kan niet worden hersteld.\n\nAl je chats, berichten en data gaan verloren als je je account reset. + Resetten + Wachtwoord + Twee-staps-verificatie ingeschakeld. Je account is met een extra wachtwoord beveiligd. + Wachtwoord vergeten? + Wachtwoordherstel + Code + Wachtwoord uitgeschakeld + Je hebt twee-staps-verificatie ingeschakeld.\nAls je inlogt op je Telegram-account heb je het ingestelde wachtwoord nodig. + Je herstel-e-mailadres %1$s is nog niet actief en in afwachting van bevestiging. Privacy en veiligheid Privacy @@ -405,6 +495,7 @@ Foto verwijderen Stel in OK + BIJSNIJDEN un1 heeft un2 verwijderd un1 heeft de groep verlaten @@ -422,6 +513,7 @@ Je hebt de groep gemaakt un1 heeft je verwijderd un1 heeft je toegevoegd + un1 is terug in de groep Dit bericht wordt niet ondersteund door jouw versie van Telegram. Werk Telegram bij om dit bericht te bekijken: http://telegram.org/update Foto Video @@ -437,12 +529,13 @@ Ongeldig telefoonnummer Code verlopen. Log opnieuw in. Te veel pogingen. Probeer het later opnieuw. + Te veel pogingen, probeer het over %1$s opnieuw Ongeldige code Ongeldige voornaam Ongeldige achternaam 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. + E-mail ons op sms@stel.com en vertel ons over je probleem. Je hebt geen apps die bestandstype \'%1$s\' kunnen verwerken, gelieve een compatibele app te installeren Deze gebruiker heeft nog geen Telegram. Wil je een uitnodiging sturen? Weet je het zeker? @@ -511,18 +604,18 @@ %1$d berichten %1$d berichten %1$d berichten - geen bestanden - %1$d bestand - %1$d bestanden - %1$d bestanden - %1$d bestanden - %1$d bestanden - van geen enkel contact - van %1$d contacten - van %1$d contacten - van %1$d contacten - van %1$d contacten - van %1$d contacten + geen items + %1$d item + %1$d items + %1$d items + %1$d items + %1$d items + van geen chats + van %1$d chat + van %1$d chats + van %1$d chats + van %1$d chats + van %1$d chats %1$d seconden %1$d seconde %1$d seconden @@ -571,7 +664,63 @@ %1$d gebruikers %1$d gebruikers %1$d gebruikers + + Bijlage: %1$d berichten + Bijlage: 1 bericht + Bijlage: %1$d berichten + Bijlage: %1$d berichten + Bijlage: %1$d berichten + Bijlage: %1$d berichten + Bijlage: %1$d bestanden + Bijlage: 1 bestand + Bijlage: %1$d bestanden + Bijlage: %1$d bestanden + Bijlage: %1$d bestanden + Bijlage: %1$d bestanden + Bijlage: %1$d foto\'s + Bijlage: 1 foto + Bijlage: %1$d foto\'s + Bijlage: %1$d foto\'s + Bijlage: %1$d foto\'s + Bijlage: %1$d foto\'s + Bijlage: %1$d foto\'s + Bijlage: 1 video + Bijlage: %1$d video\'s + Bijlage: %1$d video\'s + Bijlage: %1$d video\'s + Bijlage: %1$d video\'s + Bijlage: %1$d geluidsbestanden + Bijlage: 1 geluidsbestand + Bijlage: %1$d geluidsbestanden + Bijlage: %1$d geluidsbestanden + Bijlage: %1$d geluidsbestanden + Bijlage: %1$d geluidsbestanden + Bijlage: %1$d locaties + Bijlage: 1 locatie + Bijlage: %1$d locaties + Bijlage: %1$d locaties + Bijlage: %1$d locaties + Bijlage: %1$d locaties + Bijlage: %1$d contacten + Bijlage: 1 contact + Bijlage: %1$d contacten + Bijlage: %1$d contacten + Bijlage: %1$d contacten + Bijlage: %1$d contacten + Bijlage: %1$d stickers + Bijlage: 1 sticker + Bijlage: %1$d stickers + Bijlage: %1$d stickers + Bijlage: %1$d stickers + Bijlage: %1$d stickers + en %1$d anderen + en %1$d andere + en %1$d anderen + en %1$d anderen + en %1$d anderen + en %1$d anderen + MMMM yyyy dd MMM dd-MM-yy dd-MM-yyyy diff --git a/TMessagesProj/src/main/res/values-pt-rBR/strings.xml b/TMessagesProj/src/main/res/values-pt-rBR/strings.xml index bced87c67..b0d1b594a 100644 --- a/TMessagesProj/src/main/res/values-pt-rBR/strings.xml +++ b/TMessagesProj/src/main/res/values-pt-rBR/strings.xml @@ -5,7 +5,7 @@ Telegram Português (Brasil) - Portuguese (Brazil) + Português (Brasil) pt_BR Seu número @@ -57,6 +57,8 @@ Silenciar por %1$s Restaurar Som Em %1$s + Desativado + HASHTAGS Nova Lista de Transmissão Digite o nome da lista @@ -83,6 +85,10 @@ escrevendo... está escrevendo... estão escrevendo... + %1$s está gravando uma mensagem... + %1$s está enviando uma foto... + %1$s está enviando um vídeo... + %1$s está enviando um arquivo... Tem alguma dúvida\nsobre o Telegram? Tirar foto Galeria @@ -115,6 +121,7 @@ Anexo não suportado Definir timer de autodestruição Notificações de serviço + Obtendo informações... %1$s estabeleceu o tempo de autodestruição para %2$s Você estabeleceu o tempo de autodestruição para %1$s @@ -143,11 +150,12 @@ %1$s editou o nome do grupo %2$s %1$s editou a foto do grupo %2$s %1$s convidou %3$s para o grupo %2$s + %1$s retornou ao grupo %2$s %1$s removeu %3$s do grupo %2$s %1$s removeu você do grupo %2$s %1$s saiu do grupo %2$s %1$s entrou para o 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,\nNós detectamos que alguém acessou a sua conta a partir de um novo aparelho em %2$s\n\nAparelho: %3$s\nLocalização: %4$s\n\nSe não foi você, você pode ir em Configurações - Provacidade e Segurança - Sessões, e terminar aquela sessão.\n\nSe você acha que alguém acessou a sua conta contra a sua vontade, você pode habilitar a verificação em duas etapas nas configurações de Privacidade e Segurança.\n\nAtenciosamente,\nEquipe Telegram %1$s atualizou a foto do perfil Responder Responder para %1$s @@ -175,7 +183,7 @@ Nome do grupo %1$d/%2$d membros - Mídia compartilhada + Mídia Compartilhada Configurações Adicionar membro Apagar e sair do grupo @@ -242,6 +250,7 @@ Sem som Padrão Suporte + Somente no silencioso Papel de Parede Mensagens Enviar usando \'Enter\' @@ -270,7 +279,7 @@ Somente com a tela ligada Somente com a tela desligada Sempre mostrar pop-up - Contador de medalhas + Contador no Ícone Curta Longa Padrão do sistema @@ -294,11 +303,46 @@ ALTERAR 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. + O número %1$s já possui uma conta do Telegram. Por favor, exclua esta conta antes de migrar para o novo número. Outro + Desativado + Desativar + Desativado + Desativado + Sons no Chat + Padrão + + Sessões Ativas + Sessão atual + Nenhuma outra sessão ativa + Você pode entrar no Telegram a partir de outro celular, tablet ou computador usando o mesmo número de telefone. Todos os seus dados serão sincronizados instantaneamente. + Sessões Ativas + Controle suas sessões em outros aparelho. + Toque em uma sessão para terminá-la. + Encerrar essa sessão? + aplicativo não oficial + + Senha de Bloqueio + Alterar Senha + Quando você define uma senha adicional, um ícone de cadeado aparece na página de chats. Clique para bloquear e desbloquear o app.\n\nNota: se você esquecer a sua senha, terá de excluir e reinstalar o app. Todos os chats secretos serão perdidos. + Você verá o ícone do cadeado na página de chats. Clique para bloquear seu app do Telegram com a sua nova senha. + PIN + Senha + Insira sua senha atual + Insira uma senha + Insira sua nova senha + Insira sua senha + Re-insira sua nova senha + Senha inválida + As senhas não são iguais + Auto-bloquear + Requisitar senha se estiver ausente por muito tempo. + em %1$s + Desativado Compartilhar fotos e vídeos no chat e acessá-los em qualquer um de seus dispositivos. Arquivos + Mídia Compartilhada Compartilhar arquivos e documentos no chat e acessá-los de qualquer um de seus dispositivos. Mapa @@ -318,36 +362,82 @@ Baixar o vídeo primeiro Nenhuma foto recente Nenhum GIF recente - PROCURAR NA INTERNET - PROCURAR GIFS + BUSCAR IMAGENS + BUSCA GLOBAL + BUSCAR GIFS Procurar na web Procurar GIFs Recortar imagem Editar imagem + Realçar + Luzes + Contraste + Exposição + Calor + Saturação + Vignette + Sombras + Granulado + Nitidez + Desfoque + Desativado + Linear + Radial + Você tem certeza que deseja apagar esta foto? + Você tem certeza que deseja apagar este vídeo? + Descartar mudanças? + Limpar histórico de busca? + Limpar - Password - Change password - Old password - Enter old password - New password - Enter new password - Verify new password - Enter your password - Hint - Enter hint - Important: you will lose all your chats, messages and media in the case of a forgotten password. - Passwords do not match - Incorrect old password - Incorrect password - Incorrect new password - Hint shouldn\'t contain password - Enter password - Important: you will lose all your chats, messages and media. - Delete account - Delete my account - Hint: %1$s - Are you sure you want to delete your account? - We deeply clarify you that you will lose all your chats, messages and media. Are you really sure? + Verificação em duas etapas + Configurar senha adicional + Você pode configurar uma senha que será requisitada quando você entrar em um novo aparelho, além do código que você receberá por SMS. + Sua senha + Por favor, digite a sua senha + Insira uma senha + Por favor, digite a sua nova senha + Por favor, digite sua senha novamente + E-mail de recuperação + Seu e-mail + Por favor, adicione um e-mail válido. Essa é a única forma de recuperar uma senha esquecida. + Pular + Atenção + É sério!\n\nSe você esquecer a sua senha, você perderá o acesso a sua conta do Telegram. Não há nenhuma forma de recuperá-la. + Quase lá! + Por favor, verifique o seu e-mail (não esqueça da pasta spam) para completar a configuração da verificação em duas etapas. + Pronto! + A sua senha para a verificação em duas etapas foi ativada. + Alterar senha + Desabilitar senha + Configurar e-mail de recuperação + Alterar e-mail de recuperação. + Você tem certeza que quer desabilitar a sua senha? + Dica da senha + Por favor, crie uma dica para a sua senha + As senhas não são iguais + Cancelar a configuração da verificação em duas etapas + Por favor, siga os seguintes passos para completar a configuração da autenticação em duas etapas:\n\n1. Verifique seu e-mail ( não esqueça da pasta spam)\n%1$s\n\n2. Clique no link de validação. + A dica deve ser diferente da sua senha + E-mail inválido + Desculpe + Como você não indicou um e-mail de recuperação quando configurou a sua senha, as únicas opções restantes são lembrar a senha ou apagar a sua conta. + O código de recuperação foi enviado para o e-mail fornecido: \n\n%1$s + Por favor, verifique o seu e-mail e digite aqui o código de 6 dígitos recebido. + Está tendo problemas para acessar seu e-mail %1$s? + Se você não puder acessar o seu e-mail, as suas únicas opções são são lembrar a senha ou apagar a sua conta. + APAGAR MINHA CONTA + Se você prosseguir e apagar a sua conta, você perderá todos os seus chats e mensagens, assim como todas as suas mídias e arquivos compartilhados. + Aviso + Essa ação não pode ser revertida ou desfeita.\n\nSe você apagar a sua conta, todas as suas mensagens e chats serão apagados. + Apagar + Senha + Você habilitou a verificação em duas etapas, a sua conta está protegida com uma senha adicional. + Esqueceu a senha? + Recuperação de senha + Código + Senha desativada + Você habilitou a verificação em duas etapas. Toda vez que você entrar na sua conta em um novo aparelho, será preciso digitar a senha que você configurar aqui. + O seu e-mail de recuperação %1$s ainda não está ativo e aguarda confirmação. Privacidade e Segurança Privacidade @@ -379,7 +469,7 @@ Adicionar Usuários Desculpe, muitas solicitações. Impossível alterar os ajustes de privacidade agora, por favor aguarde. Sair de todos os dispositivos, exceto este. - Toque e segure no usuário para deletar. + Toque e segure no usuário para remover. Editar Vídeo Vídeo Original @@ -405,6 +495,7 @@ Apagar foto Aplicar OK + CORTAR un1 removeu un2 un1 saiu do grupo @@ -422,6 +513,7 @@ Você criou o grupo un1 removeu você un1 adicionou você + un1 retornou ao grupo Esta mensagem não é suportada na sua versão do Telegram. Para visualiza-la atualize seu aplicativo em http://telegram.org/update Foto Vídeo @@ -437,12 +529,13 @@ Número de telefone inválido O código expirou. Por favor, identifique-se novamente. Muitas tentativas. Por favor, tente novamente mais tarde. + Muitas tentativas, por favor tente novamente em %1$s Código inválido Nome inválido Sobrenome inválido Carregando... Você não possui um reprodutor de vídeo, instale um para continuar - Por favor, envie um email para sms@telegram.org e conte-nos sobre seu problema. + Por favor, envie um email para sms@stel.com e conte-nos sobre seu problema. Você não possui um aplicativo que suporte o tipo de arquivo \'%1$s\', por favor instale um para continuar Este usuário ainda não possui Telegram, deseja enviar um convite? Você tem certeza? @@ -451,16 +544,16 @@ Enviar mensagens para %1$s? Você tem certeza que desejar sair?\n\nSaiba que você pode usar o Telegram em vários dispositivos de uma vez.\n\nLembre-se, sair apaga todos os seus Chats Secretos. Você tem certeza que deseja terminar todas as outras sessões? - Você tem certeza que deseja deletar e sair do grupo? - Você tem certeza que deseja deletar esta conversa? + Você tem certeza que apagar e sair do grupo? + Você tem certeza que deseja apagar esta conversa? Você tem certeza que deseja compartilhar suas informações de contato? Você tem certeza que deseja bloquear este contato? Você tem certeza que deseja desbloquear este contato? - Você tem certeza que deseja deletar este contato? + Você tem certeza que deseja apagar este contato? Você tem certeza que deseja começar um chat secreto? Você tem certeza que deseja cancelar o registro? Você tem certeza que deseja limpar o histórico? - Você tem certeza que deseja deletar %1$s? + Você tem certeza que deseja apagar %1$s? Enviar mensagens para %1$s? Encaminhar mensagem para %1$s? Desculpe, esta funcionalidade não está disponível para seu país. @@ -511,18 +604,18 @@ %1$d mensagens %1$d mensagens %1$d mensagens - nenhum arquivo - %1$d arquivo - %1$d arquivos - %1$d arquivos - %1$d arquivos - %1$d arquivos - de nenhum contato - de %1$d contato - de %1$d contatos - de %1$d contatos - de %1$d contatos - de %1$d contatos + nenhum item + %1$d item + %1$d itens + %1$d itens + %1$d itens + %1$d itens + de nenhum chat + de %1$d chat + de %1$d chats + de %1$d chats + de %1$d chats + de %1$d chats %1$d segundos %1$d segundo %1$d segundos @@ -571,7 +664,63 @@ %1$d usuários %1$d usuários %1$d usuários + + %1$d mensagens encaminhadas + Mensagem encaminhada + %1$d mensagens encaminhadas + %1$d mensagens encaminhadas + %1$d mensagens encaminhadas + %1$d mensagens encaminhadas + %1$d arquivos encaminhados + Arquivo encaminhado + %1$d arquivos encaminhados + %1$d arquivos encaminhados + %1$d arquivos encaminhados + %1$d arquivos encaminhados + %1$d fotos encaminhadas + Foto encaminhada + %1$d fotos encaminhadas + %1$d fotos encaminhadas + %1$d fotos encaminhadas + %1$d fotos encaminhadas + %1$d vídeos encaminhados + Vídeo encaminhado + %1$d vídeos encaminhados + %1$d vídeos encaminhados + %1$d vídeos encaminhados + %1$d vídeos encaminhados + %1$d áudios encaminhados + Áudio encaminhado + %1$d áudios encaminhados + %1$d áudios encaminhados + %1$d áudios encaminhados + %1$d áudios encaminhados + %1$d localizações encaminhadas + Localização encaminhada + %1$d localizações encaminhadas + %1$d localizações encaminhadas + %1$d localizações encaminhadas + %1$d localizações encaminhadas + %1$d contatos encaminhados + Contato encaminhado + %1$d contatos encaminhados + %1$d contatos encaminhados + %1$d contatos encaminhados + %1$d contatos encaminhados + %1$d stickers encaminhados + Sticker encaminhado + %1$d stickers encaminhados + %1$d stickers encaminhados + %1$d stickers encaminhados + %1$d stickers encaminhados + e %1$d outros + e %1$d outro + e %1$d outros + e %1$d outros + e %1$d outros + e %1$d outros + MMMM yyyy dd MMM dd.MM.yy dd.MM.yyyy diff --git a/TMessagesProj/src/main/res/values-pt-rPT/strings.xml b/TMessagesProj/src/main/res/values-pt-rPT/strings.xml index 31f5ae720..dd6aca2f4 100644 --- a/TMessagesProj/src/main/res/values-pt-rPT/strings.xml +++ b/TMessagesProj/src/main/res/values-pt-rPT/strings.xml @@ -57,6 +57,8 @@ Silenciar por %1$s Restaurar Som Em %1$s + Desativado + HASHTAGS Nova Lista de Transmissão Digite o nome da lista @@ -83,6 +85,10 @@ escrevendo... está escrevendo... estão escrevendo... + %1$s está gravando uma mensagem... + %1$s está enviando uma foto... + %1$s está enviando um vídeo... + %1$s está enviando um arquivo... Tem alguma dúvida\nsobre o Telegram? Tirar foto Galeria @@ -115,6 +121,7 @@ Anexo não suportado Definir timer de autodestruição Notificações de serviço + Obtendo informações... %1$s estabeleceu o tempo de autodestruição para %2$s Você estabeleceu o tempo de autodestruição para %1$s @@ -143,11 +150,12 @@ %1$s editou o nome do grupo %2$s %1$s editou a foto do grupo %2$s %1$s convidou %3$s para o grupo %2$s + %1$s retornou ao grupo %2$s %1$s removeu %3$s do grupo %2$s %1$s removeu você do grupo %2$s %1$s saiu do grupo %2$s %1$s entrou para o 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,\nNós detectamos que alguém acessou a sua conta a partir de um novo aparelho em %2$s\n\nAparelho: %3$s\nLocalização: %4$s\n\nSe não foi você, você pode ir em Configurações - Provacidade e Segurança - Sessões, e terminar aquela sessão.\n\nSe você acha que alguém acessou a sua conta contra a sua vontade, você pode habilitar a verificação em duas etapas nas configurações de Privacidade e Segurança.\n\nAtenciosamente,\nEquipe Telegram %1$s atualizou a foto do perfil Responder Responder para %1$s @@ -175,7 +183,7 @@ Nome do grupo %1$d/%2$d membros - Mídia compartilhada + Mídia Compartilhada Configurações Adicionar membro Apagar e sair do grupo @@ -242,6 +250,7 @@ Sem som Padrão Suporte + Somente no silencioso Papel de Parede Mensagens Enviar usando \'Enter\' @@ -270,7 +279,7 @@ Somente com a tela ligada Somente com a tela desligada Sempre mostrar pop-up - Contador de medalhas + Contador no Ícone Curta Longa Padrão do sistema @@ -294,11 +303,46 @@ ALTERAR 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. + O número %1$s já possui uma conta do Telegram. Por favor, exclua esta conta antes de migrar para o novo número. Outro + Desativado + Desativar + Desativado + Desativado + Sons no Chat + Padrão + + Sessões Ativas + Sessão atual + Nenhuma outra sessão ativa + Você pode entrar no Telegram a partir de outro celular, tablet ou computador usando o mesmo número de telefone. Todos os seus dados serão sincronizados instantaneamente. + Sessões Ativas + Controle suas sessões em outros aparelho. + Toque em uma sessão para terminá-la. + Encerrar essa sessão? + aplicativo não oficial + + Senha de Bloqueio + Alterar Senha + Quando você define uma senha adicional, um ícone de cadeado aparece na página de chats. Clique para bloquear e desbloquear o app.\n\nNota: se você esquecer a sua senha, terá de excluir e reinstalar o app. Todos os chats secretos serão perdidos. + Você verá o ícone do cadeado na página de chats. Clique para bloquear seu app do Telegram com a sua nova senha. + PIN + Senha + Insira sua senha atual + Insira uma senha + Insira sua nova senha + Insira sua senha + Re-insira sua nova senha + Senha inválida + As senhas não são iguais + Auto-bloquear + Requisitar senha se estiver ausente por muito tempo. + em %1$s + Desativado Compartilhar fotos e vídeos no chat e acessá-los em qualquer um de seus dispositivos. Arquivos + Mídia Compartilhada Compartilhar arquivos e documentos no chat e acessá-los de qualquer um de seus dispositivos. Mapa @@ -318,36 +362,82 @@ Baixar o vídeo primeiro Nenhuma foto recente Nenhum GIF recente - PROCURAR NA INTERNET - PROCURAR GIFS + BUSCAR IMAGENS + BUSCA GLOBAL + BUSCAR GIFS Procurar na web Procurar GIFs Recortar imagem Editar imagem + Realçar + Luzes + Contraste + Exposição + Calor + Saturação + Vignette + Sombras + Granulado + Nitidez + Desfoque + Desativado + Linear + Radial + Você tem certeza que deseja apagar esta foto? + Você tem certeza que deseja apagar este vídeo? + Descartar mudanças? + Limpar histórico de busca? + Limpar - Password - Change password - Old password - Enter old password - New password - Enter new password - Verify new password - Enter your password - Hint - Enter hint - Important: you will lose all your chats, messages and media in the case of a forgotten password. - Passwords do not match - Incorrect old password - Incorrect password - Incorrect new password - Hint shouldn\'t contain password - Enter password - Important: you will lose all your chats, messages and media. - Delete account - Delete my account - Hint: %1$s - Are you sure you want to delete your account? - We deeply clarify you that you will lose all your chats, messages and media. Are you really sure? + Verificação em duas etapas + Configurar senha adicional + Você pode configurar uma senha que será requisitada quando você entrar em um novo aparelho, além do código que você receberá por SMS. + Sua senha + Por favor, digite a sua senha + Insira uma senha + Por favor, digite a sua nova senha + Por favor, digite sua senha novamente + E-mail de recuperação + Seu e-mail + Por favor, adicione um e-mail válido. Essa é a única forma de recuperar uma senha esquecida. + Pular + Atenção + É sério!\n\nSe você esquecer a sua senha, você perderá o acesso a sua conta do Telegram. Não há nenhuma forma de recuperá-la. + Quase lá! + Por favor, verifique o seu e-mail (não esqueça da pasta spam) para completar a configuração da verificação em duas etapas. + Pronto! + A sua senha para a verificação em duas etapas foi ativada. + Alterar senha + Desabilitar senha + Configurar e-mail de recuperação + Alterar e-mail de recuperação. + Você tem certeza que quer desabilitar a sua senha? + Dica da senha + Por favor, crie uma dica para a sua senha + As senhas não são iguais + Cancelar a configuração da verificação em duas etapas + Por favor, siga os seguintes passos para completar a configuração da autenticação em duas etapas:\n\n1. Verifique seu e-mail ( não esqueça da pasta spam)\n%1$s\n\n2. Clique no link de validação. + A dica deve ser diferente da sua senha + E-mail inválido + Desculpe + Como você não indicou um e-mail de recuperação quando configurou a sua senha, as únicas opções restantes são lembrar a senha ou apagar a sua conta. + O código de recuperação foi enviado para o e-mail fornecido: \n\n%1$s + Por favor, verifique o seu e-mail e digite aqui o código de 6 dígitos recebido. + Está tendo problemas para acessar seu e-mail %1$s? + Se você não puder acessar o seu e-mail, as suas únicas opções são são lembrar a senha ou apagar a sua conta. + APAGAR MINHA CONTA + Se você prosseguir e apagar a sua conta, você perderá todos os seus chats e mensagens, assim como todas as suas mídias e arquivos compartilhados. + Aviso + Essa ação não pode ser revertida ou desfeita.\n\nSe você apagar a sua conta, todas as suas mensagens e chats serão apagados. + Apagar + Senha + Você habilitou a verificação em duas etapas, a sua conta está protegida com uma senha adicional. + Esqueceu a senha? + Recuperação de senha + Código + Senha desativada + Você habilitou a verificação em duas etapas. Toda vez que você entrar na sua conta em um novo aparelho, será preciso digitar a senha que você configurar aqui. + O seu e-mail de recuperação %1$s ainda não está ativo e aguarda confirmação. Privacidade e Segurança Privacidade @@ -379,7 +469,7 @@ Adicionar Usuários Desculpe, muitas solicitações. Impossível alterar os ajustes de privacidade agora, por favor aguarde. Sair de todos os dispositivos, exceto este. - Toque e segure no usuário para deletar. + Toque e segure no usuário para remover. Editar Vídeo Vídeo Original @@ -405,6 +495,7 @@ Apagar foto Aplicar OK + CORTAR un1 removeu un2 un1 saiu do grupo @@ -422,6 +513,7 @@ Você criou o grupo un1 removeu você un1 adicionou você + un1 retornou ao grupo Esta mensagem não é suportada na sua versão do Telegram. Para visualiza-la atualize seu aplicativo em http://telegram.org/update Foto Vídeo @@ -437,12 +529,13 @@ Número de telefone inválido O código expirou. Por favor, identifique-se novamente. Muitas tentativas. Por favor, tente novamente mais tarde. + Muitas tentativas, por favor tente novamente em %1$s Código inválido Nome inválido Sobrenome inválido Carregando... Você não possui um reprodutor de vídeo, instale um para continuar - Por favor, envie um email para sms@telegram.org e conte-nos sobre seu problema. + Por favor, envie um email para sms@stel.com e conte-nos sobre seu problema. Você não possui um aplicativo que suporte o tipo de arquivo \'%1$s\', por favor instale um para continuar Este usuário ainda não possui Telegram, deseja enviar um convite? Você tem certeza? @@ -451,16 +544,16 @@ Enviar mensagens para %1$s? Você tem certeza que desejar sair?\n\nSaiba que você pode usar o Telegram em vários dispositivos de uma vez.\n\nLembre-se, sair apaga todos os seus Chats Secretos. Você tem certeza que deseja terminar todas as outras sessões? - Você tem certeza que deseja deletar e sair do grupo? - Você tem certeza que deseja deletar esta conversa? + Você tem certeza que apagar e sair do grupo? + Você tem certeza que deseja apagar esta conversa? Você tem certeza que deseja compartilhar suas informações de contato? Você tem certeza que deseja bloquear este contato? Você tem certeza que deseja desbloquear este contato? - Você tem certeza que deseja deletar este contato? + Você tem certeza que deseja apagar este contato? Você tem certeza que deseja começar um chat secreto? Você tem certeza que deseja cancelar o registro? Você tem certeza que deseja limpar o histórico? - Você tem certeza que deseja deletar %1$s? + Você tem certeza que deseja apagar %1$s? Enviar mensagens para %1$s? Encaminhar mensagem para %1$s? Desculpe, esta funcionalidade não está disponível para seu país. @@ -511,18 +604,18 @@ %1$d mensagens %1$d mensagens %1$d mensagens - nenhum arquivo - %1$d arquivo - %1$d arquivos - %1$d arquivos - %1$d arquivos - %1$d arquivos - de nenhum contato - de %1$d contato - de %1$d contatos - de %1$d contatos - de %1$d contatos - de %1$d contatos + nenhum item + %1$d item + %1$d itens + %1$d itens + %1$d itens + %1$d itens + de nenhum chat + de %1$d chat + de %1$d chats + de %1$d chats + de %1$d chats + de %1$d chats %1$d segundos %1$d segundo %1$d segundos @@ -571,7 +664,63 @@ %1$d usuários %1$d usuários %1$d usuários + + %1$d mensagens encaminhadas + Mensagem encaminhada + %1$d mensagens encaminhadas + %1$d mensagens encaminhadas + %1$d mensagens encaminhadas + %1$d mensagens encaminhadas + %1$d arquivos encaminhados + Arquivo encaminhado + %1$d arquivos encaminhados + %1$d arquivos encaminhados + %1$d arquivos encaminhados + %1$d arquivos encaminhados + %1$d fotos encaminhadas + Foto encaminhada + %1$d fotos encaminhadas + %1$d fotos encaminhadas + %1$d fotos encaminhadas + %1$d fotos encaminhadas + %1$d vídeos encaminhados + Vídeo encaminhado + %1$d vídeos encaminhados + %1$d vídeos encaminhados + %1$d vídeos encaminhados + %1$d vídeos encaminhados + %1$d áudios encaminhados + Áudio encaminhado + %1$d áudios encaminhados + %1$d áudios encaminhados + %1$d áudios encaminhados + %1$d áudios encaminhados + %1$d localizações encaminhadas + Localização encaminhada + %1$d localizações encaminhadas + %1$d localizações encaminhadas + %1$d localizações encaminhadas + %1$d localizações encaminhadas + %1$d contatos encaminhados + Contato encaminhado + %1$d contatos encaminhados + %1$d contatos encaminhados + %1$d contatos encaminhados + %1$d contatos encaminhados + %1$d stickers encaminhados + Sticker encaminhado + %1$d stickers encaminhados + %1$d stickers encaminhados + %1$d stickers encaminhados + %1$d stickers encaminhados + e %1$d outros + e %1$d outro + e %1$d outros + e %1$d outros + e %1$d outros + e %1$d outros + MMMM yyyy dd MMM dd.MM.yy dd.MM.yyyy diff --git a/TMessagesProj/src/main/res/values-v14/bools.xml b/TMessagesProj/src/main/res/values-v14/bools.xml new file mode 100644 index 000000000..639cedeac --- /dev/null +++ b/TMessagesProj/src/main/res/values-v14/bools.xml @@ -0,0 +1,5 @@ + + + + false + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-v15/bools.xml b/TMessagesProj/src/main/res/values-v15/bools.xml new file mode 100644 index 000000000..639cedeac --- /dev/null +++ b/TMessagesProj/src/main/res/values-v15/bools.xml @@ -0,0 +1,5 @@ + + + + false + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-v16/bools.xml b/TMessagesProj/src/main/res/values-v16/bools.xml new file mode 100644 index 000000000..9e9160ec0 --- /dev/null +++ b/TMessagesProj/src/main/res/values-v16/bools.xml @@ -0,0 +1,5 @@ + + + + true + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-v21/styles.xml b/TMessagesProj/src/main/res/values-v21/styles.xml index 97ee0af7d..b02410741 100644 --- a/TMessagesProj/src/main/res/values-v21/styles.xml +++ b/TMessagesProj/src/main/res/values-v21/styles.xml @@ -54,7 +54,7 @@ diff --git a/TMessagesProj/src/main/res/values/bools.xml b/TMessagesProj/src/main/res/values/bools.xml new file mode 100644 index 000000000..9e9160ec0 --- /dev/null +++ b/TMessagesProj/src/main/res/values/bools.xml @@ -0,0 +1,5 @@ + + + + true + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values/colors.xml b/TMessagesProj/src/main/res/values/colors.xml index 9b1c746d2..31a03a7c9 100755 --- a/TMessagesProj/src/main/res/values/colors.xml +++ b/TMessagesProj/src/main/res/values/colors.xml @@ -2,5 +2,4 @@ #6633B5E5 #dcdcdc - #ff54759e \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values/strings.xml b/TMessagesProj/src/main/res/values/strings.xml index 0f856f43a..847bff777 100644 --- a/TMessagesProj/src/main/res/values/strings.xml +++ b/TMessagesProj/src/main/res/values/strings.xml @@ -57,6 +57,8 @@ Mute for %1$s Unmute In %1$s + Disable + HASHTAGS New Broadcast List Enter list name @@ -83,6 +85,10 @@ typing... is typing... are typing... + %1$s is recording audio... + %1$s is sending photo... + %1$s is sending video... + %1$s is sending file... Got a question\nabout Telegram? Take photo Gallery @@ -115,6 +121,7 @@ Unsupported attachment Set self-destruct timer Service notifications + Getting Link Info... %1$s set the self-destruct timer to %2$s You set the self-destruct timer to %1$s @@ -143,11 +150,12 @@ %1$s edited the group\'s %2$s name %1$s edited the group\'s %2$s photo %1$s invited %3$s to the group %2$s + %1$s returned to the group %2$s %1$s removed %3$s from the group %2$s %1$s removed you from the group %2$s %1$s has left the group %2$s %1$s joined Telegram! - %1$s,\nWe detected a login into your account from a new device on %2$s\n\nDevice: %3$s\nLocation: %4$s\n\nIf this wasn\'t you, you can go to Settings - Privacy and Security - Terminate all other sessions.\n\nSincerely,\nThe Telegram Team + %1$s,\nWe detected a login into your account from a new device on %2$s\n\nDevice: %3$s\nLocation: %4$s\n\nIf this wasn\'t you, you can go to Settings - Privacy and Security - Sessions and terminate that session.\n\nIf you think that somebody logged in to your account against your will, you can enable two-step verification in Privacy and Security settings.\n\nSincerely,\nThe Telegram Team %1$s updated profile photo Reply Reply to %1$s @@ -242,6 +250,7 @@ No sound Default Support + Only if silent Chat Background Messages Send by Enter @@ -296,9 +305,44 @@ We will send an SMS with a confirmation code to your new number. The number %1$s is already connected to a Telegram account. Please delete that account before migrating to the new number. Other + Disabled + Disabled + Disabled + Off + In-Chat Sounds + Default + + Active Sessions + Current session + No other active sessions + You can log in to Telegram from other mobile, tablet and desktop devices, using the same phone number. All your data will be instantly synchronized. + Active Sessions + Control your sessions on other devices. + Tap on a session to terminate. + Terminate this session? + unofficial app + + Passcode Lock + Change Passcode + When you set up an additional passcode, a lock icon will appear on the chats page. Tap it to lock and unlock your Telegram app.\n\nNote: if you forget the passcode, you\'ll need to delete and reinstall the app. All secret chats will be lost. + You will now see a lock icon on the chats page. Tap it to lock your Telegram app with your new passcode. + PIN + Password + Enter your current passcode + Enter a passcode + Enter your new passcode + Enter your passcode + Re-enter your new passcode + Invalid passcode + Passcodes do not match + Auto-lock + Require passcode if away for a time. + in %1$s + Disabled Share photos and videos in this chat and access them on any of your devices. Files + Shared Media Share files and documents in this chat and access them on any of your devices. Map @@ -318,36 +362,82 @@ Please download media first No recent photos No recent GIFs - SEARCH WEB - SEARCH GIFS + FIND IMAGES + WEB SEARCH + FIND GIFS Search web Search GIFs Crop image Edit image + Enhance + Highlights + Contrast + Exposure + Warmth + Saturation + Vignette + Shadows + Grain + Sharpen + Blur + Off + Linear + Radial + Are you sure you want to delete this photo? + Are you sure you want to delete this video? + Discard changes? + Clear search history? + Clear - Password - Change password - Old password - Enter old password - New password - Enter new password - Verify new password - Enter your password - Hint - Enter hint - Important: you will lose all your chats, messages and media in the case of a forgotten password. + Two-Step Verification + Set Additional Password + You can set a password that will be required when you log in on a new device in addition to the code you get in the SMS. + Your Password + Please enter your password + Enter a password + Please enter your new password + Please re-enter your password + Recovery E-Mail + Your E-Mail + Please add your valid e-mail. It is the only way to recover a forgotten password. + Skip + Warning + No, seriously.\n\nIf you forget your password, you will lose access to your Telegram account. There will be no way to restore it. + Almost there! + Please check your e-mail (don\'t forget the spam folder) to complete Two-Step Verification setup. + Success! + Your password for Two-Step Verification is now active. + Change Password + Turn Password Off + Set Recovery E-Mail + Change Recovery E-Mail + Are you sure you want to disable your password? + Password Hint + Please create a hint for your password Passwords do not match - Incorrect old password - Incorrect password - Incorrect new password - Hint shouldn\'t contain password - Enter password - Important: you will lose all your chats, messages and media. - Delete account - Delete my account - Hint: %1$s - Are you sure you want to delete your account? - We deeply clarify you that you will lose all your chats, messages and media. Are you really sure? + Abort two-step verification setup + Please follow these steps to complete Two-Step Verification Setup:\n\n1. Check your e-mail (don\'t forget the spam folder)\n%1$s\n\n2. Click on the validation link. + Hint must be different from your password + Invalid e-mail + Sorry + Since you haven\'t provided a recovery e-mail when setting up your password, your remaining options are either to remember your password or to reset your account. + We have sent a recovery code to the e-mail you provided:\n\n%1$s + Please check your e-mail and enter the 6-digit code we have sent here. + Having trouble accessing your e-mail %1$s? + If you can\'t restore access to your e-mail, your remaining options are either to remember your password or to reset your account. + RESET MY ACCOUNT + You will lose all your chats and messages, along with any media and files you shared, if you proceed with resetting your account. + Warning + This action can not be undone.\n\nIf you reset your account, all your messages and chats will be deleted. + Reset + Password + You have enabled Two-Step Verification, so your account is protected with an additional password. + Forgot password? + Password Recovery + Code + Password deactivated + You have enabled Two-Step verification.\nYou\'ll need the password you set up here to log in to your Telegram account. + Your recovery e-mail %1$s is not yet active and pending confirmation. Privacy and Security Privacy @@ -405,6 +495,7 @@ Delete photo Set OK + CROP un1 removed un2 un1 left group @@ -422,6 +513,7 @@ You created the group un1 removed you un1 added you + un1 returned to the group This message is not supported on your version of Telegram. Update the app to view: http://telegram.org/update Photo Video @@ -437,12 +529,13 @@ Invalid phone number Code expired, please login again Too many attempts, please try again later + Too many attempts, please try again in %1$s Invalid code Invalid first name Invalid last name Loading... You don\'t have a video player, please install one to continue - Please send an email to sms@telegram.org and tell us about your problem. + Please send an email to sms@stel.com and tell us about your problem. You don\'t have applications that can handle the file type \'%1$s\', please install one to continue This user does not have Telegram yet, send an invitation? Are you sure? @@ -511,18 +604,18 @@ %1$d messages %1$d messages %1$d messages - no files - %1$d file - %1$d files - %1$d files - %1$d files - %1$d files - from no contacts - from %1$d contact - from %1$d contacts - from %1$d contacts - from %1$d contacts - from %1$d contacts + no items + %1$d item + %1$d items + %1$d items + %1$d items + %1$d items + from no chats + from %1$d chat + from %1$d chats + from %1$d chats + from %1$d chats + from %1$d chats %1$d seconds %1$d second %1$d seconds @@ -571,7 +664,63 @@ %1$d users %1$d users %1$d users + + %1$d forwarded messages + Forwarded message + %1$d forwarded messages + %1$d forwarded messages + %1$d forwarded messages + %1$d forwarded messages + %1$d forwarded files + Forwarded file + %1$d forwarded files + %1$d forwarded files + %1$d forwarded files + %1$d forwarded files + %1$d forwarded photos + Forwarded photo + %1$d forwarded photos + %1$d forwarded photos + %1$d forwarded photos + %1$d forwarded photos + %1$d forwarded videos + Forwarded video + %1$d forwarded videos + %1$d forwarded videos + %1$d forwarded videos + %1$d forwarded videos + %1$d forwarded audios + Forwarded audio + %1$d forwarded audios + %1$d forwarded audios + %1$d forwarded audios + %1$d forwarded audios + %1$d forwarded locations + Forwarded location + %1$d forwarded locations + %1$d forwarded locations + %1$d forwarded locations + %1$d forwarded locations + %1$d forwarded contacts + Forwarded contact + %1$d forwarded contacts + %1$d forwarded contacts + %1$d forwarded contacts + %1$d forwarded contacts + %1$d forwarded stickers + Forwarded sticker + %1$d forwarded stickers + %1$d forwarded stickers + %1$d forwarded stickers + %1$d forwarded stickers + and %1$d others + and %1$d other + and %1$d others + and %1$d others + and %1$d others + and %1$d others + MMMM yyyy MMM dd dd.MM.yy dd.MM.yyyy diff --git a/TMessagesProj/src/main/res/values/styles.xml b/TMessagesProj/src/main/res/values/styles.xml index bf12e881b..9884ff93b 100644 --- a/TMessagesProj/src/main/res/values/styles.xml +++ b/TMessagesProj/src/main/res/values/styles.xml @@ -42,7 +42,7 @@