diff --git a/TMessagesProj/build.gradle b/TMessagesProj/build.gradle index 5fbedf976..7ecb86372 100644 --- a/TMessagesProj/build.gradle +++ b/TMessagesProj/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:1.0.0' + classpath 'com.android.tools.build:gradle:1.1.0' } } apply plugin: 'com.android.application' @@ -82,7 +82,7 @@ android { defaultConfig { minSdkVersion 8 targetSdkVersion 21 - versionCode 423 - versionName "2.4.0" + versionCode 453 + versionName "2.5.0" } } diff --git a/TMessagesProj/jni/Android.mk b/TMessagesProj/jni/Android.mk index 88b4e6394..ae2c63233 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 1532095b2..06c5e9f3b 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 similarity index 84% rename from TMessagesProj/libs/armeabi-v7a/libtmessages.5.so rename to TMessagesProj/libs/armeabi-v7a/libtmessages.6.so index 132154abf..41f66ec83 100755 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 similarity index 76% rename from TMessagesProj/libs/armeabi/libtmessages.5.so rename to TMessagesProj/libs/armeabi/libtmessages.6.so index 3e08cd8f7..aa46c0891 100755 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 similarity index 72% rename from TMessagesProj/libs/x86/libtmessages.5.so rename to TMessagesProj/libs/x86/libtmessages.6.so index 326a064f8..e455cf5ad 100755 Binary files a/TMessagesProj/libs/x86/libtmessages.5.so and b/TMessagesProj/libs/x86/libtmessages.6.so differ diff --git a/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java b/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java index 4455445f2..c7e2065ac 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java +++ b/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java @@ -23,6 +23,7 @@ import android.os.Environment; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.Spanned; +import android.util.DisplayMetrics; import android.util.StateSet; import android.view.Display; import android.view.Surface; @@ -33,12 +34,16 @@ import android.widget.AbsListView; import android.widget.EdgeEffect; import android.widget.EditText; import android.widget.ListView; +import android.widget.ProgressBar; import android.widget.TextView; +import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.messenger.ApplicationLoader; +import org.telegram.messenger.UserConfig; +import org.telegram.ui.Components.ForegroundDetector; import org.telegram.ui.Components.NumberPicker; import org.telegram.ui.Components.TypefaceSpan; @@ -59,6 +64,7 @@ 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; static { @@ -67,7 +73,7 @@ public class AndroidUtilities { } 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 +121,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 +234,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 +248,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 +432,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 +554,18 @@ 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()); + } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java b/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java index 75cb7bcbc..4894e628e 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 1e9a454a7..997488ed5 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); @@ -633,7 +633,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 +1057,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 +1684,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 9c467f72b..6ecff83d1 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 db7b228b3..3fffe63d0 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()); @@ -544,6 +545,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 +575,9 @@ public class LocaleController { if (value == null) { value = ApplicationLoader.applicationContext.getString(res); } + if (value == null) { + value = "LOC_ERR:" + key; + } return value; } @@ -638,6 +645,9 @@ public class LocaleController { } currentLocale = newLocale; currentPluralRules = allRules.get(currentLocale.getLanguage()); + if (currentPluralRules == null) { + currentPluralRules = allRules.get("en"); + } } } } @@ -695,6 +705,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 +730,15 @@ public class LocaleController { } isRTL = lang.toLowerCase().equals("ar"); nameDisplayOrder = lang.toLowerCase().equals("ko") ? 2 : 1; - String formatString = getStringInternal("formatterMonth", R.string.formatterMonth); - if (formatString == null || formatString.length() == 0) { - formatString = "dd MMM"; - } - formatterMonth = FastDateFormat.getInstance(formatString, locale); - formatString = getStringInternal("formatterYear", R.string.formatterYear); - if (formatString == null || formatString.length() == 0) { - formatString = "dd.MM.yy"; - } - formatterYear = FastDateFormat.getInstance(formatString, locale); - - formatString = getStringInternal("formatterYearMax", R.string.formatterYearMax); - if (formatString == null || formatString.length() == 0) { - formatString = "dd.MM.yyyy"; - } - formatterYearMax = FastDateFormat.getInstance(formatString, locale); - - formatString = getStringInternal("chatDate", R.string.chatDate); - if (formatString == null || formatString.length() == 0) { - formatString = "d MMMM"; - } - chatDate = FastDateFormat.getInstance(formatString, locale); - - formatString = getStringInternal("chatFullDate", R.string.chatFullDate); - if (formatString == null || formatString.length() == 0) { - formatString = "d MMMM yyyy"; - } - chatFullDate = FastDateFormat.getInstance(formatString, locale); - - formatString = getStringInternal("formatterWeek", R.string.formatterWeek); - if (formatString == null || formatString.length() == 0) { - formatString = "EEE"; - } - formatterWeek = FastDateFormat.getInstance(formatString, locale); - - if (is24HourFormat) { - formatString = getStringInternal("formatterDay24H", R.string.formatterDay24H); - } else { - formatString = getStringInternal("formatterDay12H", R.string.formatterDay12H); - } - if (formatString == null || formatString.length() == 0) { - if (is24HourFormat) { - formatString = "HH:mm"; - } else { - formatString = "h:mm a"; - } - } - if (lang.toLowerCase().equals("ar") || lang.toLowerCase().equals("ko")) { - formatterDay = FastDateFormat.getInstance(formatString, locale); - } else { - formatterDay = FastDateFormat.getInstance(formatString, Locale.US); - } + formatterMonth = createFormatter(locale, getStringInternal("formatterMonth", R.string.formatterMonth), "dd MMM"); + formatterYear = createFormatter(locale, getStringInternal("formatterYear", R.string.formatterYear), "dd.MM.yy"); + formatterYearMax = createFormatter(locale, getStringInternal("formatterYearMax", R.string.formatterYearMax), "dd.MM.yyyy"); + chatDate = createFormatter(locale, getStringInternal("chatDate", R.string.chatDate), "d MMMM"); + chatFullDate = createFormatter(locale, getStringInternal("chatFullDate", R.string.chatFullDate), "d MMMM yyyy"); + formatterWeek = createFormatter(locale, getStringInternal("formatterWeek", R.string.formatterWeek), "EEE"); + formatterMonthYear = createFormatter(locale, getStringInternal("formatterMonthYear", R.string.formatterMonthYear), "MMMM yyyy"); + formatterDay = createFormatter(lang.toLowerCase().equals("ar") || lang.toLowerCase().equals("ko") ? locale : Locale.US, is24HourFormat ? getStringInternal("formatterDay24H", R.string.formatterDay24H) : getStringInternal("formatterDay12H", R.string.formatterDay12H), is24HourFormat ? "HH:mm" : "h:mm a"); } public static String stringForMessageListDate(long date) { diff --git a/TMessagesProj/src/main/java/org/telegram/android/MediaController.java b/TMessagesProj/src/main/java/org/telegram/android/MediaController.java index efa53b092..b520f8b8f 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"; diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java b/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java index 1c6c0dd48..86db4605c 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; @@ -199,7 +200,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 +347,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 +560,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 +585,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 +617,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 +626,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 +659,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 +671,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 +700,7 @@ public class MessageObject { } public void setIsRead() { - messageOwner.flags &=~ TLRPC.MESSAGE_FLAG_UNREAD; + messageOwner.flags &= ~TLRPC.MESSAGE_FLAG_UNREAD; } public boolean isSecretPhoto() { @@ -706,15 +710,15 @@ public class MessageObject { public boolean isSecretMedia() { return messageOwner instanceof TLRPC.TL_message_secret && (messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && messageOwner.ttl != 0 && messageOwner.ttl <= 60 || - messageOwner.media instanceof TLRPC.TL_messageMediaAudio || - messageOwner.media instanceof TLRPC.TL_messageMediaVideo); + messageOwner.media instanceof TLRPC.TL_messageMediaAudio || + messageOwner.media instanceof TLRPC.TL_messageMediaVideo); } public static void setIsUnread(TLRPC.Message message, boolean unread) { if (unread) { message.flags |= TLRPC.MESSAGE_FLAG_UNREAD; } else { - message.flags &=~ TLRPC.MESSAGE_FLAG_UNREAD; + message.flags &= ~TLRPC.MESSAGE_FLAG_UNREAD; } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java index 71bd216e9..1eea13dc7 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java @@ -102,6 +102,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 { @@ -863,6 +865,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 +947,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 +962,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 +980,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 +1439,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 +1535,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 +1556,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 +1715,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 +1870,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 +1908,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 +1955,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 +2037,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 +2856,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 +2870,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter return true; } } - } + //} return false; } diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java b/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java index 87f0e1982..160447dec 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 eecbbb175..17e55ea26 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 6e045c321..5ae1cae0b 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 c0cc5d4f9..f90fcef75 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,14 +419,18 @@ public class NotificationsController { intent.putExtra("userId", user_id); } } - if (pushDialogs.size() == 1) { - if (chat != null) { - if (chat.photo != null && chat.photo.photo_small != null && chat.photo.photo_small.volume_id != 0 && chat.photo.photo_small.local_id != 0) { - photoPath = chat.photo.photo_small; - } - } else { - if (user.photo != null && user.photo.photo_small != null && user.photo.photo_small.volume_id != 0 && user.photo.photo_small.local_id != 0) { - photoPath = user.photo.photo_small; + if (AndroidUtilities.needShowPasscode(false) || UserConfig.isWaitingForPasscodeEnter) { + photoPath = null; + } else { + if (pushDialogs.size() == 1) { + if (chat != null) { + if (chat.photo != null && chat.photo.photo_small != null && chat.photo.photo_small.volume_id != 0 && chat.photo.photo_small.local_id != 0) { + photoPath = chat.photo.photo_small; + } + } else { + if (user.photo != null && user.photo.photo_small != null && user.photo.photo_small.volume_id != 0 && user.photo.photo_small.local_id != 0) { + photoPath = user.photo.photo_small; + } } } } @@ -436,7 +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) @@ -834,7 +841,7 @@ public class NotificationsController { notifyCheck = isLast; } - if (!popupMessages.isEmpty() && oldCount != popupMessages.size()) { + if (!popupMessages.isEmpty() && oldCount != popupMessages.size() && !AndroidUtilities.needShowPasscode(false)) { if (ApplicationLoader.mainInterfacePaused || !ApplicationLoader.isScreenOn) { MessageObject messageObject = messageObjects.get(0); if (popup == 3 || popup == 1 && ApplicationLoader.isScreenOn || popup == 2 && !ApplicationLoader.isScreenOn) { @@ -988,20 +995,33 @@ public class NotificationsController { setBadge(ApplicationLoader.applicationContext, enabled ? total_unread_count : 0); } - private void setBadge(Context context, int count) { - try { - String launcherClassName = getLauncherClassName(context); - if (launcherClassName == null) { - return; + private void setBadge(final Context context, final int count) { + notificationsQueue.postRunnable(new Runnable() { + @Override + public void run() { + try { + ContentValues cv = new ContentValues(); + cv.put("tag", "org.telegram.messenger/org.telegram.ui.LaunchActivity"); + cv.put("count", count); + context.getContentResolver().insert(Uri.parse("content://com.teslacoilsw.notifier/unread_count"), cv); + } catch (Throwable e) { + //ignore + } + try { + String launcherClassName = getLauncherClassName(context); + if (launcherClassName == null) { + return; + } + Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE"); + intent.putExtra("badge_count", count); + intent.putExtra("badge_count_package_name", context.getPackageName()); + intent.putExtra("badge_count_class_name", launcherClassName); + context.sendBroadcast(intent); + } catch (Throwable e) { + FileLog.e("tmessages", e); + } } - Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE"); - intent.putExtra("badge_count", count); - intent.putExtra("badge_count_package_name", context.getPackageName()); - intent.putExtra("badge_count_class_name", launcherClassName); - context.sendBroadcast(intent); - } catch (Throwable e) { - FileLog.e("tmessages", e); - } + }); } public static String getLauncherClassName(Context context) { diff --git a/TMessagesProj/src/main/java/org/telegram/android/ScreenReceiver.java b/TMessagesProj/src/main/java/org/telegram/android/ScreenReceiver.java index e6b6c7572..d7824f18b 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/ScreenReceiver.java +++ b/TMessagesProj/src/main/java/org/telegram/android/ScreenReceiver.java @@ -28,5 +28,6 @@ public class ScreenReceiver extends BroadcastReceiver { ConnectionsManager.getInstance().setAppPaused(false, true); ApplicationLoader.isScreenOn = true; } + NotificationCenter.getInstance().postNotificationName(NotificationCenter.screenStateChanged); } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/SecretChatHelper.java b/TMessagesProj/src/main/java/org/telegram/android/SecretChatHelper.java index 6a1140245..1cc95296d 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; diff --git a/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java b/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java index b7dc050d7..4cb3e851d 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 9d9eca96d..cdb693328 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 b788712c3..481be8415 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java @@ -8,6 +8,7 @@ package org.telegram.messenger; +import android.app.Activity; import android.app.AlarmManager; import android.app.Application; import android.app.PendingIntent; @@ -19,6 +20,7 @@ import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Build; @@ -38,10 +40,13 @@ import org.telegram.android.LocaleController; import org.telegram.android.MessagesController; import org.telegram.android.NativeLoader; import org.telegram.android.ScreenReceiver; +import org.telegram.ui.Components.ForegroundDetector; +import java.io.File; import java.util.concurrent.atomic.AtomicInteger; public class ApplicationLoader extends Application { + private GoogleCloudMessaging gcm; private AtomicInteger msgId = new AtomicInteger(); private String regid; @@ -49,15 +54,80 @@ public class ApplicationLoader extends Application { public static final String PROPERTY_REG_ID = "registration_id"; private static final String PROPERTY_APP_VERSION = "appVersion"; private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000; - public static Drawable cachedWallpaper = null; + private static Drawable cachedWallpaper; + private static int selectedColor; + private static boolean isCustomTheme; + private static final Object sync = new Object(); - public static volatile Context applicationContext = null; - public static volatile Handler applicationHandler = null; + public static volatile Context applicationContext; + public static volatile Handler applicationHandler; private static volatile boolean applicationInited = false; public static volatile boolean isScreenOn = false; public static volatile boolean mainInterfacePaused = true; + public static boolean isCustomTheme() { + return isCustomTheme; + } + + public static int getSelectedColor() { + return selectedColor; + } + + public static void reloadWallpaper() { + cachedWallpaper = null; + loadWallpaper(); + } + + public static void loadWallpaper() { + if (cachedWallpaper != null) { + return; + } + Utilities.searchQueue.postRunnable(new Runnable() { + @Override + public void run() { + synchronized (sync) { + int selectedColor = 0; + try { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + int selectedBackground = preferences.getInt("selectedBackground", 1000001); + selectedColor = preferences.getInt("selectedColor", 0); + int cacheColorHint = 0; + if (selectedColor == 0) { + if (selectedBackground == 1000001) { + cachedWallpaper = applicationContext.getResources().getDrawable(R.drawable.background_hd); + isCustomTheme = false; + } else { + File toFile = new File(ApplicationLoader.applicationContext.getFilesDir(), "wallpaper.jpg"); + if (toFile.exists()) { + cachedWallpaper = Drawable.createFromPath(toFile.getAbsolutePath()); + isCustomTheme = true; + } else { + cachedWallpaper = applicationContext.getResources().getDrawable(R.drawable.background_hd); + isCustomTheme = false; + } + } + } + } catch (Throwable throwable) { + //ignore + } + if (cachedWallpaper == null) { + if (selectedColor == 0) { + selectedColor = -2693905; + } + cachedWallpaper = new ColorDrawable(selectedColor); + } + } + } + }); + } + + public static Drawable getCachedWallpaper() { + synchronized (sync) { + return cachedWallpaper; + } + } + public static void postInitApplication() { if (applicationInited) { return; @@ -117,6 +187,10 @@ public class ApplicationLoader extends Application { applicationContext = getApplicationContext(); NativeLoader.initNativeLibs(ApplicationLoader.applicationContext); + if (Build.VERSION.SDK_INT >= 14) { + new ForegroundDetector(this); + } + applicationHandler = new Handler(applicationContext.getMainLooper()); startPushService(); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java b/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java index bc3dd2995..4661c8b0a 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java @@ -452,7 +452,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 +488,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(); @@ -1406,6 +1406,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. if (rawRequest != null && (rawRequest instanceof TLRPC.TL_messages_sendMessage || rawRequest instanceof TLRPC.TL_messages_sendMedia || rawRequest instanceof TLRPC.TL_messages_forwardMessages || + rawRequest instanceof TLRPC.TL_messages_forwardMessage || rawRequest instanceof TLRPC.TL_messages_sendEncrypted || rawRequest instanceof TLRPC.TL_messages_sendEncryptedFile || rawRequest instanceof TLRPC.TL_messages_sendEncryptedService)) { @@ -1426,6 +1427,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. if (currentRawRequest instanceof TLRPC.TL_messages_sendMessage || currentRawRequest instanceof TLRPC.TL_messages_sendMedia || currentRawRequest instanceof TLRPC.TL_messages_forwardMessages || + currentRawRequest instanceof TLRPC.TL_messages_forwardMessage || currentRawRequest instanceof TLRPC.TL_messages_sendEncrypted || currentRawRequest instanceof TLRPC.TL_messages_sendEncryptedFile || currentRawRequest instanceof TLRPC.TL_messages_sendEncryptedService) { @@ -1438,6 +1440,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. if (request.rawRequest instanceof TLRPC.TL_messages_sendMessage || request.rawRequest instanceof TLRPC.TL_messages_sendMedia || request.rawRequest instanceof TLRPC.TL_messages_forwardMessages || + request.rawRequest instanceof TLRPC.TL_messages_forwardMessage || request.rawRequest instanceof TLRPC.TL_messages_sendEncrypted || request.rawRequest instanceof TLRPC.TL_messages_sendEncryptedFile || request.rawRequest instanceof TLRPC.TL_messages_sendEncryptedService) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java index b0e1ac4e9..74afae274 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/UserConfig.java b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java index 0cd098656..6094e479c 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,6 +68,12 @@ 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(); @@ -195,6 +207,11 @@ 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); @@ -214,12 +231,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 f1c865a9d..770b439af 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java @@ -109,6 +109,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); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/AccountPasswordActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/AccountPasswordActivity.java index 348d20ee9..a7c4f6b2c 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 188fdf767..732ba6f74 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBar.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBar.java @@ -13,6 +13,7 @@ import android.content.res.Configuration; import android.graphics.drawable.Drawable; import android.os.Build; import android.text.TextUtils; +import android.util.TypedValue; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -91,9 +92,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 +107,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 +137,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 +174,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 +367,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 +383,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 +474,9 @@ public class ActionBar extends FrameLayout { public void setOccupyStatusBar(boolean value) { occupyStatusBar = value; + if (actionMode != null) { + actionMode.setPadding(0, occupyStatusBar ? AndroidUtilities.statusBarHeight : 0, 0, 0); + } } public boolean getOccupyStatusBar() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java index bf295a531..398ecde2c 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 966505486..fa19aa490 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/BaseFragment.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BaseFragment.java index 9270ca1ca..46d04896f 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; } @@ -76,7 +76,7 @@ public class BaseFragment { if (parentLayout != null) { actionBar = new ActionBar(parentLayout.getContext()); actionBar.parentFragment = this; - actionBar.setBackgroundResource(R.color.header); + actionBar.setBackgroundColor(0xff54759e); actionBar.setItemsBackground(R.drawable.bar_selector); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/DrawerLayoutContainer.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/DrawerLayoutContainer.java index 1c607dd5f..600807d1f 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/ContactsSearchAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/ContactsSearchAdapter.java index e68e9be57..17dd2fe2e 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; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java index 6031ed215..e8884689c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java @@ -13,7 +13,6 @@ import android.view.View; import android.view.ViewGroup; import org.telegram.android.AndroidUtilities; -import org.telegram.android.MessageObject; import org.telegram.android.MessagesController; import org.telegram.messenger.TLRPC; import org.telegram.ui.Cells.DialogCell; @@ -24,6 +23,7 @@ public class DialogsAdapter extends BaseFragmentAdapter { private Context mContext; private boolean serverOnly; private long openedDialogId; + private int currentCount; public DialogsAdapter(Context context, boolean onlyFromServer) { mContext = context; @@ -34,6 +34,11 @@ public class DialogsAdapter extends BaseFragmentAdapter { openedDialogId = id; } + public boolean isDataSetChanged() { + int current = currentCount; + return current != getCount(); + } + @Override public boolean areAllItemsEnabled() { return true; @@ -58,6 +63,7 @@ public class DialogsAdapter extends BaseFragmentAdapter { if (!MessagesController.getInstance().dialogsEndReached) { count++; } + currentCount = count; return count; } @@ -97,22 +103,23 @@ public class DialogsAdapter extends BaseFragmentAdapter { if (view == null) { view = new DialogCell(mContext); } - ((DialogCell) view).useSeparator = (i != getCount() - 1); - TLRPC.TL_dialog dialog = null; - if (serverOnly) { - dialog = MessagesController.getInstance().dialogsServerOnly.get(i); - } else { - dialog = MessagesController.getInstance().dialogs.get(i); - if (AndroidUtilities.isTablet()) { - if (dialog.id == openedDialogId) { - view.setBackgroundColor(0x0f000000); - } else { - view.setBackgroundColor(0); + if (view instanceof DialogCell) { //TODO finally i need to find this crash + ((DialogCell) view).useSeparator = (i != getCount() - 1); + TLRPC.TL_dialog dialog = null; + if (serverOnly) { + dialog = MessagesController.getInstance().dialogsServerOnly.get(i); + } else { + dialog = MessagesController.getInstance().dialogs.get(i); + if (AndroidUtilities.isTablet()) { + if (dialog.id == openedDialogId) { + view.setBackgroundColor(0x0f000000); + } else { + view.setBackgroundColor(0); + } } } + ((DialogCell) view).setDialog(dialog, i, serverOnly); } - MessageObject message = MessagesController.getInstance().dialogMessage.get(dialog.top_message); - ((DialogCell) view).setDialog(dialog.id, message, true, dialog.last_message_date, dialog.unread_count, MessagesController.getInstance().isDialogMuted(dialog.id)); } return view; @@ -133,9 +140,6 @@ public class DialogsAdapter extends BaseFragmentAdapter { @Override public boolean isEmpty() { - if (MessagesController.getInstance().loadingDialogs && MessagesController.getInstance().dialogs.isEmpty()) { - return true; - } int count; if (serverOnly) { count = MessagesController.getInstance().dialogsServerOnly.size(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsSearchAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsSearchAdapter.java index 2424062cd..551bf48ed 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; @@ -618,7 +634,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/StickersAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/StickersAdapter.java index 2d52263fc..538756f76 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 0f91b93b1..274dd6041 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Animation/AnimatorSet10.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Animation/AnimatorSet10.java @@ -25,10 +25,10 @@ import java.util.List; public final class AnimatorSet10 extends Animator10 { - private ArrayList mPlayingSet = new ArrayList(); - private HashMap mNodeMap = new HashMap(); - private ArrayList mNodes = new ArrayList(); - private ArrayList mSortedNodes = new ArrayList(); + private ArrayList mPlayingSet = new ArrayList<>(); + private HashMap mNodeMap = new HashMap<>(); + private ArrayList mNodes = new ArrayList<>(); + private ArrayList mSortedNodes = new ArrayList<>(); private boolean mNeedsSort = true; private AnimatorSetListener mSetListener = null; boolean mTerminated = false; @@ -89,7 +89,7 @@ public final class AnimatorSet10 extends Animator10 { } public ArrayList getChildAnimations() { - ArrayList childList = new ArrayList(); + ArrayList childList = new ArrayList<>(); for (Node node : mNodes) { childList.add(node.animation); } @@ -295,7 +295,7 @@ public final class AnimatorSet10 extends Animator10 { ArrayList oldListeners = node.animation.getListeners(); if (oldListeners != null && oldListeners.size() > 0) { final ArrayList clonedListeners = new - ArrayList(oldListeners); + ArrayList<>(oldListeners); for (AnimatorListener listener : clonedListeners) { if (listener instanceof DependencyListener || @@ -306,7 +306,7 @@ public final class AnimatorSet10 extends Animator10 { } } - final ArrayList nodesToStart = new ArrayList(); + final ArrayList nodesToStart = new ArrayList<>(); for (Node node : mSortedNodes) { if (mSetListener == null) { mSetListener = new AnimatorSetListener(this); @@ -379,12 +379,12 @@ public final class AnimatorSet10 extends Animator10 { anim.mNeedsSort = true; anim.mTerminated = false; anim.mStarted = false; - anim.mPlayingSet = new ArrayList(); - anim.mNodeMap = new HashMap(); - anim.mNodes = new ArrayList(); - anim.mSortedNodes = new ArrayList(); + anim.mPlayingSet = new ArrayList<>(); + anim.mNodeMap = new HashMap<>(); + anim.mNodes = new ArrayList<>(); + anim.mSortedNodes = new ArrayList<>(); - HashMap nodeCloneMap = new HashMap(); + HashMap nodeCloneMap = new HashMap<>(); for (Node node : mNodes) { Node nodeClone = node.clone(); nodeCloneMap.put(node, nodeClone); @@ -400,7 +400,7 @@ public final class AnimatorSet10 extends Animator10 { for (AnimatorListener listener : cloneListeners) { if (listener instanceof AnimatorSetListener) { if (listenersToRemove == null) { - listenersToRemove = new ArrayList(); + listenersToRemove = new ArrayList<>(); } listenersToRemove.add(listener); } @@ -543,14 +543,14 @@ public final class AnimatorSet10 extends Animator10 { private void sortNodes() { if (mNeedsSort) { mSortedNodes.clear(); - ArrayList roots = new ArrayList(); + ArrayList roots = new ArrayList<>(); int numNodes = mNodes.size(); for (Node node : mNodes) { if (node.dependencies == null || node.dependencies.size() == 0) { roots.add(node); } } - ArrayList tmpRoots = new ArrayList(); + ArrayList tmpRoots = new ArrayList<>(); while (roots.size() > 0) { int numRoots = roots.size(); for (Node root : roots) { @@ -582,7 +582,7 @@ public final class AnimatorSet10 extends Animator10 { for (int j = 0; j < numDependencies; ++j) { Dependency dependency = node.dependencies.get(j); if (node.nodeDependencies == null) { - node.nodeDependencies = new ArrayList(); + node.nodeDependencies = new ArrayList<>(); } if (!node.nodeDependencies.contains(dependency.node)) { node.nodeDependencies.add(dependency.node); @@ -620,8 +620,8 @@ public final class AnimatorSet10 extends Animator10 { public void addDependency(Dependency dependency) { if (dependencies == null) { - dependencies = new ArrayList(); - nodeDependencies = new ArrayList(); + dependencies = new ArrayList<>(); + nodeDependencies = new ArrayList<>(); } dependencies.add(dependency); if (!nodeDependencies.contains(dependency.node)) { @@ -629,7 +629,7 @@ public final class AnimatorSet10 extends Animator10 { } Node dependencyNode = dependency.node; if (dependencyNode.nodeDependents == null) { - dependencyNode.nodeDependents = new ArrayList(); + dependencyNode.nodeDependents = new ArrayList<>(); } dependencyNode.nodeDependents.add(this); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Animation/View10.java b/TMessagesProj/src/main/java/org/telegram/ui/Animation/View10.java index 0863204d0..4a89fe9c5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Animation/View10.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Animation/View10.java @@ -31,7 +31,7 @@ public class View10 extends Animation { public static boolean NEED_PROXY = Build.VERSION.SDK_INT < 11; - private static final WeakHashMap PROXIES = new WeakHashMap(); + private static final WeakHashMap PROXIES = new WeakHashMap<>(); public static View10 wrap(View view) { View10 proxy = PROXIES.get(view); @@ -68,7 +68,7 @@ public class View10 extends Animation { setDuration(0); setFillAfter(true); view.setAnimation(this); - mView = new WeakReference(view); + mView = new WeakReference<>(view); } public float getAlpha() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/BlockedUsersActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/BlockedUsersActivity.java index 0f0eb843d..ef1e5475f 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/ChatBaseCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java index ec5ac969d..8258de3f7 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java @@ -574,9 +574,9 @@ public class ChatBaseCell extends BaseCell { if (drawCheck2) { if (!media) { if (drawCheck1) { - setDrawableBounds(checkDrawable, layoutWidth - AndroidUtilities.dp(22.5f) - checkDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.5f) - checkDrawable.getIntrinsicHeight()); + setDrawableBounds(checkDrawable, layoutWidth - AndroidUtilities.dp(22.5f) - checkDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - checkDrawable.getIntrinsicHeight()); } else { - setDrawableBounds(checkDrawable, layoutWidth - AndroidUtilities.dp(18.5f) - checkDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.5f) - checkDrawable.getIntrinsicHeight()); + setDrawableBounds(checkDrawable, layoutWidth - AndroidUtilities.dp(18.5f) - checkDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - checkDrawable.getIntrinsicHeight()); } checkDrawable.draw(canvas); } else { @@ -590,7 +590,7 @@ public class ChatBaseCell extends BaseCell { } if (drawCheck1) { if (!media) { - setDrawableBounds(halfCheckDrawable, layoutWidth - AndroidUtilities.dp(18) - halfCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.5f) - halfCheckDrawable.getIntrinsicHeight()); + setDrawableBounds(halfCheckDrawable, layoutWidth - AndroidUtilities.dp(18) - halfCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - halfCheckDrawable.getIntrinsicHeight()); halfCheckDrawable.draw(canvas); } else { setDrawableBounds(halfCheckMediaDrawable, layoutWidth - AndroidUtilities.dp(20.5f) - halfCheckMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.0f) - halfCheckMediaDrawable.getIntrinsicHeight()); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java index 87825a1c6..db40b041c 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 d04e80cc4..4c74c471a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java @@ -55,12 +55,15 @@ public class DialogCell extends BaseCell { private static Paint linePaint; private long currentDialogId; - private boolean allowPrintStrings; + private boolean isDialogCell; private int lastMessageDate; private int unreadCount; private boolean lastUnreadState; + private int lastSendState; private boolean dialogMuted; private MessageObject message; + private int index; + private boolean isServerOnly; private ImageReceiver avatarImage; private AvatarDrawable avatarDrawable; @@ -166,14 +169,24 @@ public class DialogCell extends BaseCell { avatarDrawable = new AvatarDrawable(); } - public void setDialog(long dialog_id, MessageObject messageObject, boolean usePrintStrings, int date, int unread, boolean muted) { + public void setDialog(TLRPC.TL_dialog dialog, int i, boolean server) { + currentDialogId = dialog.id; + isDialogCell = true; + index = i; + isServerOnly = server; + update(0); + } + + public void setDialog(long dialog_id, MessageObject messageObject, int date) { currentDialogId = dialog_id; message = messageObject; - allowPrintStrings = usePrintStrings; + isDialogCell = false; lastMessageDate = date; - unreadCount = unread; - dialogMuted = muted; + unreadCount = 0; lastUnreadState = messageObject != null && messageObject.isUnread(); + if (message != null) { + lastSendState = message.messageOwner.send_state; + } update(0); } @@ -211,7 +224,7 @@ public class DialogCell extends BaseCell { String countString = null; CharSequence messageString = ""; CharSequence printingString = null; - if (allowPrintStrings) { + if (isDialogCell) { printingString = MessagesController.getInstance().printingStrings.get(currentDialogId); } TextPaint currentNamePaint = namePaint; @@ -543,15 +556,15 @@ public class DialogCell extends BaseCell { if (LocaleController.isRTL) { if (nameLayout != null && nameLayout.getLineCount() > 0) { left = nameLayout.getLineLeft(0); + widthpx = Math.ceil(nameLayout.getLineWidth(0)); + if (dialogMuted) { + nameMuteLeft = (int) (nameLeft + (nameWidth - widthpx) - AndroidUtilities.dp(6) - muteDrawable.getIntrinsicWidth()); + } if (left == 0) { - widthpx = Math.ceil(nameLayout.getLineWidth(0)); if (widthpx < nameWidth) { nameLeft += (nameWidth - widthpx); } } - if (dialogMuted) { - nameMuteLeft = (nameLeft - AndroidUtilities.dp(6) - muteDrawable.getIntrinsicWidth()); - } } if (messageLayout != null && messageLayout.getLineCount() > 0) { left = messageLayout.getLineLeft(0); @@ -587,10 +600,37 @@ public class DialogCell extends BaseCell { } } + public void checkCurrentDialogIndex() { + TLRPC.TL_dialog dialog = null; + if (isServerOnly) { + dialog = MessagesController.getInstance().dialogsServerOnly.get(index); + } else { + dialog = MessagesController.getInstance().dialogs.get(index); + } + boolean update = true; + 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) { + 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 +658,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 +668,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; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/GreySectionCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/GreySectionCell.java index b13f3de75..633e02c8e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/GreySectionCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/GreySectionCell.java @@ -9,7 +9,6 @@ package org.telegram.ui.Cells; import android.content.Context; -import android.util.AttributeSet; import android.util.TypedValue; import android.view.Gravity; import android.widget.FrameLayout; @@ -21,7 +20,9 @@ import org.telegram.android.LocaleController; public class GreySectionCell extends FrameLayout { private TextView textView; - private void init() { + public GreySectionCell(Context context) { + super(context); + setBackgroundColor(0xfff2f2f2); textView = new TextView(getContext()); @@ -39,26 +40,6 @@ public class GreySectionCell extends FrameLayout { textView.setLayoutParams(layoutParams); } - public GreySectionCell(Context context) { - super(context); - init(); - } - - public GreySectionCell(Context context, AttributeSet attrs) { - super(context, attrs); - init(); - } - - public GreySectionCell(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - init(); - } - - public GreySectionCell(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - init(); - } - @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(36), MeasureSpec.EXACTLY)); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoEditToolCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoEditToolCell.java index b6be0e98c..faf3b1630 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 15a240371..2fe47d9e0 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 4879a0c09..f00434920 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoPickerPhotoCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoPickerPhotoCell.java @@ -11,7 +11,6 @@ package org.telegram.ui.Cells; import android.content.Context; import android.view.Gravity; import android.widget.FrameLayout; -import android.widget.ImageView; import org.telegram.android.AndroidUtilities; import org.telegram.messenger.R; @@ -23,7 +22,6 @@ public class PhotoPickerPhotoCell extends FrameLayout { public BackupImageView photoImage; public FrameLayout checkFrame; public CheckBox checkBox; - public ImageView editedImage; public int itemWidth; public PhotoPickerPhotoCell(Context context) { @@ -57,16 +55,6 @@ public class PhotoPickerPhotoCell extends FrameLayout { layoutParams.topMargin = AndroidUtilities.dp(6); layoutParams.rightMargin = AndroidUtilities.dp(6); checkBox.setLayoutParams(layoutParams); - - editedImage = new ImageView(context); - editedImage.setImageResource(R.drawable.photo_edit); - editedImage.setScaleType(ImageView.ScaleType.CENTER); - addView(editedImage); - layoutParams = (LayoutParams) editedImage.getLayoutParams(); - layoutParams.width = AndroidUtilities.dp(42); - layoutParams.height = AndroidUtilities.dp(42); - layoutParams.gravity = Gravity.LEFT | Gravity.TOP; - editedImage.setLayoutParams(layoutParams); } @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoPickerSearchCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoPickerSearchCell.java index ecd88357d..30c1fe4c6 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 2ddd7307b..1938fea35 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 000000000..4b7d29c58 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedMediaSectionCell.java @@ -0,0 +1,50 @@ +/* + * This is the source code of Telegram for Android v. 2.x + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2015. + */ + +package org.telegram.ui.Cells; + +import android.content.Context; +import android.util.TypedValue; +import android.view.Gravity; +import android.widget.FrameLayout; +import android.widget.TextView; + +import org.telegram.android.AndroidUtilities; +import org.telegram.android.LocaleController; + +public class SharedMediaSectionCell extends FrameLayout { + + private TextView textView; + + public SharedMediaSectionCell(Context context) { + super(context); + + textView = new TextView(getContext()); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + textView.setTextColor(0xff222222); + textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL); + addView(textView); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)textView.getLayoutParams(); + layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams.leftMargin = AndroidUtilities.dp(13); + layoutParams.rightMargin = AndroidUtilities.dp(13); + layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT; + textView.setLayoutParams(layoutParams); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(40), MeasureSpec.EXACTLY)); + } + + public void setText(String text) { + textView.setText(text); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedPhotoVideoCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedPhotoVideoCell.java new file mode 100644 index 000000000..90f3d4f54 --- /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/ChangeChatNameActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangeChatNameActivity.java index ddecb6b5a..5213e61c9 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 666525aa4..465b38ff1 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 d0dc19b26..181158062 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; @@ -1013,7 +1013,7 @@ public class ChangePhoneActivity extends BaseFragment { destroyCodeTimer(); UserConfig.setCurrentUser(user); UserConfig.saveConfig(true); - ArrayList users = new ArrayList(); + ArrayList users = new ArrayList<>(); users.add(user); MessagesStorage.getInstance().putUsersAndChats(users, null, true, true); MessagesController.getInstance().putUser(user, false); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneHelpActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneHelpActivity.java index e2c2b2cb5..a2f952728 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); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChangeUsernameActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangeUsernameActivity.java index 42c811344..0f5d84290 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 7b4590106..adbcd76d9 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,6 +42,8 @@ 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; @@ -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<>(); @@ -216,6 +218,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private final static int share_contact = 13; private final static int mute = 14; + private final static int id_chat_compose_panel = 1000; + AdapterView.OnItemLongClickListener onItemLongClickListener = new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView adapter, View view, int position, long id) { @@ -362,68 +366,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 +471,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; @@ -557,7 +501,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,17 +530,17 @@ 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); @@ -782,7 +726,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 +739,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(); - editor.putInt("notify2_" + dialog_id, 3); - editor.putInt("notifyuntil_" + dialog_id, untilTime); - long flags = ((long)untilTime << 32) | 1; + long flags = 0; + if (i == 3) { + editor.putInt("notify2_" + dialog_id, 2); + flags = 1; + } else { + editor.putInt("notify2_" + dialog_id, 3); + editor.putInt("notifyuntil_" + dialog_id, untilTime); + flags = ((long)untilTime << 32) | 1; + } MessagesStorage.getInstance().setDialogFlags(dialog_id, flags); editor.commit(); TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(dialog_id); @@ -1025,92 +978,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; } }); - 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); + if (currentEncryptedChat == null) { + TextView emptyView = new TextView(getParentActivity()); + if (currentUser != null && (currentUser.id / 1000 == 333 || currentUser.id % 1000 == 0)) { + emptyView.setText(LocaleController.getString("GotAQuestion", R.string.GotAQuestion)); + } else { + emptyView.setText(LocaleController.getString("NoMessages", R.string.NoMessages)); + } + emptyView.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 +1200,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 +1250,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 +1295,129 @@ 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()); + progressBar.setIndeterminateDrawable(getParentActivity().getResources().getDrawable(R.drawable.loading_animation)); + 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, 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); } - - if (stickersAdapter != null) { - stickersAdapter.destroy(); - } - + stickersPanel.addView(stickersListView); + layoutParams2 = (FrameLayout.LayoutParams) stickersListView.getLayoutParams(); + layoutParams2.width = FrameLayout.LayoutParams.MATCH_PARENT; + layoutParams2.height = AndroidUtilities.dp(78); + stickersListView.setLayoutParams(layoutParams2); if (currentEncryptedChat == null || currentEncryptedChat != null && AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 23) { + if (stickersAdapter != null) { + stickersAdapter.destroy(); + } stickersListView.setPadding(AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18), 0); stickersListView.setAdapter(stickersAdapter = new StickersAdapter(getParentActivity(), new StickersAdapter.StickersAdapterDelegate() { @Override @@ -1363,33 +1501,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 +1574,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 +1663,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 +1678,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 +1693,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,11 +1713,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not preferences.edit().remove("dialog_" + dialog_id).commit(); hideKeyboard = true; } else if (currentEncryptedChat instanceof TLRPC.TL_encryptedChat) { - bottomOverlay.setVisibility(View.GONE); + bottomOverlay.setVisibility(View.INVISIBLE); } if (hideKeyboard) { chatActivityEnterView.hideEmojiPopup(); - AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); + if (getParentActivity() != null) { + AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); + } } checkActionBarMenu(); } @@ -1624,7 +1783,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 +1817,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 +1844,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 +1920,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 +1958,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 +2117,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) { @@ -2828,7 +3017,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); } } @@ -2946,19 +3135,20 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (menuItem != null) { menuItem.closeSubMenu(); } - chatActivityEnterView.hideEmojiPopup(); paused = true; NotificationsController.getInstance().setOpennedDialogId(0); - - String text = chatActivityEnterView.getFieldText(); - if (text != null) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - editor.putString("dialog_" + dialog_id, text); - editor.commit(); + if (chatActivityEnterView != null) { + chatActivityEnterView.hideEmojiPopup(); + String text = chatActivityEnterView.getFieldText(); + if (text != null) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.putString("dialog_" + dialog_id, text); + editor.commit(); + } + chatActivityEnterView.setFieldFocused(false); } - chatActivityEnterView.setFieldFocused(false); MessagesController.getInstance().cancelTyping(dialog_id); if (currentEncryptedChat != null) { @@ -3071,7 +3261,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 +3275,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 +3288,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 +3380,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 +3498,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 +3528,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 +3598,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 +3610,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 +3657,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 +3719,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 +3944,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 +3991,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 +4045,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 ec5c9fd8d..5538b2233 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarDrawable.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarDrawable.java @@ -13,6 +13,7 @@ import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.os.Build; import android.text.Layout; import android.text.StaticLayout; import android.text.TextPaint; @@ -164,6 +165,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 +182,26 @@ public class AvatarDrawable extends Drawable { } lastch = lastName.substring(a, a + 1); } - text += lastch; + if (Build.VERSION.SDK_INT >= 14) { + 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 >= 14) { + 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 { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarUpdater.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/AvatarUpdater.java index 2b0150e50..0073edba1 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 7f30f2658..ad0478dec 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 556827700..7c8a41843 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java @@ -18,6 +18,7 @@ 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 +30,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; @@ -54,7 +55,7 @@ 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 +67,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; @@ -98,7 +100,13 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen private boolean ignoreTextChange; private ChatActivityEnterViewDelegate delegate; - public ChatActivityEnterView() { + public ChatActivityEnterView(Activity context, SizeNotifierRelativeLayout parent, 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 +116,31 @@ 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; + 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 +148,41 @@ 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 +198,6 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen return false; } }); - messsageEditText.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { @@ -197,7 +206,6 @@ public class ChatActivityEnterView implements NotificationCenter.NotificationCen } } }); - messsageEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { @@ -213,14 +221,164 @@ 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) { @@ -279,59 +437,56 @@ 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); } + 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 (processSendingText(messsageEditText.getText().toString())) { messsageEditText.setText(""); @@ -725,10 +880,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 a288647f5..d5441b706 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/ForegroundDetector.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ForegroundDetector.java new file mode 100644 index 000000000..b158dcac3 --- /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/LetterSectionsListView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/LetterSectionsListView.java new file mode 100644 index 000000000..aedc5bcd6 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/LetterSectionsListView.java @@ -0,0 +1,211 @@ +/* + * This is the source code of Telegram for Android v. 1.7.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2014. + */ + +package org.telegram.ui.Components; + +import android.content.Context; +import android.graphics.Canvas; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AbsListView; +import android.widget.ListAdapter; +import android.widget.ListView; + +import org.telegram.android.AndroidUtilities; +import org.telegram.android.LocaleController; +import org.telegram.messenger.FileLog; +import org.telegram.ui.Adapters.BaseSectionsAdapter; + +import java.util.ArrayList; + +public class LetterSectionsListView extends ListView implements AbsListView.OnScrollListener { + + private ArrayList headers = new ArrayList<>(); + private ArrayList headersCache = new ArrayList<>(); + private OnScrollListener mOnScrollListener; + private BaseSectionsAdapter mAdapter; + private int currentFirst = -1; + private int currentVisible = -1; + private int startSection; + private int sectionsCount; + + public LetterSectionsListView(Context context) { + super(context); + super.setOnScrollListener(this); + } + + public LetterSectionsListView(Context context, AttributeSet attrs) { + super(context, attrs); + super.setOnScrollListener(this); + } + + public LetterSectionsListView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + super.setOnScrollListener(this); + } + + @Override + public void setAdapter(ListAdapter adapter) { + if (mAdapter == adapter) { + return; + } + headers.clear(); + headersCache.clear(); + if (adapter instanceof BaseSectionsAdapter) { + mAdapter = (BaseSectionsAdapter) adapter; + } else { + mAdapter = null; + } + super.setAdapter(adapter); + } + + @Override + public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { + if (mOnScrollListener != null) { + mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); + } + if (mAdapter == null) { + return; + } + + headersCache.addAll(headers); + headers.clear(); + + if (mAdapter.getCount() == 0) { + return; + } + + if (currentFirst != firstVisibleItem || currentVisible != visibleItemCount) { + currentFirst = firstVisibleItem; + currentVisible = visibleItemCount; + + sectionsCount = 1; + startSection = mAdapter.getSectionForPosition(firstVisibleItem); + int itemNum = firstVisibleItem + mAdapter.getCountForSection(startSection) - mAdapter.getPositionInSectionForPosition(firstVisibleItem); + while (true) { + if (itemNum >= firstVisibleItem + visibleItemCount) { + break; + } + itemNum += mAdapter.getCountForSection(startSection + sectionsCount); + sectionsCount++; + } + } + + int itemNum = firstVisibleItem; + for (int a = startSection; a < startSection + sectionsCount; a++) { + View header = null; + if (!headersCache.isEmpty()) { + header = headersCache.get(0); + headersCache.remove(0); + } + header = getSectionHeaderView(a, header); + headers.add(header); + int count = mAdapter.getCountForSection(a); + if (a == startSection) { + int pos = mAdapter.getPositionInSectionForPosition(itemNum); + if (pos == count - 1) { + header.setTag(-header.getHeight()); + } else if (pos == count - 2) { + View child = getChildAt(itemNum - firstVisibleItem); + int headerTop = 0; + if (child != null) { + headerTop = child.getTop(); + } else { + headerTop = -AndroidUtilities.dp(100); + } + if (headerTop < 0) { + header.setTag(headerTop); + } else { + header.setTag(0); + } + } else { + header.setTag(0); + } + itemNum += count - mAdapter.getPositionInSectionForPosition(firstVisibleItem); + } else { + View child = getChildAt(itemNum - firstVisibleItem); + if (child != null) { + header.setTag(child.getTop()); + } else { + header.setTag(-AndroidUtilities.dp(100)); + } + itemNum += count; + } + } + } + + @Override + public void onScrollStateChanged(AbsListView view, int scrollState) { + if (mOnScrollListener != null) { + mOnScrollListener.onScrollStateChanged(view, scrollState); + } + } + + private View getSectionHeaderView(int section, View oldView) { + boolean shouldLayout = oldView == null; + View view = mAdapter.getSectionHeaderView(section, oldView, this); + if (shouldLayout) { + ensurePinnedHeaderLayout(view, false); + } + return view; + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + if (mAdapter == null || headers.isEmpty()) { + return; + } + for (View header : headers) { + ensurePinnedHeaderLayout(header, true); + } + } + + private void ensurePinnedHeaderLayout(View header, boolean forceLayout) { + if (header.isLayoutRequested() || forceLayout) { + ViewGroup.LayoutParams layoutParams = header.getLayoutParams(); + int heightSpec = MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY); + int widthSpec = MeasureSpec.makeMeasureSpec(layoutParams.width, MeasureSpec.EXACTLY); + try { + header.measure(widthSpec, heightSpec); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + header.layout(0, 0, header.getMeasuredWidth(), header.getMeasuredHeight()); + } + } + + @Override + protected void dispatchDraw(Canvas canvas) { + super.dispatchDraw(canvas); + if (mAdapter == null || headers.isEmpty()) { + return; + } + for (View header : headers) { + int saveCount = canvas.save(); + int top = (Integer)header.getTag(); + canvas.translate(LocaleController.isRTL ? getWidth() - header.getWidth() : 0, top); + canvas.clipRect(0, 0, getWidth(), header.getMeasuredHeight()); + if (top < 0) { + canvas.saveLayerAlpha(0, top, header.getWidth(), top + canvas.getHeight(), (int)(255 * (1.0f + (float)top / (float)header.getMeasuredHeight())), Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); + } + header.draw(canvas); + canvas.restoreToCount(saveCount); + } + } + + @Override + public void setOnScrollListener(OnScrollListener l) { + mOnScrollListener = l; + } + + public void setOnItemClickListener(LetterSectionsListView.OnItemClickListener listener) { + super.setOnItemClickListener(listener); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/NumberPicker.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/NumberPicker.java index a0c15f5f2..37efc31a6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/NumberPicker.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/NumberPicker.java @@ -73,7 +73,7 @@ public class NumberPicker extends LinearLayout { private OnScrollListener mOnScrollListener; private Formatter mFormatter; private long mLongPressUpdateInterval = DEFAULT_LONG_PRESS_UPDATE_INTERVAL; - private final SparseArray mSelectorIndexToStringCache = new SparseArray(); + private final SparseArray mSelectorIndexToStringCache = new SparseArray<>(); private final int[] mSelectorIndices = new int[SELECTOR_WHEEL_ITEM_COUNT]; private Paint mSelectorWheelPaint; private Drawable mVirtualButtonPressedDrawable; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/PasscodeView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PasscodeView.java new file mode 100644 index 000000000..dfd03904d --- /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 (passwordFrameLayout.getTag() != 0) { + t = (Integer) passwordFrameLayout.getTag(); + } + LayoutParams layoutParams = (LayoutParams) passwordFrameLayout.getLayoutParams(); + layoutParams.topMargin = t + layoutParams.height - keyboardHeight / 2 - (Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0); + passwordFrameLayout.setLayoutParams(layoutParams); + } + + super.onLayout(changed, left, top, right, bottom); + } + + @Override + protected void onDraw(Canvas canvas) { + if (getVisibility() != VISIBLE) { + return; + } + if (backgroundDrawable != null) { + if (backgroundDrawable instanceof ColorDrawable) { + backgroundDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight()); + backgroundDrawable.draw(canvas); + } else { + float scaleX = (float) getMeasuredWidth() / (float) backgroundDrawable.getIntrinsicWidth(); + float scaleY = (float) (getMeasuredHeight() + keyboardHeight) / (float) backgroundDrawable.getIntrinsicHeight(); + float scale = scaleX < scaleY ? scaleY : scaleX; + int width = (int) Math.ceil(backgroundDrawable.getIntrinsicWidth() * scale); + int height = (int) Math.ceil(backgroundDrawable.getIntrinsicHeight() * scale); + int x = (getMeasuredWidth() - width) / 2; + int y = (getMeasuredHeight() - height + keyboardHeight) / 2; + backgroundDrawable.setBounds(x, y, x + width, y + height); + backgroundDrawable.draw(canvas); + } + } else { + super.onDraw(canvas); + } + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoCropView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoCropView.java new file mode 100644 index 000000000..4bd9ba572 --- /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 000000000..1d7687df3 --- /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/PhotoFilterView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoFilterView.java new file mode 100644 index 000000000..5730ea768 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoFilterView.java @@ -0,0 +1,1647 @@ +/* + * 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 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); + 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)); + } + 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; + } + 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.getTexture(); + } + + 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); + } + } + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoPickerBottomLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoPickerBottomLayout.java index 97fc7e756..fb6db0a09 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoPickerBottomLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoPickerBottomLayout.java @@ -20,52 +20,43 @@ import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; import org.telegram.messenger.R; -public class PhotoPickerBottomLayout extends LinearLayout { +public class PhotoPickerBottomLayout extends FrameLayout { - public FrameLayout doneButton; + public LinearLayout doneButton; public TextView cancelButton; public TextView doneButtonTextView; public TextView doneButtonBadgeTextView; public PhotoPickerBottomLayout(Context context) { super(context); - setBackgroundColor(0xff333333); - setOrientation(HORIZONTAL); + setBackgroundColor(0xff1a1a1a); cancelButton = new TextView(context); cancelButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); cancelButton.setTextColor(0xffffffff); cancelButton.setGravity(Gravity.CENTER); cancelButton.setBackgroundResource(R.drawable.bar_selector_picker); - cancelButton.setPadding(AndroidUtilities.dp(3), 0, 0, 0); + cancelButton.setPadding(AndroidUtilities.dp(29), 0, AndroidUtilities.dp(29), 0); cancelButton.setText(LocaleController.getString("Cancel", R.string.Cancel).toUpperCase()); cancelButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); addView(cancelButton); LayoutParams layoutParams = (LayoutParams) cancelButton.getLayoutParams(); - layoutParams.width = 0; + layoutParams.width = LayoutParams.WRAP_CONTENT; layoutParams.height = LayoutParams.MATCH_PARENT; - layoutParams.weight = 1; + layoutParams.gravity = Gravity.TOP | Gravity.LEFT; cancelButton.setLayoutParams(layoutParams); - doneButton = new FrameLayout(context); + doneButton = new LinearLayout(context); + doneButton.setOrientation(LinearLayout.HORIZONTAL); doneButton.setBackgroundResource(R.drawable.bar_selector_picker); - doneButton.setPadding(0, 0, AndroidUtilities.dp(3), 0); + doneButton.setPadding(AndroidUtilities.dp(29), 0, AndroidUtilities.dp(29), 0); addView(doneButton); layoutParams = (LayoutParams) doneButton.getLayoutParams(); - layoutParams.width = 0; + layoutParams.width = LayoutParams.WRAP_CONTENT; layoutParams.height = LayoutParams.MATCH_PARENT; - layoutParams.weight = 1; + layoutParams.gravity = Gravity.TOP | Gravity.RIGHT; doneButton.setLayoutParams(layoutParams); - LinearLayout linearLayout = new LinearLayout(context); - linearLayout.setOrientation(HORIZONTAL); - doneButton.addView(linearLayout); - FrameLayout.LayoutParams layoutParams1 = (FrameLayout.LayoutParams) linearLayout.getLayoutParams(); - layoutParams1.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams1.height = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams1.gravity = Gravity.CENTER; - linearLayout.setLayoutParams(layoutParams1); - doneButtonBadgeTextView = new TextView(context); doneButtonBadgeTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); doneButtonBadgeTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13); @@ -74,28 +65,27 @@ public class PhotoPickerBottomLayout extends LinearLayout { doneButtonBadgeTextView.setBackgroundResource(R.drawable.photobadge); doneButtonBadgeTextView.setMinWidth(AndroidUtilities.dp(23)); doneButtonBadgeTextView.setPadding(AndroidUtilities.dp(8), 0, AndroidUtilities.dp(8), AndroidUtilities.dp(1)); - linearLayout.addView(doneButtonBadgeTextView); - layoutParams = (LayoutParams) doneButtonBadgeTextView.getLayoutParams(); - layoutParams.width = LayoutParams.WRAP_CONTENT; - layoutParams.height = AndroidUtilities.dp(23); - layoutParams.rightMargin = AndroidUtilities.dp(10); - doneButtonBadgeTextView.setLayoutParams(layoutParams); + doneButton.addView(doneButtonBadgeTextView); + LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams) doneButtonBadgeTextView.getLayoutParams(); + layoutParams1.width = LayoutParams.WRAP_CONTENT; + layoutParams1.height = AndroidUtilities.dp(23); + layoutParams1.rightMargin = AndroidUtilities.dp(10); + layoutParams1.gravity = Gravity.CENTER_VERTICAL; + doneButtonBadgeTextView.setLayoutParams(layoutParams1); doneButtonTextView = new TextView(context); doneButtonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); doneButtonTextView.setTextColor(0xffffffff); doneButtonTextView.setGravity(Gravity.CENTER); doneButtonTextView.setCompoundDrawablePadding(AndroidUtilities.dp(8)); - doneButtonTextView.setBackgroundResource(R.drawable.bar_selector_picker); - doneButtonTextView.setPadding(AndroidUtilities.dp(3), 0, 0, 0); doneButtonTextView.setText(LocaleController.getString("Send", R.string.Send).toUpperCase()); doneButtonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); - linearLayout.addView(doneButtonTextView); - layoutParams = (LayoutParams) doneButtonTextView.getLayoutParams(); - layoutParams.width = LayoutParams.WRAP_CONTENT; - layoutParams.gravity = Gravity.CENTER_VERTICAL; - layoutParams.height = LayoutParams.WRAP_CONTENT; - doneButtonTextView.setLayoutParams(layoutParams); + doneButton.addView(doneButtonTextView); + layoutParams1 = (LinearLayout.LayoutParams) doneButtonTextView.getLayoutParams(); + layoutParams1.width = LayoutParams.WRAP_CONTENT; + layoutParams1.gravity = Gravity.CENTER_VERTICAL; + layoutParams1.height = LayoutParams.WRAP_CONTENT; + doneButtonTextView.setLayoutParams(layoutParams1); } public void updateSelectedCount(int count, boolean disable) { @@ -103,12 +93,10 @@ public class PhotoPickerBottomLayout extends LinearLayout { doneButtonBadgeTextView.setVisibility(View.GONE); if (disable) { - doneButtonTextView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.selectphoto_small_grey, 0, 0, 0); doneButtonTextView.setTextColor(0xff999999); doneButton.setEnabled(false); } else { doneButtonTextView.setTextColor(0xffffffff); - doneButtonTextView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.selectphoto_small_active, 0, 0, 0); } } else { doneButtonTextView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/SectionsListView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SectionsListView.java index 0d833ee41..a9d4daf79 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/SectionsListView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SectionsListView.java @@ -1,9 +1,9 @@ /* - * This is the source code of Telegram for Android v. 1.7.x. + * This is the source code of Telegram for Android v. 2.x * It is licensed under GNU GPL v. 2 or later. * You should have received a copy of the license in this archive (see LICENSE). * - * Copyright Nikolai Kudashov, 2013-2014. + * Copyright Nikolai Kudashov, 2013-2015. */ package org.telegram.ui.Components; @@ -12,7 +12,6 @@ import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.view.View; -import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.ListAdapter; import android.widget.ListView; @@ -22,18 +21,12 @@ import org.telegram.android.LocaleController; import org.telegram.messenger.FileLog; import org.telegram.ui.Adapters.BaseSectionsAdapter; -import java.util.ArrayList; - public class SectionsListView extends ListView implements AbsListView.OnScrollListener { - private ArrayList headers = new ArrayList(); - private ArrayList headersCache = new ArrayList(); + private View pinnedHeader; private OnScrollListener mOnScrollListener; private BaseSectionsAdapter mAdapter; - private int currentFirst = -1; - private int currentVisible = -1; - private int startSection; - private int sectionsCount; + private int currentStartSection = -1; public SectionsListView(Context context) { super(context); @@ -55,8 +48,7 @@ public class SectionsListView extends ListView implements AbsListView.OnScrollLi if (mAdapter == adapter) { return; } - headers.clear(); - headersCache.clear(); + pinnedHeader = null; if (adapter instanceof BaseSectionsAdapter) { mAdapter = (BaseSectionsAdapter) adapter; } else { @@ -74,69 +66,38 @@ public class SectionsListView extends ListView implements AbsListView.OnScrollLi return; } - headersCache.addAll(headers); - headers.clear(); - if (mAdapter.getCount() == 0) { return; } - if (currentFirst != firstVisibleItem || currentVisible != visibleItemCount) { - currentFirst = firstVisibleItem; - currentVisible = visibleItemCount; - - sectionsCount = 1; - startSection = mAdapter.getSectionForPosition(firstVisibleItem); - int itemNum = firstVisibleItem + mAdapter.getCountForSection(startSection) - mAdapter.getPositionInSectionForPosition(firstVisibleItem); - while (true) { - if (itemNum >= firstVisibleItem + visibleItemCount) { - break; - } - itemNum += mAdapter.getCountForSection(startSection + sectionsCount); - sectionsCount++; - } + int startSection = mAdapter.getSectionForPosition(firstVisibleItem); + if (currentStartSection != startSection || pinnedHeader == null) { + pinnedHeader = getSectionHeaderView(startSection, pinnedHeader); + currentStartSection = startSection; } - int itemNum = firstVisibleItem; - for (int a = startSection; a < startSection + sectionsCount; a++) { - View header = null; - if (!headersCache.isEmpty()) { - header = headersCache.get(0); - headersCache.remove(0); - } - header = getSectionHeaderView(a, header); - headers.add(header); - int count = mAdapter.getCountForSection(a); - if (a == startSection) { - int pos = mAdapter.getPositionInSectionForPosition(itemNum); - if (pos == count - 1) { - header.setTag(-header.getHeight()); - } else if (pos == count - 2) { - View child = getChildAt(itemNum - firstVisibleItem); - int headerTop = 0; - if (child != null) { - headerTop = child.getTop(); - } else { - headerTop = -AndroidUtilities.dp(100); - } - if (headerTop < 0) { - header.setTag(headerTop); - } else { - header.setTag(0); - } - } else { - header.setTag(0); + int count = mAdapter.getCountForSection(startSection); + + int pos = mAdapter.getPositionInSectionForPosition(firstVisibleItem); + if (pos == count - 1) { + View child = getChildAt(0); + int headerHeight = pinnedHeader.getHeight(); + int headerTop = 0; + if (child != null) { + int available = child.getTop() + child.getHeight(); + if (available < headerHeight) { + headerTop = available - headerHeight; } - itemNum += count - mAdapter.getPositionInSectionForPosition(firstVisibleItem); } else { - View child = getChildAt(itemNum - firstVisibleItem); - if (child != null) { - header.setTag(child.getTop()); - } else { - header.setTag(-AndroidUtilities.dp(100)); - } - itemNum += count; + headerTop = -AndroidUtilities.dp(100); } + if (headerTop < 0) { + pinnedHeader.setTag(headerTop); + } else { + pinnedHeader.setTag(0); + } + } else { + pinnedHeader.setTag(0); } invalidate(); @@ -161,19 +122,16 @@ public class SectionsListView extends ListView implements AbsListView.OnScrollLi @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); - if (mAdapter == null || headers.isEmpty()) { + if (mAdapter == null || pinnedHeader == null) { return; } - for (View header : headers) { - ensurePinnedHeaderLayout(header, true); - } + ensurePinnedHeaderLayout(pinnedHeader, true); } private void ensurePinnedHeaderLayout(View header, boolean forceLayout) { if (header.isLayoutRequested() || forceLayout) { - ViewGroup.LayoutParams layoutParams = header.getLayoutParams(); - int heightSpec = MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY); - int widthSpec = MeasureSpec.makeMeasureSpec(layoutParams.width, MeasureSpec.EXACTLY); + int widthSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY); + int heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); try { header.measure(widthSpec, heightSpec); } catch (Exception e) { @@ -186,20 +144,15 @@ public class SectionsListView extends ListView implements AbsListView.OnScrollLi @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); - if (mAdapter == null || headers.isEmpty()) { + if (mAdapter == null || pinnedHeader == null) { return; } - for (View header : headers) { - int saveCount = canvas.save(); - int top = (Integer)header.getTag(); - canvas.translate(LocaleController.isRTL ? getWidth() - header.getWidth() : 0, top); - canvas.clipRect(0, 0, getWidth(), header.getMeasuredHeight()); - if (top < 0) { - canvas.saveLayerAlpha(0, top, header.getWidth(), top + canvas.getHeight(), (int)(255 * (1.0f + (float)top / (float)header.getMeasuredHeight())), Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); - } - header.draw(canvas); - canvas.restoreToCount(saveCount); - } + int saveCount = canvas.save(); + int top = (Integer)pinnedHeader.getTag(); + canvas.translate(LocaleController.isRTL ? getWidth() - pinnedHeader.getWidth() : 0, top); + canvas.clipRect(0, 0, getWidth(), pinnedHeader.getMeasuredHeight()); + pinnedHeader.draw(canvas); + canvas.restoreToCount(saveCount); } @Override @@ -207,7 +160,7 @@ public class SectionsListView extends ListView implements AbsListView.OnScrollLi mOnScrollListener = l; } - public void setOnItemClickListener(SectionsListView.OnItemClickListener listener) { + public void setOnItemClickListener(OnItemClickListener listener) { super.setOnItemClickListener(listener); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayout.java index 214f320f8..61e685895 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/ContactAddActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java index 19e7c29d6..b41814bdd 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 97dbea03b..9e44dcc0d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java @@ -15,6 +15,7 @@ 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 +48,7 @@ import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.Components.SectionsListView; +import org.telegram.ui.Components.LetterSectionsListView; import java.util.ArrayList; import java.util.HashMap; @@ -56,7 +57,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 +88,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 +111,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,7 +127,11 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter if (returnAsResult) { actionBar.setTitle(LocaleController.getString("SelectContact", R.string.SelectContact)); } else { - actionBar.setTitle(LocaleController.getString("NewMessageTitle", R.string.NewMessageTitle)); + 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 +158,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 +217,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 +235,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 +295,24 @@ 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); + 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) { Bundle args = new Bundle(); args.putBoolean("broadcast", true); - presentFragment(new GroupCreateActivity(args), true); + presentFragment(new GroupCreateActivity(args), false); } } } else { @@ -348,7 +354,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); } @@ -462,8 +468,13 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter TLRPC.EncryptedChat encryptedChat = (TLRPC.EncryptedChat)args[0]; Bundle args2 = new Bundle(); args2.putInt("enc_id", encryptedChat.id); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); presentFragment(new ChatActivity(args2), true); } + } else if (id == NotificationCenter.closeChats) { + if (!creatingChat) { + removeSelfFromStack(); + } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java index e1607f583..3b48f411e 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 177c9ae0b..b2229753d 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<>(); @@ -125,7 +125,7 @@ public class DocumentSelectActivity extends BaseFragment { } @Override - public View createView(LayoutInflater inflater, ViewGroup container) { + public View createView(LayoutInflater inflater) { if (!receiverRegistered) { receiverRegistered = true; IntentFilter filter = new IntentFilter(); @@ -194,7 +194,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() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java index 07dc0a608..02ee365c1 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 ab3fd663f..c5974180b 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 a4a591998..88ae3a8b7 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/LanguageSelectActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java index 0744b1ab3..e73f58576 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 daefea9ca..79cd7c00f 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 4f8347b18..a80b2d774 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 ea916e6af..952492d01 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java @@ -59,6 +59,7 @@ import org.telegram.ui.Adapters.DrawerLayoutAdapter; import org.telegram.ui.ActionBar.ActionBarLayout; import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ActionBar.DrawerLayoutContainer; +import org.telegram.ui.Components.PasscodeView; import java.io.BufferedReader; import java.io.InputStream; @@ -89,9 +90,16 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa private ImageView backgroundTablet; private DrawerLayoutContainer drawerLayoutContainer; private DrawerLayoutAdapter drawerLayoutAdapter; + private PasscodeView passcodeView; + + private Intent passcodeSaveIntent; + private boolean passcodeSaveIntentIsNew; + private boolean passcodeSaveIntentIsRestore; private boolean tabletFullSize; + private Runnable lockRunnable; + @Override protected void onCreate(Bundle savedInstanceState) { ApplicationLoader.postInitApplication(); @@ -122,6 +130,10 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa super.onCreate(savedInstanceState); + if (UserConfig.passcodeHash.length() != 0 && UserConfig.appLocked) { + UserConfig.lastPauseTime = ConnectionsManager.getInstance().getCurrentTime(); + } + int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { AndroidUtilities.statusBarHeight = getResources().getDimensionPixelSize(resourceId); @@ -276,7 +288,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, ContactsController.getInstance().getInviteText()); - startActivity(Intent.createChooser(intent, "")); + startActivityForResult(Intent.createChooser(intent, LocaleController.getString("InviteFriends", R.string.InviteFriends)), 500); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -287,7 +299,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } else if (position == 9) { try { Intent pickIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(LocaleController.getString("TelegramFaqUrl", R.string.TelegramFaqUrl))); - startActivity(pickIntent); + startActivityForResult(pickIntent, 500); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -301,6 +313,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 +330,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,113 +411,242 @@ 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) { - boolean pushOpened = false; + private void showPasscodeActivity() { + if (passcodeView == null) { + return; + } + UserConfig.appLocked = true; + if (PhotoViewer.getInstance().isVisible()) { + PhotoViewer.getInstance().closePhoto(false, true); + } + passcodeView.onShow(); + UserConfig.isWaitingForPasscodeEnter = true; + drawerLayoutContainer.setAllowOpenDrawer(false); + 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(); + } + } + }); + } - Integer push_user_id = 0; - Integer push_chat_id = 0; - Integer push_enc_id = 0; - Integer open_settings = 0; - boolean showDialogsList = false; + private boolean handleIntent(Intent intent, boolean isNew, boolean restore, boolean fromPassword) { + int flags = intent.getFlags(); + if (!fromPassword && (AndroidUtilities.needShowPasscode(true) || UserConfig.isWaitingForPasscodeEnter)) { + showPasscodeActivity(); + passcodeSaveIntent = intent; + passcodeSaveIntentIsNew = isNew; + passcodeSaveIntentIsRestore = restore; + UserConfig.saveConfig(false); + } else { + boolean pushOpened = false; - photoPathsArray = null; - videoPath = null; - sendingText = null; - documentsPathsArray = null; - documentsOriginalPathsArray = null; - documentsMimeType = null; - documentsUrisArray = null; - contactsToSend = null; + Integer push_user_id = 0; + Integer push_chat_id = 0; + Integer push_enc_id = 0; + Integer open_settings = 0; + boolean showDialogsList = false; - if (UserConfig.isClientActivated() && !UserConfig.isWaitingForPasswordEnter() && (intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) { - if (intent != null && intent.getAction() != null && !restore) { - if (Intent.ACTION_SEND.equals(intent.getAction())) { - boolean error = false; - String type = intent.getType(); - if (type != null && (type.equals("text/plain") || type.equals("message/rfc822")) && (intent.getStringExtra(Intent.EXTRA_TEXT) != null || intent.getCharSequenceExtra(Intent.EXTRA_TEXT) != null)) { - String text = intent.getStringExtra(Intent.EXTRA_TEXT); - if (text == null) { - text = intent.getCharSequenceExtra(Intent.EXTRA_TEXT).toString(); - } - String subject = intent.getStringExtra(Intent.EXTRA_SUBJECT); + photoPathsArray = null; + videoPath = null; + sendingText = null; + documentsPathsArray = null; + documentsOriginalPathsArray = null; + documentsMimeType = null; + documentsUrisArray = null; + contactsToSend = null; - if (text != null && text.length() != 0) { - if ((text.startsWith("http://") || text.startsWith("https://")) && subject != null && subject.length() != 0) { - text = subject + "\n" + text; + if (UserConfig.isClientActivated() && !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; + String type = intent.getType(); + if (type != null && (type.equals("text/plain") || type.equals("message/rfc822")) && (intent.getStringExtra(Intent.EXTRA_TEXT) != null || intent.getCharSequenceExtra(Intent.EXTRA_TEXT) != null)) { + String text = intent.getStringExtra(Intent.EXTRA_TEXT); + if (text == null) { + text = intent.getCharSequenceExtra(Intent.EXTRA_TEXT).toString(); } - sendingText = text; - } else { - error = true; - } - } else if (type != null && type.equals(ContactsContract.Contacts.CONTENT_VCARD_TYPE)) { - try { - Uri uri = (Uri) intent.getExtras().get(Intent.EXTRA_STREAM); - if (uri != null) { - ContentResolver cr = getContentResolver(); - InputStream stream = cr.openInputStream(uri); + String subject = intent.getStringExtra(Intent.EXTRA_SUBJECT); - String name = null; - String nameEncoding = null; - String nameCharset = null; - ArrayList phones = new ArrayList<>(); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream, "UTF-8")); - String line = null; - while ((line = bufferedReader.readLine()) != null) { - String[] args = line.split(":"); - if (args.length != 2) { - continue; + if (text != null && text.length() != 0) { + if ((text.startsWith("http://") || text.startsWith("https://")) && subject != null && subject.length() != 0) { + text = subject + "\n" + text; + } + sendingText = text; + } else { + error = true; + } + } else if (type != null && type.equals(ContactsContract.Contacts.CONTENT_VCARD_TYPE)) { + try { + Uri uri = (Uri) intent.getExtras().get(Intent.EXTRA_STREAM); + if (uri != null) { + ContentResolver cr = getContentResolver(); + InputStream stream = cr.openInputStream(uri); + + String name = null; + String nameEncoding = null; + String nameCharset = null; + ArrayList phones = new ArrayList<>(); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream, "UTF-8")); + String line = null; + while ((line = bufferedReader.readLine()) != null) { + String[] args = line.split(":"); + if (args.length != 2) { + continue; + } + if (args[0].startsWith("FN")) { + String[] params = args[0].split(";"); + for (String param : params) { + String[] args2 = param.split("="); + if (args2.length != 2) { + continue; + } + if (args2[0].equals("CHARSET")) { + nameCharset = args2[1]; + } else if (args2[0].equals("ENCODING")) { + nameEncoding = args2[1]; + } + } + name = args[1]; + if (nameEncoding != null && nameEncoding.equalsIgnoreCase("QUOTED-PRINTABLE")) { + while (name.endsWith("=") && nameEncoding != null) { + name = name.substring(0, name.length() - 1); + line = bufferedReader.readLine(); + if (line == null) { + break; + } + name += line; + } + byte[] bytes = Utilities.decodeQuotedPrintable(name.getBytes()); + if (bytes != null && bytes.length != 0) { + String decodedName = new String(bytes, nameCharset); + if (decodedName != null) { + name = decodedName; + } + } + } + } else if (args[0].startsWith("TEL")) { + String phone = PhoneFormat.stripExceptNumbers(args[1], true); + if (phone.length() > 0) { + phones.add(phone); + } + } } - if (args[0].startsWith("FN")) { - String[] params = args[0].split(";"); - for (String param : params) { - String[] args2 = param.split("="); - if (args2.length != 2) { - continue; - } - if (args2[0].equals("CHARSET")) { - nameCharset = args2[1]; - } else if (args2[0].equals("ENCODING")) { - nameEncoding = args2[1]; - } + if (name != null && !phones.isEmpty()) { + contactsToSend = new ArrayList<>(); + for (String phone : phones) { + TLRPC.User user = new TLRPC.TL_userContact(); + user.phone = phone; + user.first_name = name; + user.last_name = ""; + user.id = 0; + contactsToSend.add(user); } - name = args[1]; - if (nameEncoding != null && nameEncoding.equalsIgnoreCase("QUOTED-PRINTABLE")) { - while (name.endsWith("=") && nameEncoding != null) { - name = name.substring(0, name.length() - 1); - line = bufferedReader.readLine(); - if (line == null) { - break; - } - name += line; - } - byte[] bytes = Utilities.decodeQuotedPrintable(name.getBytes()); - if (bytes != null && bytes.length != 0) { - String decodedName = new String(bytes, nameCharset); - if (decodedName != null) { - name = decodedName; - } - } + } + } else { + error = true; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + error = true; + } + } else { + Parcelable parcelable = intent.getParcelableExtra(Intent.EXTRA_STREAM); + if (parcelable != null) { + String path = null; + if (!(parcelable instanceof Uri)) { + parcelable = Uri.parse(parcelable.toString()); + } + Uri uri = (Uri) parcelable; + if (uri != null && type != null && type.startsWith("image/")) { + String tempPath = Utilities.getPath(uri); + if (photoPathsArray == null) { + photoPathsArray = new ArrayList<>(); + } + photoPathsArray.add(uri); + } else { + path = Utilities.getPath(uri); + if (path != null) { + if (path.startsWith("file:")) { + path = path.replace("file://", ""); } - } else if (args[0].startsWith("TEL")) { - String phone = PhoneFormat.stripExceptNumbers(args[1], true); - if (phone.length() > 0) { - phones.add(phone); + if (type != null && type.startsWith("video/")) { + videoPath = path; + } else { + if (documentsPathsArray == null) { + documentsPathsArray = new ArrayList<>(); + documentsOriginalPathsArray = new ArrayList<>(); + } + documentsPathsArray.add(path); + documentsOriginalPathsArray.add(uri.toString()); } + } else { + if (documentsUrisArray == null) { + documentsUrisArray = new ArrayList<>(); + } + documentsUrisArray.add(uri); + documentsMimeType = type; } } - if (name != null && !phones.isEmpty()) { - contactsToSend = new ArrayList<>(); - for (String phone : phones) { - TLRPC.User user = new TLRPC.TL_userContact(); - user.phone = phone; - user.first_name = name; - user.last_name = ""; - user.id = 0; - contactsToSend.add(user); + } else { + error = true; + } + if (error) { + Toast.makeText(this, "Unsupported content", Toast.LENGTH_SHORT).show(); + } + } + } else if (intent.getAction().equals(Intent.ACTION_SEND_MULTIPLE)) { + boolean error = false; + try { + ArrayList uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); + String type = intent.getType(); + if (uris != null) { + if (type != null && type.startsWith("image/")) { + for (Parcelable parcelable : uris) { + if (!(parcelable instanceof Uri)) { + parcelable = Uri.parse(parcelable.toString()); + } + Uri uri = (Uri) parcelable; + if (photoPathsArray == null) { + photoPathsArray = new ArrayList<>(); + } + photoPathsArray.add(uri); + } + } else { + for (Parcelable parcelable : uris) { + if (!(parcelable instanceof Uri)) { + parcelable = Uri.parse(parcelable.toString()); + } + String path = Utilities.getPath((Uri) parcelable); + String originalPath = parcelable.toString(); + if (originalPath == null) { + originalPath = path; + } + if (path != null) { + if (path.startsWith("file:")) { + path = path.replace("file://", ""); + } + if (documentsPathsArray == null) { + documentsPathsArray = new ArrayList<>(); + documentsOriginalPathsArray = new ArrayList<>(); + } + documentsPathsArray.add(path); + documentsOriginalPathsArray.add(originalPath); + } } } } else { @@ -501,335 +656,247 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa FileLog.e("tmessages", e); error = true; } - } else { - Parcelable parcelable = intent.getParcelableExtra(Intent.EXTRA_STREAM); - if (parcelable != null) { - String path = null; - if (!(parcelable instanceof Uri)) { - parcelable = Uri.parse(parcelable.toString()); - } - Uri uri = (Uri) parcelable; - if (uri != null && type != null && type.startsWith("image/")) { - String tempPath = Utilities.getPath(uri); - if (photoPathsArray == null) { - photoPathsArray = new ArrayList<>(); - } - photoPathsArray.add(uri); - } else { - path = Utilities.getPath(uri); - if (path != null) { - if (path.startsWith("file:")) { - path = path.replace("file://", ""); - } - if (type != null && type.startsWith("video/")) { - videoPath = path; - } else { - if (documentsPathsArray == null) { - documentsPathsArray = new ArrayList<>(); - documentsOriginalPathsArray = new ArrayList<>(); - } - documentsPathsArray.add(path); - documentsOriginalPathsArray.add(uri.toString()); - } - } else { - if (documentsUrisArray == null) { - documentsUrisArray = new ArrayList<>(); - } - documentsUrisArray.add(uri); - documentsMimeType = type; - } - } - } else { - error = true; - } if (error) { Toast.makeText(this, "Unsupported content", Toast.LENGTH_SHORT).show(); } - } - } else if (intent.getAction().equals(Intent.ACTION_SEND_MULTIPLE)) { - boolean error = false; - try { - ArrayList uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); - String type = intent.getType(); - if (uris != null) { - if (type != null && type.startsWith("image/")) { - for (Parcelable parcelable : uris) { - if (!(parcelable instanceof Uri)) { - parcelable = Uri.parse(parcelable.toString()); - } - Uri uri = (Uri) parcelable; - if (photoPathsArray == null) { - photoPathsArray = new ArrayList<>(); - } - photoPathsArray.add(uri); - } - } else { - for (Parcelable parcelable : uris) { - if (!(parcelable instanceof Uri)) { - parcelable = Uri.parse(parcelable.toString()); - } - String path = Utilities.getPath((Uri) parcelable); - String originalPath = parcelable.toString(); - if (originalPath == null) { - originalPath = path; - } - if (path != null) { - if (path.startsWith("file:")) { - path = path.replace("file://", ""); + } else if (Intent.ACTION_VIEW.equals(intent.getAction())) { + Uri data = intent.getData(); + if (data != null) { + String username = null; + String scheme = data.getScheme(); + if (scheme != null) { + if ((scheme.equals("http") || scheme.equals("https"))) { + String host = data.getHost().toLowerCase(); + if (host.equals("telegram.me")) { + String path = data.getPath(); + if (path != null && path.length() >= 6) { + username = path.substring(1); } - if (documentsPathsArray == null) { - documentsPathsArray = new ArrayList<>(); - documentsOriginalPathsArray = new ArrayList<>(); - } - documentsPathsArray.add(path); - documentsOriginalPathsArray.add(originalPath); + } + } else if (scheme.equals("tg")) { + String url = data.toString().toLowerCase(); + if (url.startsWith("tg:resolve") || url.startsWith("tg://resolve")) { + url = url.replace("tg:resolve", "tg://telegram.org").replace("tg://resolve", "tg://telegram.org"); + data = Uri.parse(url); + username = data.getQueryParameter("domain"); } } } - } else { - error = true; - } - } catch (Exception e) { - FileLog.e("tmessages", e); - error = true; - } - if (error) { - Toast.makeText(this, "Unsupported content", Toast.LENGTH_SHORT).show(); - } - } else if (Intent.ACTION_VIEW.equals(intent.getAction())) { - Uri data = intent.getData(); - if (data != null) { - String username = null; - String scheme = data.getScheme(); - if (scheme != null) { - if ((scheme.equals("http") || scheme.equals("https"))) { - String host = data.getHost().toLowerCase(); - if (host.equals("telegram.me")) { - String path = data.getPath(); - if (path != null && path.length() >= 6) { - username = path.substring(1); - } - } - } else if (scheme.equals("tg")) { - String url = data.toString().toLowerCase(); - if (url.startsWith("tg:resolve") || url.startsWith("tg://resolve")) { - url = url.replace("tg:resolve", "tg://telegram.org").replace("tg://resolve", "tg://telegram.org"); - data = Uri.parse(url); - username = data.getQueryParameter("domain"); - } - } - } - if (username != null) { - final ProgressDialog progressDialog = new ProgressDialog(this); - progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading)); - progressDialog.setCanceledOnTouchOutside(false); - progressDialog.setCancelable(false); + if (username != null) { + final ProgressDialog progressDialog = new ProgressDialog(this); + progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.setCancelable(false); - TLRPC.TL_contacts_resolveUsername req = new TLRPC.TL_contacts_resolveUsername(); - req.username = username; - final long reqId = ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { - @Override - public void run(final TLObject response, final TLRPC.TL_error error) { - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - if (!LaunchActivity.this.isFinishing()) { - try { - progressDialog.dismiss(); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - if (error == null && actionBarLayout != null) { - TLRPC.User user = (TLRPC.User) response; - MessagesController.getInstance().putUser(user, false); - ArrayList users = new ArrayList<>(); - users.add(user); - MessagesStorage.getInstance().putUsersAndChats(users, null, false, true); - Bundle args = new Bundle(); - args.putInt("user_id", user.id); - ChatActivity fragment = new ChatActivity(args); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); - actionBarLayout.presentFragment(fragment, false, true, true); + TLRPC.TL_contacts_resolveUsername req = new TLRPC.TL_contacts_resolveUsername(); + req.username = username; + final long reqId = ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(final TLObject response, final TLRPC.TL_error error) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (!LaunchActivity.this.isFinishing()) { + try { + progressDialog.dismiss(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + if (error == null && actionBarLayout != null) { + TLRPC.User user = (TLRPC.User) response; + MessagesController.getInstance().putUser(user, false); + ArrayList users = new ArrayList<>(); + users.add(user); + MessagesStorage.getInstance().putUsersAndChats(users, null, false, true); + Bundle args = new Bundle(); + args.putInt("user_id", user.id); + ChatActivity fragment = new ChatActivity(args); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); + actionBarLayout.presentFragment(fragment, false, true, true); + } } } - } - }); - } - }); + }); + } + }); - progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, LocaleController.getString("Cancel", R.string.Cancel), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - ConnectionsManager.getInstance().cancelRpc(reqId, true); - try { - dialog.dismiss(); - } catch (Exception e) { - FileLog.e("tmessages", e); + progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, LocaleController.getString("Cancel", R.string.Cancel), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + ConnectionsManager.getInstance().cancelRpc(reqId, true); + try { + dialog.dismiss(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } } - } - }); - progressDialog.show(); - } else { - try { - Cursor cursor = getContentResolver().query(intent.getData(), null, null, null, null); - if (cursor != null) { - if (cursor.moveToFirst()) { - int userId = cursor.getInt(cursor.getColumnIndex("DATA4")); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); - push_user_id = userId; + }); + progressDialog.show(); + } else { + try { + Cursor cursor = getContentResolver().query(intent.getData(), null, null, null, null); + if (cursor != null) { + if (cursor.moveToFirst()) { + int userId = cursor.getInt(cursor.getColumnIndex("DATA4")); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); + push_user_id = userId; + } + cursor.close(); } - cursor.close(); + } catch (Exception e) { + FileLog.e("tmessages", e); } - } catch (Exception e) { - FileLog.e("tmessages", e); } } - } - } else if (intent.getAction().equals("org.telegram.messenger.OPEN_ACCOUNT")) { - open_settings = 1; - } else if (intent.getAction().startsWith("com.tmessages.openchat")) { - int chatId = intent.getIntExtra("chatId", 0); - int userId = intent.getIntExtra("userId", 0); - int encId = intent.getIntExtra("encId", 0); - if (chatId != 0) { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); - push_chat_id = chatId; - } else if (userId != 0) { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); - push_user_id = userId; - } else if (encId != 0) { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); - push_enc_id = encId; - } else { - showDialogsList = true; + } else if (intent.getAction().equals("org.telegram.messenger.OPEN_ACCOUNT")) { + open_settings = 1; + } else if (intent.getAction().startsWith("com.tmessages.openchat")) { + int chatId = intent.getIntExtra("chatId", 0); + int userId = intent.getIntExtra("userId", 0); + int encId = intent.getIntExtra("encId", 0); + if (chatId != 0) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); + push_chat_id = chatId; + } else if (userId != 0) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); + push_user_id = userId; + } else if (encId != 0) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); + push_enc_id = encId; + } else { + showDialogsList = true; + } } } } - } - if (push_user_id != 0) { - if (push_user_id == UserConfig.getClientUserId()) { - open_settings = 1; - } else { + if (push_user_id != 0) { + if (push_user_id == UserConfig.getClientUserId()) { + open_settings = 1; + } else { + Bundle args = new Bundle(); + args.putInt("user_id", push_user_id); + ChatActivity fragment = new ChatActivity(args); + if (actionBarLayout.presentFragment(fragment, false, true, true)) { + pushOpened = true; + } + } + } else if (push_chat_id != 0) { Bundle args = new Bundle(); - args.putInt("user_id", push_user_id); + args.putInt("chat_id", push_chat_id); ChatActivity fragment = new ChatActivity(args); if (actionBarLayout.presentFragment(fragment, false, true, true)) { pushOpened = true; } - } - } else if (push_chat_id != 0) { - Bundle args = new Bundle(); - args.putInt("chat_id", push_chat_id); - ChatActivity fragment = new ChatActivity(args); - if (actionBarLayout.presentFragment(fragment, false, true, true)) { - pushOpened = true; - } - } else if (push_enc_id != 0) { - Bundle args = new Bundle(); - args.putInt("enc_id", push_enc_id); - ChatActivity fragment = new ChatActivity(args); - if (actionBarLayout.presentFragment(fragment, false, true, true)) { - pushOpened = true; - } - } else if (showDialogsList) { - if (!AndroidUtilities.isTablet()) { - actionBarLayout.removeAllFragments(); - } else { - if (!layersActionBarLayout.fragmentsStack.isEmpty()) { - for (int a = 0; a < layersActionBarLayout.fragmentsStack.size() - 1; a++) { - layersActionBarLayout.removeFragmentFromStack(layersActionBarLayout.fragmentsStack.get(0)); - a--; - } - layersActionBarLayout.closeLastFragment(false); + } else if (push_enc_id != 0) { + Bundle args = new Bundle(); + args.putInt("enc_id", push_enc_id); + ChatActivity fragment = new ChatActivity(args); + if (actionBarLayout.presentFragment(fragment, false, true, true)) { + pushOpened = true; } - } - pushOpened = false; - isNew = false; - } else if (videoPath != null || photoPathsArray != null || sendingText != null || documentsPathsArray != null || contactsToSend != null || documentsUrisArray != null) { - if (!AndroidUtilities.isTablet()) { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); - } - Bundle args = new Bundle(); - args.putBoolean("onlySelect", true); - args.putString("selectAlertString", LocaleController.getString("SendMessagesTo", R.string.SendMessagesTo)); - args.putString("selectAlertStringGroup", LocaleController.getString("SendMessagesToGroup", R.string.SendMessagesToGroup)); - MessagesActivity fragment = new MessagesActivity(args); - fragment.setDelegate(this); - boolean removeLast = false; - if (AndroidUtilities.isTablet()) { - removeLast = layersActionBarLayout.fragmentsStack.size() > 0 && layersActionBarLayout.fragmentsStack.get(layersActionBarLayout.fragmentsStack.size() - 1) instanceof MessagesActivity; - } else { - removeLast = actionBarLayout.fragmentsStack.size() > 1 && actionBarLayout.fragmentsStack.get(actionBarLayout.fragmentsStack.size() - 1) instanceof MessagesActivity; - } - actionBarLayout.presentFragment(fragment, removeLast, true, true); - pushOpened = true; - if (PhotoViewer.getInstance().isVisible()) { - PhotoViewer.getInstance().closePhoto(false); + } else if (showDialogsList) { + if (!AndroidUtilities.isTablet()) { + actionBarLayout.removeAllFragments(); + } else { + if (!layersActionBarLayout.fragmentsStack.isEmpty()) { + for (int a = 0; a < layersActionBarLayout.fragmentsStack.size() - 1; a++) { + layersActionBarLayout.removeFragmentFromStack(layersActionBarLayout.fragmentsStack.get(0)); + a--; + } + layersActionBarLayout.closeLastFragment(false); + } + } + pushOpened = false; + isNew = false; + } else if (videoPath != null || photoPathsArray != null || sendingText != null || documentsPathsArray != null || contactsToSend != null || documentsUrisArray != null) { + if (!AndroidUtilities.isTablet()) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); + } + Bundle args = new Bundle(); + args.putBoolean("onlySelect", true); + args.putString("selectAlertString", LocaleController.getString("SendMessagesTo", R.string.SendMessagesTo)); + args.putString("selectAlertStringGroup", LocaleController.getString("SendMessagesToGroup", R.string.SendMessagesToGroup)); + MessagesActivity fragment = new MessagesActivity(args); + fragment.setDelegate(this); + boolean removeLast = false; + if (AndroidUtilities.isTablet()) { + removeLast = layersActionBarLayout.fragmentsStack.size() > 0 && layersActionBarLayout.fragmentsStack.get(layersActionBarLayout.fragmentsStack.size() - 1) instanceof MessagesActivity; + } else { + removeLast = actionBarLayout.fragmentsStack.size() > 1 && actionBarLayout.fragmentsStack.get(actionBarLayout.fragmentsStack.size() - 1) instanceof MessagesActivity; + } + actionBarLayout.presentFragment(fragment, removeLast, true, true); + pushOpened = true; + if (PhotoViewer.getInstance().isVisible()) { + PhotoViewer.getInstance().closePhoto(false, true); + } + + if (AndroidUtilities.isTablet()) { + actionBarLayout.showLastFragment(); + rightActionBarLayout.showLastFragment(); + } + drawerLayoutContainer.setAllowOpenDrawer(false); + } else if (open_settings != 0) { + actionBarLayout.presentFragment(new SettingsActivity(), false, true, true); + drawerLayoutContainer.setAllowOpenDrawer(false); + if (AndroidUtilities.isTablet()) { + actionBarLayout.showLastFragment(); + rightActionBarLayout.showLastFragment(); + } + pushOpened = true; } - if (AndroidUtilities.isTablet()) { - actionBarLayout.showLastFragment(); - rightActionBarLayout.showLastFragment(); - } - drawerLayoutContainer.setAllowOpenDrawer(false); - } else if (open_settings != 0) { - actionBarLayout.presentFragment(new SettingsActivity(), false, true, true); - drawerLayoutContainer.setAllowOpenDrawer(false); - if (AndroidUtilities.isTablet()) { - actionBarLayout.showLastFragment(); - rightActionBarLayout.showLastFragment(); - } - pushOpened = true; - } - if (!pushOpened && !isNew) { - if (AndroidUtilities.isTablet()) { - if (!UserConfig.isClientActivated() && !UserConfig.isWaitingForPasswordEnter()) { - if (layersActionBarLayout.fragmentsStack.isEmpty()) { - layersActionBarLayout.addFragmentToStack(new LoginActivity()); - drawerLayoutContainer.setAllowOpenDrawer(false); + if (!pushOpened && !isNew) { + if (AndroidUtilities.isTablet()) { + if (!UserConfig.isClientActivated() && !UserConfig.isWaitingForPasswordEnter()) { + if (layersActionBarLayout.fragmentsStack.isEmpty()) { + layersActionBarLayout.addFragmentToStack(new LoginActivity()); + drawerLayoutContainer.setAllowOpenDrawer(false); + } + } else { + if (actionBarLayout.fragmentsStack.isEmpty()) { + if (UserConfig.isWaitingForPasswordEnter()) { + layersActionBarLayout.addFragmentToStack(new AccountPasswordActivity(1)); + drawerLayoutContainer.setAllowOpenDrawer(false); + } else { + actionBarLayout.addFragmentToStack(new MessagesActivity(null)); + drawerLayoutContainer.setAllowOpenDrawer(true); + } + } } } else { if (actionBarLayout.fragmentsStack.isEmpty()) { - if (UserConfig.isWaitingForPasswordEnter()) { - layersActionBarLayout.addFragmentToStack(new AccountPasswordActivity(1)); + if (!UserConfig.isClientActivated() && !UserConfig.isWaitingForPasswordEnter()) { + actionBarLayout.addFragmentToStack(new LoginActivity()); drawerLayoutContainer.setAllowOpenDrawer(false); } else { - actionBarLayout.addFragmentToStack(new MessagesActivity(null)); - drawerLayoutContainer.setAllowOpenDrawer(true); + if (UserConfig.isWaitingForPasswordEnter()) { + actionBarLayout.addFragmentToStack(new AccountPasswordActivity(1)); + drawerLayoutContainer.setAllowOpenDrawer(false); + } else { + actionBarLayout.addFragmentToStack(new MessagesActivity(null)); + drawerLayoutContainer.setAllowOpenDrawer(true); + } } } } - } else { - if (actionBarLayout.fragmentsStack.isEmpty()) { - if (!UserConfig.isClientActivated() && !UserConfig.isWaitingForPasswordEnter()) { - actionBarLayout.addFragmentToStack(new LoginActivity()); - drawerLayoutContainer.setAllowOpenDrawer(false); - } else { - if (UserConfig.isWaitingForPasswordEnter()) { - actionBarLayout.addFragmentToStack(new AccountPasswordActivity(1)); - drawerLayoutContainer.setAllowOpenDrawer(false); - } else { - actionBarLayout.addFragmentToStack(new MessagesActivity(null)); - drawerLayoutContainer.setAllowOpenDrawer(true); - } - } + actionBarLayout.showLastFragment(); + if (AndroidUtilities.isTablet()) { + layersActionBarLayout.showLastFragment(); + rightActionBarLayout.showLastFragment(); } } - actionBarLayout.showLastFragment(); - if (AndroidUtilities.isTablet()) { - layersActionBarLayout.showLastFragment(); - rightActionBarLayout.showLastFragment(); - } - } - intent.setAction(null); + intent.setAction(null); + return pushOpened; + } + return false; } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); - handleIntent(intent, true, false); + handleIntent(intent, true, false, false); } @Override @@ -910,11 +977,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 +1036,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 +1062,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 +1094,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 +1118,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa @Override protected void onPause() { super.onPause(); + onPasscodePause(); actionBarLayout.onPause(); if (AndroidUtilities.isTablet()) { rightActionBarLayout.onPause(); @@ -1053,10 +1139,15 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa @Override protected void onResume() { super.onResume(); - actionBarLayout.onResume(); - if (AndroidUtilities.isTablet()) { - rightActionBarLayout.onResume(); - layersActionBarLayout.onResume(); + onPasscodeResume(); + if (passcodeView.getVisibility() != View.VISIBLE) { + actionBarLayout.onResume(); + if (AndroidUtilities.isTablet()) { + rightActionBarLayout.onResume(); + layersActionBarLayout.onResume(); + } + } else { + passcodeView.onResume(); } Utilities.checkForCrashes(this); Utilities.checkForUpdates(this); @@ -1100,6 +1191,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 +1224,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 +1339,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 +1398,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 +1418,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 195ebf11e..c3efdf404 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 2814c8b32..67f329f65 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java @@ -103,7 +103,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)); @@ -829,9 +829,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 +895,6 @@ public class LoginActivity extends BaseFragment { private String phoneHash; private String requestPhone; - private String registered; private EditText codeField; private TextView confirmTextView; private TextView timeText; @@ -1067,7 +1063,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) { @@ -1241,7 +1236,7 @@ public class LoginActivity extends BaseFragment { } 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); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java index 811f0f3e4..b0b16d52f 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("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); } - }); + 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 d79c4cfe3..21bba0e4d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java @@ -26,7 +26,6 @@ import android.view.ViewTreeObserver; import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.AbsListView; import android.widget.AdapterView; -import android.widget.BaseAdapter; import android.widget.CheckBox; import android.widget.EditText; import android.widget.FrameLayout; @@ -67,6 +66,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 +88,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 +109,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 +139,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 +178,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 +201,7 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter if (dialogsSearchAdapter != null) { dialogsSearchAdapter.searchDialogs(null, false); } + updatePasscodeButton(); } @Override @@ -196,8 +215,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 +243,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 +262,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 +329,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() { @@ -559,29 +579,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 +637,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 +681,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 ace44bad7..993396853 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); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PasscodeActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PasscodeActivity.java new file mode 100644 index 000000000..2394d61b2 --- /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("123456789")); + } 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 61646ad1e..96c5cac9d 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 910b4f444..26a04b4e0 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 5e0ff8f4e..000000000 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoEditorActivity.java +++ /dev/null @@ -1,1285 +0,0 @@ -/* - * This is the source code of Telegram for Android v. 2.0.x. - * It is licensed under GNU GPL v. 2 or later. - * You should have received a copy of the license in this archive (see LICENSE). - * - * Copyright Nikolai Kudashov, 2013-2014. - */ - -package org.telegram.ui; - -import android.content.Context; -import android.content.res.Configuration; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.net.Uri; -import android.opengl.GLES20; -import android.opengl.GLSurfaceView; -import android.opengl.GLUtils; -import android.os.Build; -import android.os.Bundle; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewTreeObserver; -import android.view.animation.AccelerateDecelerateInterpolator; -import android.view.animation.AccelerateInterpolator; -import android.view.animation.DecelerateInterpolator; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.SeekBar; - -import org.telegram.android.AndroidUtilities; -import org.telegram.android.ImageLoader; -import org.telegram.android.LocaleController; -import org.telegram.messenger.FileLog; -import org.telegram.messenger.R; -import org.telegram.ui.ActionBar.ActionBar; -import org.telegram.ui.ActionBar.ActionBarMenu; -import org.telegram.ui.ActionBar.ActionBarMenuItem; -import org.telegram.ui.ActionBar.BaseFragment; -import org.telegram.ui.AnimationCompat.AnimatorListenerAdapterProxy; -import org.telegram.ui.AnimationCompat.AnimatorSetProxy; -import org.telegram.ui.AnimationCompat.ObjectAnimatorProxy; -import org.telegram.ui.AnimationCompat.ViewProxy; -import org.telegram.ui.Cells.PhotoEditToolCell; -import org.telegram.ui.Components.RecyclerListView; - -import java.io.File; -import java.lang.reflect.Field; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; - -import javax.microedition.khronos.opengles.GL10; - -public class PhotoEditorActivity extends BaseFragment { - - private GLSurfaceView glView; - private PhotoCropView cropView; - - private SeekBar valueSeekBar; - private LinearLayout toolsView; - private LinearLayout cropButtonsView; - private ImageView imageView; - private ImageView filtersButton; - private ImageView toolButton; - private AnimatorSetProxy rotationAnimation; - - private ActionBarMenuItem doneButton; - private ActionBarMenuItem sizeButton; - private ActionBarMenuItem rotateButton; - - private boolean sameBitmap = false; - private int currentMode = 0; - private boolean freeformCrop; - private boolean onlyCrop; - - private PhotoCropActivity.PhotoEditActivityDelegate delegate; - - private int selectedTool = 0; - private int rotateDegree = 0; - - private Bitmap bitmapToEdit; - private String bitmapKey; - - private float highlightsValue = 0; //0 100 - private float contrastValue = 0; //-100 100 - private float shadowsValue = 0; //0 100 - private float exposureValue = 0; //-100 100 - private float saturationValue = 0; //-100 100 - private float warmthValue = 0; //-100 100 - private float vignetteValue = 0; //0 100 - private float grainValue = 0; //0 100 - private float width = 0; - private float height = 0; - - private boolean donePressed = false; - - private final static int done_button = 1; - private final static int rotate_button = 2; - private final static int size_button = 3; - - private class PhotoCropView extends FrameLayout { - - private Paint rectPaint; - private Paint circlePaint; - private Paint halfPaint; - private Paint shadowPaint; - private float rectSizeX = 600; - private float rectSizeY = 600; - private int draggingState = 0; - private float oldX = 0, oldY = 0; - private int bitmapWidth = 1, bitmapHeight = 1, bitmapX, bitmapY; - private float rectX = -1, rectY = -1; - - public PhotoCropView(Context context) { - super(context); - - rectPaint = new Paint(); - rectPaint.setColor(0xb2ffffff); - rectPaint.setStrokeWidth(AndroidUtilities.dp(2)); - rectPaint.setStyle(Paint.Style.STROKE); - circlePaint = new Paint(); - circlePaint.setColor(0xffffffff); - halfPaint = new Paint(); - halfPaint.setColor(0x7f000000); - shadowPaint = new Paint(); - shadowPaint.setColor(0x1a000000); - setWillNotDraw(false); - - setOnTouchListener(new OnTouchListener() { - @Override - public boolean onTouch(View view, MotionEvent motionEvent) { - float x = motionEvent.getX(); - float y = motionEvent.getY(); - int cornerSide = AndroidUtilities.dp(20); - if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { - if (rectX - cornerSide < x && rectX + cornerSide > x && rectY - cornerSide < y && rectY + cornerSide > y) { - draggingState = 1; - } else if (rectX - cornerSide + rectSizeX < x && rectX + cornerSide + rectSizeX > x && rectY - cornerSide < y && rectY + cornerSide > y) { - draggingState = 2; - } else if (rectX - cornerSide < x && rectX + cornerSide > x && rectY - cornerSide + rectSizeY < y && rectY + cornerSide + rectSizeY > y) { - draggingState = 3; - } else if (rectX - cornerSide + rectSizeX < x && rectX + cornerSide + rectSizeX > x && rectY - cornerSide + rectSizeY < y && rectY + cornerSide + rectSizeY > y) { - draggingState = 4; - } else if (rectX < x && rectX + rectSizeX > x && rectY < y && rectY + rectSizeY > y) { - draggingState = 5; - } else { - draggingState = 0; - } - if (draggingState != 0) { - PhotoCropView.this.requestDisallowInterceptTouchEvent(true); - } - oldX = x; - oldY = y; - } else if (motionEvent.getAction() == MotionEvent.ACTION_UP) { - draggingState = 0; - } else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE && draggingState != 0) { - float diffX = x - oldX; - float diffY = y - oldY; - if (draggingState == 5) { - rectX += diffX; - rectY += diffY; - - if (rectX < bitmapX) { - rectX = bitmapX; - } else if (rectX + rectSizeX > bitmapX + bitmapWidth) { - rectX = bitmapX + bitmapWidth - rectSizeX; - } - if (rectY < bitmapY) { - rectY = bitmapY; - } else if (rectY + rectSizeY > bitmapY + bitmapHeight) { - rectY = bitmapY + bitmapHeight - rectSizeY; - } - } else { - if (draggingState == 1) { - if (rectSizeX - diffX < 160) { - diffX = rectSizeX - 160; - } - if (rectX + diffX < bitmapX) { - diffX = bitmapX - rectX; - } - if (!freeformCrop) { - if (rectY + diffX < bitmapY) { - diffX = bitmapY - rectY; - } - rectX += diffX; - rectY += diffX; - rectSizeX -= diffX; - rectSizeY -= diffX; - } else { - if (rectSizeY - diffY < 160) { - diffY = rectSizeY - 160; - } - if (rectY + diffY < bitmapY) { - diffY = bitmapY - rectY; - } - rectX += diffX; - rectY += diffY; - rectSizeX -= diffX; - rectSizeY -= diffY; - } - } else if (draggingState == 2) { - if (rectSizeX + diffX < 160) { - diffX = -(rectSizeX - 160); - } - if (rectX + rectSizeX + diffX > bitmapX + bitmapWidth) { - diffX = bitmapX + bitmapWidth - rectX - rectSizeX; - } - if (!freeformCrop) { - if (rectY - diffX < bitmapY) { - diffX = rectY - bitmapY; - } - rectY -= diffX; - rectSizeX += diffX; - rectSizeY += diffX; - } else { - if (rectSizeY - diffY < 160) { - diffY = rectSizeY - 160; - } - if (rectY + diffY < bitmapY) { - diffY = bitmapY - rectY; - } - rectY += diffY; - rectSizeX += diffX; - rectSizeY -= diffY; - } - } else if (draggingState == 3) { - if (rectSizeX - diffX < 160) { - diffX = rectSizeX - 160; - } - if (rectX + diffX < bitmapX) { - diffX = bitmapX - rectX; - } - if (!freeformCrop) { - if (rectY + rectSizeX - diffX > bitmapY + bitmapHeight) { - diffX = rectY + rectSizeX - bitmapY - bitmapHeight; - } - rectX += diffX; - rectSizeX -= diffX; - rectSizeY -= diffX; - } else { - if (rectY + rectSizeY + diffY > bitmapY + bitmapHeight) { - diffY = bitmapY + bitmapHeight - rectY - rectSizeY; - } - rectX += diffX; - rectSizeX -= diffX; - rectSizeY += diffY; - if (rectSizeY < 160) { - rectSizeY = 160; - } - } - } else if (draggingState == 4) { - if (rectX + rectSizeX + diffX > bitmapX + bitmapWidth) { - diffX = bitmapX + bitmapWidth - rectX - rectSizeX; - } - if (!freeformCrop) { - if (rectY + rectSizeX + diffX > bitmapY + bitmapHeight) { - diffX = bitmapY + bitmapHeight - rectY - rectSizeX; - } - rectSizeX += diffX; - rectSizeY += diffX; - } else { - if (rectY + rectSizeY + diffY > bitmapY + bitmapHeight) { - diffY = bitmapY + bitmapHeight - rectY - rectSizeY; - } - rectSizeX += diffX; - rectSizeY += diffY; - } - if (rectSizeX < 160) { - rectSizeX = 160; - } - if (rectSizeY < 160) { - rectSizeY = 160; - } - } - } - - oldX = x; - oldY = y; - invalidate(); - } - return true; - } - }); - } - - public Bitmap getBitmap() { - float percX = (rectX - bitmapX) / bitmapWidth; - float percY = (rectY - bitmapY) / bitmapHeight; - float percSizeX = rectSizeX / bitmapWidth; - float percSizeY = rectSizeY / bitmapWidth; - int x = (int)(percX * bitmapToEdit.getWidth()); - int y = (int)(percY * bitmapToEdit.getHeight()); - int sizeX = (int)(percSizeX * bitmapToEdit.getWidth()); - int sizeY = (int)(percSizeY * bitmapToEdit.getWidth()); - if (x + sizeX > bitmapToEdit.getWidth()) { - sizeX = bitmapToEdit.getWidth() - x; - } - if (y + sizeY > bitmapToEdit.getHeight()) { - sizeY = bitmapToEdit.getHeight() - y; - } - try { - return Bitmap.createBitmap(bitmapToEdit, x, y, sizeX, sizeY); - } catch (Throwable e) { - FileLog.e("tmessags", e); - System.gc(); - try { - return Bitmap.createBitmap(bitmapToEdit, x, y, sizeX, sizeY); - } catch (Throwable e2) { - FileLog.e("tmessages", e2); - } - } - return null; - } - - @Override - protected void onDraw(Canvas canvas) { - canvas.drawRect(bitmapX, bitmapY, bitmapX + bitmapWidth, rectY, halfPaint); - canvas.drawRect(bitmapX, rectY, rectX, rectY + rectSizeY, halfPaint); - canvas.drawRect(rectX + rectSizeX, rectY, bitmapX + bitmapWidth, rectY + rectSizeY, halfPaint); - canvas.drawRect(bitmapX, rectY + rectSizeY, bitmapX + bitmapWidth, bitmapY + bitmapHeight, halfPaint); - - int side = AndroidUtilities.dp(1); - canvas.drawRect(rectX - side * 2, rectY - side * 2, rectX - side * 2 + AndroidUtilities.dp(20), rectY, circlePaint); - canvas.drawRect(rectX - side * 2, rectY - side * 2, rectX, rectY - side * 2 + AndroidUtilities.dp(20), circlePaint); - - canvas.drawRect(rectX + rectSizeX + side * 2 - AndroidUtilities.dp(20), rectY - side * 2, rectX + rectSizeX + side * 2, rectY, circlePaint); - canvas.drawRect(rectX + rectSizeX, rectY - side * 2, rectX + rectSizeX + side * 2, rectY - side * 2 + AndroidUtilities.dp(20), circlePaint); - - canvas.drawRect(rectX - side * 2, rectY + rectSizeY + side * 2 - AndroidUtilities.dp(20), rectX, rectY + rectSizeY + side * 2, circlePaint); - canvas.drawRect(rectX - side * 2, rectY + rectSizeY, rectX - side * 2 + AndroidUtilities.dp(20), rectY + rectSizeY + side * 2, circlePaint); - - canvas.drawRect(rectX + rectSizeX + side * 2 - AndroidUtilities.dp(20), rectY + rectSizeY, rectX + rectSizeX + side * 2, rectY + rectSizeY + side * 2, circlePaint); - canvas.drawRect(rectX + rectSizeX, rectY + rectSizeY + side * 2 - AndroidUtilities.dp(20), rectX + rectSizeX + side * 2, rectY + rectSizeY + side * 2, circlePaint); - - for (int a = 1; a < 3; a++) { - canvas.drawRect(rectX + rectSizeX / 3 * a - side, rectY, rectX + side * 2 + rectSizeX / 3 * a, rectY + rectSizeY, shadowPaint); - canvas.drawRect(rectX, rectY + rectSizeY / 3 * a - side, rectX + rectSizeX, rectY + rectSizeY / 3 * a + side * 2, shadowPaint); - } - - for (int a = 1; a < 3; a++) { - canvas.drawRect(rectX + rectSizeX / 3 * a, rectY, rectX + side + rectSizeX / 3 * a, rectY + rectSizeY, circlePaint); - canvas.drawRect(rectX, rectY + rectSizeY / 3 * a, rectX + rectSizeX, rectY + rectSizeY / 3 * a + side, circlePaint); - } - - canvas.drawRect(rectX, rectY, rectX + rectSizeX, rectY + rectSizeY, rectPaint); - } - } - - class MyGLSurfaceView extends GLSurfaceView { - - public MyGLSurfaceView(Context context){ - super(context); - setEGLContextClientVersion(2); - setRenderer(new MyGLRenderer()); - setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); - } - } - - public class MyGLRenderer implements GLSurfaceView.Renderer { - - private int trivialShaderProgram; - - private int positionHandle; - private int inputTexCoordHandle; - private int photoImageHandle; - private int shadowsHandle; - private int highlightsHandle; - private int exposureHandle; - private int contrastHandle; - private int saturationHandle; - private int warmthHandle; - private int vignetteHandle; - private int grainHandle; - private int grainWidthHandle; - private int grainHeightHandle; - - private int[] textures = new int[1]; - - private FloatBuffer vertexBuffer; - private FloatBuffer textureBuffer; - private FloatBuffer vertexSaveBuffer; - - private static final String trivialVertexShaderCode = - "attribute vec4 position;" + - "attribute vec4 inputTexCoord;" + - "varying vec2 texCoord;" + - "void main() {" + - "gl_Position = position;" + - "texCoord = inputTexCoord.xy;" + - "}"; - - private static final String trivialFragmentShaderCode = - "varying highp vec2 texCoord;" + - "uniform sampler2D photoImage;" + - "uniform lowp float shadows;" + - "uniform highp float width;" + - "uniform highp float height;" + - "const mediump vec3 hsLuminanceWeighting = vec3(0.3, 0.3, 0.3);" + - "uniform lowp float highlights;" + - "uniform highp float exposure;" + - "uniform lowp float contrast;" + - "const mediump vec3 satLuminanceWeighting = vec3(0.2126, 0.7152, 0.0722);" + - "uniform lowp float saturation;" + - "uniform lowp float warmth;" + - "uniform lowp float grain;" + - "const lowp float permTexUnit = 1.0 / 256.0;" + - "const lowp float permTexUnitHalf = 0.5 / 256.0;" + - "const lowp float grainsize = 2.3;" + - "uniform lowp float vignette;" + - "highp float getLuma(highp vec3 rgbP) { return (0.299 * rgbP.r) + (0.587 * rgbP.g) + (0.114 * rgbP.b); }" + - "highp vec3 rgbToYuv(highp vec3 inP) { highp vec3 outP; outP.r = getLuma(inP); outP.g = (1.0 / 1.772) * (inP.b - outP.r); outP.b = (1.0 / 1.402) * (inP.r - outP.r); return outP; }" + - "lowp vec3 yuvToRgb(highp vec3 inP) { highp float y = inP.r; highp float u = inP.g; highp float v = inP.b; lowp vec3 outP; outP.r = 1.402 * v + y; outP.g = (y - (0.299 * 1.402 / 0.587) * v - (0.114 * 1.772 / 0.587) * u); outP.b = 1.772 * u + y; return outP; } " + - "lowp float easeInOutSigmoid(lowp float value, lowp float strength) { lowp float t = 1.0 / (1.0 - strength); if (value > 0.5) { return 1.0 - pow(2.0 - 2.0 * value, t) * 0.5; } else { return pow(2.0 * value, t) * 0.5; } }" + - "highp vec4 rnm(in highp vec2 tc) { highp float noise = sin(dot(tc,vec2(12.9898,78.233))) * 43758.5453; highp float noiseR = fract(noise)*2.0-1.0; highp float noiseG = fract(noise*1.2154)*2.0-1.0; highp float noiseB = fract(noise*1.3453)*2.0-1.0; " + - "highp float noiseA = fract(noise*1.3647)*2.0-1.0; return vec4(noiseR,noiseG,noiseB,noiseA); } highp float fade(in highp float t) { return t*t*t*(t*(t*6.0-15.0)+10.0); } highp float pnoise3D(in highp vec3 p) { highp vec3 pi = permTexUnit*floor(p)+permTexUnitHalf; " + - "highp vec3 pf = fract(p); highp float perm00 = rnm(pi.xy).a ; highp vec3 grad000 = rnm(vec2(perm00, pi.z)).rgb * 4.0 - 1.0; highp float n000 = dot(grad000, pf); highp vec3 grad001 = rnm(vec2(perm00, pi.z + permTexUnit)).rgb * 4.0 - 1.0; " + - "highp float n001 = dot(grad001, pf - vec3(0.0, 0.0, 1.0)); highp float perm01 = rnm(pi.xy + vec2(0.0, permTexUnit)).a ; highp vec3 grad010 = rnm(vec2(perm01, pi.z)).rgb * 4.0 - 1.0; highp float n010 = dot(grad010, pf - vec3(0.0, 1.0, 0.0));" + - "highp vec3 grad011 = rnm(vec2(perm01, pi.z + permTexUnit)).rgb * 4.0 - 1.0; highp float n011 = dot(grad011, pf - vec3(0.0, 1.0, 1.0)); highp float perm10 = rnm(pi.xy + vec2(permTexUnit, 0.0)).a ;" + - "highp vec3 grad100 = rnm(vec2(perm10, pi.z)).rgb * 4.0 - 1.0; highp float n100 = dot(grad100, pf - vec3(1.0, 0.0, 0.0)); highp vec3 grad101 = rnm(vec2(perm10, pi.z + permTexUnit)).rgb * 4.0 - 1.0;" + - "highp float n101 = dot(grad101, pf - vec3(1.0, 0.0, 1.0)); highp float perm11 = rnm(pi.xy + vec2(permTexUnit, permTexUnit)).a ; highp vec3 grad110 = rnm(vec2(perm11, pi.z)).rgb * 4.0 - 1.0; highp float n110 = dot(grad110, pf - vec3(1.0, 1.0, 0.0));" + - "highp vec3 grad111 = rnm(vec2(perm11, pi.z + permTexUnit)).rgb * 4.0 - 1.0; highp float n111 = dot(grad111, pf - vec3(1.0, 1.0, 1.0)); highp vec4 n_x = mix(vec4(n000, n001, n010, n011), vec4(n100, n101, n110, n111), fade(pf.x));" + - "highp vec2 n_xy = mix(n_x.xy, n_x.zw, fade(pf.y)); highp float n_xyz = mix(n_xy.x, n_xy.y, fade(pf.z)); return n_xyz; } lowp vec2 coordRot(in lowp vec2 tc, in lowp float angle) { lowp float rotX = ((tc.x * 2.0 - 1.0) * cos(angle)) - ((tc.y * 2.0 - 1.0) * sin(angle));" + - "lowp float rotY = ((tc.y * 2.0 - 1.0) * cos(angle)) + ((tc.x * 2.0 - 1.0) * sin(angle)); rotX = rotX * 0.5 + 0.5; rotY = rotY * 0.5 + 0.5; return vec2(rotX,rotY); }void main() {lowp vec4 source = texture2D(photoImage, texCoord);lowp vec4 result = source;" + - "const lowp float toolEpsilon = 0.005;mediump float hsLuminance = dot(result.rgb, hsLuminanceWeighting); mediump float shadow = clamp((pow(hsLuminance, 1.0 / (shadows + 1.0)) + (-0.76) * pow(hsLuminance, 2.0 / (shadows + 1.0))) - hsLuminance, 0.0, 1.0);" + - "mediump float highlight = clamp((1.0 - (pow(1.0 - hsLuminance, 1.0 / (2.0 - highlights)) + (-0.8) * pow(1.0 - hsLuminance, 2.0 / (2.0 - highlights)))) - hsLuminance, -1.0, 0.0);" + - "lowp vec3 shresult = vec3(0.0, 0.0, 0.0) + ((hsLuminance + shadow + highlight) - 0.0) * ((result.rgb - vec3(0.0, 0.0, 0.0)) / (hsLuminance - 0.0)); result = vec4(shresult.rgb, result.a);" + - "if (abs(exposure) > toolEpsilon) { mediump float mag = exposure * 1.045; mediump float exppower = 1.0 + abs(mag); if (mag < 0.0) { exppower = 1.0 / exppower; } result.r = 1.0 - pow((1.0 - result.r), exppower);" + - "result.g = 1.0 - pow((1.0 - result.g), exppower); result.b = 1.0 - pow((1.0 - result.b), exppower); }result = vec4(((result.rgb - vec3(0.5)) * contrast + vec3(0.5)), result.a);" + - "lowp float satLuminance = dot(result.rgb, satLuminanceWeighting); lowp vec3 greyScaleColor = vec3(satLuminance); result = vec4(mix(greyScaleColor, result.rgb, saturation), result.a);" + - "if (abs(warmth) > toolEpsilon) { highp vec3 yuvVec; if (warmth > 0.0 ) { yuvVec = vec3(0.1765, -0.1255, 0.0902); } else { yuvVec = -vec3(0.0588, 0.1569, -0.1255); } highp vec3 yuvColor = rgbToYuv(result.rgb); highp float luma = yuvColor.r;" + - "highp float curveScale = sin(luma * 3.14159); yuvColor += 0.375 * warmth * curveScale * yuvVec; result.rgb = yuvToRgb(yuvColor); }if (abs(grain) > toolEpsilon) { highp vec3 rotOffset = vec3(1.425, 3.892, 5.835);" + - "highp vec2 rotCoordsR = coordRot(texCoord, rotOffset.x); highp vec3 noise = vec3(pnoise3D(vec3(rotCoordsR * vec2(width / grainsize, height / grainsize),0.0))); lowp vec3 lumcoeff = vec3(0.299,0.587,0.114);" + - "lowp float luminance = dot(result.rgb, lumcoeff); lowp float lum = smoothstep(0.2, 0.0, luminance); lum += luminance; noise = mix(noise,vec3(0.0),pow(lum,4.0)); result.rgb = result.rgb + noise * grain; }" + - "if (abs(vignette) > toolEpsilon) { const lowp float midpoint = 0.7; const lowp float fuzziness = 0.62; lowp float radDist = length(texCoord - 0.5) / sqrt(0.5);" + - "lowp float mag = easeInOutSigmoid(radDist * midpoint, fuzziness) * vignette * 0.645; result.rgb = mix(pow(result.rgb, vec3(1.0 / (1.0 - mag))), vec3(0.0), mag * mag); }gl_FragColor = result;}"; - - private int loadShader(int type, String shaderCode) { - int shader = GLES20.glCreateShader(type); - GLES20.glShaderSource(shader, shaderCode); - GLES20.glCompileShader(shader); - int[] compileStatus = new int[1]; - GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compileStatus, 0); - if (compileStatus[0] == 0) { - GLES20.glDeleteShader(shader); - shader = 0; - } - return shader; - } - - @Override - public void onSurfaceCreated(GL10 gl, javax.microedition.khronos.egl.EGLConfig config) { - - float squareCoordinates[] = { - -1.0f, 1.0f, - 1.0f, 1.0f, - -1.0f, -1.0f, - 1.0f, -1.0f}; - - ByteBuffer bb = ByteBuffer.allocateDirect(squareCoordinates.length * 4); - bb.order(ByteOrder.nativeOrder()); - vertexBuffer = bb.asFloatBuffer(); - vertexBuffer.put(squareCoordinates); - vertexBuffer.position(0); - - float squareCoordinates2[] = { - -1.0f, -1.0f, - 1.0f, -1.0f, - -1.0f, 1.0f, - 1.0f, 1.0f}; - - bb = ByteBuffer.allocateDirect(squareCoordinates2.length * 4); - bb.order(ByteOrder.nativeOrder()); - vertexSaveBuffer = bb.asFloatBuffer(); - vertexSaveBuffer.put(squareCoordinates2); - vertexSaveBuffer.position(0); - - float textureCoordinates[] = { - 0.0f, 0.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 1.0f, - }; - - bb = ByteBuffer.allocateDirect(textureCoordinates.length * 4); - bb.order(ByteOrder.nativeOrder()); - textureBuffer = bb.asFloatBuffer(); - textureBuffer.put(textureCoordinates); - textureBuffer.position(0); - - GLES20.glGenTextures(1, textures, 0); - gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); - gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); - gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); - GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmapToEdit, 0); - - int trivialVertexShader = loadShader(GLES20.GL_VERTEX_SHADER, trivialVertexShaderCode); - int trivialFragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, trivialFragmentShaderCode); - - if (trivialVertexShader != 0 && trivialFragmentShader != 0) { - trivialShaderProgram = GLES20.glCreateProgram(); - GLES20.glAttachShader(trivialShaderProgram, trivialVertexShader); - GLES20.glAttachShader(trivialShaderProgram, trivialFragmentShader); - GLES20.glBindAttribLocation(trivialShaderProgram, 0, "position"); - GLES20.glBindAttribLocation(trivialShaderProgram, 1, "inputTexCoord"); - - GLES20.glLinkProgram(trivialShaderProgram); - int[] linkStatus = new int[1]; - GLES20.glGetProgramiv(trivialShaderProgram, GLES20.GL_LINK_STATUS, linkStatus, 0); - if (linkStatus[0] == 0) { - GLES20.glDeleteProgram(trivialShaderProgram); - trivialShaderProgram = 0; - } - } - - if (trivialShaderProgram != 0) { - positionHandle = GLES20.glGetAttribLocation(trivialShaderProgram, "position"); - inputTexCoordHandle = GLES20.glGetAttribLocation(trivialShaderProgram, "inputTexCoord"); - photoImageHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "photoImage"); - shadowsHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "shadows"); - highlightsHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "highlights"); - exposureHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "exposure"); - contrastHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "contrast"); - saturationHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "saturation"); - warmthHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "warmth"); - vignetteHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "vignette"); - grainHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "grain"); - grainWidthHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "width"); - grainHeightHandle = GLES20.glGetUniformLocation(trivialShaderProgram, "height"); - GLES20.glUseProgram(trivialShaderProgram); - } - } - - public void onDrawFrame(GL10 unused) { - GLES20.glActiveTexture(GLES20.GL_TEXTURE0); - GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]); - GLES20.glUniform1i(photoImageHandle, 0); - GLES20.glUniform1f(shadowsHandle, getShadowsValue()); - GLES20.glUniform1f(highlightsHandle, getHighlightsValue()); - GLES20.glUniform1f(exposureHandle, getExposureValue()); - GLES20.glUniform1f(contrastHandle, getContrastValue()); - GLES20.glUniform1f(saturationHandle, getSaturationValue()); - GLES20.glUniform1f(warmthHandle, getWarmthValue()); - GLES20.glUniform1f(vignetteHandle, getVignetteValue()); - GLES20.glUniform1f(grainHandle, getGrainValue()); - GLES20.glUniform1f(grainWidthHandle, width); - GLES20.glUniform1f(grainHeightHandle, height); - GLES20.glEnableVertexAttribArray(inputTexCoordHandle); - GLES20.glVertexAttribPointer(inputTexCoordHandle, 2, GLES20.GL_FLOAT, false, 8, textureBuffer); - GLES20.glEnableVertexAttribArray(positionHandle); - if (donePressed) { - GLES20.glVertexAttribPointer(positionHandle, 2, GLES20.GL_FLOAT, false, 8, vertexSaveBuffer); - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - final Bitmap bitmap = saveTexture((int)width, (int)height); - donePressed = false; - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - delegate.didFinishEdit(bitmap, getArguments()); - finishFragment(); - } - }); - } - GLES20.glVertexAttribPointer(positionHandle, 2, GLES20.GL_FLOAT, false, 8, vertexBuffer); - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - } - - public void onSurfaceChanged(GL10 unused, int width, int height) { - GLES20.glViewport(0, 0, width, height); - } - - public Bitmap saveTexture(int width, int height) { - //int[] frame = new int[1]; - //GLES20.glGenFramebuffers(1, frame, 0); - //GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frame[0]); - //GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, texture, 0); - ByteBuffer buffer = ByteBuffer.allocate(width * height * 4); - GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buffer); - Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - bitmap.copyPixelsFromBuffer(buffer); - //GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); - //GLES20.glDeleteFramebuffers(1, frame, 0); - return bitmap; - } - } - - public PhotoEditorActivity(Bundle args, Bitmap bitmap, String key) { - super(args); - bitmapToEdit = bitmap; - bitmapKey = key; - if (bitmapToEdit != null && key != null) { - ImageLoader.getInstance().incrementUseCount(key); - } - } - - private float getShadowsValue() { - return (shadowsValue / 100.0f) * 0.65f; - } - - private float getHighlightsValue() { - return 1 - (highlightsValue / 100.0f); - } - - private float getExposureValue() { - return (exposureValue / 100.0f); - } - - private float getContrastValue() { - return (contrastValue / 100.0f) * 0.3f + 1; - } - - private float getWarmthValue() { - return warmthValue / 100.0f; - } - - private float getVignetteValue() { - return vignetteValue / 100.0f; - } - - private float getGrainValue() { - return grainValue / 100.0f * 0.04f; - } - - private float getSaturationValue() { - float value = (saturationValue / 100.0f); - if (value < 0) { - value *= 0.55f; - } else { - value *= 1.05f; - } - return value + 1; - } - - @Override - public boolean onFragmentCreate() { - swipeBackEnabled = false; - freeformCrop = getArguments().getBoolean("freeformCrop", false); - onlyCrop = getArguments().getBoolean("onlyCrop", false); - if (bitmapToEdit == null) { - String photoPath = getArguments().getString("photoPath"); - Uri photoUri = getArguments().getParcelable("photoUri"); - if (photoPath == null && photoUri == null) { - return false; - } - if (photoPath != null) { - File f = new File(photoPath); - if (!f.exists()) { - return false; - } - } - int size = 0; - if (AndroidUtilities.isTablet()) { - size = AndroidUtilities.dp(520); - } else { - size = Math.max(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y); - } - bitmapToEdit = ImageLoader.loadBitmap(photoPath, photoUri, size, size, true); - if (bitmapToEdit == null) { - return false; - } - } - return super.onFragmentCreate(); - } - - @Override - public void onFragmentDestroy() { - super.onFragmentDestroy(); - if (bitmapKey != null) { - if (ImageLoader.getInstance().decrementUseCount(bitmapKey) && !ImageLoader.getInstance().isInCache(bitmapKey)) { - bitmapKey = null; - } - } - if (bitmapKey == null && bitmapToEdit != null && !sameBitmap) { - bitmapToEdit.recycle(); - bitmapToEdit = null; - } - } - - @Override - public void onPause() { - super.onPause(); - if (glView != null) { - glView.onPause(); - } - } - - @Override - public void onResume() { - super.onResume(); - if (glView != null) { - glView.onResume(); - } - } - - @Override - public View createView(LayoutInflater inflater, ViewGroup container) { - if (fragmentView == null) { - actionBar.setBackgroundColor(0xff262626); - actionBar.setItemsBackground(R.drawable.bar_selector_picker); - actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setAllowOverlayTitle(true); - actionBar.setTitle(LocaleController.getString("EditImage", R.string.EditImage)); - actionBar.setCastShadows(false); - actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { - @Override - public void onItemClick(int id) { - if (id == -1) { - finishFragment(); - } else if (id == done_button) { - donePressed = true; - glView.requestRender(); - } else if (id == rotate_button) { - int newRotation = rotateDegree; - newRotation += 90; - fixLayoutInternal(newRotation, true); - } - } - }); - - ActionBarMenu menu = actionBar.createMenu(); - rotateButton = menu.addItemWithWidth(rotate_button, R.drawable.photo_rotate, AndroidUtilities.dp(56)); - sizeButton = menu.addItemWithWidth(size_button, R.drawable.photo_sizes, AndroidUtilities.dp(56)); - doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); - - rotateButton.setVisibility(View.GONE); - sizeButton.setVisibility(View.GONE); - - FrameLayout frameLayout = null; - fragmentView = frameLayout = new FrameLayout(getParentActivity()); - fragmentView.setBackgroundColor(0xff262626); - - imageView = new ImageView(getParentActivity()); - imageView.setScaleType(ImageView.ScaleType.MATRIX); - imageView.setImageBitmap(bitmapToEdit); - frameLayout.addView(imageView); - - cropView = new PhotoCropView(getParentActivity()); - cropView.setVisibility(View.GONE); - frameLayout.addView(cropView); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) cropView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - cropView.setLayoutParams(layoutParams); - - cropButtonsView = new LinearLayout(getParentActivity()); - cropButtonsView.setVisibility(View.GONE); - frameLayout.addView(cropButtonsView); - layoutParams = (FrameLayout.LayoutParams) cropButtonsView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.height = AndroidUtilities.dp(48); - layoutParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; - cropButtonsView.setLayoutParams(layoutParams); - - ImageView button = new ImageView(getParentActivity()); - button.setScaleType(ImageView.ScaleType.CENTER); - button.setImageResource(R.drawable.ic_close_white); - cropButtonsView.addView(button); - LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams) button.getLayoutParams(); - layoutParams1.width = AndroidUtilities.dp(48); - layoutParams1.height = AndroidUtilities.dp(48); - button.setLayoutParams(layoutParams1); - button.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (onlyCrop) { - finishFragment(); - } else { - switchToMode(0, true); - } - } - }); - - button = new ImageView(getParentActivity()); - button.setScaleType(ImageView.ScaleType.CENTER); - button.setImageResource(R.drawable.ic_done); - cropButtonsView.addView(button); - layoutParams1 = (LinearLayout.LayoutParams) button.getLayoutParams(); - layoutParams1.width = AndroidUtilities.dp(48); - layoutParams1.height = AndroidUtilities.dp(48); - layoutParams1.leftMargin = AndroidUtilities.dp(146); - button.setLayoutParams(layoutParams1); - button.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (onlyCrop) { - if (delegate != null && currentMode == 1) { - Bitmap bitmap = cropView.getBitmap(); - if (bitmap == bitmapToEdit) { - sameBitmap = true; - } - delegate.didFinishEdit(bitmap, getArguments()); - currentMode = 0; - finishFragment(); - } - } else { - switchToMode(0, false); - } - } - }); - - if (!onlyCrop) { - toolsView = new LinearLayout(getParentActivity()); - frameLayout.addView(toolsView); - layoutParams = (FrameLayout.LayoutParams) toolsView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; - layoutParams.height = AndroidUtilities.dp(48); - layoutParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; - toolsView.setLayoutParams(layoutParams); - - button = new ImageView(getParentActivity()); - button.setScaleType(ImageView.ScaleType.CENTER); - button.setImageResource(R.drawable.photo_crop); - toolsView.addView(button); - layoutParams1 = (LinearLayout.LayoutParams) button.getLayoutParams(); - layoutParams1.width = AndroidUtilities.dp(48); - layoutParams1.height = AndroidUtilities.dp(48); - button.setLayoutParams(layoutParams1); - button.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - switchToMode(1, true); - } - }); - - filtersButton = new ImageView(getParentActivity()); - filtersButton.setScaleType(ImageView.ScaleType.CENTER); - filtersButton.setImageResource(R.drawable.photo_filters); - toolsView.addView(filtersButton); - layoutParams1 = (LinearLayout.LayoutParams) filtersButton.getLayoutParams(); - layoutParams1.width = AndroidUtilities.dp(48); - layoutParams1.height = AndroidUtilities.dp(48); - layoutParams1.leftMargin = AndroidUtilities.dp(54); - filtersButton.setLayoutParams(layoutParams1); - - toolButton = new ImageView(getParentActivity()); - toolButton.setScaleType(ImageView.ScaleType.CENTER); - toolButton.setImageResource(R.drawable.photo_tune); - toolsView.addView(toolButton); - layoutParams1 = (LinearLayout.LayoutParams) toolButton.getLayoutParams(); - layoutParams1.width = AndroidUtilities.dp(48); - layoutParams1.height = AndroidUtilities.dp(48); - layoutParams1.leftMargin = AndroidUtilities.dp(54); - toolButton.setLayoutParams(layoutParams1); - - glView = new MyGLSurfaceView(getParentActivity()); - glView.setVisibility(View.GONE); - frameLayout.addView(glView); - layoutParams = (FrameLayout.LayoutParams) glView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT; - glView.setLayoutParams(layoutParams); - - RecyclerListView toolsView = new RecyclerListView(getParentActivity()); - LinearLayoutManager layoutManager = new LinearLayoutManager(getParentActivity()); - layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); - toolsView.setLayoutManager(layoutManager); - toolsView.setClipToPadding(false); - if (Build.VERSION.SDK_INT >= 9) { - toolsView.setOverScrollMode(RecyclerListView.OVER_SCROLL_NEVER); - } - toolsView.setAdapter(new ToolsAdapter(getParentActivity())); - toolsView.setVisibility(View.GONE); - frameLayout.addView(toolsView); - layoutParams = (FrameLayout.LayoutParams) toolsView.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = AndroidUtilities.dp(60); - layoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM; - layoutParams.bottomMargin = AndroidUtilities.dp(40); - toolsView.setLayoutParams(layoutParams); - toolsView.addOnItemTouchListener(new RecyclerListView.RecyclerListViewItemClickListener(getParentActivity(), new RecyclerListView.OnItemClickListener() { - @Override - public void onItemClick(View view, int i) { - selectedTool = i; - if (i == 0) { - valueSeekBar.setMax(100); - valueSeekBar.setProgress((int) highlightsValue); - } else if (i == 1) { - valueSeekBar.setMax(200); - valueSeekBar.setProgress((int) contrastValue + 100); - } else if (i == 2) { - valueSeekBar.setMax(200); - valueSeekBar.setProgress((int) exposureValue + 100); - } else if (i == 3) { - valueSeekBar.setMax(200); - valueSeekBar.setProgress((int) warmthValue + 100); - } else if (i == 4) { - valueSeekBar.setMax(200); - valueSeekBar.setProgress((int) saturationValue + 100); - } else if (i == 5) { - valueSeekBar.setMax(100); - valueSeekBar.setProgress((int) vignetteValue); - } else if (i == 6) { - valueSeekBar.setMax(100); - valueSeekBar.setProgress((int) shadowsValue); - } else if (i == 7) { - valueSeekBar.setMax(100); - valueSeekBar.setProgress((int) grainValue); - } - } - })); - - valueSeekBar = new SeekBar(getParentActivity()); - valueSeekBar.setVisibility(View.GONE); - valueSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if (!fromUser) { - return; - } - if (selectedTool == 0) { - highlightsValue = progress; - } else if (selectedTool == 1) { - contrastValue = progress - 100; - } else if (selectedTool == 2) { - exposureValue = progress - 100; - } else if (selectedTool == 3) { - warmthValue = progress - 100; - } else if (selectedTool == 4) { - saturationValue = progress - 100; - } else if (selectedTool == 5) { - vignetteValue = progress; - } else if (selectedTool == 6) { - shadowsValue = progress; - } else if (selectedTool == 7) { - grainValue = progress; - } - glView.requestRender(); - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - - } - }); - try { - Field field = ProgressBar.class.getDeclaredField("mMinHeight"); - field.setAccessible(true); - field.setInt(valueSeekBar, AndroidUtilities.dp(40)); - field = ProgressBar.class.getDeclaredField("mMaxHeight"); - field.setAccessible(true); - field.setInt(valueSeekBar, AndroidUtilities.dp(40)); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - frameLayout.addView(valueSeekBar); - layoutParams = (FrameLayout.LayoutParams) valueSeekBar.getLayoutParams(); - layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; - layoutParams.height = AndroidUtilities.dp(40); - layoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM; - layoutParams.leftMargin = AndroidUtilities.dp(10); - layoutParams.rightMargin = AndroidUtilities.dp(10); - valueSeekBar.setLayoutParams(layoutParams); - } else { - switchToMode(1, false); - } - - fixLayout(); - } else { - ViewGroup parent = (ViewGroup)fragmentView.getParent(); - if (parent != null) { - parent.removeView(fragmentView); - } - } - return fragmentView; - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - fixLayout(); - } - - private void switchToMode(final int mode, final boolean animated) { - if (animated) { - if (currentMode == 0) { - AnimatorSetProxy animatorSet = new AnimatorSetProxy(); - animatorSet.playTogether( - ObjectAnimatorProxy.ofFloat(doneButton, "alpha", 1.0f, 0.0f), - ObjectAnimatorProxy.ofFloat(toolsView, "translationY", 0, AndroidUtilities.dp(48))); - animatorSet.setDuration(150); - animatorSet.setInterpolator(new DecelerateInterpolator()); - animatorSet.addListener(new AnimatorListenerAdapterProxy() { - @Override - public void onAnimationEnd(Object animation) { - processFromMode(currentMode, mode, animated); - } - }); - animatorSet.start(); - } else if (currentMode == 1) { - AnimatorSetProxy animatorSet = new AnimatorSetProxy(); - animatorSet.playTogether( - ObjectAnimatorProxy.ofFloat(cropView, "alpha", 1.0f, 0.0f), - ObjectAnimatorProxy.ofFloat(cropButtonsView, "translationY", 0, AndroidUtilities.dp(48)), - ObjectAnimatorProxy.ofFloat(rotateButton, "alpha", 1.0f, 0.0f), - ObjectAnimatorProxy.ofFloat(sizeButton, "alpha", 1.0f, 0.0f)); - animatorSet.setDuration(150); - animatorSet.setInterpolator(new DecelerateInterpolator()); - animatorSet.addListener(new AnimatorListenerAdapterProxy() { - @Override - public void onAnimationEnd(Object animation) { - processFromMode(currentMode, mode, animated); - } - }); - animatorSet.start(); - } - } else { - processFromMode(currentMode, mode, animated); - } - } - - private void processFromMode(int from, int to, boolean animated) { - if (from == 0) { - doneButton.setVisibility(View.GONE); - if (toolsView != null) { - toolsView.setVisibility(View.GONE); - } - processToMode(to, animated); - } else if (from == 1) { - cropView.setVisibility(View.GONE); - rotateButton.setVisibility(View.GONE); - if (freeformCrop) { - sizeButton.setVisibility(View.GONE); - } - cropButtonsView.setVisibility(View.GONE); - processToMode(to, animated); - } - } - - private void processToMode(int to, boolean animated) { - currentMode = to; - if (currentMode == 0) { - doneButton.setVisibility(View.VISIBLE); - toolsView.setVisibility(View.VISIBLE); - actionBar.setTitle(LocaleController.getString("EditImage", R.string.EditImage)); - if (animated) { - AnimatorSetProxy animatorSet = new AnimatorSetProxy(); - animatorSet.playTogether( - ObjectAnimatorProxy.ofFloat(doneButton, "alpha", 0.0f, 1.0f), - ObjectAnimatorProxy.ofFloat(toolsView, "translationY", AndroidUtilities.dp(48), 0)); - animatorSet.setDuration(150); - animatorSet.setInterpolator(new AccelerateInterpolator()); - animatorSet.start(); - } - } else if (currentMode == 1) { - cropView.setVisibility(View.VISIBLE); - rotateButton.setVisibility(View.VISIBLE); - if (freeformCrop) { - sizeButton.setVisibility(View.VISIBLE); - } - cropButtonsView.setVisibility(View.VISIBLE); - actionBar.setTitle(LocaleController.getString("CropImage", R.string.CropImage)); - if (animated) { - AnimatorSetProxy animatorSet = new AnimatorSetProxy(); - animatorSet.playTogether( - ObjectAnimatorProxy.ofFloat(cropView, "alpha", 0.0f, 1.0f), - ObjectAnimatorProxy.ofFloat(cropButtonsView, "translationY", AndroidUtilities.dp(48), 0), - ObjectAnimatorProxy.ofFloat(rotateButton, "alpha", 0.0f, 1.0f), - ObjectAnimatorProxy.ofFloat(sizeButton, "alpha", 0.0f, 1.0f)); - animatorSet.setDuration(150); - animatorSet.setInterpolator(new AccelerateInterpolator()); - animatorSet.start(); - } - } - } - - private void fixLayoutInternal(int rotation, final boolean animated) { - if (bitmapToEdit == null || fragmentView == null) { - return; - } - - int viewWidth = fragmentView.getWidth() - AndroidUtilities.dp(28); - int viewHeight = fragmentView.getHeight() - AndroidUtilities.dp(28 + 48); - - rotateDegree = rotation; - - if (cropView != null) { - float bitmapWidth = rotation % 180 == 0 ? bitmapToEdit.getWidth() : bitmapToEdit.getHeight(); - float bitmapHeight = rotation % 180 == 0 ? bitmapToEdit.getHeight() : bitmapToEdit.getWidth(); - float scaleX = viewWidth / bitmapWidth; - float scaleY = viewHeight / bitmapHeight; - if (scaleX > scaleY) { - bitmapHeight = viewHeight; - bitmapWidth = (int)Math.ceil(bitmapWidth * scaleY); - } else { - bitmapWidth = viewWidth; - bitmapHeight = (int)Math.ceil(bitmapHeight * scaleX); - } - - float percX = (cropView.rectX - cropView.bitmapX) / cropView.bitmapWidth; - float percY = (cropView.rectY - cropView.bitmapY) / cropView.bitmapHeight; - float percSizeX = cropView.rectSizeX / cropView.bitmapWidth; - float percSizeY = cropView.rectSizeY / cropView.bitmapHeight; - cropView.bitmapWidth = (int) bitmapWidth; - cropView.bitmapHeight = (int) bitmapHeight; - - cropView.bitmapX = (int) Math.ceil((viewWidth - bitmapWidth) / 2 + AndroidUtilities.dp(14)); - cropView.bitmapY = (int) Math.ceil((viewHeight - bitmapHeight) / 2 + AndroidUtilities.dp(14)); - - if (cropView.rectX == -1 && cropView.rectY == -1) { - if (freeformCrop) { - cropView.rectY = cropView.bitmapY; - cropView.rectX = cropView.bitmapX; - cropView.rectSizeX = bitmapWidth; - cropView.rectSizeY = bitmapHeight; - } else { - if (bitmapWidth > bitmapHeight) { - cropView.rectY = cropView.bitmapY; - cropView.rectX = (viewWidth - bitmapHeight) / 2 + AndroidUtilities.dp(14); - cropView.rectSizeX = bitmapHeight; - cropView.rectSizeY = bitmapHeight; - } else { - cropView.rectX = cropView.bitmapX; - cropView.rectY = (viewHeight - bitmapWidth) / 2 + AndroidUtilities.dp(14); - cropView.rectSizeX = bitmapWidth; - cropView.rectSizeY = bitmapWidth; - } - } - } else { - if (rotation % 180 == 0) { - cropView.rectX = percX * bitmapWidth + cropView.bitmapX; - cropView.rectY = percY * bitmapHeight + cropView.bitmapY; - } else { - cropView.rectX = percY * bitmapWidth + cropView.bitmapX; - cropView.rectY = percX * bitmapHeight + cropView.bitmapY; - } - cropView.rectSizeX = percSizeX * bitmapWidth; - cropView.rectSizeY = percSizeY * bitmapHeight; - } - cropView.invalidate(); - } - - float bitmapWidth = bitmapToEdit.getWidth(); - float bitmapHeight = bitmapToEdit.getHeight(); - float scaleX = viewWidth / bitmapWidth; - float scaleY = viewHeight / bitmapHeight; - float scale; - if (scaleX > scaleY) { - bitmapHeight = viewHeight; - bitmapWidth = (int)Math.ceil(bitmapWidth * scaleY); - scale = cropView.bitmapHeight / bitmapWidth; - } else { - bitmapWidth = viewWidth; - bitmapHeight = (int)Math.ceil(bitmapHeight * scaleX); - scale = cropView.bitmapWidth / bitmapHeight; - } - - FrameLayout.LayoutParams layoutParams; - if (imageView != null) { - layoutParams = (FrameLayout.LayoutParams) imageView.getLayoutParams(); - layoutParams.leftMargin = (int) ((viewWidth - bitmapWidth) / 2 + AndroidUtilities.dp(14)); - layoutParams.topMargin = (int) ((viewHeight - bitmapHeight) / 2 + AndroidUtilities.dp(14)); - layoutParams.width = (int) bitmapWidth; - layoutParams.height = (int) bitmapHeight; - imageView.setLayoutParams(layoutParams); - - if (animated) { - ViewProxy.setAlpha(cropView, 0.0f); - rotationAnimation = new AnimatorSetProxy(); - rotationAnimation.playTogether( - ObjectAnimatorProxy.ofFloat(imageView, "scaleX", rotateDegree % 180 != 0 ? scale : 1), - ObjectAnimatorProxy.ofFloat(imageView, "scaleY", rotateDegree % 180 != 0 ? scale : 1), - ObjectAnimatorProxy.ofFloat(imageView, "rotation", rotateDegree)); - rotationAnimation.setDuration(150); - rotationAnimation.setInterpolator(new AccelerateDecelerateInterpolator()); - rotationAnimation.addListener(new AnimatorListenerAdapterProxy() { - @Override - public void onAnimationEnd(Object animation) { - if (rotationAnimation.equals(animation)) { - AnimatorSetProxy animatorSet = new AnimatorSetProxy(); - animatorSet.playTogether(ObjectAnimatorProxy.ofFloat(cropView, "alpha", 1.0f)); - animatorSet.setDuration(150); - animatorSet.setInterpolator(new AccelerateDecelerateInterpolator()); - animatorSet.start(); - rotationAnimation = null; - } - } - }); - rotationAnimation.start(); - } else { - imageView.setScaleX(rotateDegree % 180 != 0 ? scale : 1); - imageView.setScaleY(rotateDegree % 180 != 0 ? scale : 1); - imageView.setRotation(rotateDegree); - } - } - - if (glView != null) { - width = bitmapWidth; - height = bitmapHeight; - layoutParams = (FrameLayout.LayoutParams) glView.getLayoutParams(); - layoutParams.leftMargin = (int) ((viewWidth - bitmapWidth) / 2 + AndroidUtilities.dp(14)); - layoutParams.topMargin = (int) ((viewHeight - bitmapHeight) / 2 + AndroidUtilities.dp(14)); - layoutParams.width = (int) bitmapWidth; - layoutParams.height = (int) bitmapHeight; - glView.setLayoutParams(layoutParams); - glView.requestRender(); - } - } - - private void fixLayout() { - if (fragmentView == null) { - return; - } - fragmentView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { - if (fragmentView != null) { - fixLayoutInternal(rotateDegree, false); - fragmentView.getViewTreeObserver().removeOnPreDrawListener(this); - } - return false; - } - }); - } - - public void setDelegate(PhotoCropActivity.PhotoEditActivityDelegate delegate) { - this.delegate = delegate; - } - - public class ToolsAdapter extends RecyclerView.Adapter { - - private Context mContext; - - private class Holder extends RecyclerView.ViewHolder { - - public Holder(View itemView) { - super(itemView); - } - } - - public ToolsAdapter(Context context) { - mContext = context; - } - - @Override - public int getItemCount() { - return 8; - } - - @Override - public long getItemId(int i) { - return i; - } - - @Override - public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { - PhotoEditToolCell view = new PhotoEditToolCell(mContext); - return new Holder(view); - } - - @Override - public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) { - Holder holder = (Holder) viewHolder; - if (i == 0) { - ((PhotoEditToolCell) holder.itemView).setIconAndText(R.drawable.photo_editor_highlights, "Highlights"); - } else if (i == 1) { - ((PhotoEditToolCell) holder.itemView).setIconAndText(R.drawable.photo_editor_contrast, "Contrast"); - } else if (i == 2) { - ((PhotoEditToolCell) holder.itemView).setIconAndText(R.drawable.photo_editor_exposure, "Exposure"); - } else if (i == 3) { - ((PhotoEditToolCell) holder.itemView).setIconAndText(R.drawable.photo_editor_warmth, "Warmth"); - } else if (i == 4) { - ((PhotoEditToolCell) holder.itemView).setIconAndText(R.drawable.photo_editor_saturation, "Saturation"); - } else if (i == 5) { - ((PhotoEditToolCell) holder.itemView).setIconAndText(R.drawable.photo_editor_vignette, "Vignette"); - } else if (i == 6) { - ((PhotoEditToolCell) holder.itemView).setIconAndText(R.drawable.photo_editor_shadows, "Shadows"); - } else if (i == 7) { - ((PhotoEditToolCell) holder.itemView).setIconAndText(R.drawable.photo_editor_grain, "Grain"); - } - } - } -} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java index 0c573a96c..ccaef1c03 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 4def7298d..efd0e4df9 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 >= 14) { + 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,11 +2303,12 @@ 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; } @@ -1719,7 +2321,6 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat FileLog.e("tmessages", e); } - WindowManager wm = (WindowManager) parentActivity.getSystemService(Context.WINDOW_SERVICE); try { wm.addView(windowView, windowLayoutParams); @@ -1742,126 +2343,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 +2533,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 +2724,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 +2738,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 +2794,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 +2821,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 +2853,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 +2872,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 +2889,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 +2900,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 +2918,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } translationX -= moveDx; - if (scale != 1) { + if (scale != 1 || currentEditMode != 0) { translationY -= moveDy; } @@ -2225,14 +2931,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 +2959,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 +2981,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 +3002,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 +3030,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 +3059,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 +3095,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 +3121,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 +3155,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 +3164,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 +3185,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 +3217,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 +3263,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 +3331,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 +3340,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 +3400,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 +3409,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } } toggleActionBar(!isActionBarVisible, true); - } else { + } else if (sendPhotoType == 0) { checkImageView.performClick(); } return true; @@ -2690,8 +3424,8 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat return false; } if (scale == 1.0f) { - float atx = (e.getX() - containerView.getWidth() / 2) - ((e.getX() - containerView.getWidth() / 2) - translationX) * (3.0f / scale); - float aty = (e.getY() - containerView.getHeight() / 2) - ((e.getY() - containerView.getHeight() / 2) - translationY) * (3.0f / scale); + float atx = (e.getX() - getContainerViewWidth() / 2) - ((e.getX() - getContainerViewWidth() / 2) - translationX) * (3.0f / scale); + float aty = (e.getY() - getContainerViewHeight() / 2) - ((e.getY() - getContainerViewHeight() / 2) - translationY) * (3.0f / scale); updateMinMax(3.0f); if (atx < minX) { atx = minX; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java index 5c9dcae8a..3aac25c12 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, 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,15 +234,13 @@ public class PopupNotificationActivity extends Activity implements NotificationC } }); - setContentView(R.layout.popup_notification_layout); - RelativeLayout popupContainer = (RelativeLayout) findViewById(R.id.popup_container); messageContainer = new FrameLayoutTouch(this); popupContainer.addView(messageContainer, 0); actionBar = new ActionBar(this); actionBar.setOccupyStatusBar(false); actionBar.setBackButtonImage(R.drawable.ic_ab_back); - actionBar.setBackgroundResource(R.color.header); + actionBar.setBackgroundColor(0xff54759e); actionBar.setItemsBackground(R.drawable.bar_selector); popupContainer.addView(actionBar); ViewGroup.LayoutParams layoutParams = actionBar.getLayoutParams(); @@ -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 5cdc731cc..0fdf3a59f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PrivacySettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PrivacySettingsActivity.java @@ -53,6 +53,7 @@ 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; @@ -71,6 +72,7 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio lastSeenRow = rowCount++; lastSeenDetailRow = rowCount++; securitySectionRow = rowCount++; + passcodeRow = rowCount++; terminateSessionsRow = rowCount++; terminateSessionsDetailRow = rowCount++; deleteAccountSectionRow = rowCount++; @@ -90,7 +92,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 +229,12 @@ 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)); + } } } }); @@ -319,7 +327,7 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio @Override public boolean isEnabled(int i) { - return i == passwordRow || i == blockedRow || i == terminateSessionsRow || i == lastSeenRow && !ContactsController.getInstance().getLoadingLastSeenInfo() || i == deleteAccountRow && !ContactsController.getInstance().getLoadingDeleteInfo(); + return i == passcodeRow || i == passwordRow || i == blockedRow || i == terminateSessionsRow || i == lastSeenRow && !ContactsController.getInstance().getLoadingLastSeenInfo() || i == deleteAccountRow && !ContactsController.getInstance().getLoadingDeleteInfo(); } @Override @@ -357,6 +365,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()) { @@ -413,7 +423,7 @@ public class PrivacySettingsActivity extends BaseFragment implements Notificatio @Override public int getItemViewType(int i) { - if (i == lastSeenRow || i == blockedRow || i == deleteAccountRow || i == terminateSessionsRow || i == passwordRow) { + if (i == lastSeenRow || i == blockedRow || i == deleteAccountRow || i == terminateSessionsRow || i == passwordRow || i == passcodeRow) { return 0; } else if (i == deleteAccountDetailRow || i == lastSeenDetailRow || i == terminateSessionsDetailRow) { return 1; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java index fe5284968..94d875a90 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)); @@ -485,7 +485,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); } @@ -884,6 +884,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) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileNotificationsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileNotificationsActivity.java index 3675c7633..9f6a141a4 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); @@ -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("Disabled", R.string.Disabled), 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 31efa3080..b51761320 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java @@ -265,7 +265,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)); @@ -491,7 +491,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 +706,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) { @@ -994,7 +999,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter i.putExtra(Intent.EXTRA_EMAIL, new String[]{BuildVars.SEND_LOGS_EMAIL}); i.putExtra(Intent.EXTRA_SUBJECT, "last logs"); i.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); - getParentActivity().startActivity(Intent.createChooser(i, "Select email application.")); + getParentActivity().startActivityForResult(Intent.createChooser(i, "Select email application."), 500); } catch (Exception e) { e.printStackTrace(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java index 63d0da9c5..3cf311d2b 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 5b428a431..935cba2a7 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); diff --git a/TMessagesProj/src/main/res/drawable-hdpi/bottom_shadow.png b/TMessagesProj/src/main/res/drawable-hdpi/bottom_shadow.png new file mode 100755 index 000000000..5dc9ed10a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/bottom_shadow.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/doc_actions_g.png b/TMessagesProj/src/main/res/drawable-hdpi/doc_actions_g.png index c33a4c2fc..09dea5d2a 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/doc_actions_g.png and b/TMessagesProj/src/main/res/drawable-hdpi/doc_actions_g.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/edit_cancel.png b/TMessagesProj/src/main/res/drawable-hdpi/edit_cancel.png new file mode 100755 index 000000000..8fb629d04 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/edit_cancel.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/edit_doneblue.png b/TMessagesProj/src/main/res/drawable-hdpi/edit_doneblue.png new file mode 100755 index 000000000..ad5f280d1 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/edit_doneblue.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/gif_search.png b/TMessagesProj/src/main/res/drawable-hdpi/gif_search.png deleted file mode 100644 index ab687dad9..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/gif_search.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_delete_white.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_delete_white.png deleted file mode 100644 index f3273d774..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_delete_white.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_share_white.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_share_white.png deleted file mode 100644 index 2b9baf7ca..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/ic_ab_share_white.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/lock_close.png b/TMessagesProj/src/main/res/drawable-hdpi/lock_close.png new file mode 100644 index 000000000..f9b9072cd Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/lock_close.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/lock_open.png b/TMessagesProj/src/main/res/drawable-hdpi/lock_open.png new file mode 100644 index 000000000..b7cc48642 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/lock_open.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_check.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_check.png index 7d63d9115..80e7278e6 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/msg_check.png and b/TMessagesProj/src/main/res/drawable-hdpi/msg_check.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_check_w.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_check_w.png index a35fc7a4f..be83f2bf2 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/msg_check_w.png and b/TMessagesProj/src/main/res/drawable-hdpi/msg_check_w.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_halfcheck.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_halfcheck.png index 0676d17d4..f568503fd 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/msg_halfcheck.png and b/TMessagesProj/src/main/res/drawable-hdpi/msg_halfcheck.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_halfcheck_w.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_halfcheck_w.png index 950d5f251..1cb636875 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/msg_halfcheck_w.png and b/TMessagesProj/src/main/res/drawable-hdpi/msg_halfcheck_w.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_out.9.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_out.9.png index 81cd229e7..08fd35b4c 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/msg_out.9.png and b/TMessagesProj/src/main/res/drawable-hdpi/msg_out.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo.9.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo.9.png index ccfdbaa27..f8f07f7fb 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo.9.png and b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo_selected.9.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo_selected.9.png index 6b4885485..3d5b1f9fa 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo_selected.9.png and b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_photo_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/msg_out_selected.9.png b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_selected.9.png index b73ee8be8..5e01d8fe3 100755 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/msg_out_selected.9.png and b/TMessagesProj/src/main/res/drawable-hdpi/msg_out_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/passcode_check.png b/TMessagesProj/src/main/res/drawable-hdpi/passcode_check.png new file mode 100644 index 000000000..d9b4dc28d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/passcode_check.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/passcode_delete.png b/TMessagesProj/src/main/res/drawable-hdpi/passcode_delete.png new file mode 100644 index 000000000..317c52c5c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/passcode_delete.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/passcode_logo.png b/TMessagesProj/src/main/res/drawable-hdpi/passcode_logo.png new file mode 100644 index 000000000..a004ca95c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/passcode_logo.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/photo_filters.png b/TMessagesProj/src/main/res/drawable-hdpi/photo_filters.png deleted file mode 100644 index 2bd619df2..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/photo_filters.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/photo_filters_active.png b/TMessagesProj/src/main/res/drawable-hdpi/photo_filters_active.png deleted file mode 100644 index e9ad643a6..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/photo_filters_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/photo_rotate.png b/TMessagesProj/src/main/res/drawable-hdpi/photo_rotate.png deleted file mode 100644 index 31e097a2e..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/photo_rotate.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/photo_sizes.png b/TMessagesProj/src/main/res/drawable-hdpi/photo_sizes.png deleted file mode 100644 index ac8c78186..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/photo_sizes.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/photo_tune.png b/TMessagesProj/src/main/res/drawable-hdpi/photo_tune.png deleted file mode 100644 index dc365663d..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/photo_tune.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/photo_tune_active.png b/TMessagesProj/src/main/res/drawable-hdpi/photo_tune_active.png deleted file mode 100644 index 1a30ec1d4..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/photo_tune_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/search_gif.png b/TMessagesProj/src/main/res/drawable-hdpi/search_gif.png new file mode 100755 index 000000000..3be94584a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/search_gif.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/search_web.png b/TMessagesProj/src/main/res/drawable-hdpi/search_web.png new file mode 100755 index 000000000..900a5303b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/search_web.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/selectphoto_small.png b/TMessagesProj/src/main/res/drawable-hdpi/selectphoto_small.png deleted file mode 100755 index 7a023ec07..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/selectphoto_small.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/selectphoto_small_active.png b/TMessagesProj/src/main/res/drawable-hdpi/selectphoto_small_active.png deleted file mode 100755 index 7a023ec07..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/selectphoto_small_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/selectphoto_small_grey.png b/TMessagesProj/src/main/res/drawable-hdpi/selectphoto_small_grey.png deleted file mode 100755 index 6cf4bcda9..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/selectphoto_small_grey.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/share.png b/TMessagesProj/src/main/res/drawable-hdpi/share.png new file mode 100755 index 000000000..8b853cf2d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/share.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/sharedmedia.png b/TMessagesProj/src/main/res/drawable-hdpi/sharedmedia.png new file mode 100755 index 000000000..532e67de0 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/sharedmedia.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_brightness.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_brightness.png new file mode 100755 index 000000000..fe2ae0640 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_brightness.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_contrast.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_contrast.png new file mode 100755 index 000000000..21a65034b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_contrast.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_details.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_details.png new file mode 100755 index 000000000..85549500b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_details.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_enhance.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_enhance.png new file mode 100755 index 000000000..a365ce793 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_enhance.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_grain.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_grain.png new file mode 100755 index 000000000..39a73a1f7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_grain.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_highlights.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_highlights.png new file mode 100755 index 000000000..5530def4b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_highlights.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_saturation.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_saturation.png new file mode 100755 index 000000000..5d79e93f1 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_saturation.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_shadows.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_shadows.png new file mode 100755 index 000000000..0dc33aa00 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_shadows.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_vignette.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_vignette.png new file mode 100755 index 000000000..a6ac05878 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_vignette.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tool_warmth.png b/TMessagesProj/src/main/res/drawable-hdpi/tool_warmth.png new file mode 100755 index 000000000..2392e7389 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tool_warmth.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tune.png b/TMessagesProj/src/main/res/drawable-hdpi/tune.png new file mode 100755 index 000000000..ab404e6a5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tune.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/web_search.png b/TMessagesProj/src/main/res/drawable-hdpi/web_search.png deleted file mode 100644 index a73acd91c..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/web_search.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/bottom_shadow.png b/TMessagesProj/src/main/res/drawable-mdpi/bottom_shadow.png new file mode 100755 index 000000000..3e170fda5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/bottom_shadow.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/doc_actions_g.png b/TMessagesProj/src/main/res/drawable-mdpi/doc_actions_g.png index 069ff82af..1c1921a82 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/doc_actions_g.png and b/TMessagesProj/src/main/res/drawable-mdpi/doc_actions_g.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/edit_cancel.png b/TMessagesProj/src/main/res/drawable-mdpi/edit_cancel.png new file mode 100755 index 000000000..5dd045bca Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/edit_cancel.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/edit_doneblue.png b/TMessagesProj/src/main/res/drawable-mdpi/edit_doneblue.png new file mode 100755 index 000000000..494f4f85a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/edit_doneblue.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/gif_search.png b/TMessagesProj/src/main/res/drawable-mdpi/gif_search.png deleted file mode 100644 index bf910aaa5..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/gif_search.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_delete_white.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_delete_white.png deleted file mode 100644 index 49f05043b..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_delete_white.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_share_white.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_share_white.png deleted file mode 100644 index eee5acefa..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/ic_ab_share_white.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/lock_close.png b/TMessagesProj/src/main/res/drawable-mdpi/lock_close.png new file mode 100644 index 000000000..47b4dd80a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/lock_close.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/lock_open.png b/TMessagesProj/src/main/res/drawable-mdpi/lock_open.png new file mode 100644 index 000000000..689f1901e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/lock_open.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_check.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_check.png index 6f92478e4..2fdad7a38 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/msg_check.png and b/TMessagesProj/src/main/res/drawable-mdpi/msg_check.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_check_w.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_check_w.png index ab1c1ba59..f2448a0a5 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/msg_check_w.png and b/TMessagesProj/src/main/res/drawable-mdpi/msg_check_w.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_halfcheck.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_halfcheck.png index 2df5738e6..010da7c52 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/msg_halfcheck.png and b/TMessagesProj/src/main/res/drawable-mdpi/msg_halfcheck.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_halfcheck_w.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_halfcheck_w.png index b1ef529ff..d5c1888a9 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/msg_halfcheck_w.png and b/TMessagesProj/src/main/res/drawable-mdpi/msg_halfcheck_w.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_out.9.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_out.9.png index f8496cd47..f22c541f7 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/msg_out.9.png and b/TMessagesProj/src/main/res/drawable-mdpi/msg_out.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo.9.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo.9.png index d144e3552..ad4ad9ce2 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo.9.png and b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo_selected.9.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo_selected.9.png index d38cf29db..734f94360 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo_selected.9.png and b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_photo_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/msg_out_selected.9.png b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_selected.9.png index 06f6fe053..7e29c8128 100755 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/msg_out_selected.9.png and b/TMessagesProj/src/main/res/drawable-mdpi/msg_out_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/passcode_check.png b/TMessagesProj/src/main/res/drawable-mdpi/passcode_check.png new file mode 100644 index 000000000..1a39754e0 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/passcode_check.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/passcode_delete.png b/TMessagesProj/src/main/res/drawable-mdpi/passcode_delete.png new file mode 100644 index 000000000..c1ccb443b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/passcode_delete.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/passcode_logo.png b/TMessagesProj/src/main/res/drawable-mdpi/passcode_logo.png new file mode 100644 index 000000000..865cb4c97 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/passcode_logo.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/photo_filters.png b/TMessagesProj/src/main/res/drawable-mdpi/photo_filters.png deleted file mode 100644 index 890d61d5d..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/photo_filters.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/photo_filters_active.png b/TMessagesProj/src/main/res/drawable-mdpi/photo_filters_active.png deleted file mode 100644 index 62cfe9ab5..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/photo_filters_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/photo_rotate.png b/TMessagesProj/src/main/res/drawable-mdpi/photo_rotate.png deleted file mode 100644 index cdfc85301..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/photo_rotate.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/photo_sizes.png b/TMessagesProj/src/main/res/drawable-mdpi/photo_sizes.png deleted file mode 100644 index 34d1d2ba1..000000000 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 9db5621e4..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/photo_tune.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/photo_tune_active.png b/TMessagesProj/src/main/res/drawable-mdpi/photo_tune_active.png deleted file mode 100644 index 61eab0c57..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/photo_tune_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/search_gif.png b/TMessagesProj/src/main/res/drawable-mdpi/search_gif.png new file mode 100755 index 000000000..5e8873fa7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/search_gif.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/search_web.png b/TMessagesProj/src/main/res/drawable-mdpi/search_web.png new file mode 100755 index 000000000..bab8acf03 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/search_web.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/selectphoto_small.png b/TMessagesProj/src/main/res/drawable-mdpi/selectphoto_small.png deleted file mode 100755 index 051f23a6f..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/selectphoto_small.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/selectphoto_small_active.png b/TMessagesProj/src/main/res/drawable-mdpi/selectphoto_small_active.png deleted file mode 100755 index 051f23a6f..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/selectphoto_small_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/selectphoto_small_grey.png b/TMessagesProj/src/main/res/drawable-mdpi/selectphoto_small_grey.png deleted file mode 100755 index 0dcf76705..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/selectphoto_small_grey.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/share.png b/TMessagesProj/src/main/res/drawable-mdpi/share.png new file mode 100755 index 000000000..48a9439cb Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/share.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/sharedmedia.png b/TMessagesProj/src/main/res/drawable-mdpi/sharedmedia.png new file mode 100755 index 000000000..cc21392b4 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/sharedmedia.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_brightness.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_brightness.png new file mode 100755 index 000000000..bc83f7365 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_brightness.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_contrast.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_contrast.png new file mode 100755 index 000000000..ff596a32d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_contrast.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_details.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_details.png new file mode 100755 index 000000000..758b1be91 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_details.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_enhance.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_enhance.png new file mode 100755 index 000000000..caf3478b3 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_enhance.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_grain.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_grain.png new file mode 100755 index 000000000..abf87a45e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_grain.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_highlights.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_highlights.png new file mode 100755 index 000000000..ed936c7d6 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_highlights.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_saturation.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_saturation.png new file mode 100755 index 000000000..297178d03 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_saturation.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_shadows.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_shadows.png new file mode 100755 index 000000000..62adb55d0 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_shadows.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_vignette.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_vignette.png new file mode 100755 index 000000000..fd9972ceb Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_vignette.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tool_warmth.png b/TMessagesProj/src/main/res/drawable-mdpi/tool_warmth.png new file mode 100755 index 000000000..6f3d4d9fa Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tool_warmth.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tune.png b/TMessagesProj/src/main/res/drawable-mdpi/tune.png new file mode 100755 index 000000000..633d4b02d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tune.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/web_search.png b/TMessagesProj/src/main/res/drawable-mdpi/web_search.png deleted file mode 100644 index be9464961..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/web_search.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-v21/bar_selector_lock.xml b/TMessagesProj/src/main/res/drawable-v21/bar_selector_lock.xml new file mode 100644 index 000000000..d48dd0a10 --- /dev/null +++ b/TMessagesProj/src/main/res/drawable-v21/bar_selector_lock.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/bottom_shadow.png b/TMessagesProj/src/main/res/drawable-xhdpi/bottom_shadow.png new file mode 100755 index 000000000..eeb3c8374 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/bottom_shadow.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/doc_actions_g.png b/TMessagesProj/src/main/res/drawable-xhdpi/doc_actions_g.png deleted file mode 100755 index 37e756fae..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/doc_actions_g.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/edit_cancel.png b/TMessagesProj/src/main/res/drawable-xhdpi/edit_cancel.png new file mode 100755 index 000000000..bfea63bc6 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/edit_cancel.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/edit_doneblue.png b/TMessagesProj/src/main/res/drawable-xhdpi/edit_doneblue.png new file mode 100755 index 000000000..301434f89 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/edit_doneblue.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/gif_search.png b/TMessagesProj/src/main/res/drawable-xhdpi/gif_search.png deleted file mode 100644 index c4a1eb82f..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/gif_search.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_delete_white.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_delete_white.png deleted file mode 100644 index 15752143c..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_delete_white.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_share_white.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_share_white.png deleted file mode 100644 index 03b1ac32f..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/ic_ab_share_white.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/lock_close.png b/TMessagesProj/src/main/res/drawable-xhdpi/lock_close.png new file mode 100644 index 000000000..9ea564016 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/lock_close.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/lock_open.png b/TMessagesProj/src/main/res/drawable-xhdpi/lock_open.png new file mode 100644 index 000000000..c85e140b1 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/lock_open.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_check.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_check.png index f507eaf88..d214b0240 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/msg_check.png and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_check.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_check_w.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_check_w.png index be9518710..9e797a5c3 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/msg_check_w.png and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_check_w.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_halfcheck.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_halfcheck.png index 0fcf42042..7ae6e79c7 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/msg_halfcheck.png and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_halfcheck.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_halfcheck_w.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_halfcheck_w.png index 1882a27c8..dd2891607 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/msg_halfcheck_w.png and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_halfcheck_w.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_out.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out.9.png index f4e0afa5f..d7c2816f1 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/msg_out.9.png and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo.9.png index 63274aed4..c452372f3 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo.9.png and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo_selected.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo_selected.9.png index 3dd5cb9be..faa2daa55 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo_selected.9.png and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_photo_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_selected.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_selected.9.png index 5097bdcf8..65e00a868 100755 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_selected.9.png and b/TMessagesProj/src/main/res/drawable-xhdpi/msg_out_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/passcode_check.png b/TMessagesProj/src/main/res/drawable-xhdpi/passcode_check.png new file mode 100644 index 000000000..f407719d7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/passcode_check.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/passcode_delete.png b/TMessagesProj/src/main/res/drawable-xhdpi/passcode_delete.png new file mode 100644 index 000000000..57af5956d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/passcode_delete.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/passcode_logo.png b/TMessagesProj/src/main/res/drawable-xhdpi/passcode_logo.png new file mode 100644 index 000000000..92c5f2d5b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/passcode_logo.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/photo_filters.png b/TMessagesProj/src/main/res/drawable-xhdpi/photo_filters.png deleted file mode 100644 index 611021022..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/photo_filters.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/photo_filters_active.png b/TMessagesProj/src/main/res/drawable-xhdpi/photo_filters_active.png deleted file mode 100644 index 6a3090755..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/photo_filters_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/photo_rotate.png b/TMessagesProj/src/main/res/drawable-xhdpi/photo_rotate.png deleted file mode 100644 index 968e91dcd..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/photo_rotate.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/photo_sizes.png b/TMessagesProj/src/main/res/drawable-xhdpi/photo_sizes.png deleted file mode 100644 index 01f3176f5..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/photo_sizes.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/photo_tune.png b/TMessagesProj/src/main/res/drawable-xhdpi/photo_tune.png deleted file mode 100644 index 38edad85d..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/photo_tune.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/photo_tune_active.png b/TMessagesProj/src/main/res/drawable-xhdpi/photo_tune_active.png deleted file mode 100644 index e65b80362..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/photo_tune_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/search_gif.png b/TMessagesProj/src/main/res/drawable-xhdpi/search_gif.png new file mode 100755 index 000000000..5cd150ba3 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/search_gif.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/search_web.png b/TMessagesProj/src/main/res/drawable-xhdpi/search_web.png new file mode 100755 index 000000000..44532e089 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/search_web.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/selectphoto_small.png b/TMessagesProj/src/main/res/drawable-xhdpi/selectphoto_small.png deleted file mode 100755 index 5b817801c..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/selectphoto_small.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/selectphoto_small_active.png b/TMessagesProj/src/main/res/drawable-xhdpi/selectphoto_small_active.png deleted file mode 100755 index 95d818a44..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/selectphoto_small_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/selectphoto_small_grey.png b/TMessagesProj/src/main/res/drawable-xhdpi/selectphoto_small_grey.png deleted file mode 100755 index 598676b91..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/selectphoto_small_grey.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/share.png b/TMessagesProj/src/main/res/drawable-xhdpi/share.png new file mode 100755 index 000000000..d554570d9 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/share.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/sharedmedia.png b/TMessagesProj/src/main/res/drawable-xhdpi/sharedmedia.png new file mode 100755 index 000000000..ad1203f6d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/sharedmedia.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_brightness.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_brightness.png new file mode 100755 index 000000000..1d1269e01 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_brightness.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_contrast.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_contrast.png new file mode 100755 index 000000000..52ca3c908 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_contrast.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_details.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_details.png new file mode 100755 index 000000000..db56a7a9f Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_details.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_enhance.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_enhance.png new file mode 100755 index 000000000..c0e3627a9 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_enhance.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_grain.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_grain.png new file mode 100755 index 000000000..e811faeaa Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_grain.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_highlights.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_highlights.png new file mode 100755 index 000000000..38cae4551 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_highlights.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_saturation.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_saturation.png new file mode 100755 index 000000000..92f8d6c75 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_saturation.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_shadows.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_shadows.png new file mode 100755 index 000000000..99cc7f7b5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_shadows.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_vignette.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_vignette.png new file mode 100755 index 000000000..c9ae138cf Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_vignette.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tool_warmth.png b/TMessagesProj/src/main/res/drawable-xhdpi/tool_warmth.png new file mode 100755 index 000000000..aca145d12 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tool_warmth.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tune.png b/TMessagesProj/src/main/res/drawable-xhdpi/tune.png new file mode 100755 index 000000000..c6d6b9c7f Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tune.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/web_search.png b/TMessagesProj/src/main/res/drawable-xhdpi/web_search.png deleted file mode 100644 index 345a04629..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/web_search.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/bottom_shadow.png b/TMessagesProj/src/main/res/drawable-xxhdpi/bottom_shadow.png new file mode 100755 index 000000000..cf81b6c14 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/bottom_shadow.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/doc_actions_g.png b/TMessagesProj/src/main/res/drawable-xxhdpi/doc_actions_g.png index 5445d4e10..109c13fd7 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/doc_actions_g.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/doc_actions_g.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/edit_cancel.png b/TMessagesProj/src/main/res/drawable-xxhdpi/edit_cancel.png new file mode 100755 index 000000000..d050523b7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/edit_cancel.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/edit_doneblue.png b/TMessagesProj/src/main/res/drawable-xxhdpi/edit_doneblue.png new file mode 100755 index 000000000..643fa3c6e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/edit_doneblue.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/gif_search.png b/TMessagesProj/src/main/res/drawable-xxhdpi/gif_search.png deleted file mode 100644 index e71905cb8..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/gif_search.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_delete_white.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_delete_white.png deleted file mode 100644 index 4335e31da..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_delete_white.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_share_white.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_share_white.png deleted file mode 100644 index 890d00aed..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_ab_share_white.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/lock_close.png b/TMessagesProj/src/main/res/drawable-xxhdpi/lock_close.png new file mode 100644 index 000000000..716b83b66 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/lock_close.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/lock_open.png b/TMessagesProj/src/main/res/drawable-xxhdpi/lock_open.png new file mode 100644 index 000000000..3cb15715f Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/lock_open.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_check.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_check.png index 467e62be6..5a38cea3e 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_check.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_check.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_check_w.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_check_w.png index 7d2019745..7a6da6cc5 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_check_w.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_check_w.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_halfcheck.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_halfcheck.png index 73bf80ba7..4dbbf75b8 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_halfcheck.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_halfcheck.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_halfcheck_w.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_halfcheck_w.png index 03177ed49..841c77bcc 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_halfcheck_w.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_halfcheck_w.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out.9.png index 10eac9cce..b7aa02377 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out.9.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo.9.png index 1c56a391f..02e3ad804 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo.9.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo_selected.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo_selected.9.png index 7855d66fa..67713607b 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo_selected.9.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_photo_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_selected.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_selected.9.png index ad929cc4b..6ce8fda0e 100755 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_selected.9.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/msg_out_selected.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/passcode_check.png b/TMessagesProj/src/main/res/drawable-xxhdpi/passcode_check.png new file mode 100644 index 000000000..a831f4bb1 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/passcode_check.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/passcode_delete.png b/TMessagesProj/src/main/res/drawable-xxhdpi/passcode_delete.png new file mode 100644 index 000000000..cdd6dce68 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/passcode_delete.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/passcode_logo.png b/TMessagesProj/src/main/res/drawable-xxhdpi/passcode_logo.png new file mode 100644 index 000000000..af2428a20 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/passcode_logo.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_contrast.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_contrast.png deleted file mode 100644 index 78aa2b414..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_contrast.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_exposure.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_exposure.png deleted file mode 100644 index 5feb667ab..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_exposure.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_grain.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_grain.png deleted file mode 100644 index 297bc2dc9..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_grain.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_highlights.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_highlights.png deleted file mode 100644 index ce156a02a..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_highlights.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_saturation.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_saturation.png deleted file mode 100644 index c1a14fa75..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_saturation.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_shadows.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_shadows.png deleted file mode 100644 index f3ead5324..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_shadows.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_sharpen.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_sharpen.png deleted file mode 100644 index 4d6687ba8..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_sharpen.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_vignette.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_vignette.png deleted file mode 100644 index e72d3d71c..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_vignette.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_warmth.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_warmth.png deleted file mode 100644 index 9b9a258ed..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_editor_warmth.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_filters.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_filters.png deleted file mode 100644 index 29abc7eda..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_filters.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_filters_active.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_filters_active.png deleted file mode 100644 index a5bb25e5c..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_filters_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_rotate.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_rotate.png deleted file mode 100644 index 0c1a9c772..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_rotate.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_sizes.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_sizes.png deleted file mode 100644 index 40a564e6a..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_sizes.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_tune.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_tune.png deleted file mode 100644 index 254d18c76..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_tune.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_tune_active.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photo_tune_active.png deleted file mode 100644 index 3c4e05873..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/photo_tune_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/search_gif.png b/TMessagesProj/src/main/res/drawable-xxhdpi/search_gif.png new file mode 100755 index 000000000..d9e7195be Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/search_gif.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/search_web.png b/TMessagesProj/src/main/res/drawable-xxhdpi/search_web.png new file mode 100755 index 000000000..193208c52 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/search_web.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/selectphoto_small.png b/TMessagesProj/src/main/res/drawable-xxhdpi/selectphoto_small.png deleted file mode 100755 index 7620f457e..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/selectphoto_small.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/selectphoto_small_active.png b/TMessagesProj/src/main/res/drawable-xxhdpi/selectphoto_small_active.png deleted file mode 100755 index 11ac540b6..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/selectphoto_small_active.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/selectphoto_small_grey.png b/TMessagesProj/src/main/res/drawable-xxhdpi/selectphoto_small_grey.png deleted file mode 100755 index 935604b4d..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/selectphoto_small_grey.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/share.png b/TMessagesProj/src/main/res/drawable-xxhdpi/share.png new file mode 100755 index 000000000..b72403da1 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/share.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/sharedmedia.png b/TMessagesProj/src/main/res/drawable-xxhdpi/sharedmedia.png new file mode 100755 index 000000000..80dfc3838 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/sharedmedia.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_brightness.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_brightness.png new file mode 100755 index 000000000..fca4f193c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_brightness.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_contrast.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_contrast.png new file mode 100755 index 000000000..b7f4ea77c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_contrast.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_details.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_details.png new file mode 100755 index 000000000..92e5078a5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_details.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_enhance.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_enhance.png new file mode 100755 index 000000000..d3f893339 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_enhance.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_grain.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_grain.png new file mode 100755 index 000000000..fd194574e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_grain.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_highlights.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_highlights.png new file mode 100755 index 000000000..f9b3e0b14 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_highlights.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_saturation.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_saturation.png new file mode 100755 index 000000000..9918b34d4 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_saturation.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_shadows.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_shadows.png new file mode 100755 index 000000000..ba854d4b5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_shadows.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_vignette.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_vignette.png new file mode 100755 index 000000000..ba153fd42 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_vignette.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tool_warmth.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_warmth.png new file mode 100755 index 000000000..cfbf0d516 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tool_warmth.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tune.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tune.png new file mode 100755 index 000000000..eda3e5a32 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tune.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/web_search.png b/TMessagesProj/src/main/res/drawable-xxhdpi/web_search.png deleted file mode 100644 index 1fc70c4b1..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/web_search.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable/bar_selector_lock.xml b/TMessagesProj/src/main/res/drawable/bar_selector_lock.xml new file mode 100644 index 000000000..ad45bba68 --- /dev/null +++ b/TMessagesProj/src/main/res/drawable/bar_selector_lock.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout-ar/encrypted_chat_placeholder.xml b/TMessagesProj/src/main/res/layout-ar/encrypted_chat_placeholder.xml deleted file mode 100644 index c265685e2..000000000 --- a/TMessagesProj/src/main/res/layout-ar/encrypted_chat_placeholder.xml +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/chat_layout.xml b/TMessagesProj/src/main/res/layout/chat_layout.xml deleted file mode 100644 index 214bb3d69..000000000 --- a/TMessagesProj/src/main/res/layout/chat_layout.xml +++ /dev/null @@ -1,299 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/encrypted_chat_placeholder.xml b/TMessagesProj/src/main/res/layout/encrypted_chat_placeholder.xml deleted file mode 100644 index 6df0e8915..000000000 --- a/TMessagesProj/src/main/res/layout/encrypted_chat_placeholder.xml +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/media_photo_layout.xml b/TMessagesProj/src/main/res/layout/media_photo_layout.xml deleted file mode 100644 index 918626671..000000000 --- a/TMessagesProj/src/main/res/layout/media_photo_layout.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/media_video_layout.xml b/TMessagesProj/src/main/res/layout/media_video_layout.xml deleted file mode 100644 index 17de40a58..000000000 --- a/TMessagesProj/src/main/res/layout/media_video_layout.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/popup_notification_layout.xml b/TMessagesProj/src/main/res/layout/popup_notification_layout.xml deleted file mode 100644 index 3286d13b5..000000000 --- a/TMessagesProj/src/main/res/layout/popup_notification_layout.xml +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-ar/strings.xml b/TMessagesProj/src/main/res/values-ar/strings.xml index bf476db35..b81609edf 100644 --- a/TMessagesProj/src/main/res/values-ar/strings.xml +++ b/TMessagesProj/src/main/res/values-ar/strings.xml @@ -57,6 +57,7 @@ ضعه على الصامت لمدة %1$s إزالة كتم الصوت خلال %1$s + تعطيل رسالة جماعية جديدة أدخل اسم القائمة @@ -143,6 +144,7 @@ %1$s قام بتعديل اسم المجموعة %2$s %1$s قام بتغيير صورة المجموعة %2$s %1$s قام بدعوة %3$s للمجموعة %2$s + %1$s عاد إلى المجموعة %2$s %1$s قام بإخراج %3$s من المجموعة %2$s %1$s قام بإخراجك من المجموعة %2$s %1$s قام بمغادرة المجموعة %2$s @@ -296,9 +298,27 @@ سيتم إرسال رسالة قصيرة تحتوي على رمز التفعيل الخاص إلى رقمك الجديد. الرقم %1$s لديه حساب تيليجرام مسبقًا. يرجى حذف هذا الحساب قبل محاولة تغيير رقمك. آخر + + رمز المرور + غيًر رمز المرور + عندما تختار رمز مرور، ستظهر علامة قفل في صفحة المحادثات. اضغط عليها لقفل أو فتح تيليجرام.\n\nملاحظة: إذا نسيت رمز المرور، ستحتاج لحذف وإعادة تنزيل التطبيق. وستخسر كافة محادثاتك السرية وستعود المحادثات العادية فور إعادة تسجيل الدخول. + سوف ترى الآن أيقونة قفل في صفحة المحادثات. اضغط عليها لقفل تطبيق تيليجرام برمز المرور الجديد الخاص بك. + الرمز + كلمة المرور + قم بإدخال رمز المرور الخاص بك الحالي + قم بإدخال رمز المرور الخاص بك الجديد + قم بإدخال رمز المرور الخاص بك + قم بإعادة إدخال رمز المرور الخاص بك الجديدة + رمز مرور غير صحيح + رموز المرور غير متطابقة + قفل تلقائي + اطلب رمز المرور إذا غبت فترة محددة من الزمن. + خلال %1$s + معطّل شارك المقاطع المرئية والصور في هذه المحادثة لتستطيع الوصول إليها من أية جهاز من أجهزتك ملفات + الوسائط المشتركة شارك الملفات والمستندات في هذه المحادثة لتستطيع الوصول إليها من أية جهاز من أجهزتك الخريطة @@ -318,12 +338,27 @@ فضلًا، قم بتنزيل الوسائط أولًا لا توجد صور حديثة لا يوجد صور متحركة حديثة - البحث على الإنترنت - البحث عن صور متحركة + ابحث عن صور + البحث على الإنترنت + ابحث عن صور متحركة البحث على الإنترنت البحث عن صور متحركة قص الصورة تعديل الصورة + تحسين + التفتيح + التباين + التعريض + الدفء + التشبع + النقش + الظل + الحبوب + زيادة الحدة + الطمس + هل أنت متأكد من رغبتك في حذف هذه الصورة؟ + هل أنت متأكد من رغبتك في حذف هذا المقطع المرئي؟ + تجاهل التغييرات؟ Password Change password @@ -405,6 +440,7 @@ حذف الصورة تعيين موافق + قطع un1 أزال un2 غادر المجموعة العضو un1 @@ -422,6 +458,7 @@ لقد قمت بإنشاء المجموعة un1 قام بإخراجك un1 قام بإضافتك + un1 عاد إلى المجموعة نسخة تيليجرام الموجودة لديك لا تدعم هذه الرسالة. الرجاء التحديث لأحدث نسخة: http://telegram.org/update صورة مقطع مرئي @@ -511,18 +548,24 @@ %1$d رسائل %1$d رسالة %1$d رسالة - لا يوجد ملفات - %1$d ملف - %1$d ملفان - %1$d ملفات - %1$d ملف - %1$d ملف + لا يوجد ملفات + %1$d ملف + %1$d ملف + %1$d ملفات + %1$d ملف + %1$d ملف ليس من جهة اتصال من %1$d جهة اتصال من %1$d جهتان اتصال من %1$d جهات اتصال من %1$d جهة اتصال من %1$d جهة اتصال + من ولا محادثة + من %1$d محادثة + من %1$d محادثة + من %1$d محادثات + من %1$d محادثة + من %1$d محادثة %1$d ثانية %1$d ثانية %1$d ثانيتان @@ -572,6 +615,7 @@ %1$d مستخدم %1$d مستخدم + MMMM yyyy MMM dd dd.MM.yy dd.MM.yyyy diff --git a/TMessagesProj/src/main/res/values-de/strings.xml b/TMessagesProj/src/main/res/values-de/strings.xml index 8fe9a5dcf..0ed32660a 100644 --- a/TMessagesProj/src/main/res/values-de/strings.xml +++ b/TMessagesProj/src/main/res/values-de/strings.xml @@ -34,13 +34,13 @@ gestern Keine Ergebnisse Noch keine Chats… - Tippe unten auf den Sift für deine erste\nChatnachricht oder auf den Menüknopf\num die restlichen Optionen zu öffnen. + Tippe unten auf den Stift für deine erste\nChatnachricht oder auf den Menüknopf\num die restlichen Optionen zu öffnen. Warte auf Netzwerk... Verbinde… Aktualisiere… Neuer Geheimer Chat Warte, bis %s online geht… - Geheimen Chat abgebrochen + Geheimen Chat beendet Tausche Schlüssel aus… %s ist deinem geheimen Chat beigetreten. Du bist dem geheimen Chat beigetreten. @@ -57,6 +57,7 @@ Stumm für %1$s Stumm aus In %1$s + Stumm aus Neue Broadcast Liste Listenname @@ -143,6 +144,7 @@ %1$s hat den Namen der Gruppe %2$s geändert %1$s hat das Bild der Gruppe %2$s geändert %1$s hat %3$s in die Gruppe %2$s eingeladen + %1$s ist in die Gruppe %2$s zurückgekehrt %1$s hat %3$s aus der Gruppe %2$s entfernt %1$s hat dich aus der Gruppe %2$s entfernt %1$s hat die Gruppe %2$s verlassen @@ -296,10 +298,28 @@ Der Bestätigungscode kommt per SMS an deine neue Nummer. Die Telefonnummer %1$s ist bereits ein Telegram Konto. Bitte lösche es, bevor du mit der Übertragung auf das neue Konto startest. Sonstige + + Pincode + Pincode ändern + Wenn du die Code-Sperre aktivierst, erscheint ein Schloss ganz oben über der Chatliste. Tippe auf das Schloss, um deine Chats zu sperren und zu entsperren.\n\nÜbrigens: Wenn du den Pincode vergisst, musst du Telegram löschen und neu installieren. Dadurch verlierst du alle Geheimen Chats. + Du wirst nun ein Schloss über der Chatliste sehen. Tippe darauf um deine Chats mit dem neuen Pincode zu sperren. + Pincode + Kennwort + Aktuellen Pincode eingeben + Neuen Pincode eingeben + Deinen Pincode eingeben + Neuen Pincode erneut eingben + Ungültiger Pincode + Pincode falsch + Auto-Sperre + Benötigt Pincode wenn lange inaktiv. + in %1$s + Deaktiviert Die hier geteilten Bilder und Videos kannst du von jedem deiner Geräte aufrufen. Dateien - Die hier geteilten Bilder und Videos kannst du von jedem deiner Geräte aufrufen. + Geteilte Medien + Die hier geteilten Dateien kannst du von jedem deiner Geräte aufrufen. Karte Satellit @@ -319,11 +339,26 @@ Suchverlauf Suchverlauf BILDERSUCHE + BILDERSUCHE GIF-SUCHE Suche Bilder Suche GIFs Bild zuschneiden Bild bearbeiten + Verbessern + Highlights + Kontrast + Belichtung + Wärme + Sättigung + Vignette + Schatten + Körnung + Schärfe + Unschärfe + Möchtest du wirklich dieses Bild löschen? + Möchtest du wirklich dieses Video löschen? + Änderungen verwerfen? Password Change password @@ -405,6 +440,7 @@ Foto löschen Wählen OK + SCHNEIDEN un1 hat un2 aus der Gruppe entfernt un1 hat die Gruppe verlassen @@ -422,6 +458,7 @@ Du hast die Gruppe erstellt un1 hat dich aus der Gruppe entfernt un1 hat dich hinzugefügt + un1 ist in die Gruppe zurückgekehrt Diese Nachricht wird von deiner Telegram-Version nicht unterstützt. Bitte aktualisiere die App um sie zu sehen: http://telegram.org/update Foto Video @@ -511,18 +548,24 @@ %1$d Nachrichten %1$d Nachrichten %1$d Nachrichten - keine Dateien - %1$d Datei - %1$d Dateien - %1$d Dateien - %1$d Dateien - %1$d Dateien + keine Objekte + %1$d Objekt + %1$d Objekte + %1$d Objekte + %1$d Objekte + %1$d Objekte von keinem Kontakt von %1$d Kontakt von %1$d Kontakten von %1$d Kontakten von %1$d Kontakten von %1$d Kontakten + von keinen Chats + von %1$d Chat + von %1$d Chats + von %1$d Chats + von %1$d Chats + von %1$d Chats %1$d Sekunden %1$d Sekunde %1$d Sekunden @@ -572,6 +615,7 @@ %1$d Nutzer %1$d Nutzer + MMMM yyyy dd MMM dd.MM.yy dd.MM.yyyy diff --git a/TMessagesProj/src/main/res/values-es/strings.xml b/TMessagesProj/src/main/res/values-es/strings.xml index c59b5b3ed..7872194de 100644 --- a/TMessagesProj/src/main/res/values-es/strings.xml +++ b/TMessagesProj/src/main/res/values-es/strings.xml @@ -57,6 +57,7 @@ Silenciar %1$s No silenciar En %1$s + Desactivar Nueva difusión Nombre de la lista @@ -143,6 +144,7 @@ %1$s cambió el nombre del grupo %2$s %1$s cambió la foto del grupo %2$s %1$s invitó a %3$s al grupo %2$s + %1$s volvió al grupo %2$s %1$s expulsó a %3$s del grupo %2$s %1$s te expulsó del grupo %2$s %1$s dejó el grupo %2$s @@ -296,9 +298,27 @@ Enviaremos un SMS con el código de confirmación a tu nuevo número. El número %1$s ya está vinculado a una cuenta de Telegram. Por favor, elimina esa cuenta antes de migrar al nuevo número. Otras + + Código de acceso + Cambiar código de acceso + Cuando configuras un código, aparece un candado en la pantalla de chats. Toca sobre él para bloquear y desbloquear la aplicación.\n\nNota: si olvidas el código, tendrás que eliminar y reinstalar la aplicación. Perderás todos los chats secretos. + Ahora verás un candado en la pantalla de chats. Púlsalo para bloquear tu Telegram con tu nuevo código. + PIN + Contraseña + Pon tu código de acceso actual + Pon tu nuevo código de acceso + Pon tu código de acceso + Pon, otra vez, tu nuevo código + Código de acceso inválido + Los códigos de acceso no coinciden + Bloqueo automático + El bloqueo se activará transcurrido este tiempo. + en %1$s + Desactivado Comparte fotos y vídeos en este chat y accede a ellos desde cualquier dispositivo. Archivos + Multimedia Comparte archivos en este chat y accede a ellos desde cualquier dispositivo. Mapa @@ -307,9 +327,9 @@ m de distancia km de distancia Enviar ubicación - Compartir ubicación + Ubicación - Ir a Fotos y vídeos + Ir a Multimedia Guardar en galería %1$d de %2$d Galería @@ -318,12 +338,27 @@ Por favor, primero descarga la multimedia No hay fotos recientes No hay GIF recientes - BUSCAR FOTO - BUSCAR GIF + BUSCA FOTOS + BÚSQUEDA WEB + BUSCA GIF Buscar foto Buscar GIF Cortar imagen Editar imagen + Realzar + Iluminación + Contraste + Exposición + Temperatura + Saturación + Viñeta + Sombras + Grano + Nitidez + Desenfoque + ¿Quieres eliminar esta foto? + ¿Quieres eliminar este vídeo? + ¿Descartar cambios? Password Change password @@ -405,6 +440,7 @@ Eliminar foto Establecer OK + CORTAR un1 expulsó a un2 un1 dejó el grupo @@ -422,6 +458,7 @@ Creaste el grupo un1 te expulsó un1 te añadió + un1 volvió al grupo Este mensaje no lo admite tu versión de Telegram. Actualiza la app para verlo: http://telegram.org/update Foto Vídeo @@ -511,18 +548,24 @@ %1$d mensajes %1$d mensajes %1$d mensajes - sin archivos - %1$d archivo - %1$d archivos - %1$d archivos - %1$d archivos - %1$d archivos + Sin ítemes + %1$d ítem + %1$d ítemes + %1$d ítemes + %1$d ítemes + %1$d ítemes unused de %1$d contacto de %1$d contactos de %1$d contactos de %1$d contactos de %1$d contactos + desde ningún chat + desde %1$d chat + desde %1$d chats + desde %1$d chats + desde %1$d chats + desde %1$d chats %1$d segundos %1$d segundo %1$d segundos @@ -572,6 +615,7 @@ %1$d usuarios %1$d usuarios + MMMM \'de\' yyyy dd \'de\' MMM dd.MM.yy dd.MM.yyyy diff --git a/TMessagesProj/src/main/res/values-it/strings.xml b/TMessagesProj/src/main/res/values-it/strings.xml index 2a2f3da83..8f4d876d8 100644 --- a/TMessagesProj/src/main/res/values-it/strings.xml +++ b/TMessagesProj/src/main/res/values-it/strings.xml @@ -37,7 +37,7 @@ Inizia a scrivere premendo il tasto\nnuovo messaggio nell\'angolo in basso a destra\no apri il menu per avere più opzioni. Attendo la rete... Connessione in corso… - Aggiornamento in corso… + Aggiornamento… Nuova chat segreta In attesa che %s si colleghi… Chat segreta annullata @@ -57,6 +57,7 @@ Silenzia per %1$s Suona Tra %1$s + Disabilita Nuova lista broadcast Immetti il nome della lista @@ -143,6 +144,7 @@ %1$s ha modificato il nome del gruppo %2$s %1$s ha modificato la foto del gruppo %2$s %1$s ha invitato %3$s nel gruppo %2$s + %1$s è rientrato nel gruppo %2$s %1$s ha espulso %3$s dal gruppo %2$s %1$s ti ha espulso dal gruppo %2$s %1$s ha lasciato il gruppo %2$s @@ -240,7 +242,7 @@ Utenti bloccati Disconnetti Nessun suono - Predefinito + Default Supporto Sfondo chat Messaggi @@ -256,8 +258,8 @@ https://telegram.org/faq/it Eliminare la localizzazione? File della localizzazione non valido - Abilitato - Disabilitato + Abilitate + Disabilitate Servizio notifiche Se i servizi di Google Play sono sufficienti per ricevere le notifiche, è possibile disabilitare il Servizio notifiche. Ti raccomandiamo comunque di lasciarlo abilitato per lasciare l\'app attiva in background e ricevere le notifiche istantanee. Ordina per @@ -296,9 +298,27 @@ Invieremo un SMS con un codice di conferma al tuo nuovo numero. Il numero %1$s è già connesso a un account Telegram. Per favore elimina quell\'account prima di migrare ad un nuovo numero. Altro + + Codice + Cambia codice + Quando imposti un codice, un\'icona col lucchetto apparirà nella pagina delle chat. Premi su di essa per bloccare e sbloccare l\'app.\n\nNota: se ti dimentichi il codice, dovrai disinstallare e reinstallare l\'app. Tutte le chat segrete verranno perse. + Ora visualizzerai un\'icona col lucchetto nella pagina delle chat. Premi su di essa per bloccare la tua app Telegram con il codice. + PIN + Password + Inserisci il tuo codice + Inserisci il nuovo codice + Inserisci il tuo codice + Reinserisci il nuovo codice + Codice non valido + I codici non corrispondono + Blocco automatico + Richiede il codice se lontano per del tempo. + tra %1$s + Disabilitato Condividi foto e video in questa chat e accedi ad essi da ogni tuo dispositivo. File + Media condivisi Condividi file e documenti in questa chat e accedi ad essi da ogni tuo dispositivo. Mappa @@ -318,12 +338,27 @@ Scarica prima il file Nessuna foto recente Nessuna GIF recente - RICERCA WEB - RICERCA GIF + CERCA IMMAGINI + RICERCA WEB + CERCA GIF Cerca su web Cerca GIF Ritaglia immagine Modifica immagine + Migliora + Alte luci + Contrasto + Esposizione + Calore + Saturazione + Vignettatura + Ombre + Grana + Nitidezza + Sfocatura + Sei sicuro di voler eliminare questa foto? + Sei sicuro di voler eliminare questo video? + Annullare le modifiche? Password Change password @@ -405,6 +440,7 @@ Elimina foto Imposta OK + RITAGLIA un1 ha espulso un2 un1 ha lasciato il gruppo @@ -422,6 +458,7 @@ Hai creato il gruppo un1 ti ha espulso un1 ti ha aggiunto + un1 è ritentrato nel gruppo Questo messaggio non è supportato sulla tua versione di Telegram. Aggiorna l\'applicazione per visualizzarlo: http://telegram.org/update Foto Video @@ -511,18 +548,24 @@ %1$d messaggi %1$d messaggi %1$d messaggi - nessun file - %1$d file - %1$d file - %1$d file - %1$d file - %1$d file + nessun oggetto + %1$d oggetto + %1$d oggetti + %1$d oggetti + %1$d oggetti + %1$d oggetti da nessun contatto da %1$d contatto da %1$d contatti da %1$d contatti da %1$d contatti da %1$d contatti + in nessuna chat + in %1$d chat + in %1$d chat + in %1$d chat + in %1$d chat + in %1$d chat %1$d secondi %1$d secondo %1$d secondi @@ -572,6 +615,7 @@ %1$d utenti %1$d utenti + MMMM yyyy dd MMM dd.MM.yy dd.MM.yyyy diff --git a/TMessagesProj/src/main/res/values-ko/strings.xml b/TMessagesProj/src/main/res/values-ko/strings.xml index 08923ac6d..770d8960c 100644 --- a/TMessagesProj/src/main/res/values-ko/strings.xml +++ b/TMessagesProj/src/main/res/values-ko/strings.xml @@ -57,6 +57,7 @@ %1$s 동안 음소거 음소거 해제 %1$s 후 + 비활성화 새 단체 메시지 리스트 리스트 이름을 입력하세요 @@ -143,6 +144,7 @@ %1$s님이 그룹 이름을 %2$s 그룹으로 변경했습니다 %1$s님이 %2$s 그룹 사진을 변경했습니다 %1$s님이 %3$s님을 %2$s 그룹에 초대했습니다 + %1$s 님이 %2$s 그룹으로 되돌아왔습니다 %1$s님이 %3$s님을 %2$s 그룹에서 추방했습니다 %1$s님이 %2$s 그룹에서 추방했습니다 %1$s님이 %2$s 그룹을 떠났습니다 @@ -296,9 +298,27 @@ 인증코드 메시지를 새 번호로 전송하겠습니다. 그 번호는 이미 텔레그램 계정에 연결되어 있습니다. 새 번호로 이동하기 전에 %1$s 계정에서 탈퇴해 주세요. 기타 + + 잠금번호 + 잠금번호 변경 + 잠금코드를 설정하셨을 경우, 대화방에 잠금 아이콘이 표시됩니다. 해당 아이콘을 클릭하여 텔레그램 잠금 설정을 할 수 있습니다.\n\n주의: 잠금코드를 잊어버렸을 경우 앱 삭제후 재설치를 해주셔야합니다. 이 경우 비밀대화 내용은 삭제가 됩니다. + 대화방에 잠금아이콘이 표시가 됩니다. 해당 아이콘을 클릭하여 새로운 잠금코드를 설정하여 텔레그램을 잠글수 있습니다. + 핀코드 + 잠금번호 + 현재 잠금코드 입력 + 새로운 잠금코드 입력 + 잠금코드를 입력해주세요 + 잠금코드 재입력 + 올바르지 않은 잠금코드 + 잠금코드가 정확하지 않습니다 + 자동 잠금 + 일정 시간 후에 잠금코드 활성화 + %1$s 후에 + 비활성화됨 이 채팅방에서 사진이나 동영상을 공유하면 다른 기기에서도 보실 수 있습니다. 파일 + 공유된 미디어 이 채팅방에서 파일이나 문서를 공유하면 다른 기기에서도 보실 수 있습니다. 지도 @@ -318,12 +338,27 @@ 사진/동영상을 먼저 다운로드하세요 최근 사진 없음 최근에 검색한 GIF - 웹 검색 + 이미지 검색 + 웹 검색 GIF 검색 웹 검색 GIF 검색 사진 자르기 이미지 편집 + 향상 + 하이라이트 + 대비 + 노출 + 온기 + 채도 + 비네팅 + 그림자 + 그레인 + 선명 + 흐림 + 이 사진을 삭제하시겠습니까? + 이 동영상을 삭제하시겠습니까? + 변경을 취소하시겠습니까? Password Change password @@ -405,6 +440,7 @@ 사진 삭제 설정 확인 + 자르기 un1님이 un2님을 추방했습니다 un1님이 퇴장했습니다 @@ -422,6 +458,7 @@ 그룹을 만들었습니다 un1님이 추방했습니다 un1님이 그룹에 초대했습니다 + un1 님께서 그룹에 돌아오셨습니다 이 메시지는 사용 중인 텔레그램의 버전이 낮아 지원하지 않습니다. 앱을 업데이트 하세요: http://telegram.org/update 사진 동영상 @@ -511,18 +548,24 @@ 메시지 %1$d건 메시지 %1$d건 메시지 %1$d건 - 파일 없음 - 파일 %1$d개 - 파일 %1$d개 - 파일 %1$d개 - 파일 %1$d개 - 파일 %1$d개 + 아이템이 없습니다. + %1$d개 아이템 + %1$d개 아이템 + %1$d개 아이템 + %1$d개 아이템 + %1$d개 아이템 보낸곳 없음 - 채팅방 %1$d개에서 채팅방 %1$d개에서 채팅방 %1$d개에서 채팅방 %1$d개에서 채팅방 %1$d개에서 + 받은 대화 없음 + %1$d개의 대화로부터 받음 + %1$d개의 대화로부터 받음 + %1$d개의 대화로부터 받음 + %1$d개의 대화로부터 받음 + %1$d개의 대화로부터 받음 %1$d초 %1$d초 %1$d초 @@ -572,6 +615,7 @@ %1$d명의 대화상대 %1$d명의 대화상대 + MMMM yyyy M\'월\' d\'일\' yyyy.MM.dd. yyyy. MM. dd. diff --git a/TMessagesProj/src/main/res/values-nl/strings.xml b/TMessagesProj/src/main/res/values-nl/strings.xml index 945b90a44..f765c87db 100644 --- a/TMessagesProj/src/main/res/values-nl/strings.xml +++ b/TMessagesProj/src/main/res/values-nl/strings.xml @@ -57,6 +57,7 @@ %1$s stil Stil uitschakelen Over %1$s + Uitschakelen Nieuwe verzendlijst Naam van lijst @@ -143,6 +144,7 @@ %1$s heeft de naam van de groep %2$s gewijzigd %1$s heeft de afbeelding van de groep %2$s gewijzigd %1$s heeft %3$s uitgenodigd voor de groep %2$s + %1$s is terug in de groep %2$s %1$s heeft %3$s verwijderd uit de groep %2$s %1$s heeft je verwijderd uit de groep %2$s %1$s heeft de groep %2$s verlaten @@ -221,7 +223,7 @@ Een vraag stellen Animaties Deblokkeer - Houd een gebruiker ingedrukt om hem/haar te deblokkeren. + Gebruiker vasthouden om te deblokkeren. Geen geblokkeerde gebruikers Berichtmeldingen Waarschuwing @@ -296,9 +298,27 @@ We sturen een sms-bericht met verificatiecode naar je nieuwe nummer. Aan telefoonnummer %1$s is al een Telegram-account gekoppeld. Verwijder het account om te kunnen migreren naar het nieuwe nummer. Overig + + Toegangscode + Toegangscode wijzigen + Als je een toegangscode instelt verschijnt er een slotje op de chatspagina. Tik erop om Telegram te vergrendelen of te ontgrendelen.\n\nLet op: vergeet je de toegangscode dan zul je de app moeten verwijderen en herinstalleren. Alle geheime chats gaan daarbij verloren. + Je zult nu een slotje op de chatspagina zien. Tik erop om Telegram te vergrendelen met je nieuwe toegangscode. + PIN + Wachtwoord + Huidige toegangscode invoeren + Nieuwe toegangscode invoeren + Toegangscode invoeren + Nieuwe toegangscode opnieuw invoeren + Ongeldige toegangscode + Toegangscodes komen niet overeen + Automatisch vergrendelen + Vraag om toegangscode indien afwezig + over %1$s + Uitgeschakeld Deel foto\'s en video\'s in deze chat om ze op al je apparaten te kunnen benaderen. Bestanden + Gedeelde media Deel bestanden en documenten in deze chat om ze op al je apparaten te kunnen benaderen. Kaart @@ -319,11 +339,26 @@ Niets recents Niets recents ONLINE ZOEKEN - GIF\'S ZOEKEN + ZOEK OP HET WEB + GIF\'S ZOEKEN Online zoeken GIF\'s zoeken Foto bijsnijden Foto bewerken + Verbeteren + Accent + Contrast + Belichting + Warmte + Verzadiging + Vignet + Schaduwen + Korrel + Scherper + Vager + Foto echt verwijderen? + Video echt verwijderen? + Wijzigingen negeren? Password Change password @@ -405,6 +440,7 @@ Foto verwijderen Stel in OK + BIJSNIJDEN un1 heeft un2 verwijderd un1 heeft de groep verlaten @@ -422,6 +458,7 @@ Je hebt de groep gemaakt un1 heeft je verwijderd un1 heeft je toegevoegd + un1 is terug in de groep Dit bericht wordt niet ondersteund door jouw versie van Telegram. Werk Telegram bij om dit bericht te bekijken: http://telegram.org/update Foto Video @@ -511,18 +548,24 @@ %1$d berichten %1$d berichten %1$d berichten - geen bestanden - %1$d bestand - %1$d bestanden - %1$d bestanden - %1$d bestanden - %1$d bestanden + geen items + %1$d item + %1$d items + %1$d items + %1$d items + %1$d items van geen enkel contact van %1$d contacten van %1$d contacten van %1$d contacten van %1$d contacten van %1$d contacten + van geen chats + van %1$d chat + van %1$d chats + van %1$d chats + van %1$d chats + van %1$d chats %1$d seconden %1$d seconde %1$d seconden @@ -572,6 +615,7 @@ %1$d gebruikers %1$d gebruikers + MMMM yyyy dd MMM dd-MM-yy dd-MM-yyyy diff --git a/TMessagesProj/src/main/res/values-pt-rBR/strings.xml b/TMessagesProj/src/main/res/values-pt-rBR/strings.xml index bced87c67..701ca6f5b 100644 --- a/TMessagesProj/src/main/res/values-pt-rBR/strings.xml +++ b/TMessagesProj/src/main/res/values-pt-rBR/strings.xml @@ -5,7 +5,7 @@ Telegram Português (Brasil) - Portuguese (Brazil) + Português (Brasil) pt_BR Seu número @@ -57,6 +57,7 @@ Silenciar por %1$s Restaurar Som Em %1$s + Desativar Nova Lista de Transmissão Digite o nome da lista @@ -143,6 +144,7 @@ %1$s editou o nome do grupo %2$s %1$s editou a foto do grupo %2$s %1$s convidou %3$s para o grupo %2$s + %1$s retornou ao grupo %2$s %1$s removeu %3$s do grupo %2$s %1$s removeu você do grupo %2$s %1$s saiu do grupo %2$s @@ -175,7 +177,7 @@ Nome do grupo %1$d/%2$d membros - Mídia compartilhada + Mídia Compartilhada Configurações Adicionar membro Apagar e sair do grupo @@ -270,7 +272,7 @@ Somente com a tela ligada Somente com a tela desligada Sempre mostrar pop-up - Contador de medalhas + Contador no Ícone Curta Longa Padrão do sistema @@ -294,11 +296,29 @@ ALTERAR NÚMERO Novo número Vamos enviar uma SMS com um código de confirmação para o seu novo número. - O número %1$s já possui uma conta do Telegram. Por favor, delete esta conta antes de migrar para o novo número. + O número %1$s já possui uma conta do Telegram. Por favor, exclua esta conta antes de migrar para o novo número. Outro + + Senha + Alterar Senha + Quando você define uma senha adicional, um ícone de cadeado aparece na página de chats. Clique para bloquear e desbloquear o app.\n\nNota: se você esquecer a sua senha, terá de excluir e reinstalar o app. Todos os chats secretos serão perdidos. + Você verá o ícone do cadeado na página de chats. Clique para bloquear seu app do Telegram com a sua nova senha. + PIN + Senha + Insira sua senha atual + Insira sua nova senha + Insira sua senha + Re-insira sua nova senha + Senha inválida + As senhas não são iguais + Auto-bloquear + Requisitar senha se estiver ausente por muito tempo. + em %1$s + Desativado Compartilhar fotos e vídeos no chat e acessá-los em qualquer um de seus dispositivos. Arquivos + Mídia Compartilhada Compartilhar arquivos e documentos no chat e acessá-los de qualquer um de seus dispositivos. Mapa @@ -318,12 +338,27 @@ Baixar o vídeo primeiro Nenhuma foto recente Nenhum GIF recente - PROCURAR NA INTERNET - PROCURAR GIFS + BUSCAR IMAGENS + BUSCA GLOBAL + BUSCAR GIFS Procurar na web Procurar GIFs Recortar imagem Editar imagem + Aumentar + Realce + Contraste + Exposição + Calor + Saturação + Vignette + Sombras + Granulado + Nitidez + Desfoque + Você tem certeza que deseja apagar esta foto? + Você tem certeza que deseja apagar este vídeo? + Descartar mudanças? Password Change password @@ -379,7 +414,7 @@ Adicionar Usuários Desculpe, muitas solicitações. Impossível alterar os ajustes de privacidade agora, por favor aguarde. Sair de todos os dispositivos, exceto este. - Toque e segure no usuário para deletar. + Toque e segure no usuário para remover. Editar Vídeo Vídeo Original @@ -405,6 +440,7 @@ Apagar foto Aplicar OK + CORTAR un1 removeu un2 un1 saiu do grupo @@ -422,6 +458,7 @@ Você criou o grupo un1 removeu você un1 adicionou você + un1 retornou ao grupo Esta mensagem não é suportada na sua versão do Telegram. Para visualiza-la atualize seu aplicativo em http://telegram.org/update Foto Vídeo @@ -451,16 +488,16 @@ Enviar mensagens para %1$s? Você tem certeza que desejar sair?\n\nSaiba que você pode usar o Telegram em vários dispositivos de uma vez.\n\nLembre-se, sair apaga todos os seus Chats Secretos. Você tem certeza que deseja terminar todas as outras sessões? - Você tem certeza que deseja deletar e sair do grupo? - Você tem certeza que deseja deletar esta conversa? + Você tem certeza que apagar e sair do grupo? + Você tem certeza que deseja apagar esta conversa? Você tem certeza que deseja compartilhar suas informações de contato? Você tem certeza que deseja bloquear este contato? Você tem certeza que deseja desbloquear este contato? - Você tem certeza que deseja deletar este contato? + Você tem certeza que deseja apagar este contato? Você tem certeza que deseja começar um chat secreto? Você tem certeza que deseja cancelar o registro? Você tem certeza que deseja limpar o histórico? - Você tem certeza que deseja deletar %1$s? + Você tem certeza que deseja apagar %1$s? Enviar mensagens para %1$s? Encaminhar mensagem para %1$s? Desculpe, esta funcionalidade não está disponível para seu país. @@ -511,18 +548,24 @@ %1$d mensagens %1$d mensagens %1$d mensagens - nenhum arquivo - %1$d arquivo - %1$d arquivos - %1$d arquivos - %1$d arquivos - %1$d arquivos + nenhum item + %1$d item + %1$d itens + %1$d itens + %1$d itens + %1$d itens de nenhum contato de %1$d contato de %1$d contatos de %1$d contatos de %1$d contatos de %1$d contatos + de nenhum chat + de %1$d chat + de %1$d chats + de %1$d chats + de %1$d chats + de %1$d chats %1$d segundos %1$d segundo %1$d segundos @@ -572,6 +615,7 @@ %1$d usuários %1$d usuários + MMMM yyyy dd MMM dd.MM.yy dd.MM.yyyy diff --git a/TMessagesProj/src/main/res/values-pt-rPT/strings.xml b/TMessagesProj/src/main/res/values-pt-rPT/strings.xml index 31f5ae720..040317928 100644 --- a/TMessagesProj/src/main/res/values-pt-rPT/strings.xml +++ b/TMessagesProj/src/main/res/values-pt-rPT/strings.xml @@ -57,6 +57,7 @@ Silenciar por %1$s Restaurar Som Em %1$s + Desativar Nova Lista de Transmissão Digite o nome da lista @@ -143,6 +144,7 @@ %1$s editou o nome do grupo %2$s %1$s editou a foto do grupo %2$s %1$s convidou %3$s para o grupo %2$s + %1$s retornou ao grupo %2$s %1$s removeu %3$s do grupo %2$s %1$s removeu você do grupo %2$s %1$s saiu do grupo %2$s @@ -175,7 +177,7 @@ Nome do grupo %1$d/%2$d membros - Mídia compartilhada + Mídia Compartilhada Configurações Adicionar membro Apagar e sair do grupo @@ -270,7 +272,7 @@ Somente com a tela ligada Somente com a tela desligada Sempre mostrar pop-up - Contador de medalhas + Contador no Ícone Curta Longa Padrão do sistema @@ -294,11 +296,29 @@ ALTERAR NÚMERO Novo número Vamos enviar uma SMS com um código de confirmação para o seu novo número. - O número %1$s já possui uma conta do Telegram. Por favor, delete esta conta antes de migrar para o novo número. + O número %1$s já possui uma conta do Telegram. Por favor, exclua esta conta antes de migrar para o novo número. Outro + + Senha + Alterar Senha + Quando você define uma senha adicional, um ícone de cadeado aparece na página de chats. Clique para bloquear e desbloquear o app.\n\nNota: se você esquecer a sua senha, terá de excluir e reinstalar o app. Todos os chats secretos serão perdidos. + Você verá o ícone do cadeado na página de chats. Clique para bloquear seu app do Telegram com a sua nova senha. + PIN + Senha + Insira sua senha atual + Insira sua nova senha + Insira sua senha + Re-insira sua nova senha + Senha inválida + As senhas não são iguais + Auto-bloquear + Requisitar senha se estiver ausente por muito tempo. + em %1$s + Desativado Compartilhar fotos e vídeos no chat e acessá-los em qualquer um de seus dispositivos. Arquivos + Mídia Compartilhada Compartilhar arquivos e documentos no chat e acessá-los de qualquer um de seus dispositivos. Mapa @@ -318,12 +338,27 @@ Baixar o vídeo primeiro Nenhuma foto recente Nenhum GIF recente - PROCURAR NA INTERNET - PROCURAR GIFS + BUSCAR IMAGENS + BUSCA GLOBAL + BUSCAR GIFS Procurar na web Procurar GIFs Recortar imagem Editar imagem + Aumentar + Realce + Contraste + Exposição + Calor + Saturação + Vignette + Sombras + Granulado + Nitidez + Desfoque + Você tem certeza que deseja apagar esta foto? + Você tem certeza que deseja apagar este vídeo? + Descartar mudanças? Password Change password @@ -379,7 +414,7 @@ Adicionar Usuários Desculpe, muitas solicitações. Impossível alterar os ajustes de privacidade agora, por favor aguarde. Sair de todos os dispositivos, exceto este. - Toque e segure no usuário para deletar. + Toque e segure no usuário para remover. Editar Vídeo Vídeo Original @@ -405,6 +440,7 @@ Apagar foto Aplicar OK + CORTAR un1 removeu un2 un1 saiu do grupo @@ -422,6 +458,7 @@ Você criou o grupo un1 removeu você un1 adicionou você + un1 retornou ao grupo Esta mensagem não é suportada na sua versão do Telegram. Para visualiza-la atualize seu aplicativo em http://telegram.org/update Foto Vídeo @@ -451,16 +488,16 @@ Enviar mensagens para %1$s? Você tem certeza que desejar sair?\n\nSaiba que você pode usar o Telegram em vários dispositivos de uma vez.\n\nLembre-se, sair apaga todos os seus Chats Secretos. Você tem certeza que deseja terminar todas as outras sessões? - Você tem certeza que deseja deletar e sair do grupo? - Você tem certeza que deseja deletar esta conversa? + Você tem certeza que apagar e sair do grupo? + Você tem certeza que deseja apagar esta conversa? Você tem certeza que deseja compartilhar suas informações de contato? Você tem certeza que deseja bloquear este contato? Você tem certeza que deseja desbloquear este contato? - Você tem certeza que deseja deletar este contato? + Você tem certeza que deseja apagar este contato? Você tem certeza que deseja começar um chat secreto? Você tem certeza que deseja cancelar o registro? Você tem certeza que deseja limpar o histórico? - Você tem certeza que deseja deletar %1$s? + Você tem certeza que deseja apagar %1$s? Enviar mensagens para %1$s? Encaminhar mensagem para %1$s? Desculpe, esta funcionalidade não está disponível para seu país. @@ -511,18 +548,24 @@ %1$d mensagens %1$d mensagens %1$d mensagens - nenhum arquivo - %1$d arquivo - %1$d arquivos - %1$d arquivos - %1$d arquivos - %1$d arquivos + nenhum item + %1$d item + %1$d itens + %1$d itens + %1$d itens + %1$d itens de nenhum contato de %1$d contato de %1$d contatos de %1$d contatos de %1$d contatos de %1$d contatos + de nenhum chat + de %1$d chat + de %1$d chats + de %1$d chats + de %1$d chats + de %1$d chats %1$d segundos %1$d segundo %1$d segundos @@ -572,6 +615,7 @@ %1$d usuários %1$d usuários + MMMM yyyy dd MMM dd.MM.yy dd.MM.yyyy diff --git a/TMessagesProj/src/main/res/values-v21/styles.xml b/TMessagesProj/src/main/res/values-v21/styles.xml index 97ee0af7d..b02410741 100644 --- a/TMessagesProj/src/main/res/values-v21/styles.xml +++ b/TMessagesProj/src/main/res/values-v21/styles.xml @@ -54,7 +54,7 @@ diff --git a/TMessagesProj/src/main/res/values/colors.xml b/TMessagesProj/src/main/res/values/colors.xml index 9b1c746d2..31a03a7c9 100755 --- a/TMessagesProj/src/main/res/values/colors.xml +++ b/TMessagesProj/src/main/res/values/colors.xml @@ -2,5 +2,4 @@ #6633B5E5 #dcdcdc - #ff54759e \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values/strings.xml b/TMessagesProj/src/main/res/values/strings.xml index 0f856f43a..085fb7bd6 100644 --- a/TMessagesProj/src/main/res/values/strings.xml +++ b/TMessagesProj/src/main/res/values/strings.xml @@ -57,6 +57,7 @@ Mute for %1$s Unmute In %1$s + Disable New Broadcast List Enter list name @@ -143,6 +144,7 @@ %1$s edited the group\'s %2$s name %1$s edited the group\'s %2$s photo %1$s invited %3$s to the group %2$s + %1$s returned to the group %2$s %1$s removed %3$s from the group %2$s %1$s removed you from the group %2$s %1$s has left the group %2$s @@ -296,9 +298,27 @@ We will send an SMS with a confirmation code to your new number. The number %1$s is already connected to a Telegram account. Please delete that account before migrating to the new number. Other + + Passcode + Change Passcode + When you set up an additional passcode, a lock icon will appear on the chats page. Tap it to lock and unlock your Telegram app.\n\nNote: if you forget the passcode, you\'ll need to delete and reinstall the app. All secret chats will be lost. + You will now see a lock icon on the chats page. Tap it to lock your Telegram app with your new passcode. + PIN + Password + Enter your current passcode + Enter your new passcode + Enter your passcode + Re-enter your new passcode + Invalid passcode + Passcodes do not match + Auto-lock + Require passcode if away for a time. + in %1$s + Disabled Share photos and videos in this chat and access them on any of your devices. Files + Shared Media Share files and documents in this chat and access them on any of your devices. Map @@ -318,12 +338,27 @@ Please download media first No recent photos No recent GIFs - SEARCH WEB - SEARCH GIFS + FIND IMAGES + WEB SEARCH + FIND GIFS Search web Search GIFs Crop image Edit image + Enhance + Highlights + Contrast + Exposure + Warmth + Saturation + Vignette + Shadows + Grain + Sharpen + Blur + Are you sure you want to delete this photo? + Are you sure you want to delete this video? + Discard changes? Password Change password @@ -405,6 +440,7 @@ Delete photo Set OK + CROP un1 removed un2 un1 left group @@ -422,6 +458,7 @@ You created the group un1 removed you un1 added you + un1 returned to the group This message is not supported on your version of Telegram. Update the app to view: http://telegram.org/update Photo Video @@ -511,18 +548,24 @@ %1$d messages %1$d messages %1$d messages - no files - %1$d file - %1$d files - %1$d files - %1$d files - %1$d files + no items + %1$d item + %1$d items + %1$d items + %1$d items + %1$d items from no contacts from %1$d contact from %1$d contacts from %1$d contacts from %1$d contacts from %1$d contacts + from no chats + from %1$d chat + from %1$d chats + from %1$d chats + from %1$d chats + from %1$d chats %1$d seconds %1$d second %1$d seconds @@ -572,6 +615,7 @@ %1$d users %1$d users + MMMM yyyy MMM dd dd.MM.yy dd.MM.yyyy diff --git a/TMessagesProj/src/main/res/values/styles.xml b/TMessagesProj/src/main/res/values/styles.xml index bf12e881b..9884ff93b 100644 --- a/TMessagesProj/src/main/res/values/styles.xml +++ b/TMessagesProj/src/main/res/values/styles.xml @@ -42,7 +42,7 @@