diff --git a/TMessagesProj/config/debug/AndroidManifest.xml b/TMessagesProj/config/debug/AndroidManifest.xml index 7836674f..dacb8608 100644 --- a/TMessagesProj/config/debug/AndroidManifest.xml +++ b/TMessagesProj/config/debug/AndroidManifest.xml @@ -9,14 +9,14 @@ - - + + - - + + - + @@ -37,7 +37,7 @@ - + diff --git a/TMessagesProj/config/foss/AndroidManifest.xml b/TMessagesProj/config/foss/AndroidManifest.xml index df2d1e24..59b2f53b 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 17c2c245..31c5f085 100644 --- a/TMessagesProj/config/release/AndroidManifest.xml +++ b/TMessagesProj/config/release/AndroidManifest.xml @@ -9,14 +9,14 @@ - - + + - - + + - + @@ -37,7 +37,7 @@ - + diff --git a/TMessagesProj/jni/Android.mk b/TMessagesProj/jni/Android.mk index 88b4e639..ae2c6323 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.6 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 1532095b..06c5e9f3 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,110 @@ 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 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.6.so old mode 100755 new mode 100644 similarity index 84% rename from TMessagesProj/libs/armeabi-v7a/libtmessages.5.so rename to TMessagesProj/libs/armeabi-v7a/libtmessages.6.so index 132154ab..41f66ec8 Binary files a/TMessagesProj/libs/armeabi-v7a/libtmessages.5.so and b/TMessagesProj/libs/armeabi-v7a/libtmessages.6.so differ diff --git a/TMessagesProj/libs/armeabi/libtmessages.5.so b/TMessagesProj/libs/armeabi/libtmessages.6.so old mode 100755 new mode 100644 similarity index 76% rename from TMessagesProj/libs/armeabi/libtmessages.5.so rename to TMessagesProj/libs/armeabi/libtmessages.6.so index 3e08cd8f..aa46c089 Binary files a/TMessagesProj/libs/armeabi/libtmessages.5.so and b/TMessagesProj/libs/armeabi/libtmessages.6.so differ diff --git a/TMessagesProj/libs/x86/libtmessages.5.so b/TMessagesProj/libs/x86/libtmessages.6.so old mode 100755 new mode 100644 similarity index 72% rename from TMessagesProj/libs/x86/libtmessages.5.so rename to TMessagesProj/libs/x86/libtmessages.6.so index 326a064f..e455cf5a Binary files a/TMessagesProj/libs/x86/libtmessages.5.so and b/TMessagesProj/libs/x86/libtmessages.6.so differ diff --git a/TMessagesProj/src/main/AndroidManifest.xml b/TMessagesProj/src/main/AndroidManifest.xml index 5ca90c91..dd3c5fc2 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 39966ac1..878a92ac 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/org/telegram/PhoneFormat/PhoneFormat.java b/TMessagesProj/src/main/java/org/telegram/PhoneFormat/PhoneFormat.java index a6dbff0a..63081ef8 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 4455445f..fe19cfc7 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java +++ b/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java @@ -9,20 +9,30 @@ package org.telegram.android; import android.app.Activity; +import android.app.AlarmManager; import android.app.AlertDialog; +import android.app.PendingIntent; import android.content.Context; import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.content.res.Configuration; +import android.graphics.Color; import android.graphics.Point; +import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.Typeface; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.graphics.drawable.GradientDrawable; import android.os.Build; import android.os.Environment; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.Spanned; +import android.util.DisplayMetrics; +import android.util.Log; import android.util.StateSet; import android.view.Display; import android.view.Surface; @@ -33,20 +43,34 @@ 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 android.widget.Toast; +import org.telegram.messenger.ApplicationLoader; +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.ActionBar.ActionBar; +import org.telegram.ui.Components.ForegroundDetector; import org.telegram.ui.Components.NumberPicker; import org.telegram.ui.Components.TypefaceSpan; +import org.telegram.ui.LaunchActivity; +import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.PrintWriter; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.Hashtable; +import java.util.List; public class AndroidUtilities { @@ -59,15 +83,26 @@ 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(); private static Boolean isTablet = null; + public static final String THEME_PREFS = "theme"; + private static final String TAG = "AndroidUtilities"; + public static final int defColor = 0xff58BCD5;//0xff43C3DB;//0xff2f8cc9;58BCD5//0xff55abd2 + public static int themeColor = getIntColor("themeColor"); + + public static boolean needRestart = false; + + //public static boolean hideScreenshot = false; + //public static boolean hideMobile = false; + static { density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density; 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 +150,7 @@ public class AndroidUtilities { } public static void unlockOrientation(Activity activity) { - if (activity == null) { + if (activity == null || Build.VERSION.SDK_INT < 9) { return; } try { @@ -228,12 +263,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 +277,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 +461,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; @@ -530,4 +583,364 @@ public class AndroidUtilities { } return stringBuilder; } + + 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 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); + } + }*/ + //NEW + public static int getIntColor(String key){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(THEME_PREFS, Activity.MODE_PRIVATE); + return themePrefs.getInt(key, defColor); + } + + public static int getIntDef(String key, int def){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(THEME_PREFS, Activity.MODE_PRIVATE); + return themePrefs.getInt(key, def); + } + + public static int getIntAlphaColor(String key, float factor){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(THEME_PREFS, Activity.MODE_PRIVATE); + int color = themePrefs.getInt(key, defColor); + int alpha = Math.round(Color.alpha(color) * factor); + int red = Color.red(color); + int green = Color.green(color); + int blue = Color.blue(color); + return Color.argb(alpha, red, green, blue); + } + + public static int getIntDarkerColor(String key, int factor){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(THEME_PREFS, Activity.MODE_PRIVATE); + int color = themePrefs.getInt(key, defColor); + return setDarkColor(color, factor); + } + + public static int setDarkColor(int color, int factor){ + int red = Color.red(color) - factor; + int green = Color.green(color) - factor; + int blue = Color.blue(color) - factor; + if(factor < 0){ + red = (red > 0xff) ? 0xff : red; + green = (green > 0xff) ? 0xff : green; + blue = (blue > 0xff) ? 0xff : blue; + if(red == 0xff && green == 0xff && blue == 0xff){ + red = factor; + green = factor; + blue = factor; + } + } + if(factor > 0){ + red = (red < 0) ? 0 : red; + green = (green < 0) ? 0 : green; + blue = (blue < 0) ? 0 : blue; + if(red == 0 && green == 0 && blue == 0){ + red = factor; + green = factor; + blue = factor; + } + } + return Color.argb(0xff, red, green, blue); + } + + public static void setIntColor(String key, int value){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(THEME_PREFS, Activity.MODE_PRIVATE); + SharedPreferences.Editor e = themePrefs.edit(); + e.putInt(key, value); + e.commit(); + } + + public static void setBoolPref(Context context, String key, Boolean b){ + SharedPreferences sharedPref = context.getSharedPreferences(THEME_PREFS, 0); + SharedPreferences.Editor e = sharedPref.edit(); + e.putBoolean(key, b); + e.commit(); + } + + public static void setStringPref(Context context, String key, String s){ + SharedPreferences sharedPref = context.getSharedPreferences(THEME_PREFS, 0); + SharedPreferences.Editor e = sharedPref.edit(); + e.putString(key, s); + e.commit(); + } + + public static boolean getBoolPref(Context context,String key){ + boolean s = false; + if (context.getSharedPreferences(THEME_PREFS, 0).getBoolean(key, false)) s=true; + return s; + } + + public static boolean getBoolMain(String key){ + boolean s = false; + if (ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).getBoolean(key, false)) s=true; + return s; + } + + public static int getIntPref(Context context,String key){ + int i=0; + if(key.contains("picker")){ + int intColor = context.getSharedPreferences(THEME_PREFS, 0).getInt(key, Color.WHITE ); + i=intColor; + } + return i; + } +/* + public static int getIntColorDef(Context context, String key, int def){ + int i=def; + if(context.getSharedPreferences(THEME_PREFS, 0).getBoolean(key, false)){ + i = context.getSharedPreferences(THEME_PREFS, 0).getInt(key.replace("_check", "_picker"), def); + } + return i; + }*/ + + public static void setTVTextColor(Context ctx, TextView tv, String key, int def){ + if(tv==null)return; + if(getBoolPref(ctx, key)) + def = getIntPref(ctx, key.replace("_check", "_picker")); + tv.setTextColor(def); + } + + public static int getSizePref(Context context,String key, int def){ + if(key.contains("picker"))return context.getSharedPreferences(THEME_PREFS, 0).getInt(key, def); + return def; + } + + public static void paintActionBarHeader(Activity a, ActionBar ab, String hdCheck, String gdMode){ + if(ab==null)return; + ab.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#54759E"))); + if(getBoolPref(a, hdCheck)){ + int i = getIntPref(a, hdCheck.replace("_check", "_picker")); + Drawable d = new ColorDrawable(i); + try{ + ab.setBackgroundDrawable(d); + d = paintGradient(a,i,gdMode.replace("mode","color_picker"),gdMode); + if(d!=null)ab.setBackgroundDrawable(d); + } catch (Exception e) { + Log.e(TAG, e.toString()); + } + } + } + + public static Drawable paintGradient(Context c, int mainColor, String gColor, String g){ + GradientDrawable gd = null; + int[] a ={mainColor,getIntPref(c,gColor)}; + int gType = Integer.parseInt(c.getSharedPreferences(THEME_PREFS, 0).getString(g, "0")); + if(gType==2) gd = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT,a); + if(gType==1) gd = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM ,a); + return gd; + } + + public static Drawable paintDrawable(Context c, int resId, int resIdW, String color){ + Drawable d = c.getResources().getDrawable(resId); + if(color.contains("_check")){ + if(getBoolPref(c, color)){ + d = c.getResources().getDrawable(resIdW); + d.setColorFilter(getIntPref(c, color.replace("_check", "_picker")), PorterDuff.Mode.MULTIPLY); + } + } + return d; + } + + public static void restartApp(){ + Intent mRestartApp = new Intent(ApplicationLoader.applicationContext, LaunchActivity.class); + int mPendingIntentId = 123456; + PendingIntent mPendingIntent = PendingIntent.getActivity(ApplicationLoader.applicationContext, mPendingIntentId, mRestartApp, PendingIntent.FLAG_CANCEL_CURRENT); + AlarmManager mgr = (AlarmManager)ApplicationLoader.applicationContext.getSystemService(Context.ALARM_SERVICE); + mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent); + System.exit(0); + } + + public static void savePreferencesToSD(Context context, String prefName, String tName, boolean toast){ + String folder = "/Telegram/Themes"; + File dataF = new File (findPrefFolder(context),prefName); + if(checkSDStatus() > 1){ + File f = new File (Environment.getExternalStorageDirectory(), folder); + f.mkdirs(); + File sdF = new File(f, tName); + String s = getError(copyFile(dataF,sdF,true)); + if (s.equalsIgnoreCase("4")) { + if(toast && sdF.getName()!="")Toast.makeText(context,context.getString(R.string.SavedTo,sdF.getName(),folder),Toast.LENGTH_SHORT ).show(); + }else if (s.contains("0")) { + s = context.getString(R.string.SaveErrorMsg0); + Toast.makeText(context,"ERROR: "+ s ,Toast.LENGTH_LONG ).show(); + }else{ + Toast.makeText(context,"ERROR: "+s,Toast.LENGTH_LONG ).show(); + Toast.makeText(context,dataF.getAbsolutePath(),Toast.LENGTH_LONG ).show(); + } + }else{ + Toast.makeText(context,"ERROR: " + context.getString(R.string.NoMediaMessage) , Toast.LENGTH_LONG ).show(); + } + } + + public static void copyWallpaperToSD(Context context, String tName, boolean toast){ + String folder = "/Telegram/Themes"; + String nFile = "wallpaper.jpg"; + if(checkSDStatus()>0){ + File f1 = context.getFilesDir(); + f1 = new File (f1.getAbsolutePath(), nFile); + File f2 = new File (Environment.getExternalStorageDirectory(), folder); + f2.mkdirs(); + f2 = new File(f2, tName+"_"+nFile); + if(f1.length()>1){ + String s = getError(copyFile(f1,f2,true)); + if(s.contains("4")){ + if(toast && f2.getName()!="" && folder !="")Toast.makeText(context,context.getString(R.string.SavedTo,f2.getName(),folder),Toast.LENGTH_SHORT ).show(); + if(f2.getName()=="" || folder =="") Toast.makeText(context,"ERROR: "+s,Toast.LENGTH_SHORT ).show(); + + }else{ + Toast.makeText(context,"ERROR: "+s+"\n"+f1.getAbsolutePath(),Toast.LENGTH_LONG ).show(); + } + } + } + } + + static String findPrefFolder(Context context){ + File f = context.getFilesDir(); + String appDir = f.getAbsolutePath(); + File SPDir = new File (appDir.substring(0,appDir.lastIndexOf('/')+1)+ "shared_prefs/"); + if(!SPDir.exists()) {// && SPDir.isDirectory()) { + String pck = context.getPackageName(); + SPDir=new File ("/dbdata/databases/"+pck+"/shared_prefs/"); + } + //Log.i("TAG", SPDir.getAbsolutePath()); + return SPDir.getAbsolutePath(); + } + + static int checkSDStatus(){ + int b=0; + String s = Environment.getExternalStorageState(); + if (s.equals(Environment.MEDIA_MOUNTED))b=2; + else if (s.equals(Environment.MEDIA_MOUNTED_READ_ONLY))b=1; + return b; + } + + static String getError(int i){ + String s="-1"; + if(i==0)s="0: SOURCE FILE DOESN'T EXIST"; + if(i==1)s="1: DESTINATION FILE DOESN'T EXIST"; + if(i==2)s="2: NULL SOURCE & DESTINATION FILES"; + if(i==3)s="3: NULL SOURCE FILE"; + if(i==4)s="4"; + return s; + } + + //0: source file doesn't exist + //1: dest file doesn't exist + //2: source & dest = NULL + //3: source = NULL + //4: dest = NULL + static int copyFile(File sourceFile, File destFile, boolean save) { + int i=-1; + try{ + if (!sourceFile.exists()) { + return i+1; + } + if (!destFile.exists()) { + if(save)i=i+2; + destFile.createNewFile(); + } + FileChannel source = null; + FileChannel destination = null; + FileInputStream fileInputStream = new FileInputStream(sourceFile); + source = fileInputStream.getChannel(); + FileOutputStream fileOutputStream = new FileOutputStream(destFile); + destination = fileOutputStream.getChannel(); + if (destination != null && source != null) { + destination.transferFrom(source, 0, source.size()); + i=2; + } + if (source != null) { + source.close(); + i=3; + } + if (destination != null) { + destination.close(); + i=4; + } + fileInputStream.close(); + fileOutputStream.close(); + }catch (Exception e) + { + System.err.println("Error saving preferences: " + e.getMessage()); + Log.e(e.getMessage() , e.toString()); + } + return i; + } + + public static int loadPrefFromSD(Context context, String prefPath){ + File dataF = new File (findPrefFolder(context), THEME_PREFS + ".xml"); + File prefFile = new File (prefPath); + String s = getError(copyFile(prefFile, dataF, false)); + if (s.contains("0")) { + Toast.makeText(context,"ERROR: "+ context.getString(R.string.restoreErrorMsg, prefFile.getAbsolutePath()) , Toast.LENGTH_LONG ).show(); + } + return Integer.parseInt(s); + } + + public static int loadWallpaperFromSDPath(Context context, String wPath){ + String nFile = "wallpaper.jpg"; + File f1 = context.getFilesDir(); + f1= new File (f1.getAbsolutePath(), nFile); + //Log.i("f1", f1.getAbsolutePath()); + File wFile = new File (wPath); + //Log.i("wPath", wPath); + //Log.i("wFile", wFile.getAbsolutePath()); + String s = "-1"; + if (wFile.exists()){ + s = getError(copyFile(wFile,f1,false)); + if (s.contains("0")) { + Toast.makeText(context,"ERROR: "+ context.getString(R.string.restoreErrorMsg,wFile.getAbsolutePath()) ,Toast.LENGTH_LONG ).show(); + }else{ + Toast.makeText(context,"ERROR: "+s+"\n"+wFile.getAbsolutePath(),Toast.LENGTH_LONG ).show(); + } + } + return Integer.parseInt(s); + } +/* + static void modifyXMLfile(File preffile,String sname){ + try { + File file = preffile; + //Log.e("modifyXMLfile",preffile.getAbsolutePath()); + //Log.e("modifyXMLfile",preffile.exists()+""); + List lines = new ArrayList(); + // first, read the file and store the changes + BufferedReader in = new BufferedReader(new FileReader(file)); + String line = in.readLine(); + while (line != null) { + if (!line.contains(sname))lines.add(line); + //Log.e("modifyXMLfile",line); + line = in.readLine(); + } + in.close(); + // now, write the file again with the changes + PrintWriter out = new PrintWriter(file); + for (String l : lines) + out.println(l); + out.close(); + } catch (Exception e) { + e.printStackTrace(); + } + }*/ } diff --git a/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java b/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java index 75cb7bcb..4894e628 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; diff --git a/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java b/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java index 1e9a454a..2cca9e96 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,7 +640,7 @@ 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; @@ -1057,6 +1064,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 +1691,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) { diff --git a/TMessagesProj/src/main/java/org/telegram/android/ImageReceiver.java b/TMessagesProj/src/main/java/org/telegram/android/ImageReceiver.java index 9c467f72..6ecff83d 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/ImageReceiver.java +++ b/TMessagesProj/src/main/java/org/telegram/android/ImageReceiver.java @@ -69,6 +69,8 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg private int alpha = 255; private boolean isPressed; private boolean disableRecycle; + private int orientation; + private boolean centerRotation; private ImageReceiverDelegate delegate; public ImageReceiver() { @@ -209,6 +211,15 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg return isPressed; } + public void setOrientation(int angle, boolean center) { + orientation = angle; + centerRotation = center; + } + + public int getOrientation() { + return orientation; + } + public void setImageBitmap(Bitmap bitmap) { setImageBitmap(bitmap != null ? new BitmapDrawable(null, bitmap) : null); } @@ -280,8 +291,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 +332,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 +377,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 +411,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg FileLog.e("tmessages", e); } } + canvas.restore(); } } } @@ -391,6 +446,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; diff --git a/TMessagesProj/src/main/java/org/telegram/android/LocaleController.java b/TMessagesProj/src/main/java/org/telegram/android/LocaleController.java index db7b228b..1d2094bc 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 efa53b09..0207db4e 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MediaController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MediaController.java @@ -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"; @@ -1696,10 +1698,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(); } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java b/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java index 1c6c0dd4..afc8fee5 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java @@ -42,6 +42,7 @@ public class MessageObject { public int type; public int contentType; public String dateKey; + public String monthKey; public boolean deleted = false; public float audioProgress; public int audioProgressSec; @@ -71,6 +72,12 @@ public class MessageObject { textPaint.linkColor = 0xff316f9f; } + int color = AndroidUtilities.getIntDef("chatRTextColor", 0xff000000); + textPaint.setColor(color); + if(color != 0xff000000){ + textPaint.linkColor = AndroidUtilities.getIntDarkerColor("chatRTextColor", -0x50); + } + textPaint.setTextSize(AndroidUtilities.dp(MessagesController.getInstance().fontSize)); messageOwner = message; @@ -199,7 +206,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) { @@ -346,11 +353,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(); @@ -556,7 +566,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 +591,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 +623,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 +632,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 +665,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 +677,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)); } @@ -696,7 +706,7 @@ public class MessageObject { } public void setIsRead() { - messageOwner.flags &=~ TLRPC.MESSAGE_FLAG_UNREAD; + messageOwner.flags &= ~TLRPC.MESSAGE_FLAG_UNREAD; } public boolean isSecretPhoto() { @@ -714,7 +724,7 @@ public class MessageObject { if (unread) { message.flags |= TLRPC.MESSAGE_FLAG_UNREAD; } else { - message.flags &=~ TLRPC.MESSAGE_FLAG_UNREAD; + message.flags &= ~TLRPC.MESSAGE_FLAG_UNREAD; } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java index 71bd216e..a7c97325 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java @@ -9,10 +9,12 @@ 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 +22,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; @@ -86,6 +91,8 @@ 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 { @@ -102,6 +109,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,7 +147,26 @@ 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) { @@ -147,15 +175,52 @@ public class MessagesController implements NotificationCenter.NotificationCenter 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(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"; @@ -863,6 +928,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter 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); } @@ -944,10 +1010,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter } 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 +1025,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 +1043,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) { @@ -1437,8 +1502,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); } }); } @@ -1533,8 +1598,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter dialogsServerOnly.add(d); } } - NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate); NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); + NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate); } }); } @@ -1554,8 +1619,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; @@ -1713,6 +1778,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; @@ -1865,8 +1933,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 { @@ -1903,8 +1971,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter 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); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatDidCreated, chat.id); if (uploadedAvatar != null) { changeChatAvatar(chat.id, uploadedAvatar); } @@ -1950,8 +2018,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter 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); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_CHAT_MEMBERS); if (info != null) { for (TLRPC.TL_chatParticipant p : info.participants) { @@ -2032,8 +2100,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter 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); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_CHAT_MEMBERS); } boolean changed = false; if (info != null) { @@ -2851,10 +2919,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter } public boolean isDialogMuted(long dialog_id) { - TLRPC.TL_dialog dialog = dialogs_dict.get(dialog_id); + /*TLRPC.TL_dialog dialog = dialogs_dict.get(dialog_id); if (dialog != null) { return isNotifySettingsMuted(dialog.notify_settings); - } else { + } else {*/ SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); int mute_type = preferences.getInt("notify2_" + dialog_id, 0); if (mute_type == 2) { @@ -2865,7 +2933,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter return true; } } - } + //} return false; } @@ -3577,4 +3645,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 87f0e198..160447de 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java @@ -838,6 +838,59 @@ public class MessagesStorage { //database.executeFast("DELETE FROM secret_holes WHERE uid = " + high_id).stepThis().dispose(); } } + + if ((int) did == 0) { + SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "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(); @@ -3178,6 +3231,7 @@ public class MessagesStorage { NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesDeleted, mids); } }); + MessagesStorage.getInstance().updateDialogsWithReadedMessagesInternal(mids); MessagesStorage.getInstance().markMessagesAsDeletedInternal(mids); MessagesStorage.getInstance().updateDialogsWithDeletedMessagesInternal(mids); } @@ -3189,9 +3243,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 +3338,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 +3353,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)) { @@ -3471,7 +3526,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 +3550,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); diff --git a/TMessagesProj/src/main/java/org/telegram/android/NativeLoader.java b/TMessagesProj/src/main/java/org/telegram/android/NativeLoader.java index eecbbb17..17e55ea2 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 = 6; 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 6e045c32..5ae1cae0 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java +++ b/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java @@ -48,6 +48,9 @@ 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 screenStateChanged = totalEvents++; + public static final int appSwitchedToForeground = totalEvents++; public static final int httpFileDidLoaded = totalEvents++; public static final int httpFileDidFailedLoad = totalEvents++; diff --git a/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java b/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java index c0cc5d4f..cef1faa8 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java @@ -11,6 +11,7 @@ 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; @@ -29,6 +30,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,6 +50,7 @@ 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; @@ -130,7 +133,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)) { @@ -237,8 +242,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 +253,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 +269,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); @@ -416,6 +419,9 @@ public class NotificationsController { intent.putExtra("userId", user_id); } } + 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) { @@ -427,6 +433,7 @@ public class NotificationsController { } } } + } } else { if (pushDialogs.size() == 1) { intent.putExtra("encId", (int) (dialog_id >> 32)); @@ -436,7 +443,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 +458,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) @@ -462,7 +469,8 @@ public class NotificationsController { .setContentIntent(contentIntent) .setGroup("messages") .setGroupSummary(true) - .setColor(0xff2ca5e0); + //.setColor(0xff2ca5e0); + .setColor(AndroidUtilities.getIntColor("themeColor")); if (priority == 0) { mBuilder.setPriority(NotificationCompat.PRIORITY_DEFAULT); @@ -834,7 +842,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) { @@ -988,7 +996,18 @@ public class NotificationsController { setBadge(ApplicationLoader.applicationContext, enabled ? total_unread_count : 0); } - private void setBadge(Context context, int count) { + 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) { @@ -1003,6 +1022,8 @@ public class NotificationsController { FileLog.e("tmessages", e); } } + }); + } public static String getLauncherClassName(Context context) { try { diff --git a/TMessagesProj/src/main/java/org/telegram/android/ScreenReceiver.java b/TMessagesProj/src/main/java/org/telegram/android/ScreenReceiver.java index e6b6c757..d7824f18 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 6a114024..e9d672fc 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/SecretChatHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/android/SecretChatHelper.java @@ -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; @@ -1616,7 +1616,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 +1777,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 b7dc050d..4cb3e851 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java @@ -481,6 +481,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter sendMessage(null, null, null, null, null, null, user, null, null, null, peer, false, null); } + public void sendMessage(ArrayList messages) { + + } + public void sendMessage(MessageObject message) { sendMessage(null, null, null, null, null, message, null, null, null, null, message.getDialogId(), true, message.messageOwner.attachPath); } @@ -1610,6 +1614,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) { @@ -1744,7 +1749,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; @@ -1940,112 +1945,116 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter 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; + } + 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); } - } + }); + } else { + prepareSendingDocumentInternal(videoPath, videoPath, null, null, dialog_id); } - - 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/video/MP4Builder.java b/TMessagesProj/src/main/java/org/telegram/android/video/MP4Builder.java index 9d9eca96..cdb69332 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); @@ -347,7 +347,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 +418,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/messenger/ApplicationLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java index b788712c..481be841 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 bc3dd299..487f019c 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(); @@ -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"); } @@ -763,8 +768,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) { @@ -1338,6 +1347,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 +1355,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 +1417,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 +1438,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 +1451,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 +1734,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); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java index b0e1ac4e..74afae27 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java @@ -638,7 +638,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/FileUploadOperation.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java index 157103be..6bf1f236 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java @@ -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) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/HandshakeAction.java b/TMessagesProj/src/main/java/org/telegram/messenger/HandshakeAction.java index 770dbd6f..dc5f426d 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/SerializedData.java b/TMessagesProj/src/main/java/org/telegram/messenger/SerializedData.java index 59b59e6d..40847dab 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 6d51db70..a2d747a2 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/TLClassStore.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/TLClassStore.java @@ -216,6 +216,7 @@ 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); @@ -413,6 +414,7 @@ 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); } static TLClassStore store = null; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java b/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java index 2348395b..6ce1e519 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java @@ -16,7 +16,7 @@ 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 LAYER = 23; public static class ChatPhoto extends TLObject { public FileLocation photo_small; @@ -3743,6 +3743,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; @@ -5023,17 +5041,21 @@ public class TLRPC { } public static class TL_config extends TLObject { - public static int constructor = 0x2e54dd74; + public static int constructor = 0x7dae33e0; public int date; + public int expires; public boolean test_mode; public int this_dc; public ArrayList dc_options = new ArrayList<>(); + public int chat_big_size; public int chat_size_max; public int broadcast_size_max; + 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(); @@ -5041,23 +5063,37 @@ public class TLRPC { for (int a = 0; a < count; a++) { dc_options.add((TL_dcOption)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32())); } + chat_big_size = stream.readInt32(); chat_size_max = stream.readInt32(); broadcast_size_max = 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_big_size); stream.writeInt32(chat_size_max); stream.writeInt32(broadcast_size_max); + stream.writeInt32(0x1cb5c415); + count = disabled_features.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + disabled_features.get(a).serializeToStream(stream); + } } } @@ -9298,6 +9334,40 @@ public class TLRPC { //manually created + 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; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java index 0cd09865..6974ca94 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java @@ -31,6 +31,12 @@ public class UserConfig { 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; @@ -62,12 +68,19 @@ public class UserConfig { 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"); @@ -172,6 +185,7 @@ public class UserConfig { if (lastSendMessageId > -210000) { lastSendMessageId = -210000; } + data.cleanup(); Utilities.stageQueue.postRunnable(new Runnable() { @Override public void run() { @@ -195,12 +209,18 @@ public class UserConfig { 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(); } } } @@ -214,12 +234,17 @@ public class UserConfig { 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 f1c865a9..d1cff124 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java @@ -29,6 +29,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; @@ -97,6 +99,7 @@ public class Utilities { for (int a = 0; a < count; a++) { goodPrimes.add(data.readString()); } + data.cleanup(); } } catch (Exception e) { FileLog.e("tmessages", e); @@ -109,6 +112,7 @@ 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 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); @@ -228,6 +232,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 +368,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 +419,25 @@ public class Utilities { while ((bytesRead = gis.read(data)) != -1) { bytesOutput.write(data, 0, bytesRead); } + 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 +458,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 +481,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(); } } @@ -638,7 +670,7 @@ public class Utilities { } wholeString = wholeString.trim(); String lower = " " + wholeString.toLowerCase(); - + String hexDarkColor = String.format("#%06X", (0xFFFFFF & AndroidUtilities.getIntDarkerColor("themeColor", 0x15))); int index = -1; int lastIndex = 0; while ((index = lower.indexOf(" " + q, lastIndex)) != -1) { @@ -656,7 +688,8 @@ public class Utilities { builder.append(" "); } query.trim(); - builder.append(Html.fromHtml("" + query + "")); + builder.append(Html.fromHtml("" + query + "")); + //builder.append(Html.fromHtml("" + query + "")); lastIndex = end; } @@ -711,7 +744,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 index 348d20ee..a7c4f6b2 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/AccountPasswordActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/AccountPasswordActivity.java @@ -94,7 +94,7 @@ public class AccountPasswordActivity extends BaseFragment { } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { if (type == 0) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); @@ -271,7 +271,7 @@ public class AccountPasswordActivity extends BaseFragment { listAdapter.notifyDataSetChanged(); } - private void needShowAlert(final String text) { + private void ShowAlert(final String text) { if (text == null || getParentActivity() == null) { return; } @@ -355,20 +355,20 @@ public class AccountPasswordActivity extends BaseFragment { String hint = hintPasswordCell.getFieldText(); if (hasPassword) { if (oldPassword.length() == 0) { - needShowAlert(LocaleController.getString("PasswordOldIncorrect", R.string.PasswordOldIncorrect)); + ShowAlert(LocaleController.getString("PasswordOldIncorrect", R.string.PasswordOldIncorrect)); return; } } if (newPassword.length() == 0) { - needShowAlert(LocaleController.getString("PasswordNewIncorrect", R.string.PasswordNewIncorrect)); + ShowAlert(LocaleController.getString("PasswordNewIncorrect", R.string.PasswordNewIncorrect)); return; } if (!newPassword.equals(verifyPasswrod)) { - needShowAlert(LocaleController.getString("PasswordDoNotMatch", R.string.PasswordDoNotMatch)); + ShowAlert(LocaleController.getString("PasswordDoNotMatch", R.string.PasswordDoNotMatch)); return; } if (hint.toLowerCase().contains(newPassword.toLowerCase())) { - needShowAlert(LocaleController.getString("HintIncorrect", R.string.HintIncorrect)); + ShowAlert(LocaleController.getString("HintIncorrect", R.string.HintIncorrect)); return; } byte[] oldPasswordBytes = null; @@ -418,13 +418,13 @@ public class AccountPasswordActivity extends BaseFragment { finishFragment(); } else { if (error.text.contains("PASSWORD_HASH_INVALID")) { - needShowAlert(LocaleController.getString("PasswordOldIncorrect", R.string.PasswordOldIncorrect)); + ShowAlert(LocaleController.getString("PasswordOldIncorrect", R.string.PasswordOldIncorrect)); } else if (error.text.contains("NEW_PASSWORD_BAD")) { - needShowAlert(LocaleController.getString("PasswordNewIncorrect", R.string.PasswordNewIncorrect)); + ShowAlert(LocaleController.getString("PasswordNewIncorrect", R.string.PasswordNewIncorrect)); } else if (error.text.startsWith("FLOOD_WAIT")) { - needShowAlert(LocaleController.getString("FloodWait", R.string.FloodWait)); + ShowAlert(LocaleController.getString("FloodWait", R.string.FloodWait)); } else { - needShowAlert(error.text); + ShowAlert(error.text); } } } @@ -434,7 +434,7 @@ public class AccountPasswordActivity extends BaseFragment { } else if (type == 1) { String oldPassword = oldPasswordCell.getFieldText(); if (oldPassword.length() == 0) { - needShowAlert(LocaleController.getString("PasswordIncorrect", R.string.PasswordIncorrect)); + ShowAlert(LocaleController.getString("PasswordIncorrect", R.string.PasswordIncorrect)); return; } byte[] oldPasswordBytes = null; @@ -486,11 +486,11 @@ public class AccountPasswordActivity extends BaseFragment { } } else { if (error.text.contains("PASSWORD_HASH_INVALID")) { - needShowAlert(LocaleController.getString("PasswordOldIncorrect", R.string.PasswordOldIncorrect)); + ShowAlert(LocaleController.getString("PasswordOldIncorrect", R.string.PasswordOldIncorrect)); } else if (error.text.startsWith("FLOOD_WAIT")) { - needShowAlert(LocaleController.getString("FloodWait", R.string.FloodWait)); + ShowAlert(LocaleController.getString("FloodWait", R.string.FloodWait)); } else { - needShowAlert(error.text); + ShowAlert(error.text); } } } 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 188fdf76..c01b464b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBar.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBar.java @@ -8,11 +8,14 @@ package org.telegram.ui.ActionBar; +import android.app.Activity; import android.content.Context; +import android.content.SharedPreferences; 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; @@ -91,9 +94,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 +109,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(); @@ -136,7 +139,7 @@ public class ActionBar extends FrameLayout { } 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 +176,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); @@ -366,7 +369,7 @@ public class ActionBar extends FrameLayout { return; } actionMode.setVisibility(VISIBLE); - if (actionModeTop != null) { + if (occupyStatusBar && actionModeTop != null) { actionModeTop.setVisibility(VISIBLE); } if (titleFrameLayout != null) { @@ -382,7 +385,7 @@ public class ActionBar extends FrameLayout { return; } actionMode.setVisibility(GONE); - if (actionModeTop != null) { + if (occupyStatusBar && actionModeTop != null) { actionModeTop.setVisibility(GONE); } if (titleFrameLayout != null) { @@ -473,6 +476,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() { @@ -484,6 +490,11 @@ public class ActionBar extends FrameLayout { if (backButtonImageView != null) { backButtonImageView.setBackgroundResource(itemsBackgroundResourceId); } + // + //SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, Activity.MODE_PRIVATE); + //setBackgroundColor(themePrefs.getInt("themeColor", 0x000000)); + setBackgroundColor(AndroidUtilities.getIntColor("themeColor")); + // } public void setCastShadows(boolean value) { 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 bf295a53..398ecde2 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java @@ -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); @@ -321,7 +321,7 @@ public class ActionBarLayout extends FrameLayout { beginTrackingSent = false; BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 2); - View fragmentView = lastFragment.createView(parentActivity.getLayoutInflater(), null); + View fragmentView = lastFragment.createView(parentActivity.getLayoutInflater()); ViewGroup parent = (ViewGroup) fragmentView.getParent(); if (parent != null) { parent.removeView(fragmentView); @@ -502,8 +502,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; @@ -556,7 +555,7 @@ 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.createView(parentActivity.getLayoutInflater()); if (fragment.needAddActionBar() && fragment.actionBar != null) { if (removeActionBarExtraHeight) { fragment.actionBar.setOccupyStatusBar(false); @@ -585,6 +584,7 @@ public class ActionBarLayout extends FrameLayout { containerView = containerViewBack; containerViewBack = temp; containerView.setVisibility(View.VISIBLE); + setInnerTranslationX(0); bringChildToFront(containerView); @@ -633,6 +633,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 +642,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 +679,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); @@ -689,12 +712,13 @@ public class ActionBarLayout extends FrameLayout { } 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 +733,7 @@ public class ActionBarLayout extends FrameLayout { containerView.setVisibility(View.VISIBLE); previousFragment.setParentLayout(this); - View fragmentView = previousFragment.createView(parentActivity.getLayoutInflater(), null); + View fragmentView = previousFragment.createView(parentActivity.getLayoutInflater()); if (previousFragment.needAddActionBar() && previousFragment.actionBar != null) { if (removeActionBarExtraHeight) { previousFragment.actionBar.setOccupyStatusBar(false); @@ -754,6 +778,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); @@ -796,6 +825,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); @@ -823,7 +857,7 @@ 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.createView(parentActivity.getLayoutInflater()); if (previousFragment.needAddActionBar() && previousFragment.actionBar != null) { if (removeActionBarExtraHeight) { previousFragment.actionBar.setOccupyStatusBar(false); 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 96650548..fa19aa49 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenuItem.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenuItem.java @@ -348,6 +348,10 @@ public class ActionBarMenuItem extends FrameLayoutFixed { } } + public void setIcon(int resId) { + iconView.setImageResource(resId); + } + public EditText getSearchField() { return searchField; } @@ -399,7 +403,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 e67c9c64..241cf3b3 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarPopupWindow.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarPopupWindow.java @@ -200,7 +200,11 @@ public class ActionBarPopupWindow extends PopupWindow { @Override public void dismiss() { setFocusable(false); + 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 9270ca1c..72a48781 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BaseFragment.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BaseFragment.java @@ -41,7 +41,7 @@ public class BaseFragment { classGuid = ConnectionsManager.getInstance().generateClassGuid(); } - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { return null; } @@ -201,7 +201,7 @@ public class BaseFragment { return true; } - protected void showAlertDialog(AlertDialog.Builder builder) { + public void showAlertDialog(AlertDialog.Builder builder) { if (parentLayout == null || parentLayout.checkTransitionAnimation() || parentLayout.animationInProgress || parentLayout.startedTracking) { return; } 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 1c607dd5..600807d1 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()); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/ContactsAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/ContactsAdapter.java index cd50fac4..a2729f95 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/ContactsAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/ContactsAdapter.java @@ -8,13 +8,16 @@ package org.telegram.ui.Adapters; +import android.app.Activity; import android.content.Context; +import android.content.SharedPreferences; import android.os.Build; import android.view.View; import android.view.ViewGroup; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.TLRPC; import org.telegram.android.ContactsController; import org.telegram.android.MessagesController; @@ -28,6 +31,7 @@ import org.telegram.ui.Cells.UserCell; import java.util.ArrayList; import java.util.HashMap; +import java.util.Locale; public class ContactsAdapter extends BaseSectionsAdapter { @@ -187,12 +191,15 @@ public class ContactsAdapter extends BaseSectionsAdapter { if (convertView == null) { convertView = new GreySectionCell(mContext); ((GreySectionCell) convertView).setText(LocaleController.getString("Contacts", R.string.Contacts).toUpperCase()); + //((GreySectionCell) convertView).setText(String.format(Locale.US, " %d " + LocaleController.getString("Contacts", R.string.Contacts).toUpperCase(), arr0.size())); + ((GreySectionCell) convertView).setBackgroundColor(AndroidUtilities.getIntDef("contactsRowColor", 0xffffffff)); } } else if (type == 2) { if (convertView == null) { convertView = new TextCell(mContext); } TextCell actionCell = (TextCell) convertView; + actionCell.setTextColor(AndroidUtilities.getIntDef("contactsNameColor", 0xff000000)); if (needPhonebook) { actionCell.setTextAndIcon(LocaleController.getString("InviteFriends", R.string.InviteFriends), R.drawable.menu_invite); } else { @@ -207,6 +214,8 @@ public class ContactsAdapter extends BaseSectionsAdapter { } else if (type == 1) { if (convertView == null) { convertView = new TextCell(mContext); + ((TextCell) convertView).setTextColor(AndroidUtilities.getIntDef("contactsNameColor", 0xff000000)); + ((TextCell) convertView).setTextSize(AndroidUtilities.getIntDef("contactsNameSize", 16)); } ContactsController.Contact contact = ContactsController.getInstance().phoneBookContacts.get(position); if (contact.first_name != null && contact.last_name != null) { @@ -219,7 +228,9 @@ public class ContactsAdapter extends BaseSectionsAdapter { } else if (type == 0) { if (convertView == null) { convertView = new UserCell(mContext, 58); - ((UserCell) convertView).setStatusColors(0xffa8a8a8, 0xff3b84c0); + //((UserCell) convertView).setStatusColors(0xffa8a8a8, 0xff3b84c0); + ((UserCell) convertView).setStatusColors(AndroidUtilities.getIntDef("contactsStatusColor", 0xffa8a8a8), AndroidUtilities.getIntDef("contactsOnlineColor", AndroidUtilities.getIntDarkerColor("themeColor",0x15))); + ((UserCell) convertView).setNameColor(AndroidUtilities.getIntDef("contactsNameColor", 0xff000000)); } ArrayList arr = ContactsController.getInstance().usersSectionsDict.get(ContactsController.getInstance().sortedUsersSectionsArray.get(section - (onlyUsers ? 0 : 1))); @@ -236,6 +247,7 @@ public class ContactsAdapter extends BaseSectionsAdapter { } } } + parent.setBackgroundColor(AndroidUtilities.getIntDef("contactsRowColor", 0xffffffff)); return convertView; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/ContactsSearchAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/ContactsSearchAdapter.java index e68e9be5..132e24a8 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/ContactsSearchAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/ContactsSearchAdapter.java @@ -124,10 +124,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; @@ -234,7 +238,7 @@ public class ContactsSearchAdapter extends BaseContactsSearchAdapter { view = new ProfileSearchCell(mContext); } } - + String hexDarkColor = String.format("#%06X", (0xFFFFFF & AndroidUtilities.getIntDarkerColor("themeColor", 0x15))); TLRPC.User user = getItem(i); if (user != null) { CharSequence username = null; @@ -253,7 +257,8 @@ 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 = Html.fromHtml(String.format("@%s%s", user.username.substring(0, foundUserName.length()), user.username.substring(foundUserName.length()))); + //username = Html.fromHtml(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/DialogsAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java index 6031ed21..c3b27858 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java @@ -8,13 +8,17 @@ package org.telegram.ui.Adapters; +import android.app.Activity; import android.content.Context; +import android.content.SharedPreferences; 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.ApplicationLoader; +import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.ui.Cells.DialogCell; import org.telegram.ui.Cells.LoadingCell; @@ -24,6 +28,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 +39,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 +68,7 @@ public class DialogsAdapter extends BaseFragmentAdapter { if (!MessagesController.getInstance().dialogsEndReached) { count++; } + currentCount = count; return count; } @@ -97,6 +108,7 @@ public class DialogsAdapter extends BaseFragmentAdapter { if (view == null) { view = new DialogCell(mContext); } + 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) { @@ -111,13 +123,18 @@ public class DialogsAdapter extends BaseFragmentAdapter { } } } - 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)); + ((DialogCell) view).setDialog(dialog, i, serverOnly); + } } - + updateColors(viewGroup); return view; } + private void updateColors(ViewGroup viewGroup){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, Activity.MODE_PRIVATE); + viewGroup.setBackgroundColor(themePrefs.getInt("chatsRowColor", 0xffffffff)); + } + @Override public int getItemViewType(int i) { if (serverOnly && i == MessagesController.getInstance().dialogsServerOnly.size() || !serverOnly && i == MessagesController.getInstance().dialogs.size()) { @@ -133,9 +150,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 2424062c..25aeb0a9 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsSearchAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsSearchAdapter.java @@ -215,6 +215,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 +226,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 +261,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 +293,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 +305,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; @@ -378,6 +390,10 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { 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 +401,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; @@ -573,7 +589,7 @@ public class DialogsSearchAdapter extends BaseContactsSearchAdapter { int localCount = searchResult.size(); int globalCount = globalSearch.isEmpty() ? 0 : globalSearch.size() + 1; - + String hexDarkColor = String.format("#%06X", (0xFFFFFF & AndroidUtilities.getIntDarkerColor("themeColor", 0x15))); ((ProfileSearchCell) view).useSeparator = (i != getCount() - 1 && i != localCount - 1 && i != localCount + globalCount - 1); Object obj = getItem(i); if (obj instanceof TLRPC.User) { @@ -604,7 +620,8 @@ 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 = Html.fromHtml(String.format("@%s%s", user.username.substring(0, foundUserName.length()), user.username.substring(foundUserName.length()))); + //username = Html.fromHtml(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,7 +635,7 @@ 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); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DrawerLayoutAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DrawerLayoutAdapter.java index 8304f7f7..75892c2b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DrawerLayoutAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DrawerLayoutAdapter.java @@ -9,22 +9,34 @@ package org.telegram.ui.Adapters; import android.content.Context; +import android.content.pm.PackageInfo; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import org.telegram.android.LocaleController; import org.telegram.android.MessagesController; +import org.telegram.messenger.ApplicationLoader; +import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.UserConfig; -import org.telegram.ui.Cells.DrawerActionCell; import org.telegram.ui.Cells.DividerCell; -import org.telegram.ui.Cells.EmptyCell; +import org.telegram.ui.Cells.DrawerActionCell; import org.telegram.ui.Cells.DrawerProfileCell; +import org.telegram.ui.Cells.EmptyCell; +import org.telegram.ui.Cells.TextInfoCell; + +import java.util.Locale; public class DrawerLayoutAdapter extends BaseAdapter { private Context mContext; + private int versionType = 4; + private int versionRow = 10; + private int themingRow = 7; + private int communityRow = 9; + + private int rowCount = 0; public DrawerLayoutAdapter(Context context) { mContext = context; @@ -42,7 +54,8 @@ public class DrawerLayoutAdapter extends BaseAdapter { @Override public int getCount() { - return UserConfig.isClientActivated() ? 10 : 0; + //return UserConfig.isClientActivated() ? 10 : 0; + return UserConfig.isClientActivated() ? 11 : 0; } @Override @@ -89,12 +102,26 @@ public class DrawerLayoutAdapter extends BaseAdapter { actionCell.setTextAndIcon(LocaleController.getString("NewBroadcastList", R.string.NewBroadcastList), R.drawable.menu_broadcast); } else if (i == 6) { actionCell.setTextAndIcon(LocaleController.getString("Contacts", R.string.Contacts), R.drawable.menu_contacts); - } else if (i == 7) { + }/* else if (i == 7) { actionCell.setTextAndIcon(LocaleController.getString("InviteFriends", R.string.InviteFriends), R.drawable.menu_invite); + }*/ else if (i == themingRow) { + actionCell.setTextAndIcon(LocaleController.getString("Theming", R.string.Theming), R.drawable.menu_theming); } else if (i == 8) { actionCell.setTextAndIcon(LocaleController.getString("Settings", R.string.Settings), R.drawable.menu_settings); - } else if (i == 9) { + } else if (i == communityRow) { + actionCell.setTextAndIcon(LocaleController.getString("Community", R.string.Community), R.drawable.menu_forum); + } /*else if (i == 10) { actionCell.setTextAndIcon(LocaleController.getString("TelegramFaq", R.string.TelegramFaq), R.drawable.menu_help); + }*/ + } else if (type == versionType) { + view = new TextInfoCell(mContext); + if (i == versionRow) { + try { + PackageInfo pInfo = ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0); + ((TextInfoCell) view).setText(String.format(Locale.US, LocaleController.getString("TelegramForAndroid", R.string.TelegramForAndroid)+" v%s (%d)", pInfo.versionName, pInfo.versionCode)); + } catch (Exception e) { + FileLog.e("tmessages", e); + } } } @@ -110,12 +137,17 @@ public class DrawerLayoutAdapter extends BaseAdapter { } else if (i == 5) { return 2; } + //new + else if (i == versionRow) { + return versionType; + } + // return 3; } @Override public int getViewTypeCount() { - return 4; + return 5; } @Override 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 2d52263f..538756f7 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/StickersAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/StickersAdapter.java @@ -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"; 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 0f91b93b..274dd604 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/View10.java b/TMessagesProj/src/main/java/org/telegram/ui/Animation/View10.java index 0863204d..4a89fe9c 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 0f0eb843..ef1e5475 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/BlockedUsersActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/BlockedUsersActivity.java @@ -64,7 +64,7 @@ public class BlockedUsersActivity extends BaseFragment implements NotificationCe } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); actionBar.setAllowOverlayTitle(true); 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 f07555cf..f1073509 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatActionCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatActionCell.java @@ -12,6 +12,7 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.text.Layout; import android.text.Spannable; @@ -45,6 +46,8 @@ public class ChatActionCell extends BaseCell { private static Drawable backgroundBlue; private static TextPaint textPaint; + private static Drawable backgroundWhite; + private URLSpan pressedLink; private ImageReceiver imageReceiver; @@ -69,6 +72,9 @@ public class ChatActionCell extends BaseCell { backgroundBlack = getResources().getDrawable(R.drawable.system_black); backgroundBlue = getResources().getDrawable(R.drawable.system_blue); + backgroundWhite = getResources().getDrawable(R.drawable.system_white); + backgroundBlue = backgroundWhite; + textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); textPaint.setColor(0xffffffff); textPaint.linkColor = 0xffffffff; @@ -220,6 +226,7 @@ public class ChatActionCell extends BaseCell { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + updateColor(); if (currentMessageObject == null) { setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), textHeight + AndroidUtilities.dp(14)); return; @@ -286,4 +293,14 @@ public class ChatActionCell extends BaseCell { canvas.restore(); } } + + private void updateColor(){ + int color = AndroidUtilities.getIntDef("chatDateColor", 0xffffffff); + textPaint.setColor(color); + if(color != 0xffffffff){ + textPaint.linkColor = AndroidUtilities.getIntDarkerColor("chatDateColor", -0x50); + } + textPaint.setTextSize(AndroidUtilities.dp(AndroidUtilities.getIntDef("chatDateSize",16)));//16 + backgroundWhite.setColorFilter(AndroidUtilities.getIntDef("chatDateBubbleColor",0x59000000), PorterDuff.Mode.MULTIPLY); + } } 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 ec5ac969..4a2c1fba 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java @@ -11,6 +11,7 @@ package org.telegram.ui.Cells; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; +import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.text.Html; import android.text.Layout; @@ -73,6 +74,14 @@ public class ChatBaseCell extends BaseCell { private static TextPaint namePaint; private static TextPaint forwardNamePaint; + private static Drawable backgroundDrawableOutWhite; + private static Drawable backgroundDrawableOutWhiteSelected; + private static Drawable backgroundMediaDrawableOutWhite; + private static Drawable backgroundMediaDrawableOutWhiteSelected; + private static Drawable checkDrawableWhite; + private static Drawable halfCheckDrawableWhite; + private static Drawable clockDrawableWhite; + protected int backgroundWidth = 100; protected int layoutWidth; @@ -138,6 +147,15 @@ public class ChatBaseCell extends BaseCell { broadcastDrawable = getResources().getDrawable(R.drawable.broadcast3); broadcastMediaDrawable = getResources().getDrawable(R.drawable.broadcast4); + backgroundDrawableOutWhite = getResources().getDrawable(R.drawable.msg_out_white); + backgroundDrawableOutWhiteSelected = getResources().getDrawable(R.drawable.msg_out_white_selected); + backgroundMediaDrawableOutWhite = getResources().getDrawable(R.drawable.msg_out_photo_white); + backgroundMediaDrawableOutWhiteSelected = getResources().getDrawable(R.drawable.msg_out_photo_white_selected); + + checkDrawableWhite = getResources().getDrawable(R.drawable.msg_check_white); + halfCheckDrawableWhite = getResources().getDrawable(R.drawable.msg_halfcheck_white); + clockDrawableWhite = getResources().getDrawable(R.drawable.msg_clock_white); + timePaintIn = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); timePaintIn.setTextSize(AndroidUtilities.dp(12)); timePaintIn.setColor(0xffa1aab3); @@ -161,6 +179,26 @@ public class ChatBaseCell extends BaseCell { avatarDrawable = new AvatarDrawable(); } + private void updateColors(){ + int tColor = AndroidUtilities.getIntColor("themeColor"); + int lColor = AndroidUtilities.getIntDarkerColor("themeColor",-0x80); + int dColor = AndroidUtilities.getIntDarkerColor("themeColor",0x15); + backgroundDrawableOutWhite.setColorFilter(AndroidUtilities.getIntDef("chatRBubbleColor", lColor), PorterDuff.Mode.MULTIPLY); + backgroundMediaDrawableOutWhite.setColorFilter(AndroidUtilities.getIntDef("chatRBubbleColor", lColor), PorterDuff.Mode.MULTIPLY); + backgroundDrawableIn.setColorFilter(AndroidUtilities.getIntDef("chatLBubbleColor",0xffffffff), PorterDuff.Mode.MULTIPLY); + backgroundMediaDrawableIn.setColorFilter(AndroidUtilities.getIntDef("chatLBubbleColor",0xffffffff), PorterDuff.Mode.MULTIPLY); + + int checksColor = AndroidUtilities.getIntDef("chatChecksColor", tColor); + checkDrawableWhite.setColorFilter(checksColor, PorterDuff.Mode.MULTIPLY); + halfCheckDrawableWhite.setColorFilter(checksColor, PorterDuff.Mode.MULTIPLY); + clockDrawableWhite.setColorFilter(checksColor, PorterDuff.Mode.MULTIPLY); + + timePaintOut.setColor(AndroidUtilities.getIntDef("chatRTimeColor",dColor)); + timePaintOut.setTextSize(AndroidUtilities.dp(AndroidUtilities.getIntDef("chatTimeSize",12))); + timePaintIn.setColor(AndroidUtilities.getIntDef("chatLTimeColor",0xffa1aab3)); + timePaintIn.setTextSize(AndroidUtilities.dp(AndroidUtilities.getIntDef("chatTimeSize",12))); + } + @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); @@ -427,6 +465,7 @@ public class ChatBaseCell extends BaseCell { @Override protected void onDraw(Canvas canvas) { + updateColors(); if (currentMessageObject == null) { return; } @@ -444,15 +483,15 @@ public class ChatBaseCell extends BaseCell { if (currentMessageObject.isOut()) { if (isPressed() && isCheckPressed || !isCheckPressed && isPressed) { if (!media) { - currentBackgroundDrawable = backgroundDrawableOutSelected; + currentBackgroundDrawable = backgroundDrawableOutWhiteSelected;//backgroundDrawableOutSelected; } else { - currentBackgroundDrawable = backgroundMediaDrawableOutSelected; + currentBackgroundDrawable = backgroundMediaDrawableOutWhiteSelected;//backgroundMediaDrawableOutSelected; } } else { if (!media) { - currentBackgroundDrawable = backgroundDrawableOut; + currentBackgroundDrawable = backgroundDrawableOutWhite;//backgroundDrawableOut; } else { - currentBackgroundDrawable = backgroundMediaDrawableOut; + currentBackgroundDrawable = backgroundMediaDrawableOutWhite;//backgroundMediaDrawableOut; } } setDrawableBounds(currentBackgroundDrawable, layoutWidth - backgroundWidth - (!media ? 0 : AndroidUtilities.dp(9)), AndroidUtilities.dp(1), backgroundWidth, layoutHeight - AndroidUtilities.dp(2)); @@ -553,6 +592,7 @@ public class ChatBaseCell extends BaseCell { if (drawClock) { if (!media) { + clockDrawable = clockDrawableWhite; setDrawableBounds(clockDrawable, layoutWidth - AndroidUtilities.dp(18.5f) - clockDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.5f) - clockDrawable.getIntrinsicHeight()); clockDrawable.draw(canvas); } else { @@ -573,6 +613,7 @@ public class ChatBaseCell extends BaseCell { } else { if (drawCheck2) { if (!media) { + checkDrawable = checkDrawableWhite; if (drawCheck1) { setDrawableBounds(checkDrawable, layoutWidth - AndroidUtilities.dp(22.5f) - checkDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.5f) - checkDrawable.getIntrinsicHeight()); } else { @@ -590,6 +631,7 @@ public class ChatBaseCell extends BaseCell { } if (drawCheck1) { if (!media) { + halfCheckDrawable = halfCheckDrawableWhite; setDrawableBounds(halfCheckDrawable, layoutWidth - AndroidUtilities.dp(18) - halfCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.5f) - halfCheckDrawable.getIntrinsicHeight()); halfCheckDrawable.draw(canvas); } else { 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 87825a1c..db40b041 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java @@ -530,19 +530,14 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD break; } } - float maxWidth; - if (AndroidUtilities.isTablet()) { - maxWidth = (int) (AndroidUtilities.getMinTabletSide() * 0.5f); - } else { - maxWidth = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.5f); - } + float maxHeight = AndroidUtilities.displaySize.y * 0.4f; if (photoWidth == 0) { - photoWidth = (int)maxWidth; - photoHeight = photoWidth + AndroidUtilities.dp(100); + photoHeight = (int) maxHeight; + photoWidth = photoHeight + AndroidUtilities.dp(100); } - if (photoWidth > maxWidth) { - photoHeight *= maxWidth / photoWidth; - photoWidth = (int)maxWidth; + if (photoHeight > maxHeight) { + photoWidth *= maxHeight / photoHeight; + photoHeight = (int)maxHeight; } backgroundWidth = photoWidth + AndroidUtilities.dp(12); currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 80); @@ -870,8 +865,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); 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 d04e80cc..1f799a2e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java @@ -8,9 +8,12 @@ package org.telegram.ui.Cells; +import android.app.Activity; import android.content.Context; +import android.content.SharedPreferences; import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.text.Html; import android.text.Layout; @@ -22,6 +25,7 @@ import org.telegram.android.AndroidUtilities; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.LocaleController; import org.telegram.android.MessageObject; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLog; import org.telegram.messenger.TLRPC; import org.telegram.android.ContactsController; @@ -52,15 +56,26 @@ public class DialogCell extends BaseCell { private static Drawable broadcastDrawable; private static Drawable muteDrawable; + private static Drawable checkWhiteDrawable; + private static Drawable halfCheckWhiteDrawable; + private static Drawable countWhiteDrawable; + private static Drawable lockWhiteDrawable; + private static Drawable groupWhiteDrawable; + private static Drawable broadcastWhiteDrawable; + private static Drawable muteWhiteDrawable; + 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; @@ -155,6 +170,22 @@ public class DialogCell extends BaseCell { groupDrawable = getResources().getDrawable(R.drawable.list_group); broadcastDrawable = getResources().getDrawable(R.drawable.list_broadcast); muteDrawable = getResources().getDrawable(R.drawable.mute_grey); + + checkWhiteDrawable = getResources().getDrawable(R.drawable.dialogs_check_white); + checkDrawable = checkWhiteDrawable; + halfCheckWhiteDrawable = getResources().getDrawable(R.drawable.dialogs_halfcheck_white); + halfCheckDrawable = halfCheckWhiteDrawable; + countWhiteDrawable = getResources().getDrawable(R.drawable.dialogs_badge_white); + countDrawable = countWhiteDrawable; + lockWhiteDrawable = getResources().getDrawable(R.drawable.list_secret_white); + lockDrawable = lockWhiteDrawable; + groupWhiteDrawable = getResources().getDrawable(R.drawable.list_group_white); + groupDrawable = groupWhiteDrawable; + broadcastWhiteDrawable = getResources().getDrawable(R.drawable.list_broadcast_white); + broadcastDrawable = broadcastWhiteDrawable; + muteWhiteDrawable = getResources().getDrawable(R.drawable.mute_white); + muteDrawable = muteWhiteDrawable; + updateColors(); } } @@ -163,17 +194,28 @@ public class DialogCell extends BaseCell { init(); avatarImage = new ImageReceiver(this); avatarImage.setRoundRadius(AndroidUtilities.dp(26)); + //avatarImage.setRoundRadius(AndroidUtilities.dp(5)); avatarDrawable = new AvatarDrawable(); + //avatarDrawable.setRadius(5); + } + 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, boolean usePrintStrings, int date, int unread, boolean muted) { + 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 +253,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; @@ -328,9 +370,13 @@ public class DialogCell extends BaseCell { } } checkMessage = false; + String hexColor = String.format("#%06X", (0xFFFFFF & AndroidUtilities.getIntColor("themeColor"))); + String hexMsgColor = String.format("#%06X", (0xFFFFFF & AndroidUtilities.getIntDef("chatsMessageColor",0xff8f8f8f))); + String hexDarkColor = String.format("#%06X", (0xFFFFFF & AndroidUtilities.getIntDef("chatsParticipantColor", AndroidUtilities.getIntDarkerColor("themeColor",0x15)))); if (message.messageOwner.media != null && !(message.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) { currentMessagePaint = messagePrintingPaint; - messageString = Emoji.replaceEmoji(Html.fromHtml(String.format("%s: %s", name, message.messageText)), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20)); + //messageString = Emoji.replaceEmoji(Html.fromHtml(String.format("%s: %s", name, message.messageText)), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20)); + messageString = Emoji.replaceEmoji(Html.fromHtml(String.format("%s: %s", name, message.messageText)), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20)); } else { if (message.messageOwner.message != null) { String mess = message.messageOwner.message; @@ -338,7 +384,8 @@ 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(Html.fromHtml(String.format("%s: %s", name, mess.replace("<", "<").replace(">", ">"))), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20)); + messageString = Emoji.replaceEmoji(Html.fromHtml(String.format("%s: %s", name, mess.replace("<", "<").replace(">", ">"))), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20)); } } } else { @@ -543,15 +590,15 @@ public class DialogCell extends BaseCell { if (LocaleController.isRTL) { if (nameLayout != null && nameLayout.getLineCount() > 0) { left = nameLayout.getLineLeft(0); - if (left == 0) { widthpx = Math.ceil(nameLayout.getLineWidth(0)); + if (dialogMuted) { + nameMuteLeft = (int) (nameLeft + (nameWidth - widthpx) - AndroidUtilities.dp(6) - muteDrawable.getIntrinsicWidth()); + } + if (left == 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 +634,43 @@ 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.messageOwner.id != dialog.top_message || unreadCount != dialog.unread_count) { + currentDialogId = dialog.id; + update(0); + } + } + } + public void update(int mask) { + updateColors(); + 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 +698,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 +708,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; @@ -756,4 +845,44 @@ public class DialogCell extends BaseCell { avatarImage.draw(canvas); } + + private void updateColors(){ + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, Activity.MODE_PRIVATE); + int tColor = AndroidUtilities.getIntColor("themeColor"); + int dColor = AndroidUtilities.getIntDarkerColor("themeColor",0x15); + + namePaint.setTextSize(AndroidUtilities.dp(themePrefs.getInt("chatsNameSize", 17))); + namePaint.setColor(themePrefs.getInt("chatsNameColor", 0xff212121)); + + nameEncryptedPaint.setTextSize(AndroidUtilities.dp(themePrefs.getInt("chatsNameSize", 17))); + nameEncryptedPaint.setColor(themePrefs.getInt("chatsNameColor", dColor));//0xff00a60e + + nameUnknownPaint.setTextSize(AndroidUtilities.dp(themePrefs.getInt("chatsNameSize", 17))); + nameUnknownPaint.setColor(themePrefs.getInt("chatsNameColor", 0xff000000));//0xff4d83b3 + + messagePaint.setTextSize(AndroidUtilities.dp(themePrefs.getInt("chatsMessageSize", 16))); + messagePaint.setColor(themePrefs.getInt("chatsMessageColor", 0xff8f8f8f)); + //Audio Archivo ... te expulsó + messagePrintingPaint.setTextSize(AndroidUtilities.dp(themePrefs.getInt("chatsMessageSize", 16))); + messagePrintingPaint.setColor(themePrefs.getInt("chatsMessageColor", tColor));//0xff4d83b3 + + timePaint.setTextSize(AndroidUtilities.dp(themePrefs.getInt("chatsTimeSize", 13))); + timePaint.setColor(themePrefs.getInt("chatsTimeColor", 0xff999999)); + + countPaint.setTextSize(AndroidUtilities.dp(themePrefs.getInt("chatsCountSize", 13))); + countPaint.setColor(themePrefs.getInt("chatsCountColor", 0xffffffff)); + + checkWhiteDrawable.setColorFilter(AndroidUtilities.getIntDef("chatsChecksColor",AndroidUtilities.getIntColor("themeColor")), PorterDuff.Mode.MULTIPLY); + halfCheckWhiteDrawable.setColorFilter(AndroidUtilities.getIntDef("chatsChecksColor",AndroidUtilities.getIntColor("themeColor")), PorterDuff.Mode.MULTIPLY); + + countWhiteDrawable.setColorFilter(themePrefs.getInt("chatsCountBGColor", tColor), PorterDuff.Mode.MULTIPLY); + lockWhiteDrawable.setColorFilter(dColor, PorterDuff.Mode.MULTIPLY); + + int nColor = themePrefs.getInt("chatsNameColor", 0xff000000); + groupWhiteDrawable.setColorFilter(nColor, PorterDuff.Mode.MULTIPLY); + broadcastWhiteDrawable.setColorFilter(nColor, PorterDuff.Mode.MULTIPLY); + + int mColor = themePrefs.getInt("chatsMuteColor", 0xffa8a8a8); + muteWhiteDrawable.setColorFilter(mColor, PorterDuff.Mode.MULTIPLY); + } } 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 f1dfbb2e..053af150 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DrawerProfileCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DrawerProfileCell.java @@ -8,7 +8,11 @@ package org.telegram.ui.Cells; +import android.app.Activity; import android.content.Context; +import android.content.SharedPreferences; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.os.Build; import android.util.TypedValue; import android.view.Gravity; @@ -18,7 +22,9 @@ import android.widget.TextView; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.AndroidUtilities; import org.telegram.android.ContactsController; +import org.telegram.android.MessagesController; import org.telegram.messenger.TLRPC; +import org.telegram.messenger.UserConfig; import org.telegram.ui.Components.AvatarDrawable; import org.telegram.ui.Components.BackupImageView; @@ -86,6 +92,7 @@ public class DrawerProfileCell extends FrameLayout { } else { super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(148), MeasureSpec.EXACTLY)); } + updateColors(); } public void setUser(TLRPC.User user) { @@ -102,4 +109,23 @@ public class DrawerProfileCell extends FrameLayout { avatarDrawable.setColor(0xff5c98cd); avatarImageView.setImage(photo, "50_50", avatarDrawable); } + + private void updateColors(){ + setBackgroundColor(AndroidUtilities.getIntColor("themeColor")); + phoneTextView.setTextColor(AndroidUtilities.getIntDarkerColor("themeColor",-0x40)); + TLRPC.User user = MessagesController.getInstance().getUser(UserConfig.getClientUserId()); + TLRPC.FileLocation photo = null; + if (user.photo != null) { + photo = user.photo.photo_small; + } + AvatarDrawable avatarDrawable = new AvatarDrawable(user); + avatarDrawable.setColor(AndroidUtilities.getIntDarkerColor("themeColor",0x15)); + avatarImageView.setImage(photo, "50_50", avatarDrawable); + + if(AndroidUtilities.getBoolMain("hideMobile")){ + phoneTextView.setVisibility(GONE); + }else{ + phoneTextView.setVisibility(VISIBLE); + } + } } 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 b13f3de7..633e02c8 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/HeaderCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/HeaderCell.java index fcfd8b2e..3cc09042 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/HeaderCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/HeaderCell.java @@ -8,7 +8,9 @@ package org.telegram.ui.Cells; +import android.app.Activity; import android.content.Context; +import android.content.SharedPreferences; import android.util.AttributeSet; import android.util.TypedValue; import android.view.Gravity; @@ -26,7 +28,10 @@ public class HeaderCell extends FrameLayout { textView = new TextView(getContext()); textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); - textView.setTextColor(0xff3e90cf); + //textView.setTextColor(0xff3e90cf); + // + textView.setTextColor(AndroidUtilities.getIntColor("themeColor")); + // textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL); addView(textView); FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)textView.getLayoutParams(); 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 b6be0e98..faf3b163 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,54 @@ 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); + } } } 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 15a24037..2fe47d9e 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,7 @@ import android.util.TypedValue; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; -import android.widget.FrameLayout; +import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; @@ -23,8 +23,9 @@ 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); @@ -35,7 +36,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; @@ -146,7 +147,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); @@ -167,16 +170,21 @@ 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)); } + + ViewGroup.LayoutParams layoutParams = getLayoutParams(); + if (layoutParams != null) { + layoutParams.height = AndroidUtilities.dp(4) + itemWidth; + setLayoutParams(layoutParams); + } + super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } 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 4879a0c0..f0043492 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 ecd88357..30c1fe4c 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; @@ -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/SharedDocumentCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedDocumentCell.java index 2ddd7307..1938fea3 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedDocumentCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedDocumentCell.java @@ -249,6 +249,12 @@ public class SharedDocumentCell extends FrameLayout implements MediaController. } } + @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) { + 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(GONE); + 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 { + nameTextView.setText(""); + extTextView.setText(""); + dateTextView.setText(""); + placeholderImabeView.setVisibility(VISIBLE); + extTextView.setVisibility(VISIBLE); thumbImageView.setVisibility(GONE); 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))))); + 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())) { 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 00000000..4b7d29c5 --- /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 00000000..90f3d4f5 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedPhotoVideoCell.java @@ -0,0 +1,255 @@ +/* + * 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.view.ViewGroup; +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 static interface SharedPhotoVideoCellDelegate { + public abstract void didClickItem(SharedPhotoVideoCell cell, int index, MessageObject messageObject, int a); + public abstract 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.imageReceiver.setNeedsQualityThumb(true); + imageView.imageReceiver.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(GONE); + 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(GONE); + 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 : GONE); + } + 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.imageReceiver.setParentMessageObject(messageObject); + photoVideoView.imageView.imageReceiver.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(GONE); + 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(GONE); + photoVideoView.imageView.setImageResource(R.drawable.photo_placeholder_in); + } + } else { + photoVideoViews[a].setVisibility(GONE); + 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/TextCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextCell.java index 0c05b6e5..c392bcb9 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextCell.java @@ -48,7 +48,8 @@ public class TextCell extends FrameLayout { textView.setLayoutParams(layoutParams); valueTextView = new TextView(context); - valueTextView.setTextColor(0xff2f8cc9); + //valueTextView.setTextColor(0xff2f8cc9); + valueTextView.setTextColor(AndroidUtilities.getIntColor("themeColor")); valueTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); valueTextView.setLines(1); valueTextView.setMaxLines(1); @@ -95,6 +96,10 @@ public class TextCell extends FrameLayout { textView.setTextColor(color); } + public void setTextSize(int size) { + textView.setTextSize(size); + } + public void setText(String text) { textView.setText(text); imageView.setVisibility(GONE); 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 e6c0414c..c2be7360 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextSettingsCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextSettingsCell.java @@ -56,7 +56,10 @@ public class TextSettingsCell extends FrameLayout { textView.setLayoutParams(layoutParams); valueTextView = new TextView(context); - valueTextView.setTextColor(0xff2f8cc9); + //valueTextView.setTextColor(0xff2f8cc9); + // + valueTextView.setTextColor(AndroidUtilities.getIntColor("themeColor")); + // valueTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); valueTextView.setLines(1); valueTextView.setMaxLines(1); 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 c5bda382..7136d2c3 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/UserCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/UserCell.java @@ -48,7 +48,9 @@ public class UserCell extends FrameLayout { private TLRPC.FileLocation lastAvatar = null; private int statusColor = 0xffa8a8a8; - private int statusOnlineColor = 0xff3b84c0; + private int statusOnlineColor = AndroidUtilities.getIntDarkerColor("themeColor",0x15);//0xff3b84c0; + + private int nameColor = 0xff000000; public UserCell(Context context, int padding) { super(context); @@ -67,6 +69,7 @@ public class UserCell extends FrameLayout { avatarDrawable = new AvatarDrawable(); nameTextView = new TextView(context); + //ContactsNamesColor nameTextView.setTextColor(0xff212121); nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 17); nameTextView.setLines(1); @@ -165,6 +168,10 @@ public class UserCell extends FrameLayout { statusOnlineColor = onlineColor; } + public void setNameColor(int color) { + nameColor = color; + } + public void update(int mask) { if (currentUser == null) { return; @@ -214,6 +221,8 @@ public class UserCell extends FrameLayout { nameTextView.setText(currentName); } else { nameTextView.setText(ContactsController.formatName(currentUser.first_name, currentUser.last_name)); + nameTextView.setTextColor(nameColor); + nameTextView.setTextSize(AndroidUtilities.getIntDef("contactsNameSize", 17)); } if (currrntStatus != null) { statusTextView.setText(currrntStatus); @@ -227,7 +236,7 @@ public class UserCell extends FrameLayout { statusTextView.setTextColor(statusColor); } } - + statusTextView.setTextSize(AndroidUtilities.getIntDef("contactsStatusSize", 14)); imageView.setVisibility(currentDrawable == 0 ? GONE : 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 ddecb6b5..5213e61c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChangeChatNameActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangeChatNameActivity.java @@ -55,7 +55,7 @@ public class ChangeChatNameActivity extends BaseFragment { } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChangeNameActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangeNameActivity.java index 666525aa..465b38ff 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChangeNameActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangeNameActivity.java @@ -48,7 +48,7 @@ public class ChangeNameActivity extends BaseFragment { private final static int done_button = 1; @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); actionBar.setAllowOverlayTitle(true); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java index d0dc19b2..9a1bdcd5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java @@ -101,7 +101,7 @@ public class ChangePhoneActivity extends BaseFragment { } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setTitle(LocaleController.getString("AppName", R.string.AppName)); actionBar.setBackButtonImage(R.drawable.ic_ab_back); @@ -289,9 +289,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 +533,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 +544,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); } @@ -815,7 +816,8 @@ public class ChangePhoneActivity extends BaseFragment { TextView wrongNumber = new TextView(context); wrongNumber.setGravity(Gravity.LEFT | Gravity.CENTER_HORIZONTAL); - wrongNumber.setTextColor(0xff4d83b3); + //wrongNumber.setTextColor(0xff4d83b3); + wrongNumber.setTextColor(AndroidUtilities.getIntColor("themeColor")); wrongNumber.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); wrongNumber.setLineSpacing(AndroidUtilities.dp(2), 1.0f); wrongNumber.setPadding(0, AndroidUtilities.dp(24), 0, 0); @@ -1013,7 +1015,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 e2c2b2cb..34b5d446 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneHelpActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneHelpActivity.java @@ -35,7 +35,7 @@ import org.telegram.ui.ActionBar.BaseFragment; public class ChangePhoneHelpActivity extends BaseFragment { @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); actionBar.setAllowOverlayTitle(true); @@ -118,7 +118,8 @@ public class ChangePhoneHelpActivity extends BaseFragment { textView = new TextView(getParentActivity()); textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); textView.setGravity(Gravity.CENTER_HORIZONTAL); - textView.setTextColor(0xff4d83b3); + //textView.setTextColor(0xff4d83b3); + textView.setTextColor(AndroidUtilities.getIntColor("themeColor")); 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)); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChangeUsernameActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangeUsernameActivity.java index 42c81134..0f5d8429 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChangeUsernameActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangeUsernameActivity.java @@ -61,7 +61,7 @@ public class ChangeUsernameActivity extends BaseFragment { private final static int done_button = 1; @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); actionBar.setAllowOverlayTitle(true); @@ -205,14 +205,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 7b459010..1bbd3576 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -19,7 +19,7 @@ import android.content.pm.PackageManager; 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; @@ -42,29 +42,36 @@ import android.widget.AdapterView; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; +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.AndroidUtilities; +import org.telegram.android.ContactsController; +import org.telegram.android.ImageReceiver; import org.telegram.android.LocaleController; import org.telegram.android.MediaController; +import org.telegram.android.MessageObject; +import org.telegram.android.MessagesController; import org.telegram.android.MessagesStorage; +import org.telegram.android.NotificationCenter; import org.telegram.android.NotificationsController; import org.telegram.android.SecretChatHelper; import org.telegram.android.SendMessagesHelper; import org.telegram.messenger.ApplicationLoader; -import org.telegram.messenger.FileLoader; -import org.telegram.messenger.TLRPC; -import org.telegram.android.ContactsController; -import org.telegram.messenger.FileLog; -import org.telegram.android.MessageObject; import org.telegram.messenger.ConnectionsManager; -import org.telegram.android.MessagesController; -import org.telegram.android.NotificationCenter; +import org.telegram.messenger.FileLoader; +import org.telegram.messenger.FileLog; import org.telegram.messenger.R; +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.ActionBarMenuItem; +import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.Adapters.BaseFragmentAdapter; import org.telegram.ui.Adapters.StickersAdapter; import org.telegram.ui.AnimationCompat.AnimatorListenerAdapterProxy; @@ -77,14 +84,9 @@ import org.telegram.ui.Cells.ChatBaseCell; import org.telegram.ui.Cells.ChatContactCell; import org.telegram.ui.Cells.ChatMediaCell; import org.telegram.ui.Cells.ChatMessageCell; -import org.telegram.ui.ActionBar.ActionBar; -import org.telegram.ui.ActionBar.ActionBarMenu; -import org.telegram.ui.ActionBar.ActionBarMenuItem; import org.telegram.ui.Components.AvatarDrawable; import org.telegram.ui.Components.BackupImageView; -import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.Components.ChatActivityEnterView; -import org.telegram.android.ImageReceiver; import org.telegram.ui.Components.FrameLayoutFixed; import org.telegram.ui.Components.LayoutListView; import org.telegram.ui.Components.RecyclerListView; @@ -107,8 +109,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 +123,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,8 +135,9 @@ 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 boolean allowStickersPanel; private AnimatorSetProxy runningAnimation; @@ -151,7 +154,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not 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<>(); @@ -215,6 +217,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 attach_music = 15; + + private final static int id_chat_compose_panel = 1000; AdapterView.OnItemLongClickListener onItemLongClickListener = new AdapterView.OnItemLongClickListener() { @Override @@ -362,68 +367,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } 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); @@ -528,7 +472,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not MediaController.getInstance().stopAudio(); } - public View createView(LayoutInflater inflater, ViewGroup container) { + @Override + public View createView(LayoutInflater inflater) { if (fragmentView == null) { lastPrintString = null; lastStatus = null; @@ -537,6 +482,33 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not 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 { + action = "bigchat_upload_document"; + } + } else { + if (id == attach_photo || id == attach_gallery) { + action = "chat_upload_photo"; + } else { + action = "chat_upload_document"; + } + } + } else { + if (id == attach_photo || id == attach_gallery) { + action = "pm_upload_photo"; + } else { + action = "pm_upload_document"; + } + } + if (action != null && !MessagesController.isFeatureEnabled(action, ChatActivity.this)) { + return; + } + } if (id == -1) { finishFragment(); } else if (id == -2) { @@ -557,7 +529,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not FileLog.e("tmessages", e); } } else if (id == attach_gallery) { - PhotoAlbumPickerActivity fragment = new PhotoAlbumPickerActivity(); + PhotoAlbumPickerActivity fragment = new PhotoAlbumPickerActivity(false); fragment.setDelegate(new PhotoAlbumPickerActivity.PhotoAlbumPickerActivityDelegate() { @Override public void didSelectPhotos(ArrayList photos) { @@ -586,23 +558,31 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not Intent pickIntent = new Intent(); pickIntent.setType("video/*"); pickIntent.setAction(Intent.ACTION_GET_CONTENT); - pickIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, (long) (1024 * 1024 * 1000)); + 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 * 1000)); + takeVideoIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, (long) (1024 * 1024 * 1536)); currentPicturePath = video.getAbsolutePath(); } - Intent chooserIntent = Intent.createChooser(pickIntent, ""); + 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); } +//PLUS + } else if (id == attach_music) { + try { + Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI); + startActivityForResult(pickIntent, 3); + } catch (Exception e) { + FileLog.e("tmessages", e); + } } else if (id == attach_location) { if (!isGoogleMapsInstalled()) { return; @@ -782,7 +762,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not 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.formatString("MuteFor", R.string.MuteFor, LocaleController.formatPluralString("Days", 2)), + LocaleController.getString("MuteDisable", R.string.MuteDisable) }; builder.setItems(items, new DialogInterface.OnClickListener() { @Override @@ -794,13 +775,21 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not 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); - long flags = ((long)untilTime << 32) | 1; + flags = ((long)untilTime << 32) | 1; + } MessagesStorage.getInstance().setDialogFlags(dialog_id, flags); editor.commit(); TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(dialog_id); @@ -973,6 +962,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not 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_music, LocaleController.getString("ChatMusic", R.string.ChatMusic), R.drawable.ic_attach_music); 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); @@ -981,6 +971,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not 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_music, LocaleController.getString("ChatMusic", R.string.ChatMusic), R.drawable.ic_attach_music); 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); @@ -1025,92 +1016,170 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not actionMode.getItem(copy).setVisibility(selectedMessagesCanCopyIds.size() != 0 ? View.VISIBLE : View.GONE); checkActionBarMenu(); - fragmentView = inflater.inflate(R.layout.chat_layout, container, false); + fragmentView = new SizeNotifierRelativeLayout(getParentActivity()); + SizeNotifierRelativeLayout contentView = (SizeNotifierRelativeLayout) fragmentView; - View contentView = fragmentView.findViewById(R.id.chat_layout); - TextView emptyView = (TextView) fragmentView.findViewById(R.id.searchEmptyView); - emptyViewContainer = fragmentView.findViewById(R.id.empty_view); + contentView.setBackgroundImage(ApplicationLoader.getCachedWallpaper()); + isCustomTheme = ApplicationLoader.isCustomTheme(); + + emptyViewContainer = new FrameLayout(getParentActivity()); + 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(getParentActivity()); + 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)); - 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); + } + emptyView.setPadding(AndroidUtilities.dp(7), AndroidUtilities.dp(1), AndroidUtilities.dp(7), AndroidUtilities.dp(1)); + emptyView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + emptyView.setGravity(Gravity.CENTER); + emptyView.setTextColor(0xffffffff); + emptyView.setBackgroundResource(isCustomTheme ? R.drawable.system_black : R.drawable.system_blue); + 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 { - chatListView.setCacheColorHint(0); - try { - if (ApplicationLoader.cachedWallpaper != null) { - isCustomTheme = selectedBackground != 1000001; - ((SizeNotifierRelativeLayout) contentView).setBackgroundImage(ApplicationLoader.cachedWallpaper); + LinearLayout secretChatPlaceholder = new LinearLayout(getParentActivity()); + secretChatPlaceholder.setBackgroundResource(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(getParentActivity()); + 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 { - if (selectedBackground == 1000001) { - ((SizeNotifierRelativeLayout) contentView).setBackgroundImage(R.drawable.background_hd); - ApplicationLoader.cachedWallpaper = ((SizeNotifierRelativeLayout) contentView).getBackgroundImage(); - } 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; - } - } + secretViewStatusTextView.setText(LocaleController.formatString("EncryptedPlaceholderTitleOutgoing", R.string.EncryptedPlaceholderTitleOutgoing, currentUser.last_name)); } - } catch (Throwable e) { - contentView.setBackgroundColor(-2693905); - chatListView.setCacheColorHint(-2693905); - FileLog.e("tmessages", e); + } 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(getParentActivity()); + 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(getParentActivity()); + 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(getParentActivity()); + imageView.setImageResource(R.drawable.ic_lock_white); + + textView = new TextView(getParentActivity()); + 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); } } - 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 = new LayoutListView(getParentActivity()); + chatListView.setAdapter(chatAdapter = new ChatAdapter(getParentActivity())); + 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); - - final Rect scrollRect = new Rect(); - + 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) { @@ -1169,7 +1238,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not return false; } }); - chatListView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { @@ -1220,8 +1288,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not 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) { @@ -1264,22 +1333,133 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } }); - stickersListView = (RecyclerListView) fragmentView.findViewById(R.id.stickers_listview); + progressView = new FrameLayout(getParentActivity()); + progressView.setVisibility(View.INVISIBLE); + progressView.setBackgroundResource(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(getParentActivity()); + try { + progressBar.setIndeterminateDrawable(getParentActivity().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 (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() { + 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); + } + } + } + }); + + stickersPanel = new FrameLayout(getParentActivity()); + 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(getParentActivity()); 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); } - + 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(); } - - 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 @@ -1363,33 +1543,48 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not })); } - 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)); + ImageView imageView = new ImageView(getParentActivity()); + 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); - if (loading && messages.isEmpty()) { - progressView.setVisibility(View.VISIBLE); - chatListView.setEmptyView(null); - } else { - progressView.setVisibility(View.INVISIBLE); - chatListView.setEmptyView(emptyViewContainer); - } + bottomOverlay = new FrameLayout(getParentActivity()); + 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); - pagedownButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - scrollToLastMessage(); - } - }); + bottomOverlayText = new TextView(getParentActivity()); + 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(getParentActivity()); + 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) { @@ -1421,42 +1616,46 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } }); - updateBottomOverlay(); + bottomOverlayChatText = new TextView(getParentActivity()); + 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); - 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); + pagedownButton = new ImageView(getParentActivity()); + 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) { + scrollToLastMessage(); } - 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)); - } - } - - updateSecretStatus(); + if (loading && messages.isEmpty()) { + progressView.setVisibility(View.VISIBLE); + chatListView.setEmptyView(null); + } else { + progressView.setVisibility(View.INVISIBLE); + chatListView.setEmptyView(emptyViewContainer); } + + updateContactStatus(); + updateBottomOverlay(); + updateSecretStatus(); } else { ViewGroup parent = (ViewGroup)fragmentView.getParent(); if (parent != null) { @@ -1506,7 +1705,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not return; } if (show) { - if (pagedownButton.getVisibility() == View.GONE) { + if (pagedownButton.getVisibility() == View.INVISIBLE) { if (animated) { pagedownButton.setVisibility(View.VISIBLE); ViewProxy.setAlpha(pagedownButton, 0); @@ -1521,11 +1720,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not 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 +1735,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; @@ -1556,12 +1755,14 @@ 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(); + if (getParentActivity() != null) { AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); } + } checkActionBarMenu(); } @@ -1624,7 +1825,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (!(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) { return 0; } else { - return 6; + return 7; } } else { return -1; @@ -1658,8 +1859,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; @@ -1681,7 +1886,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (!(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) { return 0; } else { - return 6; + return 7; } } else if (messageObject.type == 10 || messageObject.type == 11) { if (messageObject.isSending()) { @@ -1757,7 +1962,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not int type = getMessageType(message); - if (type < 2 || type == 6) { + if (type < 2 || type == 7) { return; } addToSelectedMessages(message); @@ -1795,12 +2000,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() { @@ -1960,8 +2159,40 @@ 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); + } else if (photoEntry.path != null) { + SendMessagesHelper.prepareSendingPhoto(photoEntry.path, null, dialog_id); + } + } + }); Utilities.addMediaToGallery(currentPicturePath); - SendMessagesHelper.prepareSendingPhoto(currentPicturePath, null, dialog_id); currentPicturePath = null; } else if (requestCode == 1) { if (data == null || data.getData() == null) { @@ -2027,6 +2258,22 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not return; } SendMessagesHelper.prepareSendingDocument(tempPath, originalPath, null, null, dialog_id); + } else if (requestCode == 3) { + if (data == null || data.getData() == null) { + showAttachmentError(); + return; + } + String tempPath = Utilities.getPath(data.getData()); + String originalPath = tempPath; + if (tempPath == null) { + originalPath = data.toString(); + tempPath = MediaController.copyDocumentToCache(data.getData(), "file"); + } + if (tempPath == null) { + showAttachmentError(); + return; + } + SendMessagesHelper.prepareSendingDocument(tempPath, originalPath, null, null, dialog_id); } } } @@ -2828,7 +3075,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); } } @@ -2932,6 +3179,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not chatListView.setOnItemLongClickListener(onItemLongClickListener); chatListView.setOnItemClickListener(onItemClickListener); chatListView.setLongClickable(true); + updateColors(); + } + + private void updateColors(){ + actionBar.setBackgroundColor(AndroidUtilities.getIntDef("chatHeaderColor", AndroidUtilities.getIntColor("themeColor"))); + nameTextView.setTextColor(AndroidUtilities.getIntDef("chatNameColor", 0xffffffff)); + nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, AndroidUtilities.getIntDef("chatNameSize", 18)); + onlineTextView.setTextColor(AndroidUtilities.getIntDef("chatStatusColor", AndroidUtilities.getIntDarkerColor("themeColor",-0x40))); + onlineTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, AndroidUtilities.getIntDef("chatStatusSize", 14)); } @Override @@ -2946,10 +3202,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (menuItem != null) { menuItem.closeSubMenu(); } - chatActivityEnterView.hideEmojiPopup(); paused = true; NotificationsController.getInstance().setOpennedDialogId(0); - + if (chatActivityEnterView != null) { + chatActivityEnterView.hideEmojiPopup(); String text = chatActivityEnterView.getFieldText(); if (text != null) { SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); @@ -2957,8 +3213,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not editor.putString("dialog_" + dialog_id, text); editor.commit(); } - chatActivityEnterView.setFieldFocused(false); + } + MessagesController.getInstance().cancelTyping(dialog_id); if (currentEncryptedChat != null) { @@ -3071,7 +3328,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) { @@ -3085,7 +3342,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not items = new CharSequence[] {LocaleController.getString("Retry", R.string.Retry), LocaleController.getString("Delete", R.string.Delete)}; } else if (type == 1) { items = new CharSequence[] {LocaleController.getString("Delete", R.string.Delete)}; - } else if (type == 6) { + } 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)}; } else { if (currentEncryptedChat == null) { @@ -3098,6 +3355,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not 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)}; + } 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)}; } } else { if (type == 2) { @@ -3188,6 +3447,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } } else if (type == 6) { + if (i == 0) { + processSelectedOption(7); + } else if (i == 1) { + processSelectedOption(6); + } else if (i == 2) { + processSelectedOption(2); + } else if (i == 3) { + processSelectedOption(1); + } + } else if (type == 7) { if (i == 0) { processSelectedOption(0); } else if (i == 1) { @@ -3296,7 +3565,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,6 +3595,28 @@ 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); + } + } } selectedObject = null; } @@ -3374,7 +3665,6 @@ 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()) { @@ -3387,6 +3677,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not parentActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); } } + forwardSelectedMessages(did, param); } else { activity.finishFragment(); } @@ -3433,7 +3724,7 @@ 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); } @@ -3495,6 +3786,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) { @@ -3715,7 +4011,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 +4058,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); @@ -3816,7 +4112,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); } 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 ec5c9fd8..a98cf669 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarDrawable.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarDrawable.java @@ -12,7 +12,9 @@ import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.Rect; +import android.graphics.RectF; import android.graphics.drawable.Drawable; +import android.os.Build; import android.text.Layout; import android.text.StaticLayout; import android.text.TextPaint; @@ -51,6 +53,7 @@ public class AvatarDrawable extends Drawable { private boolean isProfile; private boolean drawBrodcast; private boolean drawPhoto; + private int radius; public AvatarDrawable() { super(); @@ -62,6 +65,7 @@ public class AvatarDrawable extends Drawable { broadcastDrawable = ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.broadcast_w); } + radius = 26; } public AvatarDrawable(TLRPC.User user) { @@ -155,6 +159,10 @@ public class AvatarDrawable extends Drawable { color = value; } + public void setRadius(int value) { + radius = value; + } + public void setInfo(int id, String firstName, String lastName, boolean isBroadcast) { if (isProfile) { color = arrColorsProfiles[getColorIndex(id)]; @@ -164,6 +172,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,8 +189,26 @@ public class AvatarDrawable extends Drawable { } lastch = lastName.substring(a, a + 1); } + 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 { @@ -213,6 +244,9 @@ public class AvatarDrawable extends Drawable { canvas.save(); canvas.translate(bounds.left, bounds.top); canvas.drawCircle(size / 2, size / 2, size / 2, paint); + //Rect rect = new Rect(0, 0, size, size); + //RectF rectF = new RectF(rect); + //canvas.drawRoundRect( rectF, AndroidUtilities.dp(26), AndroidUtilities.dp(26), paint); if (drawBrodcast && broadcastDrawable != null) { int x = (size - broadcastDrawable.getIntrinsicWidth()) / 2; 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 2b0150e5..0073edba 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,10 +26,13 @@ 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; @@ -68,13 +73,33 @@ 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) { + if (!photos.isEmpty()) { + Bitmap bitmap = ImageLoader.loadBitmap(photos.get(0), null, 800, 800, true); + processBitmap(bitmap); + } + } + + @Override + public void didSelectWebPhotos(ArrayList photos) { + + } + + @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 +127,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 7f30f265..ad0478de 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/BackupImageView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/BackupImageView.java @@ -68,6 +68,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); 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 55682770..82f30679 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java @@ -11,13 +11,16 @@ package org.telegram.ui.Components; import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; +import android.graphics.PorterDuff; import android.graphics.Rect; +import android.graphics.drawable.Drawable; 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; @@ -29,8 +32,8 @@ 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.TextView; @@ -39,22 +42,23 @@ import org.telegram.android.Emoji; import org.telegram.android.LocaleController; import org.telegram.android.MediaController; import org.telegram.android.MessagesController; +import org.telegram.android.NotificationCenter; import org.telegram.android.SendMessagesHelper; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; -import org.telegram.android.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.messenger.UserConfig; +import org.telegram.ui.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.messenger.ApplicationLoader; import java.lang.reflect.Field; -public class ChatActivityEnterView implements NotificationCenter.NotificationCenterDelegate, SizeNotifierRelativeLayout.SizeNotifierRelativeLayoutDelegate { +public class ChatActivityEnterView extends LinearLayout implements NotificationCenter.NotificationCenterDelegate, SizeNotifierRelativeLayout.SizeNotifierRelativeLayoutDelegate { public static interface ChatActivityEnterViewDelegate { public abstract void onMessageSend(); @@ -66,17 +70,18 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen } private EditText messsageEditText; - private ImageButton sendButton; + 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 PowerManager.WakeLock mWakeLock; private AnimatorSetProxy runningAnimation; private AnimatorSetProxy runningAnimation2; private ObjectAnimatorProxy runningAnimationAudio; @@ -94,11 +99,18 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen private boolean recordingAudio; private Activity parentActivity; + private BaseFragment parentFragment; private long dialog_id; private boolean ignoreTextChange; private ChatActivityEnterViewDelegate delegate; - public ChatActivityEnterView() { + public ChatActivityEnterView(Activity context, SizeNotifierRelativeLayout parent, BaseFragment fragment, boolean isChat) { + super(context); + setOrientation(HORIZONTAL); + 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 +120,32 @@ 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; - } - } - - 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); + addView(frameLayout); + LayoutParams layoutParams = (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; + layoutParams1.topMargin = AndroidUtilities.dp(2); + emojiButton.setLayoutParams(layoutParams1); emojiButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { @@ -173,6 +153,27 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen } }); + messsageEditText = new EditText(context); + messsageEditText.setHint(LocaleController.getString("TypeMessage", R.string.TypeMessage)); + messsageEditText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI); + messsageEditText.setInputType(messsageEditText.getInputType() | EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE); + messsageEditText.setSingleLine(false); + messsageEditText.setMaxLines(4); + messsageEditText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + messsageEditText.setGravity(Gravity.BOTTOM); + messsageEditText.setPadding(0, AndroidUtilities.dp(11), 0, AndroidUtilities.dp(12)); + messsageEditText.setBackgroundDrawable(null); + AndroidUtilities.clearCursorDrawable(messsageEditText); + messsageEditText.setTextColor(0xff000000); + messsageEditText.setHintTextColor(0xffb2b2b2); + frameLayout.addView(messsageEditText); + layoutParams1 = (FrameLayout.LayoutParams) messsageEditText.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); + messsageEditText.setLayoutParams(layoutParams1); messsageEditText.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View view, int i, KeyEvent keyEvent) { @@ -188,7 +189,6 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen return false; } }); - messsageEditText.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { @@ -197,7 +197,6 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen } } }); - messsageEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { @@ -213,18 +212,185 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen return false; } }); - - sendButton.setOnClickListener(new View.OnClickListener() { + messsageEditText.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 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++; + } } }); + 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; + layoutParams1.topMargin = AndroidUtilities.dp(2); + 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; + layoutParams1.topMargin = AndroidUtilities.dp(2); + recordPanel.setLayoutParams(layoutParams1); + + slideText = new LinearLayout(context); + slideText.setOrientation(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 = (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 = (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(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 = (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 = (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); + addView(frameLayout1); + layoutParams = (LayoutParams) frameLayout1.getLayoutParams(); + layoutParams.width = AndroidUtilities.dp(48); + layoutParams.height = AndroidUtilities.dp(48); + layoutParams.gravity = Gravity.BOTTOM; + layoutParams.topMargin = AndroidUtilities.dp(2); + frameLayout1.setLayoutParams(layoutParams); + + audioSendButton = new ImageView(context); + audioSendButton.setScaleType(ImageView.ScaleType.CENTER_INSIDE); + audioSendButton.setImageResource(R.drawable.mic_button_states); + audioSendButton.setBackgroundColor(0xffffffff); + 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); updateAudioRecordIntefrace(); @@ -279,60 +445,87 @@ 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); + 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); + + updateColors(); + } + + private void updateColors() { + Drawable send = parentActivity.getResources().getDrawable(R.drawable.ic_send_white); + send.setColorFilter(AndroidUtilities.getIntDef("chatSendIconColor", AndroidUtilities.getIntColor("themeColor")), PorterDuff.Mode.MULTIPLY); + sendButton.setImageDrawable(send); + messsageEditText.setTextColor(AndroidUtilities.getIntDef("chatEditTextColor",0xff000000)); + messsageEditText.setTextSize(AndroidUtilities.getIntDef("chatEditTextSize",18)); + int color = AndroidUtilities.getIntDef("chatEditTextBGColor", 0xffffffff); + setBackgroundColor(color); + audioSendButton.setBackgroundColor(0x00000000); + } + + 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; } private void sendMessage() { + 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; + } + } if (processSendingText(messsageEditText.getText().toString())) { messsageEditText.setText(""); lastTypingTimeSend = 0; @@ -699,7 +892,11 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen emojiButton.setImageResource(R.drawable.ic_msg_panel_smiles); } if (emojiPopup != null) { + try { emojiPopup.dismiss(); + } catch (Exception e) { + //don't promt + } } if (sizeNotifierRelativeLayout != null) { sizeNotifierRelativeLayout.post(new Runnable() { @@ -725,10 +922,6 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen this.delegate = delegate; } - public void setDialogId(long id) { - dialog_id = id; - } - public void setFieldText(String text) { if (messsageEditText == null) { return; 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 a288647f..d5441b70 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; @@ -27,9 +26,11 @@ public class ClippingImageView extends View { 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; @@ -48,7 +49,9 @@ public class ClippingImageView extends View { super(context); paint = new Paint(); paint.setFilterBitmap(true); - drawRect = new Rect(); + matrix = new Matrix(); + drawRect = new RectF(); + bitmapRect = new RectF(); } public int getClipBottom() { @@ -85,6 +88,7 @@ public class ClippingImageView extends View { drawListener.onDraw(); } canvas.save(); + if (needRadius) { roundRect.set(0, 0, getWidth(), getHeight()); shaderMatrix.reset(); @@ -92,10 +96,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 +154,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/ColorSelectorDialog.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ColorSelectorDialog.java new file mode 100644 index 00000000..33c3f8c9 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ColorSelectorDialog.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2011 Devmil (Michael Lamers) + * Mail: develmil@googlemail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.telegram.ui.Components; + +import android.app.Dialog; +import android.content.Context; +import android.graphics.Color; +import android.os.Bundle; +import android.view.Gravity; +import android.view.MotionEvent; +import android.view.View; +import android.widget.Button; + +import org.telegram.messenger.R; + +public class ColorSelectorDialog extends Dialog implements +ColorPickerView.OnColorChangedListener, +View.OnClickListener { + + public final static int BOTTOM = 1; + public final static int RIGHT = 2; + public final static int TOP = 3; + public final static int LEFT = 4; + public final static int CENTER = 0; + + private org.telegram.ui.Components.ColorSelectorView content; + private OnColorChangedListener listener; + private int initColor; + private int color; + private Button btnOld; + private Button btnNew; + private HistorySelectorView history; + private int side; + private int offset; + + private boolean alpha; + + public interface OnColorChangedListener + { + public void colorChanged(int color); + + //void onOk(OnColorChangedListener dialog, int color); + } + /* + private void onColorChanged() + { + if(listener != null) + listener.colorChanged(getColor()); + }*/ + + public int getColor() { + return color; + } + + public ColorSelectorDialog(Context context, OnColorChangedListener listener, int initColor, int side, int offset, boolean alpha) { + super(context, R.style.myBackgroundStyle); + this.listener = listener; + this.initColor = initColor; + this.side = side; + this.offset = offset; + this.alpha = alpha; + } + + public ColorSelectorDialog(Context context, int initColor, int side) { + super(context, R.style.myBackgroundStyle); + this.initColor = initColor; + this.side = side; + this.offset = offset; + } + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.colordialog); + + if (this.side == RIGHT) { + getWindow().setGravity(Gravity.RIGHT); + android.view.WindowManager.LayoutParams p = getWindow().getAttributes(); + p.x = offset; + getWindow().setAttributes(p); + } else if (this.side == BOTTOM ) { +// getWindow().setGravity(Gravity.BOTTOM); +// android.view.WindowManager.LayoutParams p = getWindow().getAttributes(); +// p.y = offset; +// getWindow().setAttributes(p); + } + + btnOld = (Button)findViewById(R.id.button_old); + btnOld.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + dismiss(); + } + }); + + btnNew = (Button)findViewById(R.id.button_new); + btnNew.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(listener != null) { + listener.colorChanged(color); + } + history.selectColor(color); + dismiss(); + } + }); + + content = (ColorSelectorView)findViewById(R.id.content); + content.setDialog(this); + content.setOnColorChangedListener(new ColorSelectorView.OnColorChangedListener() { + @Override + public void colorChanged(int color) { + colorChangedInternal(color); + } + }); + + history = (HistorySelectorView) findViewById(R.id.historyselector); + history.setOnColorChangedListener(new HistorySelectorView.OnColorChangedListener() { + @Override + public void colorChanged(int color) { + colorChangedInternal(color); + content.setColor(color); + } + }); + + + btnOld.setBackgroundColor(initColor); + btnOld.setTextColor(~initColor | 0xFF000000); + + content.setColor(initColor); + } + + private void colorChangedInternal(int color) + { + btnNew.setBackgroundColor(color); + btnNew.setTextColor(~color | 0xFF000000); //without alpha + color = adjustAlpha(color,this.alpha); + this.color = color; + } + + private int adjustAlpha(int color, boolean b) { + int alpha = (b) ? Color.alpha(color) : 0xff; + int red = Color.red(color); + int green = Color.green(color); + int blue = Color.blue(color); + return Color.argb(alpha, red, green, blue); + } + + public void setColor(int color) + { + content.setColor(color); + } + + + @Override + public boolean onTouchEvent(MotionEvent event) + { + + if(event.getAction() == MotionEvent.ACTION_OUTSIDE){ + System.out.println("TOuch outside the dialog ******************** "); + this.dismiss(); + } + return super.onTouchEvent(event); + } + + public void setOnColorChangedListener(OnColorChangedListener mlistener){ + listener = mlistener; + } + /* + @Override + public void onClick(View v) { + if (v.getId() == R.id.button_new) { + if (listener != null) { + listener.onColorChanged(color); + } + } + dismiss(); + }*/ + + public void onClick(View v) { + if(listener != null) { + listener.colorChanged(color); + } + history.selectColor(color); + dismiss(); + } + + @Override + public void onColorChanged(int color) { + if(listener != null) + listener.colorChanged(getColor()); + + } + +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ColorSelectorView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ColorSelectorView.java new file mode 100644 index 00000000..787ae17e --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ColorSelectorView.java @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2011 Devmil (Michael Lamers) + * Mail: develmil@googlemail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.telegram.ui.Components; + +import android.app.Dialog; +import android.content.Context; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.TabHost; +import android.widget.TabHost.TabContentFactory; +import android.widget.TabHost.TabSpec; +import android.widget.TextView; + +import org.telegram.messenger.R; + +public class ColorSelectorView extends LinearLayout { + private static final String HSV_TAG = "HSV"; + private static final String RGB_TAG = "RGB"; + private static final String HEX_TAG = "HEX"; + + private org.telegram.ui.Components.RgbSelectorView rgbSelector; + private org.telegram.ui.Components.HsvSelectorView hsvSelector; + private org.telegram.ui.Components.HexSelectorView hexSelector; + private TabHost tabs; + + private int maxHeight = 0; + private int maxWidth = 0; + + private int color; + + private OnColorChangedListener listener; + + public ColorSelectorView(Context context) { + super(context); + init(); + } + + public ColorSelectorView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public void setColor(int color) { + setColor(color, null); + } + + public void setDialog(Dialog d) { + hexSelector.setDialog(d); + } + + private void setColor(int color, View sender) { + if (this.color == color) + return; + this.color = color; + if (sender != hsvSelector) + hsvSelector.setColor(color); + if (sender != rgbSelector) + rgbSelector.setColor(color); + if (sender != hexSelector) + hexSelector.setColor(color); + onColorChanged(); + } + + public int getColor() { + return color; + } + + private void init() { + LayoutInflater inflater = (LayoutInflater) getContext() + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View contentView = inflater.inflate(R.layout.color_colorselectview, + null); + + addView(contentView, new LayoutParams(LayoutParams.FILL_PARENT, + LayoutParams.FILL_PARENT)); + + hsvSelector = new HsvSelectorView(getContext()); + hsvSelector.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, + LayoutParams.FILL_PARENT)); + hsvSelector + .setOnColorChangedListener(new HsvSelectorView.OnColorChangedListener() { + @Override + public void colorChanged(int color) { + setColor(color); + } + }); + rgbSelector = new RgbSelectorView(getContext()); + rgbSelector.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, + LayoutParams.FILL_PARENT)); + rgbSelector + .setOnColorChangedListener(new RgbSelectorView.OnColorChangedListener() { + @Override + public void colorChanged(int color) { + setColor(color); + } + }); + hexSelector = new HexSelectorView(getContext()); + hexSelector.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, + LayoutParams.FILL_PARENT)); + hexSelector + .setOnColorChangedListener(new HexSelectorView.OnColorChangedListener() { + @Override + public void colorChanged(int color) { + setColor(color); + } + }); + + + tabs = (TabHost) contentView + .findViewById(R.id.colorview_tabColors); + //tabs.getTabWidget().setDividerDrawable(new ColorDrawable(0xBDBDBD)); + + tabs.setup(); + ColorTabContentFactory factory = new ColorTabContentFactory(); + //TabSpec hsvTab = tabs.newTabSpec(HSV_TAG).setIndicator("HSV", getContext().getResources().getDrawable(R.drawable.hsv32)) + // .setContent(factory); + //View tabview = createTabView(tabs.getContext(), HEX_TAG); + TabSpec hsvTab = tabs.newTabSpec(HSV_TAG).setIndicator(createTabView(tabs.getContext(), HSV_TAG)) + .setContent(factory); + //TabSpec rgbTab = tabs.newTabSpec(RGB_TAG).setIndicator("RGB", getContext().getResources().getDrawable(R.drawable.rgb32)) + // .setContent(factory); + TabSpec rgbTab = tabs.newTabSpec(RGB_TAG).setIndicator(createTabView(tabs.getContext(), RGB_TAG)) + .setContent(factory); + //TabSpec hexTab = tabs.newTabSpec(HEX_TAG).setIndicator("HEX", getContext().getResources().getDrawable(R.drawable.hex32)) + //.setContent(factory); + + TabSpec hexTab = tabs.newTabSpec(HEX_TAG).setIndicator(createTabView(tabs.getContext(), HEX_TAG)) + .setContent(factory); + tabs.addTab(hsvTab); + tabs.addTab(rgbTab); + tabs.addTab(hexTab); + } + + private static View createTabView(final Context context, final String text) { + View view = LayoutInflater.from(context).inflate(R.layout.tabs_bg, null); + TextView tv = (TextView) view.findViewById(R.id.tabsText); + tv.setText(text); + return view; + } + + + class ColorTabContentFactory implements TabContentFactory { + @Override + public View createTabContent(String tag) { + if (HSV_TAG.equals(tag)) { + return hsvSelector; + } + if (RGB_TAG.equals(tag)) { + return rgbSelector; + } + if (HEX_TAG.equals(tag)) { + return hexSelector; + } + + return null; + } + } + + private void onColorChanged() + { + if(listener != null) + listener.colorChanged(getColor()); + } + + public void setOnColorChangedListener(OnColorChangedListener listener) + { + this.listener = listener; + } + + public interface OnColorChangedListener + { + public void colorChanged(int color); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + if(HSV_TAG.equals(tabs.getCurrentTabTag())) + { + maxHeight = getMeasuredHeight(); + maxWidth = getMeasuredWidth(); + } + setMeasuredDimension(maxWidth, maxHeight); + } +} 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 708e00f0..e3ea7753 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiView.java @@ -158,6 +158,13 @@ public class EmojiView extends LinearLayout { if (Emoji.data[0] == null || Emoji.data[0].length == 0) { pager.setCurrentItem(1); } + + updateColors(tabs); + } + + private void updateColors(PagerSlidingTabStrip tabs) { + setBackgroundColor(AndroidUtilities.getIntDef("chatEmojiViewBGColor",0xff222222)); + tabs.setIndicatorColor(AndroidUtilities.getIntDef("chatEmojiViewTabColor",AndroidUtilities.getIntDarkerColor("themeColor",0x15)));//0xff33b5e5 } private void saveRecents() { 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 00000000..b158dcac --- /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 { + public void onBecameForeground(); + public 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/HexSelectorView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/HexSelectorView.java new file mode 100644 index 00000000..dbac54ec --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/HexSelectorView.java @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2011 Devmil (Michael Lamers) + * Mail: develmil@googlemail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.telegram.ui.Components; + +import android.app.Dialog; +import android.content.Context; +import android.text.Editable; +import android.text.TextWatcher; +import android.util.AttributeSet; +import android.util.Log; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.WindowManager; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.TextView.OnEditorActionListener; + +import org.telegram.messenger.R; + +public class HexSelectorView extends LinearLayout { + + private EditText edit; + private int color; + private TextView txtError; + private Button btnSave; + private Dialog dialog; + + private OnColorChangedListener listener; + + public HexSelectorView(Context context) { + super(context); + init(); + } + + public HexSelectorView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + + public void setDialog(Dialog d) { + this.dialog = d; + } + + private void init() + { + LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View content = inflater.inflate(R.layout.color_hexview, null); + addView(content, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); + + txtError = (TextView)content.findViewById(R.id.color_hex_txtError); + + edit = (EditText)content.findViewById(R.id.color_hex_edit); + edit.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + if (hasFocus) { + if (dialog != null) dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); + } + } + }); + edit.setOnKeyListener(new OnKeyListener() { + @Override + public boolean onKey(View v, int keyCode, KeyEvent event) { + Log.d("HexSelector", "onKey: keyCode" + keyCode + " event: " + event); + validateColorInTextView(); + return false; + } + }); + edit.addTextChangedListener(new TextWatcher() { + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + @Override + public void beforeTextChanged(CharSequence s, int start, int count, + int after) { + } + @Override + public void afterTextChanged(Editable s) { + validateColorInTextView(); + } + }); + edit.setOnEditorActionListener(new OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_NULL) { + validateColorInTextView(); + InputMethodManager in = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + in.hideSoftInputFromWindow(edit.getApplicationWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); + return true; + } + return false; + } + }); + btnSave = (Button)content.findViewById(R.id.color_hex_btnSave); + btnSave.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + validateColorInTextView(); + } + }); + } + + public void validateColorInTextView() { + try + { + String hex = edit.getText().toString().toUpperCase().trim(); + Log.d("HexSelector", "String parsing: " + hex); +// String prefix = ""; + if(hex.startsWith("0x")) + { + hex = hex.substring(2); +// prefix = "0x"; + } + if(hex.startsWith("#")) + { + hex = hex.substring(1); +// prefix = "#"; + } + /* + if(hex.length() == 6) + { + hex = "FF" + hex; + }*/ + if(hex.length() != 8) + throw new Exception(); + color = (int) Long.parseLong(hex, 16); + txtError.setVisibility(GONE); + onColorChanged(); + } + catch(Exception e) + { + Log.d("HexSelector", "String parsing died"); + e.printStackTrace(); + txtError.setVisibility(VISIBLE); + } + } + + public int getColor() + { + return color; + } + + public void setColor(int color) + { + if(color == this.color)return; + this.color = color; + //if (!edit.hasFocus()) { + edit.setText(padLeft(Integer.toHexString(color).toUpperCase(), '0', 8)); + //} + txtError.setVisibility(GONE); + } + + private String padLeft(String string, char padChar, int size) + { + if(string.length() >= size) + return string; + StringBuilder result = new StringBuilder(); + for(int i=string.length(); i=0; i--) { + final int color = colors.getInt(i); + ViewGroup boxgroup = (ViewGroup)inflater.inflate(R.layout.color_historyview_item, colorlist, false); + TextView box = (TextView)boxgroup.findViewById(R.id.colorbox); + box.setBackgroundColor(color); + //box.setText("#"+Integer.toHexString(color)); + colorlist.addView(boxgroup ); + box.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + setColor(color); + onColorChanged(); + } + }); + } + } catch (Exception e) { + e.printStackTrace(); + } + + } + + public void readColors() { + SharedPreferences prefs = getContext().getSharedPreferences(PREFS_NAME, 0); + try { + colors = new JSONArray(prefs.getString(HISTORY, "")); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void selectColor(int color) { + try { + SharedPreferences prefs = getContext().getSharedPreferences(PREFS_NAME, 0); + if (colors == null) colors = new JSONArray(); + boolean dontadd = false; + for (int i=0; i < colors.length(); i++) { + if (colors.getInt(i) == color) { //reusing a recent color! shit. + dontadd = true; + colors = moveValueToFront(colors, i, color); + } + } + if (!dontadd) colors.put(color); + if (colors.length() > MAX_COLORS) { + JSONArray newcolors = new JSONArray(); + for (int i=colors.length()-MAX_COLORS; i < colors.length(); i++) { + newcolors.put(colors.getInt(i)); + } + colors = newcolors; + } + Editor edit = prefs.edit(); + edit.putString(HISTORY, colors.toString()); + edit.commit(); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + public JSONArray moveValueToFront(JSONArray array, int index, int color) throws JSONException { + LinkedList list = new LinkedList(); + for (int i=0; i < array.length(); i++) { + list.add(array.getInt(i)); + } + + list.add(color); + list.remove(index); + + array = new JSONArray(); + for (int i : list) { + array.put(i); + } + + return array; + } + + + private void setColor(int color) { + this.color = color; + } + + private int getColor() { + return color; + } + + private void onColorChanged() + { + if(listener != null) + listener.colorChanged(getColor()); + } + + public void setOnColorChangedListener(OnColorChangedListener listener) + { + this.listener = listener; + } + + public interface OnColorChangedListener + { + public void colorChanged(int color); + } + +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/HsvAlphaSelectorView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/HsvAlphaSelectorView.java new file mode 100644 index 00000000..4a6647ae --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/HsvAlphaSelectorView.java @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2011 Devmil (Michael Lamers) + * Mail: develmil@googlemail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.telegram.ui.Components; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.LinearGradient; +import android.graphics.Paint; +import android.graphics.Shader; +import android.graphics.Shader.TileMode; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.MotionEvent; +import android.widget.ImageView; +import android.widget.ImageView.ScaleType; +import android.widget.LinearLayout; + +import org.telegram.messenger.R; + +public class HsvAlphaSelectorView extends LinearLayout { + + private Drawable seekSelector; + private ImageView imgSeekSelector; + private int minOffset = 0; + private ImageView imgAlpha; + + private int alpha = 0; + private int color = Color.WHITE; + + private boolean dirty = true; + + private OnAlphaChangedListener listener; + + public HsvAlphaSelectorView(Context context) { + super(context); + init(); + } + + public HsvAlphaSelectorView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public void setMinContentOffset(int minOffset) { + this.minOffset = minOffset; + LayoutParams params = new LayoutParams(imgAlpha.getLayoutParams()); + params.setMargins(0, getOffset(), 0, getSelectorOffset()); + imgAlpha.setLayoutParams(params); + } + + private void init() { + seekSelector = getContext().getResources().getDrawable( + R.drawable.color_seekselector); + buildUI(); + } + + private void buildUI() { + setOrientation(LinearLayout.HORIZONTAL); + setGravity(Gravity.CENTER_HORIZONTAL); + setWillNotDraw(false); + + imgSeekSelector = new ImageView(getContext()); + imgSeekSelector.setImageDrawable(seekSelector); + LayoutParams paramsSeek = new LayoutParams(seekSelector + .getIntrinsicWidth(), seekSelector.getIntrinsicHeight()); + addView(imgSeekSelector, paramsSeek); + + imgAlpha = new ImageView(getContext()); + imgAlpha.setBackgroundDrawable(getContext().getResources().getDrawable(R.drawable.transparentbackrepeat)); + imgAlpha.setScaleType(ScaleType.FIT_XY); + LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, + LayoutParams.FILL_PARENT); + params.setMargins(0, getOffset(), 0, getSelectorOffset()); + addView(imgAlpha, params); + } + + @Override + protected void onDraw(Canvas canvas) { + if(dirty) + { + dirty = false; + setAlphaImage(); + } + super.onDraw(canvas); + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + super.onLayout(changed, l, t, r, b); + placeSelector(); + } + + private void placeSelector() + { + int alphaY = (int)(((float)(255 - alpha) / 255.f) * imgAlpha.getHeight()); + + int halfHeight = getSelectorOffset(); + int vertOffset = imgAlpha.getTop(); + + imgSeekSelector.layout(0, alphaY + vertOffset - halfHeight, imgSeekSelector.getWidth(), alphaY + vertOffset - halfHeight + imgSeekSelector.getHeight()); + } + + private int getSelectorOffset() + { + return (int) Math.ceil(imgSeekSelector.getHeight() / 2.f); + } + + private int getOffset() { + return Math.max(minOffset, (int) Math.ceil((double) seekSelector + .getIntrinsicHeight() / 2)); + } + + private boolean down = false; + + @Override + public boolean onTouchEvent(MotionEvent event) { + if(event.getAction() == MotionEvent.ACTION_DOWN) + { + down = true; + setPosition((int)event.getY()); + return true; + } + if(event.getAction() == MotionEvent.ACTION_UP) + { + down = false; + return true; + } + if(down && event.getAction() == MotionEvent.ACTION_MOVE) + { + setPosition((int)event.getY()); + return true; + } + return super.onTouchEvent(event); + } + + private void setPosition(int y) + { + int alphaY = y - imgAlpha.getTop(); + alpha = 255 - Math.min(255, Math.max(0, (int) (((float) alphaY / imgAlpha.getHeight()) * 255.f))); + + placeSelector(); + + onAlphaChanged(); + } + + public void setAlpha(int alpha) + { + if(this.alpha == alpha) + return; + this.alpha = alpha; + placeSelector(); + } + + public float getAlpha() + { + return alpha; + } + + public void setColor(int color) + { + if(this.color == color) + return; + this.color = color; + setAlphaImage(); + } + + private void setAlphaImage() + { + if(imgAlpha.getHeight() <= 0) + { + dirty = true; + invalidate(); + return; + } + Paint paint = new Paint(); + Shader shader; + Bitmap drawCache = null; + if (drawCache == null) { + + int colorFullAlpha = color | 0xFF000000; + int colorNoAlpha = color & 0x00FFFFFF; + + shader = new LinearGradient(0, imgAlpha.getHeight(), 0, 0, + colorNoAlpha, colorFullAlpha, TileMode.CLAMP); + + paint.setShader(shader); + + drawCache = Bitmap.createBitmap(imgAlpha.getWidth(), imgAlpha.getHeight(), + Bitmap.Config.ARGB_8888); + Canvas cacheCanvas = new Canvas(drawCache); + cacheCanvas.drawRect(0.f, 0.f, imgAlpha.getWidth(), imgAlpha.getHeight(), + paint); + + imgAlpha.setImageBitmap(drawCache); + } + } + + public void setOnAlphaChangedListener(OnAlphaChangedListener listener) + { + this.listener = listener; + } + + private void onAlphaChanged() + { + if(listener != null) + listener.alphaChanged(this, alpha); + } + + public interface OnAlphaChangedListener + { + public void alphaChanged(HsvAlphaSelectorView sender, int alpha); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/HsvColorValueView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/HsvColorValueView.java new file mode 100644 index 00000000..fa774ff1 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/HsvColorValueView.java @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2011 Devmil (Michael Lamers) + * Mail: develmil@googlemail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.telegram.ui.Components; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ComposeShader; +import android.graphics.LinearGradient; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.Shader; +import android.graphics.Shader.TileMode; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.widget.FrameLayout; +import android.widget.ImageView; + +import org.telegram.messenger.R; + +public class HsvColorValueView extends FrameLayout { + private Paint paint; + private Shader outerShader; + private Shader innerShader; + private float hue = 0; + + private Bitmap drawCache = null; + private Drawable colorSelector; + private ImageView selectorView; + + private int lastMeasuredSize = -1; + + private float saturation = 0; + private float value = 1; + + private OnSaturationOrValueChanged listener; + + public HsvColorValueView(Context context) { + super(context); + init(); + } + + public HsvColorValueView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public HsvColorValueView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + private void init() { + colorSelector = getContext().getResources().getDrawable( + R.drawable.color_selector); + selectorView = new ImageView(getContext()); + selectorView.setImageDrawable(colorSelector); + addView(selectorView, new LayoutParams(colorSelector.getIntrinsicWidth(), colorSelector.getIntrinsicHeight())); + setWillNotDraw(false); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + lastMeasuredSize = Math.min(getMeasuredHeight(), getMeasuredWidth()); + setMeasuredDimension(lastMeasuredSize, lastMeasuredSize); + if (drawCache != null + && drawCache.getHeight() != getBackgroundSize(lastMeasuredSize)) + { + drawCache.recycle(); + drawCache = null; + } + } + + public int getBackgroundOffset() { + return (int) Math + .ceil((double) (colorSelector.getIntrinsicHeight() / 2.f)); + } + + private int getBackgroundSize(int availableSize) { + int offset = getBackgroundOffset(); + return availableSize - 2 * offset; + } + + public int getBackgroundSize() + { + ensureCache(); + if (drawCache != null) return drawCache.getHeight(); + return 0; + } + + private void ensureCache() + { + if (paint == null) { + paint = new Paint(); + } + int baseSize = getHeight(); + if(baseSize <= 0) + baseSize = getMeasuredHeight(); + if(baseSize <= 0) + baseSize = lastMeasuredSize; + int backgroundSize = getBackgroundSize(baseSize); + if (drawCache == null && backgroundSize > 0) { + outerShader = new LinearGradient(0.f, 0.f, 0.f, backgroundSize, + 0xffffffff, 0xff000000, TileMode.CLAMP); + + float[] tmp00 = new float[3]; + tmp00[1] = tmp00[2] = 1.f; + tmp00[0] = hue; + int rgb = Color.HSVToColor(tmp00); + + innerShader = new LinearGradient(0.f, 0.f, backgroundSize, 0.f, + 0xffffffff, rgb, TileMode.CLAMP); + ComposeShader shader = new ComposeShader(outerShader, innerShader, + PorterDuff.Mode.MULTIPLY); + + paint.setShader(shader); + + drawCache = Bitmap.createBitmap(backgroundSize, backgroundSize, + Bitmap.Config.ARGB_8888); + Canvas cacheCanvas = new Canvas(drawCache); + cacheCanvas.drawRect(0.f, 0.f, backgroundSize, backgroundSize, + paint); + } + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + ensureCache(); + canvas.drawBitmap(drawCache, getBackgroundOffset(), getBackgroundOffset(), paint); + } + + private boolean down = false; + + @Override + public boolean onTouchEvent(MotionEvent event) { + if(event.getAction() == MotionEvent.ACTION_DOWN) + { + down = true; + return true; + } + if(event.getAction() == MotionEvent.ACTION_UP) + { + down = false; + setSelectorPosition((int)event.getX() - getBackgroundOffset(), (int)event.getY() - getBackgroundOffset(), true); + return true; + } + if(event.getAction() == MotionEvent.ACTION_MOVE && down) + { + setSelectorPosition((int)event.getX() - getBackgroundOffset(), (int)event.getY() - getBackgroundOffset(), false); + return true; + } + return super.onTouchEvent(event); + } + + private void setSatAndValueFromPos(int x, int y, boolean up) + { + int offset = getBackgroundOffset(); + + saturation = ((x - offset) / (float)getBackgroundSize()); + value = 1.f - ((y - offset) / (float)getBackgroundSize()); + + onSaturationOrValueChanged(up); + } + + private void setSelectorPosition(int x, int y, boolean up) + { + setSatAndValueFromPos(x, y, up); + placeSelector(); + } + + private void placeSelector() + { + int offset = getBackgroundOffset(); + int halfSize = (int) Math.ceil(selectorView.getHeight() / 2.f); + + int x = (int)(getBackgroundSize() * saturation); + int y = (int)(getBackgroundSize() * (1.f - value)); + + int left = Math.max(0, Math.min(getBackgroundSize(), x)) + offset - halfSize; + int top = Math.max(0, Math.min(getBackgroundSize(), y)) + offset - halfSize; + + selectorView.layout(left, top, left + selectorView.getWidth(), top + selectorView.getHeight()); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, + int bottom) { + super.onLayout(changed, left, top, right, bottom); + placeSelector(); + } + + private void setPosFromSatAndValue() + { + if(drawCache != null) + placeSelector(); + } + + public void setHue(float hue) { + this.hue = hue; + drawCache = null; + invalidate(); + } + + public void setSaturation(float sat) + { + saturation = sat; + setPosFromSatAndValue(); + } + + public float getSaturation() + { + return saturation; + } + + public void setValue(float value) + { + this.value = value; + setPosFromSatAndValue(); + } + + public float getValue() + { + return value; + } + + public void setOnSaturationOrValueChanged(OnSaturationOrValueChanged listener) + { + this.listener = listener; + } + + private void onSaturationOrValueChanged(boolean up) + { + if(listener != null) + listener.saturationOrValueChanged(this, saturation, value, up); + } + + public interface OnSaturationOrValueChanged + { + public void saturationOrValueChanged(HsvColorValueView sender, float saturation, float value, boolean up); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/HsvHueSelectorView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/HsvHueSelectorView.java new file mode 100644 index 00000000..29c124b7 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/HsvHueSelectorView.java @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2011 Devmil (Michael Lamers) + * Mail: develmil@googlemail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.telegram.ui.Components; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.MotionEvent; +import android.widget.ImageView; +import android.widget.ImageView.ScaleType; +import android.widget.LinearLayout; + +import org.telegram.messenger.R; + +public class HsvHueSelectorView extends LinearLayout { + + private Drawable seekSelector; + private ImageView imgSeekSelector; + private int minOffset = 0; + private ImageView imgHue; + + private float hue = 0; + + private OnHueChangedListener listener; + + public HsvHueSelectorView(Context context) { + super(context); + init(); + } + + public HsvHueSelectorView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public void setMinContentOffset(int minOffset) { + this.minOffset = minOffset; + LayoutParams params = new LayoutParams(imgHue.getLayoutParams()); + params.setMargins(0, getOffset(), 0, getSelectorOffset()); + imgHue.setLayoutParams(params); + } + + private void init() { + seekSelector = getContext().getResources().getDrawable( + R.drawable.color_seekselector); + buildUI(); + } + + private void buildUI() { + setOrientation(LinearLayout.HORIZONTAL); + setGravity(Gravity.CENTER_HORIZONTAL); + + imgSeekSelector = new ImageView(getContext()); + imgSeekSelector.setImageDrawable(seekSelector); + LayoutParams paramsSeek = new LayoutParams(seekSelector + .getIntrinsicWidth(), seekSelector.getIntrinsicHeight()); + addView(imgSeekSelector, paramsSeek); + + imgHue = new ImageView(getContext()); + imgHue.setImageDrawable(getContext().getResources().getDrawable( + R.drawable.color_hue)); + imgHue.setScaleType(ScaleType.FIT_XY); + LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, + LayoutParams.FILL_PARENT); + params.setMargins(0, getOffset(), 0, getSelectorOffset()); + addView(imgHue, params); + + } + + private int getOffset() { + return Math.max(minOffset, getSelectorOffset()); + } + + private int getSelectorOffset() { + return (int) Math.ceil(seekSelector.getIntrinsicHeight() / 2.f); + } + + private boolean down = false; + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + down = true; + setPosition((int) event.getY()); + return true; + } + if (event.getAction() == MotionEvent.ACTION_UP) { + down = false; + return true; + } + if (down && event.getAction() == MotionEvent.ACTION_MOVE) { + setPosition((int) event.getY()); + return true; + } + return super.onTouchEvent(event); + } + + private void setPosition(int y) { + int hueY = y - getOffset(); + + hue = Math.max(Math.min( + 360.f - (((float) hueY / imgHue.getHeight()) * 360.f), 360.f), + 0.f); + + placeSelector(); + + onHueChanged(); + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + super.onLayout(changed, l, t, r, b); + placeSelector(); + } + + private void placeSelector() { + int hueY = (int) ((((360.f - hue) / 360.f)) * imgHue.getHeight()); + imgSeekSelector.layout(0, hueY + getOffset() - getSelectorOffset(), imgSeekSelector + .getWidth(), hueY + getOffset() - getSelectorOffset() + imgSeekSelector.getHeight()); + } + + public void setHue(float hue) { + if(this.hue == hue) + return; + this.hue = hue; + placeSelector(); + } + + public float getHue() { + return hue; + } + + public void setOnHueChangedListener(OnHueChangedListener listener) { + this.listener = listener; + } + + private void onHueChanged() { + if (listener != null) + listener.hueChanged(this, hue); + } + + public interface OnHueChangedListener { + public void hueChanged(HsvHueSelectorView sender, float hue); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/HsvSelectorView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/HsvSelectorView.java new file mode 100644 index 00000000..916699d7 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/HsvSelectorView.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2011 Devmil (Michael Lamers) + * Mail: develmil@googlemail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.telegram.ui.Components; + +import android.content.Context; +import android.graphics.Color; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.LinearLayout; + +import org.telegram.messenger.R; + +public class HsvSelectorView extends LinearLayout { + + private HsvAlphaSelectorView alphaSelector; + private HsvHueSelectorView hueSelector; + private HsvColorValueView hsvColorValueView; + + private int color; + + private OnColorChangedListener listener; + + public HsvSelectorView(Context context) { + super(context); + init(); + } + + public HsvSelectorView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + private void init() { + buildUI(); + } + + private void buildUI() { + LayoutInflater inflater = (LayoutInflater) getContext() + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View hsvView = inflater.inflate(R.layout.color_hsvview, null); + this.addView(hsvView, new LayoutParams(LayoutParams.FILL_PARENT, + LayoutParams.FILL_PARENT)); + + alphaSelector = (HsvAlphaSelectorView) hsvView + .findViewById(R.id.color_hsv_alpha); + hsvColorValueView = (HsvColorValueView) hsvView + .findViewById(R.id.color_hsv_value); + hueSelector = (HsvHueSelectorView) hsvView.findViewById(R.id.color_hsv_hue); + + alphaSelector.setOnAlphaChangedListener(new HsvAlphaSelectorView.OnAlphaChangedListener() { + @Override + public void alphaChanged(HsvAlphaSelectorView sender, int alpha) { + internalSetColor(getCurrentColor(true), true); + } + }); + + hsvColorValueView.setOnSaturationOrValueChanged(new HsvColorValueView.OnSaturationOrValueChanged() { + @Override + public void saturationOrValueChanged(HsvColorValueView sender, + float saturation, float value, boolean up) { + alphaSelector.setColor(getCurrentColor(false)); + internalSetColor(getCurrentColor(true), up); + } + }); + hueSelector.setOnHueChangedListener(new HsvHueSelectorView.OnHueChangedListener() { + @Override + public void hueChanged(HsvHueSelectorView sender, float hue) { + hsvColorValueView.setHue(hue); + alphaSelector.setColor(getCurrentColor(false)); + internalSetColor(getCurrentColor(true), true); + } + }); + + setColor(Color.BLACK); + } + + private int getCurrentColor(boolean includeAlpha) + { + float[] hsv = new float[3]; + hsv[0] = hueSelector.getHue(); + hsv[1] = hsvColorValueView.getSaturation(); + hsv[2] = hsvColorValueView.getValue(); + int alpha = includeAlpha ? (int)alphaSelector.getAlpha() : 255; + return Color.HSVToColor(alpha, hsv); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + LayoutParams paramsAlpha = new LayoutParams(alphaSelector.getLayoutParams()); + LayoutParams paramsHue = new LayoutParams(hueSelector.getLayoutParams()); + + paramsAlpha.height = hsvColorValueView.getHeight(); + paramsHue.height = hsvColorValueView.getHeight(); + + hueSelector.setMinContentOffset(hsvColorValueView.getBackgroundOffset()); + alphaSelector.setMinContentOffset(hsvColorValueView.getBackgroundOffset()); + + alphaSelector.setLayoutParams(paramsAlpha); + hueSelector.setLayoutParams(paramsHue); + + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + public int getColor() + { + return color; + } + + private void internalSetColor(int color, boolean fire) + { + this.color = color; + if(fire) + onColorChanged(); + } + + public void setColor(int color) + { + int alpha = Color.alpha(color); + alphaSelector.setAlpha(alpha); + int colorWithoutAlpha = color | 0xFF000000; + float[] hsv = new float[3]; + Color.colorToHSV(colorWithoutAlpha, hsv); + hueSelector.setHue(hsv[0]); + hsvColorValueView.setHue(hsv[0]); + hsvColorValueView.setSaturation(hsv[1]); + hsvColorValueView.setValue(hsv[2]); + alphaSelector.setColor(color); + internalSetColor(color, this.color != color); + } + + private void onColorChanged() + { + if(listener != null) + listener.colorChanged(color); + } + + public void setOnColorChangedListener(OnColorChangedListener listener) + { + this.listener = listener; + } + + public interface OnColorChangedListener + { + public void colorChanged(int color); + } + +} 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 00000000..aedc5bcd --- /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 a0c15f5f..5f272dd6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/NumberPicker.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/NumberPicker.java @@ -22,6 +22,7 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Align; +import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.text.TextUtils; import android.util.AttributeSet; @@ -39,6 +40,7 @@ import android.widget.LinearLayout; import android.widget.TextView; import org.telegram.messenger.R; +import org.telegram.android.AndroidUtilities; import java.util.Locale; @@ -73,7 +75,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; @@ -123,7 +125,9 @@ public class NumberPicker extends LinearLayout { private void init() { mSolidColor = 0; - mSelectionDivider = getResources().getDrawable(R.drawable.numberpicker_selection_divider); + //mSelectionDivider = getResources().getDrawable(R.drawable.numberpicker_selection_divider); + mSelectionDivider = getResources().getDrawable(R.drawable.numberpicker_selection_divider_white); + mSelectionDivider.setColorFilter(AndroidUtilities.getIntColor("themeColor"), PorterDuff.Mode.MULTIPLY); mSelectionDividerHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, UNSCALED_DEFAULT_SELECTION_DIVIDER_HEIGHT, getResources().getDisplayMetrics()); mSelectionDividersDistance = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, UNSCALED_DEFAULT_SELECTION_DIVIDERS_DISTANCE, getResources().getDisplayMetrics()); 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 00000000..caa51062 --- /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 static interface PasscodeViewDelegate { + public abstract 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 ((Integer) 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 00000000..4bd9ba57 --- /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 static interface PhotoCropViewDelegate { + public abstract 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 00000000..1d7687df --- /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 abstract interface PhotoEditorSeekBarDelegate { + public 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/PhotoFilterLinearBlurControl.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoFilterLinearBlurControl.java new file mode 100644 index 00000000..86e4505f --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoFilterLinearBlurControl.java @@ -0,0 +1,417 @@ +/* + * 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.PointF; +import android.graphics.RectF; +import android.util.SizeF; +import android.widget.FrameLayout; + +public class PhotoFilterLinearBlurControl extends FrameLayout { + + private final static float LinearBlurInsetProximity = 20; + private final static float LinearBlurMinimumFalloff = 0.1f; + private final static float LinearBlurMinimumDifference = 0.02f; + private final static float LinearBlurViewCenterInset = 30.0f; + private final static float LinearBlurViewRadiusInset = 30.0f; + + private enum LinearBlurViewActiveControl { + TGLinearBlurViewActiveControlNone, + TGLinearBlurViewActiveControlCenter, + TGLinearBlurViewActiveControlInnerRadius, + TGLinearBlurViewActiveControlOuterRadius, + TGLinearBlurViewActiveControlWholeArea, + TGLinearBlurViewActiveControlRotation + } + + private LinearBlurViewActiveControl activeControl; + private PointF startCenterPoint = new PointF(); + private PointF startDistance = new PointF(); + private PointF startRadius = new PointF(); + private boolean isTracking; + private SizeF actualAreaSize; + private PointF centerPoint; + private float falloff; + private float size; + private float angle; + + //@property (nonatomic, copy) void (^valueChanged)(CGPoint centerPoint, CGFloat falloff, CGFloat size, CGFloat angle); + //@property (nonatomic, copy) void(^interactionEnded)(void); + //UILongPressGestureRecognizer *_pressGestureRecognizer; + //UIPanGestureRecognizer *_panGestureRecognizer; + //UIPinchGestureRecognizer *_pinchGestureRecognizer; + + public PhotoFilterLinearBlurControl(Context context) { + super(context); + + setWillNotDraw(false); + + centerPoint = new PointF(0.5f, 0.5f); + falloff = 0.15f; + size = 0.35f; + + /*_pressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handlePress:)]; + _pressGestureRecognizer.delegate = self; + _pressGestureRecognizer.minimumPressDuration = 0.1f; + [self addGestureRecognizer:_pressGestureRecognizer]; + + _panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; + _panGestureRecognizer.delegate = self; + [self addGestureRecognizer:_panGestureRecognizer]; + + _pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)]; + _pinchGestureRecognizer.delegate = self; + [self addGestureRecognizer:_pinchGestureRecognizer];*/ + } + + + private void handlePress() { + /*switch (gestureRecognizer.state) { + case UIGestureRecognizerStateBegan: + [self setSelected:true animated:true]; + break; + + case UIGestureRecognizerStateEnded: + case UIGestureRecognizerStateCancelled: + case UIGestureRecognizerStateFailed: + [self setSelected:false animated:true]; + break; + + default: + break; + }*/ + } + + private void handlePan() { + /*CGPoint location = [gestureRecognizer locationInView:self]; + CGPoint centerPoint = [self _actualCenterPoint]; + CGPoint delta = CGPointMake(location.x - centerPoint.x, location.y - centerPoint.y); + CGFloat radialDistance = sqrtf(delta.x * delta.x + delta.y * delta.y); + CGFloat distance = fabsf(delta.x * cosf(self.angle + (CGFloat)M_PI_2) + delta.y * sinf(self.angle + (CGFloat)M_PI_2)); + + CGFloat shorterSide = (self.actualAreaSize.width > self.actualAreaSize.height) ? self.actualAreaSize.height : self.actualAreaSize.width; + + CGFloat innerRadius = shorterSide * self.falloff; + CGFloat outerRadius = shorterSide * self.size; + + switch (gestureRecognizer.state) { + case UIGestureRecognizerStateBegan: + { + bool close = fabsf(outerRadius - innerRadius) < TGLinearBlurInsetProximity; + CGFloat innerRadiusOuterInset = close ? 0 : TGLinearBlurViewRadiusInset; + CGFloat outerRadiusInnerInset = close ? 0 : TGLinearBlurViewRadiusInset; + + if (radialDistance < TGLinearBlurViewCenterInset) + { + _activeControl = TGLinearBlurViewActiveControlCenter; + _startCenterPoint = centerPoint; + } + else if (distance > innerRadius - TGLinearBlurViewRadiusInset && distance < innerRadius + innerRadiusOuterInset) + { + _activeControl = TGLinearBlurViewActiveControlInnerRadius; + _startDistance = distance; + _startRadius = innerRadius; + } + else if (distance > outerRadius - outerRadiusInnerInset && distance < outerRadius + TGLinearBlurViewRadiusInset) + { + _activeControl = TGLinearBlurViewActiveControlOuterRadius; + _startDistance = distance; + _startRadius = outerRadius; + } + else if (distance <= innerRadius - TGLinearBlurViewRadiusInset || distance >= outerRadius + TGLinearBlurViewRadiusInset) + { + _activeControl = TGLinearBlurViewActiveControlRotation; + } + + [self setSelected:true animated:true]; + } + break; + + case UIGestureRecognizerStateChanged: + { + switch (_activeControl) + { + case TGLinearBlurViewActiveControlCenter: + { + CGPoint translation = [gestureRecognizer translationInView:self]; + + CGRect actualArea = CGRectMake((self.frame.size.width - self.actualAreaSize.width) / 2, (self.frame.size.height - self.actualAreaSize.height) / 2, self.actualAreaSize.width, self.actualAreaSize.height); + + CGPoint newPoint = CGPointMake(MAX(CGRectGetMinX(actualArea), MIN(CGRectGetMaxX(actualArea), _startCenterPoint.x + translation.x)), + MAX(CGRectGetMinY(actualArea), MIN(CGRectGetMaxY(actualArea), _startCenterPoint.y + translation.y))); + + CGPoint offset = CGPointMake(0, (self.actualAreaSize.width - self.actualAreaSize.height) / 2); + CGPoint actualPoint = CGPointMake(newPoint.x - actualArea.origin.x, newPoint.y - actualArea.origin.y); + self.centerPoint = CGPointMake((actualPoint.x + offset.x) / self.actualAreaSize.width, (actualPoint.y + offset.y) / self.actualAreaSize.width); + } + break; + + case TGLinearBlurViewActiveControlInnerRadius: + { + CGFloat delta = distance - _startDistance; + self.falloff = MIN(MAX(TGLinearBlurMinimumFalloff, (_startRadius + delta) / shorterSide), self.size - TGLinearBlurMinimumDifference); + } + break; + + case TGLinearBlurViewActiveControlOuterRadius: + { + CGFloat delta = distance - _startDistance; + self.size = MAX(self.falloff + TGLinearBlurMinimumDifference, (_startRadius + delta) / shorterSide); + } + break; + + case TGLinearBlurViewActiveControlRotation: + { + CGPoint translation = [gestureRecognizer translationInView:self]; + bool clockwise = false; + + bool right = location.x > centerPoint.x; + bool bottom = location.y > centerPoint.y; + + if (!right && !bottom) + { + if (fabsf(translation.y) > fabsf(translation.x)) + { + if (translation.y < 0) + clockwise = true; + } + else + { + if (translation.x > 0) + clockwise = true; + } + } + else if (right && !bottom) + { + if (fabsf(translation.y) > fabsf(translation.x)) + { + if (translation.y > 0) + clockwise = true; + } + else + { + if (translation.x > 0) + clockwise = true; + } + } + else if (right && bottom) + { + if (fabsf(translation.y) > fabsf(translation.x)) + { + if (translation.y > 0) + clockwise = true; + } + else + { + if (translation.x < 0) + clockwise = true; + } + } + else + { + if (fabsf(translation.y) > fabsf(translation.x)) + { + if (translation.y < 0) + clockwise = true; + } + else + { + if (translation.x < 0) + clockwise = true; + } + } + + CGFloat delta = sqrtf(translation.x * translation.x + translation.y * translation.y); + + CGFloat angleInDegrees = TGRadiansToDegrees(_angle); + CGFloat newAngleInDegrees = angleInDegrees + delta * (clockwise * 2 - 1) / (CGFloat)M_PI / 1.15f; + + _angle = TGDegreesToRadians(newAngleInDegrees); + + [gestureRecognizer setTranslation:CGPointZero inView:self]; + } + break; + + default: + break; + } + + [self setNeedsDisplay]; + + if (self.valueChanged != nil) + self.valueChanged(self.centerPoint, self.falloff, self.size, self.angle); + } + break; + + case UIGestureRecognizerStateEnded: + case UIGestureRecognizerStateCancelled: + case UIGestureRecognizerStateFailed: + { + _activeControl = TGLinearBlurViewActiveControlNone; + + [self setSelected:false animated:true]; + + if (self.interactionEnded != nil) + self.interactionEnded(); + } + break; + + default: + break; + }*/ + } + + private void handlePinch() { + /*switch (gestureRecognizer.state) { + case UIGestureRecognizerStateBegan: { + _activeControl = TGLinearBlurViewActiveControlWholeArea; + [self setSelected:true animated:true]; + } + case UIGestureRecognizerStateChanged: { + CGFloat scale = gestureRecognizer.scale; + + self.falloff = MAX(TGLinearBlurMinimumFalloff, self.falloff * scale); + self.size = MAX(self.falloff + TGLinearBlurMinimumDifference, self.size * scale); + + gestureRecognizer.scale = 1.0f; + + [self setNeedsDisplay]; + + if (self.valueChanged != nil) + self.valueChanged(self.centerPoint, self.falloff, self.size, self.angle); + } + break; + + case UIGestureRecognizerStateEnded: { + _activeControl = TGLinearBlurViewActiveControlNone; + [self setSelected:false animated:true]; + } + break; + + case UIGestureRecognizerStateCancelled: + case UIGestureRecognizerStateFailed: { + _activeControl = TGLinearBlurViewActiveControlNone; + [self setSelected:false animated:true]; + } + break; + + default: + break; + }*/ + } + + /*- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer + { + if (gestureRecognizer == _pressGestureRecognizer || gestureRecognizer == _panGestureRecognizer) + { + CGPoint location = [gestureRecognizer locationInView:self]; + CGPoint centerPoint = [self _actualCenterPoint]; + CGPoint delta = CGPointMake(location.x - centerPoint.x, location.y - centerPoint.y); + CGFloat radialDistance = sqrtf(delta.x * delta.x + delta.y * delta.y); + CGFloat distance = fabsf(delta.x * cosf(self.angle + (CGFloat)M_PI_2) + delta.y * sinf(self.angle + (CGFloat)M_PI_2)); + + CGFloat innerRadius = [self _actualInnerRadius]; + CGFloat outerRadius = [self _actualOuterRadius]; + + bool close = fabsf(outerRadius - innerRadius) < TGLinearBlurInsetProximity; + CGFloat innerRadiusOuterInset = close ? 0 : TGLinearBlurViewRadiusInset; + CGFloat outerRadiusInnerInset = close ? 0 : TGLinearBlurViewRadiusInset; + + if (radialDistance < TGLinearBlurViewCenterInset && gestureRecognizer == _panGestureRecognizer) + return true; + else if (distance > innerRadius - TGLinearBlurViewRadiusInset && distance < innerRadius + innerRadiusOuterInset) + return true; + else if (distance > outerRadius - outerRadiusInnerInset && distance < outerRadius + TGLinearBlurViewRadiusInset) + return true; + else if ((distance <= innerRadius - TGLinearBlurViewRadiusInset) || distance >= outerRadius + TGLinearBlurViewRadiusInset) + return true; + + return false; + } + + return true; + } + + - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer + { + if (gestureRecognizer == _pressGestureRecognizer || otherGestureRecognizer == _pressGestureRecognizer) + return true; + + return false; + }*/ + + 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; + }*/ + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + /*PointF centerPoint = getActualCenterPoint(); + float innerRadius = getActualInnerRadius(); + float outerRadius = getActualOuterRadius(); + + CGContextTranslateCTM(context, centerPoint.x, centerPoint.y); + CGContextRotateCTM(context, self.angle); + + CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); + CGContextSetShadowWithColor(context, CGSizeZero, 2.5f, [UIColor colorWithWhite:0.0f alpha:0.3f].CGColor); + + float space = 6.0f; + float length = 12.0f; + float thickness = 1.5f; + for (int i = 0; i < 30; i++) { + CGContextAddRect(context, CGRectMake(i * (length + space), -innerRadius, length, thickness)); + CGContextAddRect(context, CGRectMake(-i * (length + space) - space - length, -innerRadius, length, thickness)); + + CGContextAddRect(context, CGRectMake(i * (length + space), innerRadius, length, thickness)); + CGContextAddRect(context, CGRectMake(-i * (length + space) - space - length, innerRadius, length, thickness)); + } + + length = 6.0f; + thickness = 1.5f; + for (int i = 0; i < 64; i++) { + CGContextAddRect(context, CGRectMake(i * (length + space), -outerRadius, length, thickness)); + CGContextAddRect(context, CGRectMake(-i * (length + space) - space - length, -outerRadius, length, thickness)); + + CGContextAddRect(context, CGRectMake(i * (length + space), outerRadius, length, thickness)); + CGContextAddRect(context, CGRectMake(-i * (length + space) - space - length, outerRadius, length, thickness)); + } + + CGContextFillPath(context); + + CGContextFillEllipseInRect(context, CGRectMake(-16 / 2, - 16 / 2, 16, 16));*/ + } + + private PointF getActualCenterPoint() { + RectF actualArea = new RectF((getWidth() - actualAreaSize.getWidth()) / 2, (getHeight() - actualAreaSize.getHeight()) / 2, actualAreaSize.getWidth(), actualAreaSize.getHeight()); + PointF offset = new PointF(0, (actualAreaSize.getWidth() - actualAreaSize.getHeight()) / 2); + return new PointF(actualArea.left - offset.x + centerPoint.x * actualAreaSize.getWidth(), actualArea.top - offset.y + centerPoint.y * actualAreaSize.getWidth()); + } + + private float getActualInnerRadius() { + float shorterSide = (actualAreaSize.getWidth() > actualAreaSize.getHeight()) ? actualAreaSize.getHeight() : actualAreaSize.getWidth(); + return shorterSide * falloff; + } + + private float getActualOuterRadius() { + float shorterSide = (actualAreaSize.getWidth() > actualAreaSize.getHeight()) ? actualAreaSize.getHeight() : actualAreaSize.getWidth(); + return shorterSide * size; + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoFilterRadialBlurControl.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoFilterRadialBlurControl.java new file mode 100644 index 00000000..1dd438fb --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoFilterRadialBlurControl.java @@ -0,0 +1,12 @@ +/* + * 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 PhotoFilterRadialBlurControl { +} 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 00000000..2037f1d1 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoFilterView.java @@ -0,0 +1,1658 @@ +/* + * 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 = -1; + private int sharpenTool = 9; + + 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 ToolsAdapter toolsAdapter; + private PhotoEditorSeekBar valueSeekBar; + private FrameLayout toolsView; + private FrameLayout editView; + private TextView paramTextView; + private TextView valueTextView; + private TextView doneTextView; + private TextView cancelTextView; + private TextureView textureView; + private EGLThread eglThread; + private RecyclerListView recyclerListView; + + 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 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 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[2]; + private int[] renderFrameBuffer = new int[2]; + 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 final static int PGPhotoEnhanceHistogramBins = 256; + private final static int PGPhotoEnhanceSegments = 4; + + 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, 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 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); + //enhance draw + 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); + + //sharpen draw + 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); + + //custom params draw + 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); + + //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[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[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(2, renderFrameBuffer, 0); + GLES20.glGenTextures(2, 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); + } + + 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() { + 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(); + } + } + + @Override + public void onSurfaceTextureSizeChanged(SurfaceTexture surface, final int width, final int height) { + if (eglThread != null) { + eglThread.setSurfaceTextureSize(width, height); + eglThread.requestRender(); + eglThread.postRunnable(new Runnable() { + @Override + public void run() { + eglThread.requestRender(); + } + }); + } + } + + @Override + public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { + if (eglThread != null) { + eglThread.shutdown(); + eglThread = null; + } + return true; + } + + @Override + public void onSurfaceTextureUpdated(SurfaceTexture surface) { + + } + }); + + 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) { + + } + 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; + } + if (eglThread != null) { + eglThread.requestRender(); + } + 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(); + } + }); + + 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(); + } + } + }); + editView.addView(valueSeekBar); + layoutParams = (FrameLayout.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); + } + + 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); + } + } + + public void setShowOriginal(boolean value) { + if (showOriginal == value) { + return; + } + showOriginal = value; + if (eglThread != null) { + eglThread.requestRender(); + } + } + + public void switchToOrFromEditMode() { + final View viewFrom; + final View viewTo; + if (editView.getVisibility() == GONE) { + viewFrom = toolsView; + viewTo = editView; + } else { + selectedTool = -1; + viewFrom = editView; + viewTo = toolsView; + } + + 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); + + 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 10; + } + + @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) { + ((PhotoEditToolCell) holder.itemView).setIconAndTextAndValue(R.drawable.tool_details, LocaleController.getString("Blur", R.string.Blur), 0); //TODO add 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 97fc7e75..fb6db0a0 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/RgbSelectorView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/RgbSelectorView.java new file mode 100644 index 00000000..933dd7f1 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/RgbSelectorView.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2011 Devmil (Michael Lamers) + * Mail: develmil@googlemail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.telegram.ui.Components; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.SeekBar; + +import org.telegram.messenger.R; + +public class RgbSelectorView extends LinearLayout { + + private SeekBar seekRed; + private SeekBar seekGreen; + private SeekBar seekBlue; + private SeekBar seekAlpha; + private ImageView imgPreview; + private OnColorChangedListener listener; + + public RgbSelectorView(Context context) { + super(context); + init(); + } + + public RgbSelectorView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + private void init() + { + LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View rgbView = inflater.inflate(R.layout.color_rgbview, null); + + addView(rgbView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); + + SeekBar.OnSeekBarChangeListener listener = new SeekBar.OnSeekBarChangeListener() { + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + } + + @Override + public void onProgressChanged(SeekBar seekBar, int progress, + boolean fromUser) { + setPreviewImage(); + onColorChanged(); + } + }; + + seekRed = (SeekBar)rgbView.findViewById(R.id.color_rgb_seekRed); + seekRed.setOnSeekBarChangeListener(listener); + seekGreen = (SeekBar)rgbView.findViewById(R.id.color_rgb_seekGreen); + seekGreen.setOnSeekBarChangeListener(listener); + seekBlue = (SeekBar)rgbView.findViewById(R.id.color_rgb_seekBlue); + seekBlue.setOnSeekBarChangeListener(listener); + seekAlpha = (SeekBar)rgbView.findViewById(R.id.color_rgb_seekAlpha); + seekAlpha.setOnSeekBarChangeListener(listener); + imgPreview = (ImageView)rgbView.findViewById(R.id.color_rgb_imgpreview); + + setColor(Color.BLACK); + } + + private void setPreviewImage() + { + Bitmap preview = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); + preview.setPixel(0, 0, getColor()); + + imgPreview.setImageBitmap(preview); + } + + public int getColor() + { + return Color.argb(seekAlpha.getProgress(), seekRed.getProgress(), seekGreen.getProgress(), seekBlue.getProgress()); + } + + public void setColor(int color) + { + seekAlpha.setProgress(Color.alpha(color)); + seekRed.setProgress(Color.red(color)); + seekGreen.setProgress(Color.green(color)); + seekBlue.setProgress(Color.blue(color)); + setPreviewImage(); + } + + private void onColorChanged() + { + if(listener != null) + listener.colorChanged(getColor()); + } + + public void setOnColorChangedListener(OnColorChangedListener listener) + { + this.listener = listener; + } + + public interface OnColorChangedListener + { + public void colorChanged(int color); + } +} 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 0d833ee4..a9d4daf7 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/SeekBarPreference.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SeekBarPreference.java new file mode 100644 index 00000000..bd684d67 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SeekBarPreference.java @@ -0,0 +1,264 @@ +package org.telegram.ui.Components; + +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.TypedArray; +import android.preference.Preference; +import android.util.AttributeSet; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewParent; +import android.widget.RelativeLayout; +import android.widget.SeekBar; +import android.widget.SeekBar.OnSeekBarChangeListener; +import android.widget.TextView; + +import org.telegram.messenger.R; + +public class SeekBarPreference extends Preference implements OnSeekBarChangeListener { + + private static final String THEME_PREFS = "theme"; + + private final String TAG = getClass().getName(); + + private static final String ANDROIDNS="http://schemas.android.com/apk/res/android"; + private static final String ROBOBUNNYNS="http://robobunny.com"; + private static final int DEFAULT_VALUE = 50; + + private int mMaxValue = 100; + private int mMinValue = 0; + private int mInterval = 1; + private int mCurrentValue; + private String mUnitsLeft = ""; + private String mUnitsRight = ""; + private SeekBar mSeekBar; + + private TextView mStatusText; + + private RelativeLayout layout = null; + + public SeekBarPreference(Context context, AttributeSet attrs) { + super(context, attrs); + initPreference(context, attrs); + } + + public SeekBarPreference(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + initPreference(context, attrs); + } + + private void initPreference(Context context, AttributeSet attrs) { + setValuesFromXml(attrs); + mSeekBar = new SeekBar(context, attrs); + mSeekBar.setMax(mMaxValue - mMinValue); + mSeekBar.setOnSeekBarChangeListener(this); + } + + private void setValuesFromXml(AttributeSet attrs) { + mMaxValue = attrs.getAttributeIntValue(ANDROIDNS, "max", 100); + mMinValue = attrs.getAttributeIntValue(ROBOBUNNYNS, "min", 0); + + mUnitsLeft = getAttributeStringValue(attrs, ROBOBUNNYNS, "unitsLeft", ""); + String units = getAttributeStringValue(attrs, ROBOBUNNYNS, "units", ""); + mUnitsRight = getAttributeStringValue(attrs, ROBOBUNNYNS, "unitsRight", units); + + try { + String newInterval = attrs.getAttributeValue(ROBOBUNNYNS, "interval"); + if(newInterval != null) + mInterval = Integer.parseInt(newInterval); + } + catch(Exception e) { + Log.e(TAG, "Invalid interval value", e); + } + + } + + private String getAttributeStringValue(AttributeSet attrs, String namespace, String name, String defaultValue) { + String value = attrs.getAttributeValue(namespace, name); + if(value == null) + value = defaultValue; + + return value; + } + + @Override + protected View onCreateView(ViewGroup parent){ + + try { + LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + + layout = (RelativeLayout)mInflater.inflate(R.layout.seek_bar_preference, parent, false); + } + catch(Exception e) + { + Log.e(TAG, "Error creating seek bar preference", e); + } + + return layout; + + } + + @Override + public void onBindView(View view) { + try{ + super.onBindView(view); + + try + { + // move our seekbar to the new view we've been given + ViewParent oldContainer = mSeekBar.getParent(); + ViewGroup newContainer = (ViewGroup) view.findViewById(R.id.seekBarPrefBarContainer); + + if (oldContainer != newContainer) { + // remove the seekbar from the old view + if (oldContainer != null) { + ((ViewGroup) oldContainer).removeView(mSeekBar); + } + // remove the existing seekbar (there may not be one) and add ours + newContainer.removeAllViews(); + /* + newContainer.addView(mSeekBar, ViewGroup.LayoutParams.FILL_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT);*/ + newContainer.addView(mSeekBar, ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT); + } + } + + catch(Exception ex) { + Log.e(TAG, "Error binding view: " + ex.toString()); + } + + if(!this.layout.isEnabled() && this.layout != null){ + this.mSeekBar.setEnabled(false); + } + + updateView(view); + }catch(NullPointerException ex) { + return; + } + } + + + /** + * Update a SeekBarPreference view with our current state + * @param view + */ + protected void updateView(View view) { + + try { + RelativeLayout layout = (RelativeLayout)view; + + mStatusText = (TextView)layout.findViewById(R.id.seekBarPrefValue); + mStatusText.setText(String.valueOf(mCurrentValue)); + mStatusText.setMinimumWidth(30); + + mSeekBar.setProgress(mCurrentValue - mMinValue); + + TextView unitsRight = (TextView)layout.findViewById(R.id.seekBarPrefUnitsRight); + unitsRight.setText(mUnitsRight); + + TextView unitsLeft = (TextView)layout.findViewById(R.id.seekBarPrefUnitsLeft); + unitsLeft.setText(mUnitsLeft); + + } + catch(Exception e) { + Log.e(TAG, "Error updating seek bar preference", e); + } + + } + + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + try{ + int newValue = progress + mMinValue; + + if(newValue > mMaxValue) + newValue = mMaxValue; + else if(newValue < mMinValue) + newValue = mMinValue; + else if(mInterval != 1 && newValue % mInterval != 0) + newValue = Math.round(((float) newValue) / mInterval)*mInterval; + + // change rejected, revert to the previous value + if(!callChangeListener(newValue)){ + seekBar.setProgress(mCurrentValue - mMinValue); + return; + } + + // change accepted, store it + mCurrentValue = newValue; + mStatusText.setText(String.valueOf(newValue)); + persistInt(newValue); + }catch(NullPointerException ex) { + return; + } + } + + ///Added by Sergio 04/12/2012 + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + mSeekBar.setEnabled(enabled); + } + @Override + public void onDependencyChanged(Preference dependency, boolean disableDependent) + { + super.onDependencyChanged(dependency, disableDependent); + + // /see if it has been initialized + if (this.layout != null) + { + this.mSeekBar.setEnabled(!disableDependent); + this.mStatusText.setEnabled(!disableDependent); + } + } + /// + + @Override + public void onStartTrackingTouch(SeekBar seekBar) {} + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + notifyChanged(); + if(mUnitsRight.contains("r") || mUnitsRight.contains("Mb")){ + SharedPreferences sharedPref = mSeekBar.getContext().getSharedPreferences(THEME_PREFS, 0); + SharedPreferences.Editor e = sharedPref.edit(); + e.putBoolean("need_reboot",true); + e.commit(); + } + } + + + @Override + protected Object onGetDefaultValue(TypedArray ta, int index){ + + int defaultValue = ta.getInt(index, DEFAULT_VALUE); + return defaultValue; + + } + + @Override + protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { + + if(restoreValue) { + mCurrentValue = getPersistedInt(mCurrentValue); + } + else { + int temp = 0; + try { + temp = (Integer)defaultValue; + } + catch(Exception ex) { + Log.e(TAG, "Invalid default value: " + defaultValue.toString()); + } + + persistInt(temp); + mCurrentValue = temp; + } + + } + +} + 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 214f320f..61e68589 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayout.java @@ -11,6 +11,7 @@ package org.telegram.ui.Components; 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,7 +23,8 @@ 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); @@ -56,6 +58,10 @@ public class SizeNotifierRelativeLayout extends RelativeLayout { return backgroundDrawable; } + public void setDelegate(SizeNotifierRelativeLayoutDelegate delegate) { + this.delegate = delegate; + } + @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); @@ -63,7 +69,7 @@ public class SizeNotifierRelativeLayout extends RelativeLayout { View rootView = this.getRootView(); int usableViewHeight = rootView.getHeight() - AndroidUtilities.statusBarHeight - AndroidUtilities.getViewInset(rootView); this.getWindowVisibleDisplayFrame(rect); - int keyboardHeight = usableViewHeight - (rect.bottom - rect.top); + keyboardHeight = usableViewHeight - (rect.bottom - rect.top); delegate.onSizeChanged(keyboardHeight); } } @@ -71,15 +77,20 @@ public class SizeNotifierRelativeLayout extends RelativeLayout { @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/Switch.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/Switch.java index f1a940f4..524dfd0c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/Switch.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/Switch.java @@ -418,10 +418,12 @@ public class Switch extends CompoundButton { } if (mTrackDrawable != null) { - mTrackDrawable.setColorFilter(new PorterDuffColorFilter(checked ? 0xffa0d6fa : 0xffc7c7c7, PorterDuff.Mode.MULTIPLY)); + //mTrackDrawable.setColorFilter(new PorterDuffColorFilter(checked ? 0xffa0d6fa : 0xffc7c7c7, PorterDuff.Mode.MULTIPLY)); + mTrackDrawable.setColorFilter(new PorterDuffColorFilter(checked ? AndroidUtilities.getIntAlphaColor("themeColor",0.5f) : 0xffc7c7c7, PorterDuff.Mode.MULTIPLY)); } if (mThumbDrawable != null) { - mThumbDrawable.setColorFilter(new PorterDuffColorFilter(checked ? 0xff45abef : 0xffededed, PorterDuff.Mode.MULTIPLY)); + //mThumbDrawable.setColorFilter(new PorterDuffColorFilter(checked ? 0xff45abef : 0xffededed, PorterDuff.Mode.MULTIPLY)); + mThumbDrawable.setColorFilter(new PorterDuffColorFilter(checked ? AndroidUtilities.getIntColor("themeColor") : 0xffededed, PorterDuff.Mode.MULTIPLY)); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java index 19e7c29d..b41814bd 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java @@ -78,7 +78,7 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); actionBar.setAllowOverlayTitle(true); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java index 97dbea03..b21c4294 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java @@ -11,10 +11,13 @@ package org.telegram.ui; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; 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; @@ -47,7 +50,7 @@ import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.Components.SectionsListView; +import org.telegram.ui.Components.LetterSectionsListView; import java.util.ArrayList; import java.util.HashMap; @@ -56,7 +59,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter private BaseSectionsAdapter listViewAdapter; private TextView emptyTextView; - private SectionsListView listView; + private LetterSectionsListView listView; private ContactsSearchAdapter searchListViewAdapter; private boolean searchWas; @@ -87,6 +90,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,11 +113,12 @@ 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) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { searching = false; searchWas = false; @@ -124,8 +129,12 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter 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)); } @@ -151,7 +160,6 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter 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) { @@ -211,7 +219,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter emptyTextView = new TextView(getParentActivity()); emptyTextView.setTextColor(0xff808080); - emptyTextView.setTextSize(20); + emptyTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); emptyTextView.setGravity(Gravity.CENTER); emptyTextView.setText(LocaleController.getString("NoContacts", R.string.NoContacts)); emptyTextLayout.addView(emptyTextView); @@ -229,7 +237,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter layoutParams1.weight = 0.5f; frameLayout.setLayoutParams(layoutParams1); - listView = new SectionsListView(getParentActivity()); + listView = new LetterSectionsListView(getParentActivity()); listView.setEmptyView(emptyTextLayout); listView.setVerticalScrollBarEnabled(false); listView.setDivider(null); @@ -289,24 +297,30 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, ContactsController.getInstance().getInviteText()); - getParentActivity().startActivity(Intent.createChooser(intent, "")); + getParentActivity().startActivityForResult(Intent.createChooser(intent, LocaleController.getString("InviteFriends", R.string.InviteFriends)), 500); } catch (Exception e) { FileLog.e("tmessages", e); } } } else { if (row == 0) { - presentFragment(new GroupCreateActivity(), true); + if (!MessagesController.isFeatureEnabled("chat_create", ContactsActivity.this)) { + return; + } + presentFragment(new GroupCreateActivity(), false); } 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); + 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), true); + presentFragment(new GroupCreateActivity(args), false); } } } else { @@ -348,7 +362,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter 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); + getParentActivity().startActivityForResult(intent, 500); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -436,6 +450,12 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter if (listViewAdapter != null) { listViewAdapter.notifyDataSetChanged(); } + updateColors(); + } + + private void updateColors(){ + actionBar.setBackgroundColor(AndroidUtilities.getIntDef("contactsHeaderColor", AndroidUtilities.getIntColor("themeColor"))); + } @Override @@ -462,8 +482,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 e1607f58..3b48f411 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java @@ -32,7 +32,7 @@ import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.Components.SectionsListView; +import org.telegram.ui.Components.LetterSectionsListView; public class CountrySelectActivity extends BaseFragment { @@ -40,7 +40,7 @@ public class CountrySelectActivity extends BaseFragment { public abstract void didSelectCountry(String name); } - private SectionsListView listView; + private LetterSectionsListView listView; private TextView emptyTextView; private CountryAdapter listViewAdapter; private CountrySearchAdapter searchListViewAdapter; @@ -61,7 +61,7 @@ public class CountrySelectActivity extends BaseFragment { } @Override - public View createView(LayoutInflater inflater, final ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); actionBar.setAllowOverlayTitle(true); @@ -88,7 +88,6 @@ public class CountrySelectActivity extends BaseFragment { 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); @@ -165,7 +164,7 @@ public class CountrySelectActivity extends BaseFragment { layoutParams1.weight = 0.5f; frameLayout.setLayoutParams(layoutParams1); - listView = new SectionsListView(getParentActivity()); + listView = new LetterSectionsListView(getParentActivity()); listView.setEmptyView(emptyTextLayout); listView.setVerticalScrollBarEnabled(false); listView.setDivider(null); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java index 177c9ae0..e0bc4227 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java @@ -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<>(); @@ -73,6 +73,8 @@ public class DocumentSelectActivity extends BaseFragment { private final static int done = 3; + public String fileFilter = "*"; + private class ListItem { int icon; String title; @@ -122,10 +124,11 @@ public class DocumentSelectActivity extends BaseFragment { FileLog.e("tmessages", e); } super.onFragmentDestroy(); + fileFilter = "*"; } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (!receiverRegistered) { receiverRegistered = true; IntentFilter filter = new IntentFilter(); @@ -194,7 +197,7 @@ public class DocumentSelectActivity extends BaseFragment { 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); + fragmentView = inflater.inflate(R.layout.document_select_layout, null, false); listAdapter = new ListAdapter(getParentActivity()); emptyView = (TextView)fragmentView.findViewById(R.id.searchEmptyView); emptyView.setOnTouchListener(new View.OnTouchListener() { @@ -452,6 +455,9 @@ public class DocumentSelectActivity extends BaseFragment { item.subtitle = LocaleController.getString("Folder", R.string.Folder); } else { String fname = file.getName(); + if (!fileFilter.equals("*") && !fname.toLowerCase().endsWith(fileFilter)) { + continue; + } String[] sp = fname.split("\\."); item.ext = sp.length > 1 ? sp[sp.length - 1] : "?"; item.subtitle = Utilities.formatFileSize(file.length()); @@ -573,7 +579,7 @@ public class DocumentSelectActivity extends BaseFragment { fs.subtitle = LocaleController.getString("GalleryInfo", R.string.GalleryInfo); fs.icon = R.drawable.ic_storage_gallery; fs.file = null; - items.add(fs); + if(fileFilter.equals("*"))items.add(fs); AndroidUtilities.clearDrawableAnimation(listView); scrolling = true; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java index 07dc0a60..02ee365c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java @@ -54,7 +54,7 @@ import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.Cells.UserCell; -import org.telegram.ui.Components.SectionsListView; +import org.telegram.ui.Components.LetterSectionsListView; import java.util.ArrayList; import java.util.HashMap; @@ -93,7 +93,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen private ContactsAdapter listViewAdapter; private TextView emptyTextView; private EditText userSelectEditText; - private SectionsListView listView; + private LetterSectionsListView listView; private ContactsSearchAdapter searchListViewAdapter; private GroupCreateActivityDelegate delegate; @@ -141,7 +141,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { searching = false; searchWas = false; @@ -307,7 +307,6 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen 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) { @@ -357,7 +356,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen layoutParams.weight = 0.5f; frameLayout2.setLayoutParams(layoutParams); - listView = new SectionsListView(getParentActivity()); + listView = new LetterSectionsListView(getParentActivity()); listView.setEmptyView(emptyTextLayout); listView.setVerticalScrollBarEnabled(false); listView.setDivider(null); @@ -434,7 +433,6 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen 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) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java index ab3fd663..c5974180 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,7 +138,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); actionBar.setAllowOverlayTitle(true); @@ -402,6 +402,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati FileLog.e("tmessages", e); } } + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); Bundle args2 = new Bundle(); args2.putInt("chat_id", (Integer)args[0]); presentFragment(new ChatActivity(args2), true); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/IdenticonActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/IdenticonActivity.java index a4a59199..88ae3a8b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/IdenticonActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/IdenticonActivity.java @@ -45,7 +45,7 @@ public class IdenticonActivity extends BaseFragment { } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); actionBar.setAllowOverlayTitle(true); @@ -60,7 +60,7 @@ public class IdenticonActivity extends BaseFragment { } }); - fragmentView = inflater.inflate(R.layout.identicon_layout, container, false); + 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); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/IntroActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/IntroActivity.java index 983d43cd..c9a62d8b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/IntroActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/IntroActivity.java @@ -272,7 +272,8 @@ public class IntroActivity extends Activity { for (int a = 0; a < count; a++) { View child = bottomPages.getChildAt(a); if (a == position) { - child.setBackgroundColor(0xff2ca5e0); + //child.setBackgroundColor(0xff2ca5e0); + child.setBackgroundColor(0xff58BCD5); } else { child.setBackgroundColor(0xffbbbbbb); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java index 0744b1ab..e73f5857 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java @@ -52,7 +52,7 @@ public class LanguageSelectActivity extends BaseFragment { public ArrayList searchResult; @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { searching = false; searchWas = false; @@ -285,7 +285,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 daefea9c..79cd7c00 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LastSeenActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LastSeenActivity.java @@ -99,7 +99,7 @@ public class LastSeenActivity extends BaseFragment implements NotificationCenter } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); actionBar.setAllowOverlayTitle(true); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LastSeenUsersActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LastSeenUsersActivity.java index 4f8347b1..a80b2d77 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LastSeenUsersActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LastSeenUsersActivity.java @@ -75,7 +75,7 @@ public class LastSeenUsersActivity extends BaseFragment implements NotificationC } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); actionBar.setAllowOverlayTitle(true); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java index ea916e6a..23faa576 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java @@ -59,11 +59,13 @@ 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; import java.io.InputStreamReader; import java.util.ArrayList; +import java.util.Locale; import java.util.Map; public class LaunchActivity extends Activity implements ActionBarLayout.ActionBarLayoutDelegate, NotificationCenter.NotificationCenterDelegate, MessagesActivity.MessagesActivityDelegate { @@ -89,9 +91,19 @@ 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; + + private int themingRow = 7; + private int communityRow = 9; + @Override protected void onCreate(Bundle savedInstanceState) { ApplicationLoader.postInitApplication(); @@ -122,6 +134,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); @@ -254,6 +270,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 +283,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)); @@ -271,23 +293,36 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } else if (position == 6) { presentFragment(new ContactsActivity(null)); drawerLayoutContainer.closeDrawer(false); - } else if (position == 7) { + } else if (position == themingRow) { + /* try { 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); - } + }*/ + presentFragment(new ThemingActivity()); drawerLayoutContainer.closeDrawer(false); } else if (position == 8) { presentFragment(new SettingsActivity()); drawerLayoutContainer.closeDrawer(false); - } else if (position == 9) { + } else if (position == 10) { 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); + } + drawerLayoutContainer.closeDrawer(false); + } else if (position == communityRow) { + try { + String link = "https://plus.google.com/communities/106927015963860485525";//https://plus.google.com/101839105638971401281/posts" + if(Locale.getDefault().getLanguage().contains("es")){ + link = "https://plus.google.com/communities/111922519175849600270"; + } + startActivityForResult(new Intent(Intent.ACTION_VIEW, Uri.parse(link)), 500); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -301,6 +336,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(); @@ -309,6 +353,11 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa 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()) { @@ -385,11 +434,48 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa drawerLayoutContainer.setAllowOpenDrawer(allowOpen); } - handleIntent(getIntent(), false, savedInstanceState != null); + handleIntent(getIntent(), false, savedInstanceState != null, false); needLayout(); } - private void handleIntent(Intent intent, boolean isNew, boolean restore) { + 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); + 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); + actionBarLayout.showLastFragment(); + if (AndroidUtilities.isTablet()) { + layersActionBarLayout.showLastFragment(); + rightActionBarLayout.showLastFragment(); + } + } + }); + } + + 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; Integer push_user_id = 0; @@ -407,7 +493,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa documentsUrisArray = null; contactsToSend = null; - if (UserConfig.isClientActivated() && !UserConfig.isWaitingForPasswordEnter() && (intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) { + if (UserConfig.isClientActivated() && !UserConfig.isWaitingForPasswordEnter() && (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; @@ -483,6 +569,12 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } } } + try { + bufferedReader.close(); + stream.close(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } if (name != null && !phones.isEmpty()) { contactsToSend = new ArrayList<>(); for (String phone : phones) { @@ -765,7 +857,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa actionBarLayout.presentFragment(fragment, removeLast, true, true); pushOpened = true; if (PhotoViewer.getInstance().isVisible()) { - PhotoViewer.getInstance().closePhoto(false); + PhotoViewer.getInstance().closePhoto(false, true); } if (AndroidUtilities.isTablet()) { @@ -782,6 +874,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } pushOpened = true; } + if (!pushOpened && !isNew) { if (AndroidUtilities.isTablet()) { if (!UserConfig.isClientActivated() && !UserConfig.isWaitingForPasswordEnter()) { @@ -824,12 +917,15 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } 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 @@ -910,11 +1006,20 @@ 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 +1065,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 +1091,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 +1123,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 +1147,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa @Override protected void onPause() { super.onPause(); + onPasscodePause(); actionBarLayout.onPause(); if (AndroidUtilities.isTablet()) { rightActionBarLayout.onPause(); @@ -1053,11 +1168,16 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa @Override protected void onResume() { super.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); ApplicationLoader.mainInterfacePaused = false; @@ -1100,6 +1220,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]; @@ -1132,6 +1253,62 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa actionBarLayout.presentFragment(new AccountPasswordActivity(1), true); drawerLayoutContainer.setAllowOpenDrawer(false); } + } else if (id == NotificationCenter.screenStateChanged) { + if (!ApplicationLoader.mainInterfacePaused) { + if (!ApplicationLoader.isScreenOn) { + onPasscodePause(); + } else { + onPasscodeResume(); + } + } + } 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 +1368,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 +1427,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 +1447,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); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java index 195ebf11..c3efdf40 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java @@ -91,7 +91,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); actionBar.setAllowOverlayTitle(true); @@ -139,9 +139,9 @@ public class LocationActivity extends BaseFragment implements NotificationCenter 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); + fragmentView = inflater.inflate(R.layout.location_view_layout, null, false); } else { - fragmentView = inflater.inflate(R.layout.location_attach_layout, container, false); + fragmentView = inflater.inflate(R.layout.location_attach_layout, null, false); } avatarImageView = (BackupImageView)fragmentView.findViewById(R.id.location_avatar_view); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java index 2814c8b3..a090bf74 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java @@ -58,6 +58,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; @@ -103,7 +104,7 @@ public class LoginActivity extends BaseFragment { } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setTitle(LocaleController.getString("AppName", R.string.AppName)); @@ -685,6 +686,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); } @@ -829,9 +831,6 @@ public class LoginActivity extends BaseFragment { 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) { @@ -898,7 +897,6 @@ public class LoginActivity extends BaseFragment { private String phoneHash; private String requestPhone; - private String registered; private EditText codeField; private TextView confirmTextView; private TextView timeText; @@ -985,7 +983,8 @@ public class LoginActivity extends BaseFragment { problemText.setVisibility(time < 1000 ? VISIBLE : GONE); problemText.setGravity(Gravity.LEFT); problemText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); - problemText.setTextColor(0xff4d83b3); + //problemText.setTextColor(0xff4d83b3); + problemText.setTextColor(AndroidUtilities.getIntColor("themeColor")); problemText.setLineSpacing(AndroidUtilities.dp(2), 1.0f); problemText.setPadding(0, AndroidUtilities.dp(2), 0, AndroidUtilities.dp(12)); addView(problemText); @@ -1026,7 +1025,8 @@ public class LoginActivity extends BaseFragment { TextView wrongNumber = new TextView(context); wrongNumber.setGravity(Gravity.LEFT | Gravity.CENTER_HORIZONTAL); - wrongNumber.setTextColor(0xff4d83b3); + //wrongNumber.setTextColor(0xff4d83b3); + wrongNumber.setTextColor(AndroidUtilities.getIntColor("themeColor")); wrongNumber.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); wrongNumber.setLineSpacing(AndroidUtilities.dp(2), 1.0f); wrongNumber.setPadding(0, AndroidUtilities.dp(24), 0, 0); @@ -1067,7 +1067,6 @@ public class LoginActivity extends BaseFragment { String phone = params.getString("phone"); requestPhone = params.getString("phoneFormated"); phoneHash = params.getString("phoneHash"); - registered = params.getString("registered"); time = params.getInt("calltime"); if (phone == null) { @@ -1238,10 +1237,16 @@ 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")) { Bundle params = new Bundle(); params.putString("phoneFormated", requestPhone); params.putString("phoneHash", phoneHash); @@ -1439,7 +1444,8 @@ public class LoginActivity extends BaseFragment { TextView wrongNumber = new TextView(context); wrongNumber.setText(LocaleController.getString("CancelRegistration", R.string.CancelRegistration)); wrongNumber.setGravity(Gravity.LEFT | Gravity.CENTER_HORIZONTAL); - wrongNumber.setTextColor(0xff4d83b3); + //wrongNumber.setTextColor(0xff4d83b3); + wrongNumber.setTextColor(AndroidUtilities.getIntColor("themeColor")); wrongNumber.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); wrongNumber.setLineSpacing(AndroidUtilities.dp(2), 1.0f); wrongNumber.setPadding(0, AndroidUtilities.dp(24), 0, 0); @@ -1541,6 +1547,12 @@ 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)); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java index 811f0f3e..4b328481 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java @@ -33,10 +33,8 @@ 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; @@ -46,34 +44,46 @@ 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 +93,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 +104,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.messageOwner.id)) { + 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.messageOwner.id, messageObject); + if (!enc) { + if (messageObject.messageOwner.id > 0) { + max_id = Math.min(messageObject.messageOwner.id, max_id); + } + } else { + max_id = Math.max(messageObject.messageOwner.id, 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.messageOwner.id); + 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,7 +217,7 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); actionBar.setTitle(""); @@ -152,13 +229,14 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No if (Build.VERSION.SDK_INT < 11 && listView != null) { listView.setAdapter(null); listView = null; - listAdapter = null; + photoVideoAdapter = null; + documentsAdapter = null; } finishFragment(); } else if (id == -2) { selectedFiles.clear(); actionBar.hideActionMode(); - mediaListView.invalidateViews(); + listView.invalidateViews(); } else if (id == shared_media_item) { if (selectedMode == 0) { return; @@ -176,7 +254,7 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No return; } AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setMessage(LocaleController.formatString("AreYouSureDeleteMessages", R.string.AreYouSureDeleteMessages, LocaleController.formatPluralString("files", selectedFiles.size()))); + 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 @@ -265,16 +343,29 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No @Override public void onSearchExpand() { dropDownContainer.setVisibility(View.GONE); + searching = true; } @Override public void onSearchCollapse() { dropDownContainer.setVisibility(View.VISIBLE); + documentsSearchAdapter.searchDocuments(null); + searching = false; + searchWas = false; + switchToCurrentSelectedMode(); } @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)); @@ -282,7 +373,7 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No 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(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(); @@ -348,206 +439,83 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No } actionModeViews.add(actionMode.addItem(delete, R.drawable.ic_ab_fwd_delete, R.drawable.bar_selector_mode, null, AndroidUtilities.dp(54))); + photoVideoAdapter = new SharedPhotoVideoAdapter(getParentActivity()); + documentsAdapter = new SharedDocumentsAdapter(getParentActivity()); + documentsSearchAdapter = new DocumentsSearchAdapter(getParentActivity()); 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 = new SectionsListView(getParentActivity()); + listView.setDivider(null); + listView.setDividerHeight(0); 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); + 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.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()) { - return; - } - if (selectedMode == 0) { - PhotoViewer.getInstance().setParentActivity(getParentActivity()); - PhotoViewer.getInstance().openPhoto(sharedMediaData[selectedMode].messages, i, MediaActivity.this); - } else if (selectedMode == 1) { - + 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 absListView, int i) { - + 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 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); + 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(getParentActivity())); + } emptyView = new LinearLayout(getParentActivity()); 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; @@ -584,6 +552,7 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No 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; @@ -621,16 +590,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 +601,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 +625,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 +657,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 +686,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.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; + } } } } @@ -811,106 +778,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.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 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.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 (view instanceof SharedPhotoVideoCell) { + ((SharedPhotoVideoCell) view).setChecked(a, selectedFiles.containsKey(message.messageOwner.id), 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 +1001,456 @@ 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.messageOwner.id), !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.messageOwner.id), !scrolling); + } else { + cell.setChecked(a, false, !scrolling); + } + } else { + cell.setItem(a, index, null); + } + } + } + } 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.messageOwner.id); + } + 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.messageOwner.id), !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 d79c4cfe..a9777d0c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java @@ -10,10 +10,15 @@ package org.telegram.ui; import android.animation.ObjectAnimator; import android.animation.StateListAnimator; +import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; +import android.content.SharedPreferences; import android.content.res.Configuration; +import android.graphics.Color; import android.graphics.Outline; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; import android.view.Gravity; @@ -37,6 +42,7 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; import org.telegram.android.MessageObject; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLog; import org.telegram.messenger.TLRPC; import org.telegram.android.ContactsController; @@ -67,6 +73,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; @@ -88,6 +95,8 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter private long openedDialogId = 0; + private static final int passcode_menu_item = 1; + public static interface MessagesActivityDelegate { public abstract void didSelectDialog(MessagesActivity fragment, long dialog_id, boolean param); } @@ -107,6 +116,10 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter 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 (getArguments() != null) { onlySelect = arguments.getBoolean("onlySelect", false); @@ -133,25 +146,37 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter 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) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { + searching = false; + searchWas = false; + ActionBarMenu menu = actionBar.createMenu(); + if (!onlySelect) { + 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) { messagesListView.setEmptyView(searchEmptyView); - emptyView.setVisibility(View.GONE); - progressView.setVisibility(View.GONE); + emptyView.setVisibility(View.INVISIBLE); + progressView.setVisibility(View.INVISIBLE); if (!onlySelect) { floatingButton.setVisibility(View.GONE); } } + updatePasscodeButton(); } @Override @@ -160,14 +185,14 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter searchWas = false; if (messagesListView != null) { if (MessagesController.getInstance().loadingDialogs && MessagesController.getInstance().dialogs.isEmpty()) { - searchEmptyView.setVisibility(View.GONE); - emptyView.setVisibility(View.GONE); + searchEmptyView.setVisibility(View.INVISIBLE); + emptyView.setVisibility(View.INVISIBLE); progressView.setVisibility(View.VISIBLE); messagesListView.setEmptyView(progressView); } else { messagesListView.setEmptyView(emptyView); - searchEmptyView.setVisibility(View.GONE); - progressView.setVisibility(View.GONE); + searchEmptyView.setVisibility(View.INVISIBLE); + progressView.setVisibility(View.INVISIBLE); } if (!onlySelect) { floatingButton.setVisibility(View.VISIBLE); @@ -183,6 +208,7 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter if (dialogsSearchAdapter != null) { dialogsSearchAdapter.searchDialogs(null, false); } + updatePasscodeButton(); } @Override @@ -196,8 +222,8 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter } if (searchEmptyView != null && messagesListView.getEmptyView() == emptyView) { messagesListView.setEmptyView(searchEmptyView); - emptyView.setVisibility(View.GONE); - progressView.setVisibility(View.GONE); + emptyView.setVisibility(View.INVISIBLE); + progressView.setVisibility(View.INVISIBLE); } } if (dialogsSearchAdapter != null) { @@ -224,14 +250,15 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter } 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, container, false); + fragmentView = inflater.inflate(R.layout.messages_list, null, false); dialogsAdapter = new DialogsAdapter(getParentActivity(), serverOnly); if (AndroidUtilities.isTablet() && openedDialogId != 0) { @@ -242,8 +269,8 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter @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); + progressView.setVisibility(search ? View.VISIBLE : View.INVISIBLE); + searchEmptyView.setVisibility(search ? View.INVISIBLE : View.VISIBLE); messagesListView.setEmptyView(search ? progressView : searchEmptyView); } } @@ -309,14 +336,14 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter }); if (MessagesController.getInstance().loadingDialogs && MessagesController.getInstance().dialogs.isEmpty()) { - searchEmptyView.setVisibility(View.GONE); - emptyView.setVisibility(View.GONE); + searchEmptyView.setVisibility(View.INVISIBLE); + emptyView.setVisibility(View.INVISIBLE); progressView.setVisibility(View.VISIBLE); messagesListView.setEmptyView(progressView); } else { messagesListView.setEmptyView(emptyView); - searchEmptyView.setVisibility(View.GONE); - progressView.setVisibility(View.GONE); + searchEmptyView.setVisibility(View.INVISIBLE); + progressView.setVisibility(View.INVISIBLE); } messagesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @@ -531,6 +558,17 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter if (dialogsSearchAdapter != null) { dialogsSearchAdapter.notifyDataSetChanged(); } + updateColors(); + } + + private void updateColors(){ + actionBar.setBackgroundColor(AndroidUtilities.getIntDef("chatsHeaderColor", AndroidUtilities.getIntColor("themeColor"))); + Drawable floatingDrawableWhite = fragmentView.getResources().getDrawable(R.drawable.floating_white); + floatingDrawableWhite.setColorFilter(AndroidUtilities.getIntDef("chatsFloatingBGColor", AndroidUtilities.getIntColor("themeColor")), PorterDuff.Mode.MULTIPLY); + floatingButton.setBackgroundDrawable(floatingDrawableWhite); + Drawable pencilDrawableWhite = fragmentView.getResources().getDrawable(R.drawable.floating_pencil); + pencilDrawableWhite.setColorFilter(AndroidUtilities.getIntDef("chatsFloatingPencilColor", 0xffffffff), PorterDuff.Mode.MULTIPLY); + floatingButton.setImageDrawable(pencilDrawableWhite); } @Override @@ -559,29 +597,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 +655,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 +699,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); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/NotificationsSettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/NotificationsSettingsActivity.java index ace44bad..b35674fd 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/NotificationsSettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/NotificationsSettingsActivity.java @@ -154,7 +154,7 @@ public class NotificationsSettingsActivity extends BaseFragment implements Notif } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); actionBar.setAllowOverlayTitle(true); @@ -753,7 +753,7 @@ 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); } 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 00000000..a0548ca3 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/PasscodeActivity.java @@ -0,0 +1,710 @@ +/* + * 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.AnimationCompat.AnimatorListenerAdapterProxy; +import org.telegram.ui.AnimationCompat.AnimatorSetProxy; +import org.telegram.ui.AnimationCompat.ObjectAnimatorProxy; +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(LayoutInflater inflater) { + if (fragmentView == null) { + 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(getParentActivity()); + 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(getParentActivity()); + titleTextView.setTextColor(0xff757575); + if (type == 1) { + titleTextView.setText(LocaleController.getString("EnterNewPasscode", R.string.EnterNewPasscode)); + } 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(getParentActivity()); + 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(getParentActivity(), 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(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; + 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(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 = new ListAdapter(getParentActivity())); + 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); + } + } + }); + } + } 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(); + } + 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); + } + shakeTextView(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 shakeTextView(final float x, final int num) { + if (num == 6) { + titleTextView.clearAnimation(); + return; + } + AnimatorSetProxy animatorSetProxy = new AnimatorSetProxy(); + animatorSetProxy.playTogether(ObjectAnimatorProxy.ofFloat(titleTextView, "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() { + if (getParentActivity() == null) { + return; + } + Vibrator v = (Vibrator) getParentActivity().getSystemService(Context.VIBRATOR_SERVICE); + if (v != null) { + v.vibrate(200); + } + shakeTextView(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 61646ad1..96c5cac9 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java @@ -67,9 +67,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,7 +96,7 @@ public class PhotoAlbumPickerActivity extends BaseFragment implements Notificati @SuppressWarnings("unchecked") @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackgroundColor(0xff333333); actionBar.setItemsBackground(R.drawable.bar_selector_picker); @@ -292,7 +298,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) { @@ -364,7 +374,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 +413,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 +453,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); @@ -464,6 +482,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 +493,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 910b4f44..26a04b4e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoCropActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoCropActivity.java @@ -303,6 +303,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,7 +432,7 @@ public class PhotoCropActivity extends BaseFragment { } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackgroundColor(0xff333333); actionBar.setItemsBackground(R.drawable.bar_selector_picker); 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 5e0ff8f4..00000000 --- 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 0c573a96..ccaef1c0 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java @@ -12,7 +12,6 @@ import android.app.Activity; import android.content.Context; 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 +32,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 +45,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,7 +65,7 @@ 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(); @@ -102,16 +99,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,7 +140,7 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen @SuppressWarnings("unchecked") @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackgroundColor(0xff333333); actionBar.setItemsBackground(R.drawable.bar_selector_picker); @@ -257,7 +256,7 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams(); layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.bottomMargin = AndroidUtilities.dp(48); + layoutParams.bottomMargin = singlePhoto ? 0 : AndroidUtilities.dp(48); listView.setLayoutParams(layoutParams); listView.setAdapter(listAdapter = new ListAdapter(getParentActivity())); AndroidUtilities.setListViewEdgeEffectColor(listView, 0xff333333); @@ -278,7 +277,7 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen return; } PhotoViewer.getInstance().setParentActivity(getParentActivity()); - PhotoViewer.getInstance().openPhotoForSelect(arrayList, i, PhotoPickerActivity.this); + PhotoViewer.getInstance().openPhotoForSelect(arrayList, i, singlePhoto ? 1 : 0, PhotoPickerActivity.this); } }); @@ -300,7 +299,7 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen layoutParams = (FrameLayout.LayoutParams) emptyView.getLayoutParams(); layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.bottomMargin = AndroidUtilities.dp(48); + layoutParams.bottomMargin = singlePhoto ? 0 : AndroidUtilities.dp(48); emptyView.setLayoutParams(layoutParams); emptyView.setOnTouchListener(new View.OnTouchListener() { @Override @@ -336,7 +335,7 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams(); layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.bottomMargin = AndroidUtilities.dp(48); + layoutParams.bottomMargin = singlePhoto ? 0 : AndroidUtilities.dp(48); progressView.setLayoutParams(layoutParams); ProgressBar progressBar = new ProgressBar(getParentActivity()); @@ -370,6 +369,9 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen sendSelectedPhotos(); } }); + if (singlePhoto) { + photoPickerBottomLayout.setVisibility(View.GONE); + } listView.setEmptyView(emptyView); photoPickerBottomLayout.updateSelectedCount(selectedPhotos.size() + selectedWebPhotos.size(), true); @@ -464,6 +466,40 @@ 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); @@ -618,20 +654,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 +676,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 +955,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 +977,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 +1017,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); + 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 4def7298..4cf2e10a 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,6 +353,58 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat public int radius; } + public static class EmptyPhotoViewerProvider implements PhotoViewerProvider { + @Override + public PlaceProviderObject getPlaceForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index) { + return null; + } + + @Override + public Bitmap getThumbForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index) { + return null; + } + + @Override + public void willSwitchFromPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index) { + + } + + @Override + public void willHidePhotoViewer() { + + } + + @Override + public boolean isPhotoChecked(int index) { + return false; + } + + @Override + public void setPhotoChecked(int index) { + + } + + @Override + public void cancelButtonPressed() { + + } + + @Override + public void sendButtonPressed(int index) { + + } + + @Override + public int getSelectedCount() { + return 0; + } + + @Override + public void updatePhotoAtIndex(int index) { + + } + } + public static interface PhotoViewerProvider { public PlaceProviderObject getPlaceForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index); @@ -355,6 +423,8 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat public void sendButtonPressed(int index); public int getSelectedCount(); + + public void updatePhotoAtIndex(int index); } private class FrameLayoutTouchListener extends FrameLayout { @@ -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) { @@ -520,11 +594,19 @@ 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 (opennedFromMedia) { + imagesArrTemp.add(message); + if (message.messageOwner.id == currentMessage.messageOwner.id) { + foundIndex = added; + } + added++; + } else { + added++; + imagesArrTemp.add(0, message); + if (message.messageOwner.id == currentMessage.messageOwner.id) { + foundIndex = arr.size() - added; + } } } } @@ -548,7 +630,11 @@ 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).messageOwner.id, SharedMediaQuery.MEDIA_PHOTOVIDEO, true, classGuid); + } else { + SharedMediaQuery.loadMedia(currentDialogId, 0, 100, imagesArrTemp.get(0).messageOwner.id, SharedMediaQuery.MEDIA_PHOTOVIDEO, true, classGuid); + } } } } else { @@ -556,19 +642,29 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat for (MessageObject message : arr) { if (!imagesByIds.containsKey(message.messageOwner.id)) { added++; - imagesArr.add(0, message); + if (opennedFromMedia) { + imagesArr.add(message); + } else { + imagesArr.add(0, message); + } imagesByIds.put(message.messageOwner.id, 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) { @@ -646,14 +742,14 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); builder.setPositiveButton(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.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, 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.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); @@ -1270,24 +1826,29 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat imagesArrLocations.add(fileLocation); imagesArrLocationsSizes.add(object.size); avatarsArr.add(new TLRPC.TL_photoEmpty()); + bottomLayout.clearAnimation(); bottomLayout.setVisibility(View.GONE); 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); + if (!opennedFromMedia) { + Collections.reverse(imagesArr); + index = imagesArr.size() - index - 1; + } for (MessageObject message : imagesArr) { imagesByIds.put(message.messageOwner.id, 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 +1861,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 +1913,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 +1925,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.messageOwner.id, 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.messageOwner.id, 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 +1961,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 +1980,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 +2025,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 +2171,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 +2187,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 { @@ -1684,7 +2281,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 +2303,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 +2341,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 +2531,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 +2722,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 +2736,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 +2792,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 +2819,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 +2851,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 +2870,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 +2887,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 +2898,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 +2916,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } translationX -= moveDx; - if (scale != 1) { + if (scale != 1 || currentEditMode != 0) { translationY -= moveDy; } @@ -2225,14 +2929,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 +2957,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 +2979,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 +3000,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 +3028,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 +3057,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 +3093,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 +3119,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 +3153,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 +3162,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 +3183,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 +3215,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 +3261,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 +3329,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 +3338,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 +3398,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 +3407,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } } toggleActionBar(!isActionBarVisible, true); - } else { + } else if (sendPhotoType == 0) { checkImageView.performClick(); } return true; @@ -2690,8 +3422,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 5c9dcae8..22d7b199 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,7 +160,38 @@ 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, true); + 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() { @@ -202,8 +234,6 @@ 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); @@ -292,8 +322,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); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PrivacySettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PrivacySettingsActivity.java index 5cdc731c..2b8bab64 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PrivacySettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PrivacySettingsActivity.java @@ -8,10 +8,12 @@ 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; @@ -24,8 +26,10 @@ import android.widget.Toast; import org.telegram.android.AndroidUtilities; import org.telegram.android.ContactsController; import org.telegram.android.LocaleController; +import org.telegram.android.MediaController; import org.telegram.android.MessagesController; import org.telegram.android.NotificationCenter; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; @@ -37,6 +41,7 @@ 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.TextCheckCell; import org.telegram.ui.Cells.TextInfoPrivacyCell; import org.telegram.ui.Cells.TextSettingsCell; @@ -53,10 +58,12 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio private int securitySectionRow; private int terminateSessionsRow; private int passwordRow; + private int passcodeRow; private int terminateSessionsDetailRow; private int deleteAccountSectionRow; private int deleteAccountRow; private int deleteAccountDetailRow; + private int hideMobileNumberRow; private int rowCount; @Override @@ -67,10 +74,12 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio rowCount = 0; privacySectionRow = rowCount++; + hideMobileNumberRow = rowCount++; blockedRow = rowCount++; lastSeenRow = rowCount++; lastSeenDetailRow = rowCount++; securitySectionRow = rowCount++; + passcodeRow = rowCount++; terminateSessionsRow = rowCount++; terminateSessionsDetailRow = rowCount++; deleteAccountSectionRow = rowCount++; @@ -90,7 +99,7 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); actionBar.setAllowOverlayTitle(true); @@ -227,6 +236,22 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio presentFragment(new LastSeenActivity()); } else if (i == passwordRow) { presentFragment(new AccountPasswordActivity(0)); + } else if (i == passcodeRow) { + if (UserConfig.passcodeHash.length() > 0) { + presentFragment(new PasscodeActivity(2)); + } else { + presentFragment(new PasscodeActivity(0)); + } + } else if (i == hideMobileNumberRow) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + boolean scr = preferences.getBoolean("hideMobile", false); + SharedPreferences.Editor editor = preferences.edit(); + editor.putBoolean("hideMobile", !scr); + editor.commit(); + //AndroidUtilities.hideMobile = !scr; + if (view instanceof TextCheckCell) { + ((TextCheckCell) view).setChecked(!scr); + } } } }); @@ -319,7 +344,8 @@ 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 == terminateSessionsRow || i == lastSeenRow && !ContactsController.getInstance().getLoadingLastSeenInfo() || i == deleteAccountRow && !ContactsController.getInstance().getLoadingDeleteInfo() || + i == hideMobileNumberRow; } @Override @@ -357,6 +383,8 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio textCell.setText(LocaleController.getString("TerminateAllSessions", R.string.TerminateAllSessions), false); } else if (i == passwordRow) { textCell.setText(LocaleController.getString("Password", R.string.Password), true); + } else if (i == passcodeRow) { + textCell.setText(LocaleController.getString("Passcode", R.string.Passcode), true); } else if (i == lastSeenRow) { String value; if (ContactsController.getInstance().getLoadingLastSeenInfo()) { @@ -407,25 +435,38 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio } else if (i == deleteAccountSectionRow) { ((HeaderCell) view).setText(LocaleController.getString("DeleteAccountTitle", R.string.DeleteAccountTitle)); } + } else if (type == 3) { + if (view == null) { + view = new TextCheckCell(mContext); + view.setBackgroundColor(0xffffffff); + } + TextCheckCell textCell = (TextCheckCell) view; + + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + if (i == hideMobileNumberRow) { + textCell.setTextAndCheck(LocaleController.getString("HideMobile", R.string.HideMobile), preferences.getBoolean("hideMobile", false), false); + } } return view; } @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 == terminateSessionsRow || i == passwordRow || i == passcodeRow) { return 0; } else if (i == deleteAccountDetailRow || i == lastSeenDetailRow || i == terminateSessionsDetailRow) { return 1; - } else if (i == securitySectionRow || i == deleteAccountSectionRow || i == privacySectionRow) { + } else if (i == securitySectionRow || i == deleteAccountSectionRow || i == privacySectionRow ) { return 2; + } else if (i == hideMobileNumberRow) { + return 3; } return 0; } @Override public int getViewTypeCount() { - return 3; + return 4; } @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java index fe528496..74ae1269 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java @@ -224,7 +224,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackgroundColor(AvatarDrawable.getProfileBackColorForId(user_id != 0 ? 5 : chat_id)); actionBar.setItemsBackground(AvatarDrawable.getButtonColorForId(user_id != 0 ? 5 : chat_id)); @@ -397,7 +397,8 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. nameTextView.setLayoutParams(layoutParams); onlineTextView = new TextView(getParentActivity()); - onlineTextView.setTextColor(AvatarDrawable.getProfileTextColorForId(user_id != 0 ? 5 : chat_id)); + //onlineTextView.setTextColor(AvatarDrawable.getProfileTextColorForId(user_id != 0 ? 5 : chat_id)); + onlineTextView.setTextColor(AndroidUtilities.getIntDarkerColor("themeColor",-0x40)); onlineTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); onlineTextView.setLines(1); onlineTextView.setMaxLines(1); @@ -485,7 +486,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. try { Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:+" + user.phone)); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - getParentActivity().startActivity(intent); + getParentActivity().startActivityForResult(intent, 500); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -800,6 +801,7 @@ 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) { + if (listView != null) { int count = listView.getChildCount(); for (int a = 0; a < count; a++) { View child = listView.getChildAt(a); @@ -809,6 +811,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } } } + } } else if (id == NotificationCenter.contactsDidLoaded) { createActionBarMenu(); } else if (id == NotificationCenter.mediaCountDidLoaded) { @@ -884,6 +887,11 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. fixLayout(); } + @Override + public void updatePhotoAtIndex(int index) { + + } + @Override public PhotoViewer.PlaceProviderObject getPlaceForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index) { if (fileLocation == null) { @@ -1323,7 +1331,8 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. textCell.setTextAndIcon(LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.profile_list); } else if (i == startSecretChatRow) { textCell.setText(LocaleController.getString("StartEncryptedChat", R.string.StartEncryptedChat)); - textCell.setTextColor(0xff37a919); + //textCell.setTextColor(0xff37a919); + textCell.setTextColor(AndroidUtilities.getIntDarkerColor("themeColor",0x15)); } else if (i == settingsKeyRow) { IdenticonDrawable identiconDrawable = new IdenticonDrawable(); TLRPC.EncryptedChat encryptedChat = MessagesController.getInstance().getEncryptedChat((int)(dialog_id >> 32)); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileNotificationsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileNotificationsActivity.java index 3675c763..9e30daad 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileNotificationsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileNotificationsActivity.java @@ -85,7 +85,7 @@ public class ProfileNotificationsActivity extends BaseFragment implements Notifi } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); actionBar.setAllowOverlayTitle(true); @@ -120,7 +120,7 @@ public class ProfileNotificationsActivity extends BaseFragment implements Notifi 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("VibrationDisabled", R.string.VibrationDisabled), LocaleController.getString("SettingsDefault", R.string.SettingsDefault), LocaleController.getString("SystemDefault", R.string.SystemDefault), LocaleController.getString("Short", R.string.Short), @@ -158,7 +158,7 @@ public class ProfileNotificationsActivity extends BaseFragment implements Notifi builder.setItems(new CharSequence[] { LocaleController.getString("Default", R.string.Default), LocaleController.getString("Enabled", R.string.Enabled), - LocaleController.getString("Disabled", R.string.Disabled) + LocaleController.getString("NotificationsDisabled", R.string.NotificationsDisabled) }, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface d, int which) { @@ -402,7 +402,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 +415,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,10 +425,16 @@ 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)); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java index 31efa308..dc8be64a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java @@ -43,6 +43,7 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; +import android.widget.Toast; import org.telegram.android.AndroidUtilities; import org.telegram.android.ContactsController; @@ -212,8 +213,10 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter rowCount = 0; overscrollRow = rowCount++; emptyRow = rowCount++; - numberSectionRow = rowCount++; - numberRow = rowCount++; + if(!AndroidUtilities.getBoolMain("hideMobile")){ + numberSectionRow = rowCount++; + numberRow = rowCount++; + } usernameRow = rowCount++; settingsSectionRow = rowCount++; settingsSectionRow2 = rowCount++; @@ -236,12 +239,13 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter supportSectionRow2 = rowCount++; askQuestionRow = rowCount++; telegramFaqRow = rowCount++; + sendLogsRow = rowCount++; if (BuildVars.DEBUG_VERSION) { - sendLogsRow = rowCount++; + //sendLogsRow = rowCount++; clearLogsRow = rowCount++; switchBackendButtonRow = rowCount++; } - versionRow = rowCount++; + //versionRow = rowCount++; //contactsSectionRow = rowCount++; //contactsReimportRow = rowCount++; //contactsSortRow = rowCount++; @@ -265,7 +269,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackgroundColor(AvatarDrawable.getProfileBackColorForId(5)); actionBar.setItemsBackground(AvatarDrawable.getButtonColorForId(5)); @@ -361,7 +365,9 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter nameTextView.setLayoutParams(layoutParams); onlineTextView = new TextView(getParentActivity()); - onlineTextView.setTextColor(AvatarDrawable.getProfileTextColorForId(5)); + //onlineTextView.setTextColor(AvatarDrawable.getProfileTextColorForId(5)); + onlineTextView.setTextColor(AndroidUtilities.getIntDarkerColor("themeColor",-0x40)); + onlineTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); onlineTextView.setLines(1); onlineTextView.setMaxLines(1); @@ -412,6 +418,11 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter editor.putInt("fons_size", numberPicker.getValue()); MessagesController.getInstance().fontSize = numberPicker.getValue(); editor.commit(); + // + SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, Activity.MODE_PRIVATE); + SharedPreferences.Editor edit = themePrefs.edit(); + edit.putInt("chatTextSize", numberPicker.getValue()); + edit.commit(); if (listView != null) { listView.invalidateViews(); } @@ -491,7 +502,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter } else if (i == telegramFaqRow) { try { Intent pickIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(LocaleController.getString("TelegramFaqUrl", R.string.TelegramFaqUrl))); - getParentActivity().startActivity(pickIntent); + getParentActivity().startActivityForResult(pickIntent, 500); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -706,6 +717,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) { @@ -777,6 +793,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 +824,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) { @@ -966,7 +984,9 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter photoBig = user.photo.photo_big; } AvatarDrawable avatarDrawable = new AvatarDrawable(user, true); - avatarDrawable.setColor(0xff5c98cd); + //avatarDrawable.setColor(0xff5c98cd); + avatarDrawable.setColor(AndroidUtilities.getIntDarkerColor("themeColor",0x10)); + if (avatarImage != null) { avatarImage.setImage(photo, "50_50", avatarDrawable); avatarImage.imageReceiver.setVisible(!PhotoViewer.getInstance().isShowingImage(photoBig), false); @@ -974,6 +994,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter onlineTextView.setText(LocaleController.getString("Online", R.string.Online)); avatarImage.imageReceiver.setVisible(!PhotoViewer.getInstance().isShowingImage(photoBig), false); + } } private void sendLogs() { @@ -994,9 +1015,18 @@ 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(); + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (getParentActivity() != null) { + Toast toast = Toast.makeText(getParentActivity(), LocaleController.getString("SendLogsEmpty", R.string.SendLogsEmpty), Toast.LENGTH_SHORT); + toast.show(); + } + } + }); } } @@ -1084,7 +1114,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter } else if (i == backgroundRow) { textCell.setText(LocaleController.getString("ChatBackground", R.string.ChatBackground), true); } else if (i == sendLogsRow) { - textCell.setText("Send Logs", true); + textCell.setText(LocaleController.getString("SendLogs", R.string.SendLogs), true); } else if (i == clearLogsRow) { textCell.setText("Clear Logs", true); } else if (i == askQuestionRow) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java index 63d0da9c..3cf311d2 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java @@ -221,7 +221,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackgroundColor(0xff333333); actionBar.setItemsBackground(R.drawable.bar_selector_white); @@ -259,7 +259,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur ActionBarMenu menu = actionBar.createMenu(); menu.addItemWithWidth(1, R.drawable.ic_done, AndroidUtilities.dp(56)); - fragmentView = inflater.inflate(R.layout.video_editor_layout, container, false); + 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); @@ -578,6 +578,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 5b428a43..b6fe2827 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,7 +101,7 @@ public class WallpapersActivity extends BaseFragment implements NotificationCent } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (fragmentView == null) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); actionBar.setAllowOverlayTitle(true); @@ -148,7 +148,7 @@ public class WallpapersActivity extends BaseFragment implements NotificationCent editor.putInt("selectedBackground", selectedBackground); editor.putInt("selectedColor", selectedColor); editor.commit(); - ApplicationLoader.cachedWallpaper = null; + ApplicationLoader.reloadWallpaper(); } finishFragment(); } @@ -158,7 +158,7 @@ public class WallpapersActivity extends BaseFragment implements NotificationCent 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); + fragmentView = inflater.inflate(R.layout.settings_wallpapers_layout, null, false); listAdapter = new ListAdapter(getParentActivity()); progressBar = (ProgressBar)fragmentView.findViewById(R.id.action_progress); @@ -223,17 +223,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 +428,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/bottom_shadow.png b/TMessagesProj/src/main/res/drawable-hdpi/bottom_shadow.png new file mode 100644 index 00000000..5dc9ed10 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/color_hue.png b/TMessagesProj/src/main/res/drawable-hdpi/color_hue.png new file mode 100644 index 00000000..d8ed4875 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/color_hue.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/color_seekselector.png b/TMessagesProj/src/main/res/drawable-hdpi/color_seekselector.png new file mode 100644 index 00000000..39eef75f Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/color_seekselector.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/color_selector.png b/TMessagesProj/src/main/res/drawable-hdpi/color_selector.png new file mode 100644 index 00000000..8679d40e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/color_selector.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/dialogbg.xml b/TMessagesProj/src/main/res/drawable-hdpi/dialogbg.xml new file mode 100644 index 00000000..a4153cc5 --- /dev/null +++ b/TMessagesProj/src/main/res/drawable-hdpi/dialogbg.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/drawable-hdpi/dialogs_badge_white.9.png b/TMessagesProj/src/main/res/drawable-hdpi/dialogs_badge_white.9.png new file mode 100644 index 00000000..bfb893a5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/dialogs_badge_white.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/dialogs_check_white.png b/TMessagesProj/src/main/res/drawable-hdpi/dialogs_check_white.png new file mode 100644 index 00000000..6fdce764 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/dialogs_check_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/dialogs_halfcheck_white.png b/TMessagesProj/src/main/res/drawable-hdpi/dialogs_halfcheck_white.png new file mode 100644 index 00000000..76576b61 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/dialogs_halfcheck_white.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 c33a4c2f..09dea5d2 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 100644 index 00000000..8fb629d0 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 100644 index 00000000..ad5f280d 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/floating_white.png b/TMessagesProj/src/main/res/drawable-hdpi/floating_white.png new file mode 100644 index 00000000..de9e52d6 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/floating_white.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 ab687dad..00000000 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/ic_ab_delete_white.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_delete_white.png deleted file mode 100644 index f3273d77..00000000 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_share_white.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_share_white.png deleted file mode 100644 index 2b9baf7c..00000000 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/ic_attach_music.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_music.png new file mode 100644 index 00000000..151f180b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_music.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_launcher.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_launcher.png index a819fd9f..28aabef6 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/ic_launcher.png and b/TMessagesProj/src/main/res/drawable-hdpi/ic_launcher.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_send_white.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_send_white.png new file mode 100644 index 00000000..72fb088d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/ic_send_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/intro1.png b/TMessagesProj/src/main/res/drawable-hdpi/intro1.png index a8d1b924..d0caa77a 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/intro1.png and b/TMessagesProj/src/main/res/drawable-hdpi/intro1.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/list_broadcast_white.png b/TMessagesProj/src/main/res/drawable-hdpi/list_broadcast_white.png new file mode 100644 index 00000000..6e354f3c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/list_broadcast_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/list_group_white.png b/TMessagesProj/src/main/res/drawable-hdpi/list_group_white.png new file mode 100644 index 00000000..a9cfa9bb Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/list_group_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/list_secret_white.png b/TMessagesProj/src/main/res/drawable-hdpi/list_secret_white.png new file mode 100644 index 00000000..e2615cea Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/list_secret_white.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 00000000..f9b9072c 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 00000000..b7cc4864 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/menu_forum.png b/TMessagesProj/src/main/res/drawable-hdpi/menu_forum.png new file mode 100644 index 00000000..7f34f559 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/menu_forum.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/menu_theming.png b/TMessagesProj/src/main/res/drawable-hdpi/menu_theming.png new file mode 100644 index 00000000..0f3f38a1 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/menu_theming.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 7d63d911..80e7278e 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 a35fc7a4..be83f2bf 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_check_white.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_check_white.png new file mode 100644 index 00000000..a35fc7a4 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/msg_check_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_clock_white.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_clock_white.png new file mode 100644 index 00000000..a7f059cb Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/msg_clock_white.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 0676d17d..f568503f 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 950d5f25..1cb63687 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_halfcheck_white.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_halfcheck_white.png new file mode 100644 index 00000000..950d5f25 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/msg_halfcheck_white.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 81cd229e..08fd35b4 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 ccfdbaa2..f8f07f7f 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 6b488548..3d5b1f9f 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_photo_white.9.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo_white.9.png new file mode 100644 index 00000000..e92d7aed Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo_white.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo_white_selected.9.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo_white_selected.9.png new file mode 100644 index 00000000..c3c1c291 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo_white_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 b73ee8be..5e01d8fe 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/msg_out_white.9.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_white.9.png new file mode 100644 index 00000000..13be4937 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_white.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_out_white_selected.9.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_white_selected.9.png new file mode 100644 index 00000000..875e511a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_white_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/mute_white.png b/TMessagesProj/src/main/res/drawable-hdpi/mute_white.png new file mode 100644 index 00000000..39c09866 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/mute_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/notification.png b/TMessagesProj/src/main/res/drawable-hdpi/notification.png index e9ba1901..7c7ccf3b 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/notification.png and b/TMessagesProj/src/main/res/drawable-hdpi/notification.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/numberpicker_selection_divider_white.9.png b/TMessagesProj/src/main/res/drawable-hdpi/numberpicker_selection_divider_white.9.png new file mode 100644 index 00000000..77e096cd Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/numberpicker_selection_divider_white.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 00000000..d9b4dc28 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 00000000..317c52c5 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 00000000..a004ca95 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 2bd619df..00000000 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 e9ad643a..00000000 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 31e097a2..00000000 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 ac8c7818..00000000 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 dc365663..00000000 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 1a30ec1d..00000000 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/regbtn2.9.png b/TMessagesProj/src/main/res/drawable-hdpi/regbtn2.9.png index 715b972e..c734e29a 100644 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/regbtn2.9.png and b/TMessagesProj/src/main/res/drawable-hdpi/regbtn2.9.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 100644 index 00000000..3be94584 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 100644 index 00000000..900a5303 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/selector_orange_gradient.xml b/TMessagesProj/src/main/res/drawable-hdpi/selector_orange_gradient.xml new file mode 100644 index 00000000..8d11da8d --- /dev/null +++ b/TMessagesProj/src/main/res/drawable-hdpi/selector_orange_gradient.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file 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 7a023ec0..00000000 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 7a023ec0..00000000 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 6cf4bcda..00000000 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 100644 index 00000000..8b853cf2 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 100644 index 00000000..532e67de 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_white.9.png b/TMessagesProj/src/main/res/drawable-hdpi/system_white.9.png new file mode 100644 index 00000000..e92d7aed Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/system_white.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tab_bg_selected.xml b/TMessagesProj/src/main/res/drawable-hdpi/tab_bg_selected.xml new file mode 100644 index 00000000..47e5005a --- /dev/null +++ b/TMessagesProj/src/main/res/drawable-hdpi/tab_bg_selected.xml @@ -0,0 +1,6 @@ + + + + diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tab_bg_selector.xml b/TMessagesProj/src/main/res/drawable-hdpi/tab_bg_selector.xml new file mode 100644 index 00000000..4ede9cf3 --- /dev/null +++ b/TMessagesProj/src/main/res/drawable-hdpi/tab_bg_selector.xml @@ -0,0 +1,10 @@ + + + + + + + diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tab_bg_unselected.xml b/TMessagesProj/src/main/res/drawable-hdpi/tab_bg_unselected.xml new file mode 100644 index 00000000..c890cef3 --- /dev/null +++ b/TMessagesProj/src/main/res/drawable-hdpi/tab_bg_unselected.xml @@ -0,0 +1,6 @@ + + + + diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tab_text_selector.xml b/TMessagesProj/src/main/res/drawable-hdpi/tab_text_selector.xml new file mode 100644 index 00000000..2c74af62 --- /dev/null +++ b/TMessagesProj/src/main/res/drawable-hdpi/tab_text_selector.xml @@ -0,0 +1,7 @@ + + + + + + + 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 100644 index 00000000..fe2ae064 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 100644 index 00000000..21a65034 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 100644 index 00000000..85549500 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 100644 index 00000000..a365ce79 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 100644 index 00000000..39a73a1f 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 100644 index 00000000..5530def4 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 100644 index 00000000..5d79e93f 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 100644 index 00000000..0dc33aa0 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 100644 index 00000000..a6ac0587 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 100644 index 00000000..2392e738 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/transparentback.png b/TMessagesProj/src/main/res/drawable-hdpi/transparentback.png new file mode 100644 index 00000000..0c283adb Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/transparentback.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/transparentbackrepeat.xml b/TMessagesProj/src/main/res/drawable-hdpi/transparentbackrepeat.xml new file mode 100644 index 00000000..f2bb5bf6 --- /dev/null +++ b/TMessagesProj/src/main/res/drawable-hdpi/transparentbackrepeat.xml @@ -0,0 +1,3 @@ + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tune.png b/TMessagesProj/src/main/res/drawable-hdpi/tune.png new file mode 100644 index 00000000..ab404e6a 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 a73acd91..00000000 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/bottom_shadow.png b/TMessagesProj/src/main/res/drawable-mdpi/bottom_shadow.png new file mode 100644 index 00000000..3e170fda 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/dialogs_badge_white.9.png b/TMessagesProj/src/main/res/drawable-mdpi/dialogs_badge_white.9.png new file mode 100644 index 00000000..2391e2ba Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/dialogs_badge_white.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/dialogs_check_white.png b/TMessagesProj/src/main/res/drawable-mdpi/dialogs_check_white.png new file mode 100644 index 00000000..6880468f Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/dialogs_check_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/dialogs_halfcheck_white.png b/TMessagesProj/src/main/res/drawable-mdpi/dialogs_halfcheck_white.png new file mode 100644 index 00000000..ec0e2099 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/dialogs_halfcheck_white.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 069ff82a..1c1921a8 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 100644 index 00000000..5dd045bc 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 100644 index 00000000..494f4f85 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/floating_white.png b/TMessagesProj/src/main/res/drawable-mdpi/floating_white.png new file mode 100644 index 00000000..35eb5bbb Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/floating_white.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 bf910aaa..00000000 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/ic_ab_delete_white.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_delete_white.png deleted file mode 100644 index 49f05043..00000000 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_share_white.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_share_white.png deleted file mode 100644 index eee5acef..00000000 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/ic_attach_music.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_music.png new file mode 100644 index 00000000..8c4d5506 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_music.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_launcher.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_launcher.png index e245bb9c..c73d06f7 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/ic_launcher.png and b/TMessagesProj/src/main/res/drawable-mdpi/ic_launcher.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_send_white.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_send_white.png new file mode 100644 index 00000000..a99e5f8e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/ic_send_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/intro1.png b/TMessagesProj/src/main/res/drawable-mdpi/intro1.png index 9acf0679..7710170d 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/intro1.png and b/TMessagesProj/src/main/res/drawable-mdpi/intro1.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/list_broadcast_white.png b/TMessagesProj/src/main/res/drawable-mdpi/list_broadcast_white.png new file mode 100644 index 00000000..73811338 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/list_broadcast_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/list_group_white.png b/TMessagesProj/src/main/res/drawable-mdpi/list_group_white.png new file mode 100644 index 00000000..5b856c54 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/list_group_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/list_secret_white.png b/TMessagesProj/src/main/res/drawable-mdpi/list_secret_white.png new file mode 100644 index 00000000..371e8ff0 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/list_secret_white.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 00000000..47b4dd80 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 00000000..689f1901 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/menu_forum.png b/TMessagesProj/src/main/res/drawable-mdpi/menu_forum.png new file mode 100644 index 00000000..e5609973 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/menu_forum.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/menu_theming.png b/TMessagesProj/src/main/res/drawable-mdpi/menu_theming.png new file mode 100644 index 00000000..2ece2e05 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/menu_theming.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 6f92478e..2fdad7a3 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 ab1c1ba5..f2448a0a 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_check_white.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_check_white.png new file mode 100644 index 00000000..ab1c1ba5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/msg_check_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_clock_white.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_clock_white.png new file mode 100644 index 00000000..0c3c9442 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/msg_clock_white.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 2df5738e..010da7c5 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 b1ef529f..d5c1888a 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_halfcheck_white.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_halfcheck_white.png new file mode 100644 index 00000000..b1ef529f Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/msg_halfcheck_white.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 f8496cd4..f22c541f 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 d144e355..ad4ad9ce 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 d38cf29d..734f9436 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_photo_white.9.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo_white.9.png new file mode 100644 index 00000000..c5c6aa59 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo_white.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo_white_selected.9.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo_white_selected.9.png new file mode 100644 index 00000000..e9f759e8 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo_white_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 06f6fe05..7e29c812 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/msg_out_white.9.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_white.9.png new file mode 100644 index 00000000..80b828c1 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_white.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_out_white_selected.9.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_white_selected.9.png new file mode 100644 index 00000000..c75c27e9 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_white_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/mute_white.png b/TMessagesProj/src/main/res/drawable-mdpi/mute_white.png new file mode 100644 index 00000000..a663553c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/mute_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/notification.png b/TMessagesProj/src/main/res/drawable-mdpi/notification.png index 675c7502..6d985631 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/notification.png and b/TMessagesProj/src/main/res/drawable-mdpi/notification.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 00000000..1a39754e 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 00000000..c1ccb443 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 00000000..865cb4c9 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 890d61d5..00000000 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 62cfe9ab..00000000 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 cdfc8530..00000000 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_sizes.png b/TMessagesProj/src/main/res/drawable-mdpi/photo_sizes.png deleted file mode 100644 index 34d1d2ba..00000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/photo_sizes.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 9db5621e..00000000 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 61eab0c5..00000000 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/regbtn2.9.png b/TMessagesProj/src/main/res/drawable-mdpi/regbtn2.9.png index 9068fa94..d411cc97 100644 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/regbtn2.9.png and b/TMessagesProj/src/main/res/drawable-mdpi/regbtn2.9.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 100644 index 00000000..5e8873fa 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 100644 index 00000000..bab8acf0 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 051f23a6..00000000 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 051f23a6..00000000 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 0dcf7670..00000000 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 100644 index 00000000..48a9439c 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 100644 index 00000000..cc21392b 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_white.9.png b/TMessagesProj/src/main/res/drawable-mdpi/system_white.9.png new file mode 100644 index 00000000..c5c6aa59 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/system_white.9.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 100644 index 00000000..bc83f736 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 100644 index 00000000..ff596a32 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 100644 index 00000000..758b1be9 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 100644 index 00000000..caf3478b 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 100644 index 00000000..abf87a45 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 100644 index 00000000..ed936c7d 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 100644 index 00000000..297178d0 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 100644 index 00000000..62adb55d 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 100644 index 00000000..fd9972ce 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 100644 index 00000000..6f3d4d9f 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 100644 index 00000000..633d4b02 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 be946496..00000000 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 00000000..d48dd0a1 --- /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/bottom_shadow.png b/TMessagesProj/src/main/res/drawable-xhdpi/bottom_shadow.png new file mode 100644 index 00000000..eeb3c837 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/dialogs_badge_white.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/dialogs_badge_white.9.png new file mode 100644 index 00000000..8dba389e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/dialogs_badge_white.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/dialogs_check_white.png b/TMessagesProj/src/main/res/drawable-xhdpi/dialogs_check_white.png new file mode 100644 index 00000000..4e55d2f3 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/dialogs_check_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/dialogs_halfcheck_white.png b/TMessagesProj/src/main/res/drawable-xhdpi/dialogs_halfcheck_white.png new file mode 100644 index 00000000..e2a475fa Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/dialogs_halfcheck_white.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 37e756fa..bc4b1d28 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 100644 index 00000000..bfea63bc 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 100644 index 00000000..301434f8 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/floating_white.png b/TMessagesProj/src/main/res/drawable-xhdpi/floating_white.png new file mode 100644 index 00000000..c838c541 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/floating_white.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 c4a1eb82..00000000 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/ic_ab_delete_white.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_delete_white.png deleted file mode 100644 index 15752143..00000000 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_share_white.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_share_white.png deleted file mode 100644 index 03b1ac32..00000000 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/ic_attach_music.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_music.png new file mode 100644 index 00000000..5af747ad Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_music.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_launcher.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_launcher.png index 1c307e8e..c9db807e 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/ic_launcher.png and b/TMessagesProj/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_send_white.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_send_white.png new file mode 100644 index 00000000..6f6b730b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/ic_send_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/intro1.png b/TMessagesProj/src/main/res/drawable-xhdpi/intro1.png index 526e860d..79648be3 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/intro1.png and b/TMessagesProj/src/main/res/drawable-xhdpi/intro1.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/list_broadcast_white.png b/TMessagesProj/src/main/res/drawable-xhdpi/list_broadcast_white.png new file mode 100644 index 00000000..02e98068 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/list_broadcast_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/list_group_white.png b/TMessagesProj/src/main/res/drawable-xhdpi/list_group_white.png new file mode 100644 index 00000000..7b648b2d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/list_group_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/list_secret_white.png b/TMessagesProj/src/main/res/drawable-xhdpi/list_secret_white.png new file mode 100644 index 00000000..70e46939 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/list_secret_white.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 00000000..9ea56401 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 00000000..c85e140b 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/menu_forum.png b/TMessagesProj/src/main/res/drawable-xhdpi/menu_forum.png new file mode 100644 index 00000000..ad852de0 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/menu_forum.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/menu_theming.png b/TMessagesProj/src/main/res/drawable-xhdpi/menu_theming.png new file mode 100644 index 00000000..ceceef5b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/menu_theming.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 f507eaf8..d214b024 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 be951871..9e797a5c 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_check_white.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_check_white.png new file mode 100644 index 00000000..be951871 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_check_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_clock_white.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_clock_white.png new file mode 100644 index 00000000..50d10cbe Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_clock_white.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 0fcf4204..7ae6e79c 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 1882a27c..dd289160 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_halfcheck_white.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_halfcheck_white.png new file mode 100644 index 00000000..1882a27c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_halfcheck_white.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 f4e0afa5..d7c2816f 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 63274aed..c452372f 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 3dd5cb9b..faa2daa5 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_photo_white.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo_white.9.png new file mode 100644 index 00000000..248b9ba2 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo_white.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo_white_selected.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo_white_selected.9.png new file mode 100644 index 00000000..be51394a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo_white_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 5097bdcf..65e00a86 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/msg_out_white.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_white.9.png new file mode 100644 index 00000000..61ddb0f2 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_white.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_white_selected.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_white_selected.9.png new file mode 100644 index 00000000..fc7de308 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_white_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/mute_white.png b/TMessagesProj/src/main/res/drawable-xhdpi/mute_white.png new file mode 100644 index 00000000..c1760b06 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/mute_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/notification.png b/TMessagesProj/src/main/res/drawable-xhdpi/notification.png index fb978758..e8c2c724 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/notification.png and b/TMessagesProj/src/main/res/drawable-xhdpi/notification.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 00000000..f407719d 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 00000000..57af5956 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 00000000..92c5f2d5 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 61102102..00000000 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 6a309075..00000000 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 968e91dc..00000000 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 01f3176f..00000000 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 38edad85..00000000 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 e65b8036..00000000 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/regbtn2.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/regbtn2.9.png index 815fed37..b1450d44 100644 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/regbtn2.9.png and b/TMessagesProj/src/main/res/drawable-xhdpi/regbtn2.9.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 100644 index 00000000..5cd150ba 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 100644 index 00000000..44532e08 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 5b817801..00000000 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 95d818a4..00000000 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 598676b9..00000000 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 100644 index 00000000..d554570d 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 100644 index 00000000..ad1203f6 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_white.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/system_white.9.png new file mode 100644 index 00000000..248b9ba2 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/system_white.9.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 100644 index 00000000..1d1269e0 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 100644 index 00000000..52ca3c90 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 100644 index 00000000..db56a7a9 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 100644 index 00000000..c0e3627a 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 100644 index 00000000..e811faea 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 100644 index 00000000..38cae455 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 100644 index 00000000..92f8d6c7 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 100644 index 00000000..99cc7f7b 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 100644 index 00000000..c9ae138c 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 100644 index 00000000..aca145d1 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 100644 index 00000000..c6d6b9c7 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 345a0462..00000000 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/bottom_shadow.png b/TMessagesProj/src/main/res/drawable-xxhdpi/bottom_shadow.png new file mode 100644 index 00000000..cf81b6c1 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/dialogs_badge_white.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/dialogs_badge_white.9.png new file mode 100644 index 00000000..7774832c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/dialogs_badge_white.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/dialogs_check_white.png b/TMessagesProj/src/main/res/drawable-xxhdpi/dialogs_check_white.png new file mode 100644 index 00000000..0560c926 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/dialogs_check_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/dialogs_halfcheck_white.png b/TMessagesProj/src/main/res/drawable-xxhdpi/dialogs_halfcheck_white.png new file mode 100644 index 00000000..8da07186 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/dialogs_halfcheck_white.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 5445d4e1..109c13fd 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 100644 index 00000000..d050523b 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 100644 index 00000000..643fa3c6 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/floating_white.png b/TMessagesProj/src/main/res/drawable-xxhdpi/floating_white.png new file mode 100644 index 00000000..3715273b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/floating_white.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 e71905cb..00000000 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/ic_ab_delete_white.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_delete_white.png deleted file mode 100644 index 4335e31d..00000000 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_share_white.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_share_white.png deleted file mode 100644 index 890d00ae..00000000 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/ic_attach_music.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_music.png new file mode 100644 index 00000000..e5830295 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_music.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_launcher.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_launcher.png index d48a051a..5d836e3b 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_launcher.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_send_white.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_send_white.png new file mode 100644 index 00000000..c9b37406 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_send_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/intro1.png b/TMessagesProj/src/main/res/drawable-xxhdpi/intro1.png index b8633f74..8d0e1e1e 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/intro1.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/intro1.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/list_broadcast_white.png b/TMessagesProj/src/main/res/drawable-xxhdpi/list_broadcast_white.png new file mode 100644 index 00000000..c1a16839 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/list_broadcast_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/list_group_white.png b/TMessagesProj/src/main/res/drawable-xxhdpi/list_group_white.png new file mode 100644 index 00000000..85db5a9a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/list_group_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/list_secret_white.png b/TMessagesProj/src/main/res/drawable-xxhdpi/list_secret_white.png new file mode 100644 index 00000000..5f970753 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/list_secret_white.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 00000000..716b83b6 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 00000000..3cb15715 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/menu_forum.png b/TMessagesProj/src/main/res/drawable-xxhdpi/menu_forum.png new file mode 100644 index 00000000..a4ef52ce Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/menu_forum.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/menu_theming.png b/TMessagesProj/src/main/res/drawable-xxhdpi/menu_theming.png new file mode 100644 index 00000000..eb03acd5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/menu_theming.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 467e62be..5a38cea3 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 7d201974..7a6da6cc 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_check_white.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_check_white.png new file mode 100644 index 00000000..7d201974 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_check_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_clock_white.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_clock_white.png new file mode 100644 index 00000000..4bf6b168 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_clock_white.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 73bf80ba..4dbbf75b 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 03177ed4..841c77bc 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_halfcheck_white.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_halfcheck_white.png new file mode 100644 index 00000000..03177ed4 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_halfcheck_white.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 10eac9cc..b7aa0237 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 1c56a391..02e3ad80 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 7855d66f..67713607 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_photo_white.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo_white.9.png new file mode 100644 index 00000000..7ca493f7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo_white.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo_white_selected.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo_white_selected.9.png new file mode 100644 index 00000000..95285c5c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo_white_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 ad929cc4..6ce8fda0 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/msg_out_white.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_white.9.png new file mode 100644 index 00000000..aa97f34c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_white.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_white_selected.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_white_selected.9.png new file mode 100644 index 00000000..f60c1ea7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_white_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/mute_white.png b/TMessagesProj/src/main/res/drawable-xxhdpi/mute_white.png new file mode 100644 index 00000000..f1380afe Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/mute_white.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/notification.png b/TMessagesProj/src/main/res/drawable-xxhdpi/notification.png index 6ed95b8f..3d157c46 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/notification.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/notification.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 00000000..a831f4bb 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 00000000..cdd6dce6 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 00000000..af2428a2 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 78aa2b41..00000000 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 5feb667a..00000000 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 297bc2dc..00000000 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 ce156a02..00000000 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 c1a14fa7..00000000 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 f3ead532..00000000 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 4d6687ba..00000000 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 e72d3d71..00000000 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 9b9a258e..00000000 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 29abc7ed..00000000 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 a5bb25e5..00000000 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 0c1a9c77..00000000 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 40a564e6..00000000 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 254d18c7..00000000 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 3c4e0587..00000000 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/regbtn2.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/regbtn2.9.png index d5cf498e..34f1b1ea 100644 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/regbtn2.9.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/regbtn2.9.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 100644 index 00000000..d9e7195b 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 100644 index 00000000..193208c5 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 7620f457..00000000 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 11ac540b..00000000 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 935604b4..00000000 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 100644 index 00000000..b72403da 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 100644 index 00000000..80dfc383 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_white.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/system_white.9.png new file mode 100644 index 00000000..7ca493f7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/system_white.9.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 100644 index 00000000..fca4f193 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 100644 index 00000000..b7f4ea77 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 100644 index 00000000..92e5078a 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 100644 index 00000000..d3f89333 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 100644 index 00000000..fd194574 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 100644 index 00000000..f9b3e0b1 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 100644 index 00000000..9918b34d 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 100644 index 00000000..ba854d4b 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 100644 index 00000000..ba153fd4 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 100644 index 00000000..cfbf0d51 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 100644 index 00000000..eda3e5a3 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 1fc70c4b..00000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/web_search.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxxhdpi/ic_launcher.png b/TMessagesProj/src/main/res/drawable-xxxhdpi/ic_launcher.png index e3bcba53..6c16da14 100644 Binary files a/TMessagesProj/src/main/res/drawable-xxxhdpi/ic_launcher.png and b/TMessagesProj/src/main/res/drawable-xxxhdpi/ic_launcher.png 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 00000000..ad45bba6 --- /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 c265685e..00000000 --- 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 214bb3d6..00000000 --- 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/color_colorselectview.xml b/TMessagesProj/src/main/res/layout/color_colorselectview.xml new file mode 100644 index 00000000..f622643f --- /dev/null +++ b/TMessagesProj/src/main/res/layout/color_colorselectview.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/color_hexview.xml b/TMessagesProj/src/main/res/layout/color_hexview.xml new file mode 100644 index 00000000..b0e3218f --- /dev/null +++ b/TMessagesProj/src/main/res/layout/color_hexview.xml @@ -0,0 +1,12 @@ + + + + + + +