diff --git a/TMessagesProj/build.gradle b/TMessagesProj/build.gradle index 13f028064..0be48dbc6 100644 --- a/TMessagesProj/build.gradle +++ b/TMessagesProj/build.gradle @@ -1,11 +1,3 @@ -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath 'com.android.tools.build:gradle:1.2.3' - } -} apply plugin: 'com.android.application' repositories { @@ -13,7 +5,7 @@ repositories { } dependencies { - compile 'com.android.support:support-v4:22.1.+' + compile 'com.android.support:support-v4:22.2.+' compile 'com.google.android.gms:play-services:3.2.+' compile 'net.hockeyapp.android:HockeySDK:3.5.+' compile 'com.googlecode.mp4parser:isoparser:1.0.+' @@ -81,7 +73,7 @@ android { defaultConfig { minSdkVersion 8 targetSdkVersion 22 - versionCode 542 - versionName "2.9.1" + versionCode 572 + versionName "3.0.1" } } diff --git a/TMessagesProj/jni/image.c b/TMessagesProj/jni/image.c index a3a0fb862..a2cc1dfb8 100644 --- a/TMessagesProj/jni/image.c +++ b/TMessagesProj/jni/image.c @@ -430,7 +430,7 @@ JNIEXPORT void Java_org_telegram_messenger_Utilities_loadBitmap(JNIEnv *env, jcl AndroidBitmapInfo info; int i; - + if ((i = AndroidBitmap_getInfo(env, bitmap, &info)) >= 0) { char *fileName = (*env)->GetStringUTFChars(env, path, NULL); FILE *infile; @@ -438,7 +438,7 @@ JNIEXPORT void Java_org_telegram_messenger_Utilities_loadBitmap(JNIEnv *env, jcl if ((infile = fopen(fileName, "rb"))) { struct my_error_mgr jerr; struct jpeg_decompress_struct cinfo; - + cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = my_error_exit; @@ -557,7 +557,7 @@ JNIEXPORT jobject Java_org_telegram_messenger_Utilities_loadWebpImage(JNIEnv *en if (!WebPDecodeRGBAInto((uint8_t*)inputBuffer, len, (uint8_t*)bitmapPixels, bitmapInfo.height * bitmapInfo.stride, bitmapInfo.stride)) { AndroidBitmap_unlockPixels(env, outputBitmap); (*env)->DeleteLocalRef(env, outputBitmap); - (*env)->ThrowNew(env, jclass_RuntimeException, "Failed to unlock Bitmap pixels"); + (*env)->ThrowNew(env, jclass_RuntimeException, "Failed to decode webp image"); return 0; } diff --git a/TMessagesProj/libs/armeabi-v7a/libtmessages.8.so b/TMessagesProj/libs/armeabi-v7a/libtmessages.8.so index b73f401f3..ebbd6bff2 100755 Binary files a/TMessagesProj/libs/armeabi-v7a/libtmessages.8.so and b/TMessagesProj/libs/armeabi-v7a/libtmessages.8.so differ diff --git a/TMessagesProj/libs/armeabi/libtmessages.8.so b/TMessagesProj/libs/armeabi/libtmessages.8.so index b720a57b4..fdd6919ec 100755 Binary files a/TMessagesProj/libs/armeabi/libtmessages.8.so and b/TMessagesProj/libs/armeabi/libtmessages.8.so differ diff --git a/TMessagesProj/libs/x86/libtmessages.8.so b/TMessagesProj/libs/x86/libtmessages.8.so index 0b3e8df01..22a292919 100755 Binary files a/TMessagesProj/libs/x86/libtmessages.8.so and b/TMessagesProj/libs/x86/libtmessages.8.so differ diff --git a/TMessagesProj/src/main/java/org/telegram/SQLite/SQLitePreparedStatement.java b/TMessagesProj/src/main/java/org/telegram/SQLite/SQLitePreparedStatement.java index 6335d93b8..573107797 100755 --- a/TMessagesProj/src/main/java/org/telegram/SQLite/SQLitePreparedStatement.java +++ b/TMessagesProj/src/main/java/org/telegram/SQLite/SQLitePreparedStatement.java @@ -8,9 +8,11 @@ package org.telegram.SQLite; +import org.telegram.messenger.BuildVars; import org.telegram.messenger.FileLog; import java.nio.ByteBuffer; +import java.util.HashMap; public class SQLitePreparedStatement { private boolean isFinalized = false; @@ -19,6 +21,8 @@ public class SQLitePreparedStatement { private int queryArgsCount; private boolean finalizeAfterQuery = false; + private static HashMap hashMap; + public int getStatementHandle() { return sqliteStatementHandle; } @@ -26,6 +30,15 @@ public class SQLitePreparedStatement { public SQLitePreparedStatement(SQLiteDatabase db, String sql, boolean finalize) throws SQLiteException { finalizeAfterQuery = finalize; sqliteStatementHandle = prepare(db.getSQLiteHandle(), sql); + if (BuildVars.DEBUG_VERSION) { + if (hashMap == null) { + hashMap = new HashMap<>(); + } + hashMap.put(this, sql); + for (HashMap.Entry entry : hashMap.entrySet()) { + FileLog.d("tmessages", "exist entry = " + entry.getValue()); + } + } } @@ -88,6 +101,9 @@ public class SQLitePreparedStatement { return; } try { + if (BuildVars.DEBUG_VERSION) { + hashMap.remove(this); + } isFinalized = true; finalize(sqliteStatementHandle); } catch (SQLiteException e) { diff --git a/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java b/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java index 17acc3426..89992d69d 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java +++ b/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java @@ -616,22 +616,31 @@ public class AndroidUtilities { } } + public static final int FLAG_TAG_BR = 1; + public static final int FLAG_TAG_BOLD = 2; + public static final int FLAG_TAG_COLOR = 4; + public static final int FLAG_TAG_ALL = FLAG_TAG_BR | FLAG_TAG_BOLD | FLAG_TAG_COLOR; + public static Spannable replaceTags(String str) { + return replaceTags(str, FLAG_TAG_ALL); + } + + public static Spannable replaceTags(String str, int flag) { try { int start; - int startColor = -1; int end; StringBuilder stringBuilder = new StringBuilder(str); - while ((start = stringBuilder.indexOf("
")) != -1) { - stringBuilder.replace(start, start + 4, "\n"); - } - while ((start = stringBuilder.indexOf("
")) != -1) { - stringBuilder.replace(start, start + 5, "\n"); + if ((flag & FLAG_TAG_BR) != 0) { + while ((start = stringBuilder.indexOf("
")) != -1) { + stringBuilder.replace(start, start + 4, "\n"); + } + while ((start = stringBuilder.indexOf("
")) != -1) { + stringBuilder.replace(start, start + 5, "\n"); + } } ArrayList bolds = new ArrayList<>(); - ArrayList colors = new ArrayList<>(); - while ((start = stringBuilder.indexOf("")) != -1 || (startColor = stringBuilder.indexOf("")) != -1) { stringBuilder.replace(start, start + 3, ""); end = stringBuilder.indexOf(""); if (end == -1) { @@ -640,17 +649,20 @@ public class AndroidUtilities { stringBuilder.replace(end, end + 4, ""); bolds.add(start); bolds.add(end); - } else if (startColor != -1) { - stringBuilder.replace(startColor, startColor + 2, ""); - end = stringBuilder.indexOf(">", startColor); - int color = Color.parseColor(stringBuilder.substring(startColor, end)); - stringBuilder.replace(startColor, end + 1, ""); + } + } + ArrayList colors = new ArrayList<>(); + if ((flag & FLAG_TAG_COLOR) != 0) { + while ((start = stringBuilder.indexOf("", start); + int color = Color.parseColor(stringBuilder.substring(start, end)); + stringBuilder.replace(start, end + 1, ""); end = stringBuilder.indexOf(""); stringBuilder.replace(end, end + 4, ""); - colors.add(startColor); + colors.add(start); colors.add(end); colors.add(color); - startColor = -1; } } SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(stringBuilder); diff --git a/TMessagesProj/src/main/java/org/telegram/android/AnimationCompat/AnimatorSetProxy.java b/TMessagesProj/src/main/java/org/telegram/android/AnimationCompat/AnimatorSetProxy.java index 18c6b12da..be5993931 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/AnimationCompat/AnimatorSetProxy.java +++ b/TMessagesProj/src/main/java/org/telegram/android/AnimationCompat/AnimatorSetProxy.java @@ -89,6 +89,15 @@ public class AnimatorSetProxy { return this; } + public AnimatorSetProxy setStartDelay(long delay) { + if (View10.NEED_PROXY) { + ((AnimatorSet10) animatorSet).setStartDelay(delay); + } else { + ((AnimatorSet) animatorSet).setStartDelay(delay); + } + return this; + } + public void start() { if (View10.NEED_PROXY) { ((AnimatorSet10) animatorSet).start(); diff --git a/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java b/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java index da56c872d..a4bb1c349 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/ContactsController.java @@ -956,14 +956,8 @@ public class ContactsController { public int compare(TLRPC.TL_contact tl_contact, TLRPC.TL_contact tl_contact2) { TLRPC.User user1 = usersDict.get(tl_contact.user_id); TLRPC.User user2 = usersDict.get(tl_contact2.user_id); - String name1 = user1.first_name; - if (name1 == null || name1.length() == 0) { - name1 = user1.last_name; - } - String name2 = user2.first_name; - if (name2 == null || name2.length() == 0) { - name2 = user2.last_name; - } + String name1 = UserObject.getFirstName(user1); + String name2 = UserObject.getFirstName(user2); return name1.compareTo(name2); } }); @@ -989,10 +983,7 @@ public class ContactsController { contactsByPhonesDict.put(user.phone, value); } - String key = user.first_name; - if (key == null || key.length() == 0) { - key = user.last_name; - } + String key = UserObject.getFirstName(user); if (key.length() > 1) { key = key.substring(0, 1); } @@ -1160,14 +1151,8 @@ public class ContactsController { public int compare(TLRPC.TL_contact tl_contact, TLRPC.TL_contact tl_contact2) { TLRPC.User user1 = MessagesController.getInstance().getUser(tl_contact.user_id); TLRPC.User user2 = MessagesController.getInstance().getUser(tl_contact2.user_id); - String name1 = user1.first_name; - if (name1 == null || name1.length() == 0) { - name1 = user1.last_name; - } - String name2 = user2.first_name; - if (name2 == null || name2.length() == 0) { - name2 = user2.last_name; - } + String name1 = UserObject.getFirstName(user1); + String name2 = UserObject.getFirstName(user2); return name1.compareTo(name2); } }); @@ -1183,10 +1168,7 @@ public class ContactsController { continue; } - String key = user.first_name; - if (key == null || key.length() == 0) { - key = user.last_name; - } + String key = UserObject.getFirstName(user); if (key.length() > 1) { key = key.substring(0, 1); } @@ -1638,7 +1620,7 @@ public class ContactsController { for (TLRPC.User user : users) { if (user.phone != null && user.phone.length() > 0) { - CharSequence name = ContactsController.formatName(user.first_name, user.last_name); + CharSequence name = UserObject.getUserName(user); MessagesStorage.getInstance().applyPhoneBookUpdates(user.phone, ""); Contact contact = contactsBookSPhones.get(user.phone); if (contact != null) { diff --git a/TMessagesProj/src/main/java/org/telegram/android/Emoji.java b/TMessagesProj/src/main/java/org/telegram/android/Emoji.java index 988a94b9e..71a5e9b72 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/Emoji.java +++ b/TMessagesProj/src/main/java/org/telegram/android/Emoji.java @@ -21,6 +21,7 @@ import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.text.Spannable; +import android.text.Spanned; import android.text.style.DynamicDrawableSpan; import android.text.style.ImageSpan; import android.view.View; @@ -416,6 +417,14 @@ public class Emoji { return false; } + private static boolean isNextCharIsColor(CharSequence cs, int i) { + if (i + 2 >= cs.length()) { + return false; + } + int value = cs.charAt(i + 1) << 16 | cs.charAt(i + 2); + return value == 0xd83cdffb || value == 0xd83cdffc || value == 0xd83cdffd || value == 0xd83cdffe || value == 0xd83cdfff; + } + public static CharSequence replaceEmoji(CharSequence cs, Paint.FontMetricsInt fontMetrics, int size) { if (cs == null || cs.length() == 0) { return cs; @@ -439,12 +448,16 @@ public class Emoji { buf |= c; EmojiDrawable d = Emoji.getEmojiDrawable(buf); if (d != null) { + boolean nextIsSkinTone = isNextCharIsColor(cs, i); EmojiSpan span = new EmojiSpan(d, DynamicDrawableSpan.ALIGN_BOTTOM, size, fontMetrics); emojiCount++; if (c >= 0xDDE6 && c <= 0xDDFA) { - s.setSpan(span, i - 3, i + 1, 0); + s.setSpan(span, i - 3, i + (nextIsSkinTone ? 3 : 1), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } else { - s.setSpan(span, i - 1, i + 1, 0); + s.setSpan(span, i - 1, i + (nextIsSkinTone ? 3 : 1), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } + if (nextIsSkinTone) { + i += 2; } } buf = 0; @@ -457,9 +470,13 @@ public class Emoji { buf |= c; EmojiDrawable d = Emoji.getEmojiDrawable(buf); if (d != null) { + boolean nextIsSkinTone = isNextCharIsColor(cs, i); EmojiSpan span = new EmojiSpan(d, DynamicDrawableSpan.ALIGN_BOTTOM, size, fontMetrics); emojiCount++; - s.setSpan(span, i - 1, i + 1, 0); + s.setSpan(span, i - 1, i + (nextIsSkinTone ? 3 : 1), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + if (nextIsSkinTone) { + i += 2; + } } buf = 0; } @@ -467,9 +484,13 @@ public class Emoji { } else if (inArray(c, emojiChars)) { EmojiDrawable d = Emoji.getEmojiDrawable(c); if (d != null) { + boolean nextIsSkinTone = isNextCharIsColor(cs, i); EmojiSpan span = new EmojiSpan(d, DynamicDrawableSpan.ALIGN_BOTTOM, size, fontMetrics); emojiCount++; - s.setSpan(span, i, i + 1, 0); + s.setSpan(span, i, i + (nextIsSkinTone ? 3 : 1), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + if (nextIsSkinTone) { + i += 2; + } } } if (emojiCount >= 50) { diff --git a/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java b/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java index 9bbefe8e4..3cf8e8277 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java @@ -46,6 +46,7 @@ import java.lang.reflect.Method; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; +import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.ArrayList; @@ -140,62 +141,67 @@ public class ImageLoader { fileOutputStream = new RandomAccessFile(tempFile, "rws"); } catch (Throwable e) { - FileLog.e("tmessages", e); - } - - try { - if (httpConnection != null && httpConnection instanceof HttpURLConnection) { - int code = ((HttpURLConnection) httpConnection).getResponseCode(); - if (code != HttpURLConnection.HTTP_OK && code != HttpURLConnection.HTTP_ACCEPTED && code != HttpURLConnection.HTTP_NOT_MODIFIED) { - canRetry = false; - } + if (e instanceof UnknownHostException) { + canRetry = false; } - } catch (Exception e) { FileLog.e("tmessages", e); } - if (httpConnectionStream != null) { + if (canRetry) { try { - byte[] data = new byte[1024 * 4]; - while (true) { - if (isCancelled()) { - break; + if (httpConnection != null && httpConnection instanceof HttpURLConnection) { + int code = ((HttpURLConnection) httpConnection).getResponseCode(); + if (code != HttpURLConnection.HTTP_OK && code != HttpURLConnection.HTTP_ACCEPTED && code != HttpURLConnection.HTTP_NOT_MODIFIED) { + canRetry = false; } - try { - int read = httpConnectionStream.read(data); - if (read > 0) { - fileOutputStream.write(data, 0, read); - } else if (read == -1) { - done = true; - break; - } else { + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + + if (httpConnectionStream != null) { + try { + byte[] data = new byte[1024 * 4]; + while (true) { + if (isCancelled()) { + break; + } + try { + int read = httpConnectionStream.read(data); + if (read > 0) { + fileOutputStream.write(data, 0, read); + } else if (read == -1) { + done = true; + break; + } else { + break; + } + } catch (Exception e) { + FileLog.e("tmessages", e); break; } - } catch (Exception e) { - FileLog.e("tmessages", e); - break; } + } catch (Throwable e) { + FileLog.e("tmessages", e); + } + } + + try { + if (fileOutputStream != null) { + fileOutputStream.close(); + fileOutputStream = null; } } catch (Throwable e) { FileLog.e("tmessages", e); } - } - try { - if (fileOutputStream != null) { - fileOutputStream.close(); - fileOutputStream = null; + try { + if (httpConnectionStream != null) { + httpConnectionStream.close(); + } + } catch (Throwable e) { + FileLog.e("tmessages", e); } - } catch (Throwable e) { - FileLog.e("tmessages", e); - } - - try { - if (httpConnectionStream != null) { - httpConnectionStream.close(); - } - } catch (Throwable e) { - FileLog.e("tmessages", e); } return done; @@ -537,7 +543,7 @@ public class ImageLoader { boolean canDeleteFile = true; boolean useNativeWebpLoaded = false; - if (Build.VERSION.SDK_INT < 18) { + if (Build.VERSION.SDK_INT < 19) { RandomAccessFile randomAccessFile = null; try { randomAccessFile = new RandomAccessFile(cacheFileFinal, "r"); @@ -1892,13 +1898,6 @@ public class ImageLoader { BitmapFactory.decodeFileDescriptor(fileDescriptor, null, bmOptions); } catch (Throwable e) { FileLog.e("tmessages", e); - try { - if (parcelFD != null) { - parcelFD.close(); - } - } catch (Throwable e2) { - FileLog.e("tmessages", e2); - } return null; } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/LocaleController.java b/TMessagesProj/src/main/java/org/telegram/android/LocaleController.java index cf89fe20f..e2311bf80 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/LocaleController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/LocaleController.java @@ -807,7 +807,7 @@ public class LocaleController { return getString("Online", R.string.Online); } } - if (user == null || user.status == null || user.status.expires == 0 || user instanceof TLRPC.TL_userDeleted || user instanceof TLRPC.TL_userEmpty) { + if (user == null || user.status == null || user.status.expires == 0 || UserObject.isDeleted(user) || user instanceof TLRPC.TL_userEmpty) { return getString("ALongTimeAgo", R.string.ALongTimeAgo); } else { int currentTime = ConnectionsManager.getInstance().getCurrentTime(); diff --git a/TMessagesProj/src/main/java/org/telegram/android/MediaController.java b/TMessagesProj/src/main/java/org/telegram/android/MediaController.java index a0ff51259..273f3ba88 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MediaController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MediaController.java @@ -41,6 +41,7 @@ import android.net.Uri; import android.os.Build; import android.os.Environment; import android.os.ParcelFileDescriptor; +import android.os.PowerManager; import android.os.Vibrator; import android.provider.MediaStore; import android.view.View; @@ -198,6 +199,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel private SensorManager sensorManager; private Sensor proximitySensor; private boolean ignoreProximity; + private PowerManager.WakeLock proximityWakeLock; private ArrayList videoConvertQueue = new ArrayList<>(); private final Object videoQueueSync = new Object(); @@ -220,6 +222,8 @@ public class MediaController implements NotificationCenter.NotificationCenterDel private boolean saveToGallery = true; + public static AlbumEntry allPhotosAlbumEntry; + private HashMap>> loadingFileObservers = new HashMap<>(); private HashMap observersByTag = new HashMap<>(); private boolean listenerInProgress = false; @@ -355,6 +359,40 @@ public class MediaController implements NotificationCenter.NotificationCenterDel } } + /*private class GalleryObserverInternal extends ContentObserver { + public GalleryObserverInternal() { + super(null); + } + + @Override + public void onChange(boolean selfChange) { + super.onChange(selfChange); + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + loadGalleryPhotosAlbums(0); + } + }, 2000); + } + } + + private class GalleryObserverExternal extends ContentObserver { + public GalleryObserverExternal() { + super(null); + } + + @Override + public void onChange(boolean selfChange) { + super.onChange(selfChange); + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + loadGalleryPhotosAlbums(0); + } + }, 2000); + } + }*/ + private ExternalObserver externalObserver = null; private InternalObserver internalObserver = null; private long lastSecretChatEnterTime = 0; @@ -428,6 +466,8 @@ public class MediaController implements NotificationCenter.NotificationCenterDel try { sensorManager = (SensorManager) ApplicationLoader.applicationContext.getSystemService(Context.SENSOR_SERVICE); proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); + PowerManager powerManager = (PowerManager) ApplicationLoader.applicationContext.getSystemService(Context.POWER_SERVICE); + proximityWakeLock = powerManager.newWakeLock(0x00000020, "proximity"); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -484,6 +524,17 @@ public class MediaController implements NotificationCenter.NotificationCenterDel MediaStore.Images.ImageColumns.TITLE }; } + + /*try { + ApplicationLoader.applicationContext.getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, false, new GalleryObserverExternal()); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + try { + ApplicationLoader.applicationContext.getContentResolver().registerContentObserver(MediaStore.Images.Media.INTERNAL_CONTENT_URI, false, new GalleryObserverInternal()); + } catch (Exception e) { + FileLog.e("tmessages", e); + }*/ } private void startProgressTimer() { @@ -1191,7 +1242,10 @@ public class MediaController implements NotificationCenter.NotificationCenterDel if (sensorManager != null && proximitySensor != null) { sensorManager.unregisterListener(this); } - } catch (Exception e) { + if (proximityWakeLock != null && proximityWakeLock.isHeld()) { + proximityWakeLock.release(); + } + } catch (Throwable e) { FileLog.e("tmessages", e); } } @@ -1204,6 +1258,9 @@ public class MediaController implements NotificationCenter.NotificationCenterDel if (sensorManager != null && proximitySensor != null) { sensorManager.registerListener(this, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL); } + if (!NotificationsController.getInstance().audioManager.isWiredHeadsetOn() && proximityWakeLock != null && !proximityWakeLock.isHeld()) { + proximityWakeLock.acquire(); + } } catch (Exception e) { FileLog.e("tmessages", e); } @@ -1319,7 +1376,14 @@ public class MediaController implements NotificationCenter.NotificationCenterDel } NotificationCenter.getInstance().postNotificationName(NotificationCenter.audioDidStarted, messageObject); clenupPlayer(true); - final File cacheFile = FileLoader.getPathToMessage(messageObject.messageOwner); + File file = null; + if (messageObject.messageOwner.attachPath != null && messageObject.messageOwner.attachPath.length() > 0) { + file = new File(messageObject.messageOwner.attachPath); + if (!file.exists()) { + file = null; + } + } + final File cacheFile = file != null ? file : FileLoader.getPathToMessage(messageObject.messageOwner); if (isOpusFile(cacheFile.getAbsolutePath()) == 1) { synchronized (playerObjectSync) { @@ -2094,7 +2158,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel try { albums.clear(); - allPhotosAlbum = null; + AlbumEntry allVideosAlbum = null; cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projectionVideo, "", null, MediaStore.Video.Media.DATE_TAKEN + " DESC"); if (cursor != null) { int imageIdColumn = cursor.getColumnIndex(MediaStore.Video.Media._ID); @@ -2116,12 +2180,12 @@ public class MediaController implements NotificationCenter.NotificationCenterDel PhotoEntry photoEntry = new PhotoEntry(bucketId, imageId, dateTaken, path, 0, true); - if (allPhotosAlbum == null) { - allPhotosAlbum = new AlbumEntry(0, LocaleController.getString("AllVideo", R.string.AllVideo), photoEntry, true); - videoAlbumsSorted.add(0, allPhotosAlbum); + if (allVideosAlbum == null) { + allVideosAlbum = new AlbumEntry(0, LocaleController.getString("AllVideo", R.string.AllVideo), photoEntry, true); + videoAlbumsSorted.add(0, allVideosAlbum); } - if (allPhotosAlbum != null) { - allPhotosAlbum.addPhoto(photoEntry); + if (allVideosAlbum != null) { + allVideosAlbum.addPhoto(photoEntry); } AlbumEntry albumEntry = albums.get(bucketId); @@ -2153,9 +2217,11 @@ public class MediaController implements NotificationCenter.NotificationCenterDel final Integer cameraAlbumIdFinal = cameraAlbumId; final Integer cameraAlbumVideoIdFinal = cameraAlbumVideoId; + final AlbumEntry allPhotosAlbumFinal = allPhotosAlbum; AndroidUtilities.runOnUIThread(new Runnable() { @Override public void run() { + allPhotosAlbumEntry = allPhotosAlbumFinal; NotificationCenter.getInstance().postNotificationName(NotificationCenter.albumsDidLoaded, guid, albumsSorted, cameraAlbumIdFinal, videoAlbumsSorted, cameraAlbumVideoIdFinal); } }); diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java b/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java index ed916003e..48aaa2651 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java @@ -61,6 +61,8 @@ public class MessageObject { public int textHeight; public int blockHeight = Integer.MAX_VALUE; + public static Pattern urlPattern; + public static class TextLayoutBlock { public StaticLayout textLayout; public float textXOffset = 0; @@ -212,7 +214,7 @@ public class MessageObject { messageText = LocaleController.formatString("MessageLifetimeChangedOutgoing", R.string.MessageLifetimeChangedOutgoing, AndroidUtilities.formatTTLString(message.action.ttl)); } else { if (fromUser != null) { - messageText = LocaleController.formatString("MessageLifetimeChanged", R.string.MessageLifetimeChanged, fromUser.first_name, AndroidUtilities.formatTTLString(message.action.ttl)); + messageText = LocaleController.formatString("MessageLifetimeChanged", R.string.MessageLifetimeChanged, UserObject.getFirstName(fromUser), AndroidUtilities.formatTTLString(message.action.ttl)); } else { messageText = LocaleController.formatString("MessageLifetimeChanged", R.string.MessageLifetimeChanged, "", AndroidUtilities.formatTTLString(message.action.ttl)); } @@ -222,7 +224,7 @@ public class MessageObject { messageText = LocaleController.getString("MessageLifetimeYouRemoved", R.string.MessageLifetimeYouRemoved); } else { if (fromUser != null) { - messageText = LocaleController.formatString("MessageLifetimeRemoved", R.string.MessageLifetimeRemoved, fromUser.first_name); + messageText = LocaleController.formatString("MessageLifetimeRemoved", R.string.MessageLifetimeRemoved, UserObject.getFirstName(fromUser)); } else { messageText = LocaleController.formatString("MessageLifetimeRemoved", R.string.MessageLifetimeRemoved, ""); } @@ -239,20 +241,17 @@ public class MessageObject { to_user = MessagesController.getInstance().getUser(messageOwner.to_id.user_id); } } - String name = ""; - if (to_user != null) { - name = to_user.first_name; - } + String name = to_user != null ? UserObject.getFirstName(to_user) : ""; messageText = LocaleController.formatString("NotificationUnrecognizedDevice", R.string.NotificationUnrecognizedDevice, name, date, message.action.title, message.action.address); } else if (message.action instanceof TLRPC.TL_messageActionUserJoined) { if (fromUser != null) { - messageText = LocaleController.formatString("NotificationContactJoined", R.string.NotificationContactJoined, ContactsController.formatName(fromUser.first_name, fromUser.last_name)); + messageText = LocaleController.formatString("NotificationContactJoined", R.string.NotificationContactJoined, UserObject.getUserName(fromUser)); } else { messageText = LocaleController.formatString("NotificationContactJoined", R.string.NotificationContactJoined, ""); } } else if (message.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) { if (fromUser != null) { - messageText = LocaleController.formatString("NotificationContactNewPhoto", R.string.NotificationContactNewPhoto, ContactsController.formatName(fromUser.first_name, fromUser.last_name)); + messageText = LocaleController.formatString("NotificationContactNewPhoto", R.string.NotificationContactNewPhoto, UserObject.getUserName(fromUser)); } else { messageText = LocaleController.formatString("NotificationContactNewPhoto", R.string.NotificationContactNewPhoto, ""); } @@ -274,7 +273,7 @@ public class MessageObject { messageText = LocaleController.formatString("MessageLifetimeChangedOutgoing", R.string.MessageLifetimeChangedOutgoing, AndroidUtilities.formatTTLString(action.ttl_seconds)); } else { if (fromUser != null) { - messageText = LocaleController.formatString("MessageLifetimeChanged", R.string.MessageLifetimeChanged, fromUser.first_name, AndroidUtilities.formatTTLString(action.ttl_seconds)); + messageText = LocaleController.formatString("MessageLifetimeChanged", R.string.MessageLifetimeChanged, UserObject.getFirstName(fromUser), AndroidUtilities.formatTTLString(action.ttl_seconds)); } else { messageText = LocaleController.formatString("MessageLifetimeChanged", R.string.MessageLifetimeChanged, "", AndroidUtilities.formatTTLString(action.ttl_seconds)); } @@ -284,7 +283,7 @@ public class MessageObject { messageText = LocaleController.getString("MessageLifetimeYouRemoved", R.string.MessageLifetimeYouRemoved); } else { if (fromUser != null) { - messageText = LocaleController.formatString("MessageLifetimeRemoved", R.string.MessageLifetimeRemoved, fromUser.first_name); + messageText = LocaleController.formatString("MessageLifetimeRemoved", R.string.MessageLifetimeRemoved, UserObject.getFirstName(fromUser)); } else { messageText = LocaleController.formatString("MessageLifetimeRemoved", R.string.MessageLifetimeRemoved, ""); } @@ -484,7 +483,7 @@ public class MessageObject { } public CharSequence replaceWithLink(CharSequence source, String param, TLRPC.User user) { - String name = ContactsController.formatName(user.first_name, user.last_name); + String name = UserObject.getUserName(user); int start = TextUtils.indexOf(source, param); URLSpanNoUnderlineBold span = new URLSpanNoUnderlineBold("" + user.id); SpannableStringBuilder builder = new SpannableStringBuilder(TextUtils.replace(source, new String[]{param}, new String[]{name})); @@ -524,8 +523,8 @@ public class MessageObject { return FileLoader.MEDIA_DIR_CACHE; } - private boolean containsUrls(CharSequence message) { - if (message == null || message.length() < 3 || message.length() > 1024 * 20) { + private static boolean containsUrls(CharSequence message) { + if (message == null || message.length() < 2 || message.length() > 1024 * 20) { return false; } @@ -550,7 +549,7 @@ public class MessageObject { } else if (!(c != ' ' && digitsInRow > 0)) { digitsInRow = 0; } - if ((c == '@' || c == '#') && i == 0 || i != 0 && (message.charAt(i - 1) == ' ' || message.charAt(i - 1) == '\n')) { + if ((c == '@' || c == '#' || c == '/') && i == 0 || i != 0 && (message.charAt(i - 1) == ' ' || message.charAt(i - 1) == '\n')) { return true; } if (c == ':') { @@ -613,14 +612,16 @@ public class MessageObject { } } - private void addUsernamesAndHashtags(CharSequence charSequence) { + private static void addUsernamesAndHashtags(CharSequence charSequence) { try { - Pattern pattern = Pattern.compile("(^|\\s)@[a-zA-Z\\d_]{5,32}|(^|\\s)#[\\w\\.]+"); - Matcher matcher = pattern.matcher(charSequence); + if (urlPattern == null) { + urlPattern = Pattern.compile("(^|\\s)/[a-zA-Z@\\d_]{1,255}|(^|\\s)@[a-zA-Z\\d_]{5,32}|(^|\\s)#[\\w\\.]+"); + } + Matcher matcher = urlPattern.matcher(charSequence); while (matcher.find()) { int start = matcher.start(); int end = matcher.end(); - if (charSequence.charAt(start) != '@' && charSequence.charAt(start) != '#') { + if (charSequence.charAt(start) != '@' && charSequence.charAt(start) != '#' && charSequence.charAt(start) != '/') { start++; } URLSpanNoUnderline url = new URLSpanNoUnderline(charSequence.subSequence(start, end).toString()); @@ -631,14 +632,7 @@ public class MessageObject { } } - private void generateLayout() { - if (type != 0 || messageOwner.to_id == null || messageText == null || messageText.length() == 0) { - return; - } - - generateLinkDescription(); - textLayoutBlocks = new ArrayList<>(); - + public static void addLinks(CharSequence messageText) { if (messageText instanceof Spannable && containsUrls(messageText)) { if (messageText.length() < 100) { try { @@ -655,6 +649,17 @@ public class MessageObject { } addUsernamesAndHashtags(messageText); } + } + + private void generateLayout() { + if (type != 0 || messageOwner.to_id == null || messageText == null || messageText.length() == 0) { + return; + } + + generateLinkDescription(); + textLayoutBlocks = new ArrayList<>(); + + addLinks(messageText); int maxWidth; if (AndroidUtilities.isTablet()) { @@ -903,7 +908,7 @@ public class MessageObject { } public boolean isSendError() { - return messageOwner.send_state == MESSAGE_SEND_STATE_SEND_ERROR; + return messageOwner.send_state == MESSAGE_SEND_STATE_SEND_ERROR && messageOwner.id < 0; } public boolean isSent() { diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java index 01b18bb9a..156d4b38c 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java @@ -18,7 +18,10 @@ import android.os.Build; import android.os.Bundle; import android.util.Base64; import android.util.SparseArray; +import android.widget.Toast; +import org.telegram.android.query.BotQuery; +import org.telegram.android.query.StickersQuery; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; @@ -52,6 +55,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter public ArrayList dialogs = new ArrayList<>(); public ArrayList dialogsServerOnly = new ArrayList<>(); + public ArrayList dialogsGroupsOnly = new ArrayList<>(); public ConcurrentHashMap dialogs_dict = new ConcurrentHashMap<>(100, 1.0f, 2); public HashMap dialogMessage = new HashMap<>(); public ConcurrentHashMap> printingUsers = new ConcurrentHashMap<>(20, 1.0f, 2); @@ -238,7 +242,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } public void addSupportUser() { - TLRPC.TL_userForeign user = new TLRPC.TL_userForeign(); + TLRPC.TL_userForeign_old2 user = new TLRPC.TL_userForeign_old2(); user.phone = "333"; user.id = 333000; user.first_name = "Telegram"; @@ -247,7 +251,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter user.photo = new TLRPC.TL_userProfilePhotoEmpty(); putUser(user, true); - user = new TLRPC.TL_userForeign(); + user = new TLRPC.TL_userForeign_old2(); user.phone = "42777"; user.id = 777000; user.first_name = "Telegram"; @@ -264,7 +268,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter TLRPC.InputUser inputUser; if (user.id == UserConfig.getClientUserId()) { inputUser = new TLRPC.TL_inputUserSelf(); - } else if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { + } else if (user.access_hash != 0) { inputUser = new TLRPC.TL_inputUserForeign(); inputUser.user_id = user.id; inputUser.access_hash = user.access_hash; @@ -372,11 +376,13 @@ public class MessagesController implements NotificationCenter.NotificationCenter NotificationsController.getInstance().cleanup(); SendMessagesHelper.getInstance().cleanUp(); SecretChatHelper.getInstance().cleanUp(); + StickersQuery.cleanup(); dialogs_dict.clear(); exportedChats.clear(); dialogs.clear(); dialogsServerOnly.clear(); + dialogsGroupsOnly.clear(); users.clear(); usersByUsernames.clear(); chats.clear(); @@ -595,6 +601,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter AndroidUtilities.runOnUIThread(new Runnable() { @Override public void run() { + for (int a = 0; a < res.full_chat.bot_info.size(); a++) { + TLRPC.BotInfo botInfo = res.full_chat.bot_info.get(a); + BotQuery.putBotInfo(botInfo); + } exportedChats.put(chat_id, res.full_chat.exported_invite); loadingFullChats.remove((Integer) chat_id); loadedFullChats.add(chat_id); @@ -633,10 +643,13 @@ public class MessagesController implements NotificationCenter.NotificationCenter AndroidUtilities.runOnUIThread(new Runnable() { @Override public void run() { + TLRPC.TL_userFull userFull = (TLRPC.TL_userFull) response; + if (userFull.bot_info instanceof TLRPC.TL_botInfo) { + BotQuery.putBotInfo(userFull.bot_info); + } loadingFullUsers.remove((Integer) user.id); loadedFullUsers.add(user.id); String names = user.first_name + user.last_name + user.username; - TLRPC.TL_userFull userFull = (TLRPC.TL_userFull) response; ArrayList users = new ArrayList<>(); users.add(userFull.user); putUsers(users, false); @@ -644,6 +657,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (!names.equals(userFull.user.first_name + userFull.user.last_name + userFull.user.username)) { NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_NAME); } + if (userFull.bot_info instanceof TLRPC.TL_botInfo) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.botInfoDidLoaded, userFull.bot_info, classGuid); + } } }); } else { @@ -1083,6 +1099,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (!onlyHistory) { dialogs.remove(dialog); dialogsServerOnly.remove(dialog); + dialogsGroupsOnly.remove(dialog); dialogs_dict.remove(did); totalDialogsCount--; } else { @@ -1118,12 +1135,15 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (lower_part != 0) { TLRPC.TL_messages_deleteHistory req = new TLRPC.TL_messages_deleteHistory(); req.offset = offset; - if (did < 0) { + if (lower_part < 0) { req.peer = new TLRPC.TL_inputPeerChat(); req.peer.chat_id = -lower_part; } else { TLRPC.User user = getUser(lower_part); - if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { + if (user == null) { + return; + } + if (user.access_hash != 0) { req.peer = new TLRPC.TL_inputPeerForeign(); req.peer.access_hash = user.access_hash; } else { @@ -1424,18 +1444,17 @@ public class MessagesController implements NotificationCenter.NotificationCenter req.peer.chat_id = -lower_part; } else { TLRPC.User user = getUser(lower_part); - if (user != null) { - if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { - req.peer = new TLRPC.TL_inputPeerForeign(); - req.peer.user_id = user.id; - req.peer.access_hash = user.access_hash; - } else { - req.peer = new TLRPC.TL_inputPeerContact(); - req.peer.user_id = user.id; - } - } else { + if (user == null) { return; } + if (user.access_hash != 0) { + req.peer = new TLRPC.TL_inputPeerForeign(); + req.peer.user_id = user.id; + req.peer.access_hash = user.access_hash; + } else { + req.peer = new TLRPC.TL_inputPeerContact(); + req.peer.user_id = user.id; + } } if (action == 0) { req.action = new TLRPC.TL_sendMessageTypingAction(); @@ -1515,7 +1534,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (user == null) { return; } - if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { + if (user.access_hash != 0) { req.peer = new TLRPC.TL_inputPeerForeign(); req.peer.user_id = user.id; req.peer.access_hash = user.access_hash; @@ -1556,9 +1575,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (!isCache) { ImageLoader.saveMessagesThumbs(messagesRes.messages); } - if (!isCache && allowCache) { - MessagesStorage.getInstance().putMessages(messagesRes, dialog_id); - } if (high_id != 1 && lower_id != 0 && isCache && messagesRes.messages.size() == 0 && (load_type == 0 || load_type == 2 || load_type == 3)) { AndroidUtilities.runOnUIThread(new Runnable() { @Override @@ -1568,15 +1584,27 @@ public class MessagesController implements NotificationCenter.NotificationCenter }); return; } - final HashMap usersLocal = new HashMap<>(); + final HashMap usersDict = new HashMap<>(); for (TLRPC.User u : messagesRes.users) { - usersLocal.put(u.id, u); + usersDict.put(u.id, u); + } + if (!isCache && allowCache) { + for (int a = 0; a < messagesRes.messages.size(); a++) { + TLRPC.Message message = messagesRes.messages.get(a); + if (message.action instanceof TLRPC.TL_messageActionChatDeleteUser) { + TLRPC.User user = usersDict.get(message.action.user_id); + if (user != null && (user.flags & TLRPC.USER_FLAG_BOT) != 0) { + message.reply_markup = new TLRPC.TL_replyKeyboardHide(); + } + } + } + MessagesStorage.getInstance().putMessages(messagesRes, dialog_id); } final ArrayList objects = new ArrayList<>(); ArrayList messagesToReload = null; for (TLRPC.Message message : messagesRes.messages) { message.dialog_id = dialog_id; - objects.add(new MessageObject(message, usersLocal, true)); + objects.add(new MessageObject(message, usersDict, true)); if (isCache) { if (message.media instanceof TLRPC.TL_messageMediaUnsupported) { if (message.media.bytes.length == 0 || message.media.bytes.length == 1 && message.media.bytes[0] < TLRPC.LAYER) { @@ -1750,6 +1778,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter dialogs.clear(); dialogsServerOnly.clear(); + dialogsGroupsOnly.clear(); dialogs.addAll(dialogs_dict.values()); Collections.sort(dialogs, new Comparator() { @Override @@ -1767,6 +1796,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter int high_id = (int) (d.id >> 32); if ((int) d.id != 0 && high_id != 1) { dialogsServerOnly.add(d); + if (d.id < 0) { + dialogsGroupsOnly.add(d); + } } } NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); @@ -1798,11 +1830,26 @@ public class MessagesController implements NotificationCenter.NotificationCenter } final HashMap new_dialogs_dict = new HashMap<>(); final HashMap new_dialogMessage = new HashMap<>(); - final HashMap usersLocal = new HashMap<>(); + final HashMap usersDict = new HashMap<>(); int new_totalDialogsCount; + for (TLRPC.User u : dialogsRes.users) { + usersDict.put(u.id, u); + } + if (!isCache) { ImageLoader.saveMessagesThumbs(dialogsRes.messages); + + for (int a = 0; a < dialogsRes.messages.size(); a++) { + TLRPC.Message message = dialogsRes.messages.get(a); + if (message.action instanceof TLRPC.TL_messageActionChatDeleteUser) { + TLRPC.User user = usersDict.get(message.action.user_id); + if (user != null && (user.flags & TLRPC.USER_FLAG_BOT) != 0) { + message.reply_markup = new TLRPC.TL_replyKeyboardHide(); + } + } + } + MessagesStorage.getInstance().putDialogs(dialogsRes); } @@ -1813,12 +1860,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter new_totalDialogsCount = dialogsRes.dialogs.size(); } - for (TLRPC.User u : dialogsRes.users) { - usersLocal.put(u.id, u); - } - for (TLRPC.Message m : dialogsRes.messages) { - new_dialogMessage.put(m.id, new MessageObject(m, usersLocal, false)); + new_dialogMessage.put(m.id, new MessageObject(m, usersDict, false)); } for (TLRPC.TL_dialog d : dialogsRes.dialogs) { if (d.last_message_date == 0) { @@ -1887,6 +1930,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter dialogs.clear(); dialogsServerOnly.clear(); + dialogsGroupsOnly.clear(); dialogs.addAll(dialogs_dict.values()); Collections.sort(dialogs, new Comparator() { @Override @@ -1904,6 +1948,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter int high_id = (int) (d.id >> 32); if ((int) d.id != 0 && high_id != 1) { dialogsServerOnly.add(d); + if (d.id < 0) { + dialogsGroupsOnly.add(d); + } } } @@ -1969,7 +2016,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (user == null) { return; } - if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { + if (user.access_hash != 0) { req.peer = new TLRPC.TL_inputPeerForeign(); req.peer.user_id = user.id; req.peer.access_hash = user.access_hash; @@ -2165,18 +2212,47 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } - public void addUserToChat(int chat_id, final TLRPC.User user, final TLRPC.ChatParticipants info, int count_fwd) { + public void sendBotStart(final TLRPC.User user, String botHash) { + TLRPC.TL_messages_startBot req = new TLRPC.TL_messages_startBot(); + req.bot = getInputUser(user); + req.chat_id = 0; + req.start_param = botHash; + req.random_id = Utilities.random.nextLong(); + ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, TLRPC.TL_error error) { + if (error != null) { + return; + } + processUpdates((TLRPC.Updates) response, false); + } + }); + } + + public void addUserToChat(int chat_id, final TLRPC.User user, final TLRPC.ChatParticipants info, int count_fwd, String botHash) { if (user == null) { return; } if (chat_id > 0) { - TLRPC.TL_messages_addChatUser req = new TLRPC.TL_messages_addChatUser(); - req.chat_id = chat_id; - req.fwd_limit = count_fwd; - req.user_id = getInputUser(user); + TLObject request; - ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + if (botHash == null) { + TLRPC.TL_messages_addChatUser req = new TLRPC.TL_messages_addChatUser(); + req.chat_id = chat_id; + req.fwd_limit = count_fwd; + req.user_id = getInputUser(user); + request = req; + } else { + TLRPC.TL_messages_startBot req = new TLRPC.TL_messages_startBot(); + req.bot = getInputUser(user); + req.chat_id = chat_id; + req.start_param = botHash; + req.random_id = Utilities.random.nextLong(); + request = req; + } + + ConnectionsManager.getInstance().performRpc(request, new RPCRequest.RPCRequestDelegate() { @Override public void run(TLObject response, TLRPC.TL_error error) { if (error != null) { @@ -2711,7 +2787,16 @@ public class MessagesController implements NotificationCenter.NotificationCenter ImageLoader.saveMessagesThumbs(res.new_messages); final ArrayList pushMessages = new ArrayList<>(); - for (TLRPC.Message message : res.new_messages) { + for (int a = 0; a < res.new_messages.size(); a++) { + TLRPC.Message message = res.new_messages.get(a); + + if (message.action instanceof TLRPC.TL_messageActionChatDeleteUser) { + TLRPC.User user = usersDict.get(message.action.user_id); + if (user != null && (user.flags & TLRPC.USER_FLAG_BOT) != 0) { + message.reply_markup = new TLRPC.TL_replyKeyboardHide(); + } + } + MessageObject obj = new MessageObject(message, usersDict, true); if (!obj.isOut() && obj.isUnread()) { @@ -3311,6 +3396,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (u.userId == update.user_id) { exist = true; u.lastTime = currentTime; + if (u.action.getClass() != update.action.getClass()) { + printChanged = true; + } u.action = update.action; break; } @@ -3565,6 +3653,15 @@ public class MessagesController implements NotificationCenter.NotificationCenter }); if (!messagesArr.isEmpty()) { + for (int a = 0; a < messagesArr.size(); a++) { + TLRPC.Message message = messagesArr.get(a); + if (message.action instanceof TLRPC.TL_messageActionChatDeleteUser) { + TLRPC.User user = usersDict.get(message.action.user_id); + if (user != null && (user.flags & TLRPC.USER_FLAG_BOT) != 0) { + message.reply_markup = new TLRPC.TL_replyKeyboardHide(); + } + } + } MessagesStorage.getInstance().putMessages(messagesArr, true, true, false, MediaController.getInstance().getAutodownloadMask()); } @@ -3604,7 +3701,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } else if (update instanceof TLRPC.TL_updateUserName) { if (currentUser != null) { - if (!(currentUser instanceof TLRPC.TL_userContact)) { + if (!UserObject.isContact(currentUser)) { currentUser.first_name = update.first_name; currentUser.last_name = update.last_name; } @@ -3812,8 +3909,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter } if (!deletedMessages.isEmpty()) { MessagesStorage.getInstance().markMessagesAsDeleted(deletedMessages, true); - } - if (!deletedMessages.isEmpty()) { MessagesStorage.getInstance().updateDialogsWithDeletedMessages(deletedMessages, true); } if (!tasks.isEmpty()) { @@ -3948,6 +4043,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (changed) { dialogsServerOnly.clear(); + dialogsGroupsOnly.clear(); Collections.sort(dialogs, new Comparator() { @Override public int compare(TLRPC.TL_dialog tl_dialog, TLRPC.TL_dialog tl_dialog2) { @@ -3964,6 +4060,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter int high_id = (int) (d.id >> 32); if ((int) d.id != 0 && high_id != 1) { dialogsServerOnly.add(d); + if (d.id < 0) { + dialogsGroupsOnly.add(d); + } } } } @@ -4022,6 +4121,14 @@ public class MessagesController implements NotificationCenter.NotificationCenter fragment.presentFragment(new ChatActivity(args)); } } + } else { + if (fragment != null && fragment.getParentActivity() != null) { + try { + Toast.makeText(fragment.getParentActivity(), LocaleController.getString("NoUsernameFound", R.string.NoUsernameFound), Toast.LENGTH_SHORT).show(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } } } }); diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java b/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java index 7cde65697..b5030041b 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java @@ -17,6 +17,7 @@ import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.SQLite.SQLiteCursor; import org.telegram.SQLite.SQLiteDatabase; import org.telegram.SQLite.SQLitePreparedStatement; +import org.telegram.android.query.BotQuery; import org.telegram.android.query.SharedMediaQuery; import org.telegram.messenger.BuffersStorage; import org.telegram.messenger.ByteBufferDesc; @@ -121,7 +122,7 @@ public class MessagesStorage { database.executeFast("CREATE TABLE dialog_settings(did INTEGER PRIMARY KEY, flags INTEGER);").stepThis().dispose(); database.executeFast("CREATE TABLE messages_seq(mid INTEGER PRIMARY KEY, seq_in INTEGER, seq_out INTEGER);").stepThis().dispose(); database.executeFast("CREATE TABLE web_recent_v3(id TEXT, type INTEGER, image_url TEXT, thumb_url TEXT, local_url TEXT, width INTEGER, height INTEGER, size INTEGER, date INTEGER, PRIMARY KEY (id, type));").stepThis().dispose(); - database.executeFast("CREATE TABLE stickers(id INTEGER PRIMARY KEY, data BLOB, date INTEGER);").stepThis().dispose(); + database.executeFast("CREATE TABLE stickers_v2(id INTEGER PRIMARY KEY, data BLOB, date INTEGER, hash TEXT);").stepThis().dispose(); database.executeFast("CREATE TABLE hashtag_recent_v2(id TEXT PRIMARY KEY, date INTEGER);").stepThis().dispose(); database.executeFast("CREATE TABLE webpage_pending(id INTEGER, mid INTEGER, PRIMARY KEY (id, mid));").stepThis().dispose(); @@ -163,8 +164,13 @@ public class MessagesStorage { //kev-value database.executeFast("CREATE TABLE keyvalue(id TEXT PRIMARY KEY, value TEXT)").stepThis().dispose(); + //bots + database.executeFast("CREATE TABLE bot_info(uid INTEGER PRIMARY KEY, info BLOB)").stepThis().dispose(); + database.executeFast("CREATE TABLE bot_keyboard(uid INTEGER PRIMARY KEY, mid INTEGER, info BLOB)").stepThis().dispose(); + database.executeFast("CREATE INDEX IF NOT EXISTS bot_keyboard_idx_mid ON bot_keyboard(mid);").stepThis().dispose(); + //version - database.executeFast("PRAGMA user_version = 17").stepThis().dispose(); + database.executeFast("PRAGMA user_version = 20").stepThis().dispose(); } else { try { SQLiteCursor cursor = database.queryFinalized("SELECT seq, pts, date, qts, lsv, sg, pbytes FROM params WHERE id = 1"); @@ -195,7 +201,7 @@ public class MessagesStorage { } } int version = database.executeInt("PRAGMA user_version"); - if (version < 17) { + if (version < 20) { updateDbToLastVersion(version); } } @@ -349,8 +355,6 @@ public class MessagesStorage { version = 11; } if (version == 11) { - database.executeFast("CREATE TABLE IF NOT EXISTS stickers(id INTEGER PRIMARY KEY, data BLOB, date INTEGER);").stepThis().dispose(); - database.executeFast("PRAGMA user_version = 12").stepThis().dispose(); version = 12; } if (version == 12) { @@ -389,7 +393,24 @@ public class MessagesStorage { database.executeFast("ALTER TABLE dialogs ADD COLUMN inbox_max INTEGER default 0").stepThis().dispose(); database.executeFast("ALTER TABLE dialogs ADD COLUMN outbox_max INTEGER default 0").stepThis().dispose(); database.executeFast("PRAGMA user_version = 17").stepThis().dispose(); - //version = 17; + version = 17; + } + if (version == 17) { + database.executeFast("CREATE TABLE bot_info(uid INTEGER PRIMARY KEY, info BLOB)").stepThis().dispose(); + database.executeFast("PRAGMA user_version = 18").stepThis().dispose(); + version = 18; + } + if (version == 18) { + database.executeFast("DROP TABLE IF EXISTS stickers;").stepThis().dispose(); + database.executeFast("CREATE TABLE IF NOT EXISTS stickers_v2(id INTEGER PRIMARY KEY, data BLOB, date INTEGER, hash TEXT);").stepThis().dispose(); + database.executeFast("PRAGMA user_version = 19").stepThis().dispose(); + version = 19; + } + if (version == 19) { + database.executeFast("CREATE TABLE IF NOT EXISTS bot_keyboard(uid INTEGER PRIMARY KEY, mid INTEGER, info BLOB)").stepThis().dispose(); + database.executeFast("CREATE INDEX IF NOT EXISTS bot_keyboard_idx_mid ON bot_keyboard(mid);").stepThis().dispose(); + database.executeFast("PRAGMA user_version = 20").stepThis().dispose(); + //version = 20; } } catch (Exception e) { FileLog.e("tmessages", e); @@ -934,8 +955,10 @@ public class MessagesStorage { 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 bot_keyboard WHERE uid = " + did).stepThis().dispose(); database.executeFast("DELETE FROM media_counts_v2 WHERE uid = " + did).stepThis().dispose(); database.executeFast("DELETE FROM media_v2 WHERE uid = " + did).stepThis().dispose(); + BotQuery.clearBotKeyboard(did, null); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -2762,6 +2785,7 @@ public class MessagesStorage { HashMap mediaTypes = new HashMap<>(); HashMap messagesIdsMap = new HashMap<>(); HashMap messagesMediaIdsMap = new HashMap<>(); + HashMap botKeyboards = new HashMap<>(); StringBuilder messageIds = new StringBuilder(); StringBuilder messageMediaIds = new StringBuilder(); SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)"); @@ -2796,6 +2820,17 @@ public class MessagesStorage { messagesMediaIdsMap.put(message.id, dialog_id); mediaTypes.put(message.id, SharedMediaQuery.getMediaType(message)); } + + if (message.reply_markup != null && ((message.reply_markup.flags & 4) == 0 || (message.flags & 16) != 0)) { + TLRPC.Message oldMessage = botKeyboards.get(dialog_id); + if (oldMessage == null || oldMessage.id < message.id) { + botKeyboards.put(dialog_id, message); + } + } + } + + for (HashMap.Entry entry : botKeyboards.entrySet()) { + BotQuery.putBotKeyboard(entry.getKey(), entry.getValue()); } if (messageMediaIds.length() > 0) { @@ -2842,7 +2877,8 @@ public class MessagesStorage { } int downloadMediaMask = 0; - for (TLRPC.Message message : messages) { + for (int a = 0; a < messages.size(); a++) { + TLRPC.Message message = messages.get(a); fixUnsupportedMedia(message); long dialog_id = message.dialog_id; @@ -3307,7 +3343,7 @@ public class MessagesStorage { TLRPC.User updateUser = usersDict.get(user.id); if (updateUser != null) { if (updateUser.first_name != null && updateUser.last_name != null) { - if (!(user instanceof TLRPC.TL_userContact)) { + if (!UserObject.isContact(user)) { user.first_name = updateUser.first_name; user.last_name = updateUser.last_name; } @@ -3505,9 +3541,11 @@ public class MessagesStorage { cursor.dispose(); FileLoader.getInstance().deleteFiles(filesToDelete); database.executeFast(String.format(Locale.US, "DELETE FROM messages WHERE mid IN(%s)", ids)).stepThis().dispose(); + database.executeFast(String.format(Locale.US, "DELETE FROM bot_keyboard WHERE mid IN(%s)", ids)).stepThis().dispose(); database.executeFast(String.format(Locale.US, "DELETE FROM messages_seq WHERE mid IN(%s)", ids)).stepThis().dispose(); database.executeFast(String.format(Locale.US, "DELETE FROM media_v2 WHERE mid IN(%s)", ids)).stepThis().dispose(); database.executeFast("DELETE FROM media_counts_v2 WHERE 1").stepThis().dispose(); + BotQuery.clearBotKeyboard(0, messages); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -3526,7 +3564,7 @@ public class MessagesStorage { } cursor.dispose(); database.beginTransaction(); - SQLitePreparedStatement state = database.executeFast("UPDATE dialogs SET last_mid = (SELECT mid FROM messages WHERE uid = ? AND date = (SELECT MAX(date) FROM messages WHERE uid = ? )) WHERE did = ?"); + SQLitePreparedStatement state = database.executeFast("UPDATE dialogs SET unread_count = 0, last_mid = (SELECT mid FROM messages WHERE uid = ? AND date = (SELECT MAX(date) FROM messages WHERE uid = ? )) WHERE did = ?"); for (long did : dialogsToUpdate) { state.requery(); state.bindLong(1, did); @@ -3688,7 +3726,9 @@ public class MessagesStorage { if (!messages.messages.isEmpty()) { SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)"); SQLitePreparedStatement state2 = database.executeFast("REPLACE INTO media_v2 VALUES(?, ?, ?, ?, ?)"); - for (TLRPC.Message message : messages.messages) { + TLRPC.Message botKeyboard = null; + for (int a = 0; a < messages.messages.size(); a++) { + TLRPC.Message message = messages.messages.get(a); fixUnsupportedMedia(message); state.requery(); ByteBufferDesc data = buffersStorage.getFreeBuffer(message.getObjectSize()); @@ -3714,9 +3754,18 @@ public class MessagesStorage { state2.step(); } buffersStorage.reuseFreeBuffer(data); + + if (message.reply_markup != null && ((message.reply_markup.flags & 4) == 0 || (message.flags & 16) != 0)) { + if (botKeyboard == null || botKeyboard.id < message.id) { + botKeyboard = message; + } + } } state.dispose(); state2.dispose(); + if (botKeyboard != null) { + BotQuery.putBotKeyboard(dialog_id, botKeyboard); + } } putUsersInternal(messages.users); putChatsInternal(messages.chats); @@ -3853,7 +3902,8 @@ public class MessagesStorage { try { database.beginTransaction(); final HashMap new_dialogMessage = new HashMap<>(); - for (TLRPC.Message message : dialogs.messages) { + for (int a = 0; a < dialogs.messages.size(); a++) { + TLRPC.Message message = dialogs.messages.get(a); new_dialogMessage.put(message.id, message); } @@ -3863,7 +3913,9 @@ public class MessagesStorage { SQLitePreparedStatement state3 = database.executeFast("REPLACE INTO media_v2 VALUES(?, ?, ?, ?, ?)"); SQLitePreparedStatement state4 = database.executeFast("REPLACE INTO dialog_settings VALUES(?, ?)"); - for (TLRPC.TL_dialog dialog : dialogs.dialogs) { + for (int a = 0; a < dialogs.dialogs.size(); a++) { + TLRPC.TL_dialog dialog = dialogs.dialogs.get(a); + state.requery(); state2.requery(); state4.requery(); @@ -3872,23 +3924,41 @@ public class MessagesStorage { uid = -dialog.peer.chat_id; } TLRPC.Message message = new_dialogMessage.get(dialog.top_message); - fixUnsupportedMedia(message); - ByteBufferDesc data = buffersStorage.getFreeBuffer(message.getObjectSize()); - message.serializeToStream(data); - state.bindInteger(1, message.id); - state.bindInteger(2, uid); - state.bindInteger(3, MessageObject.getUnreadFlags(message)); - state.bindInteger(4, message.send_state); - state.bindInteger(5, message.date); - state.bindByteBuffer(6, data.buffer); - state.bindInteger(7, (MessageObject.isOut(message) ? 1 : 0)); - state.bindInteger(8, 0); - state.bindInteger(9, 0); - state.step(); + if (message != null) { + if (message.reply_markup != null && ((message.reply_markup.flags & 4) == 0 || (message.flags & 16) != 0)) { + BotQuery.putBotKeyboard(uid, message); + } + + fixUnsupportedMedia(message); + ByteBufferDesc data = buffersStorage.getFreeBuffer(message.getObjectSize()); + message.serializeToStream(data); + + state.bindInteger(1, message.id); + state.bindInteger(2, uid); + state.bindInteger(3, MessageObject.getUnreadFlags(message)); + state.bindInteger(4, message.send_state); + state.bindInteger(5, message.date); + state.bindByteBuffer(6, data.buffer); + state.bindInteger(7, (MessageObject.isOut(message) ? 1 : 0)); + state.bindInteger(8, 0); + state.bindInteger(9, 0); + state.step(); + + if (SharedMediaQuery.canAddMessageToMedia(message)) { + state3.requery(); + state3.bindLong(1, message.id); + state3.bindInteger(2, uid); + state3.bindInteger(3, message.date); + state3.bindInteger(4, SharedMediaQuery.getMediaType(message)); + state3.bindByteBuffer(5, data.buffer); + state3.step(); + } + buffersStorage.reuseFreeBuffer(data); + } state2.bindLong(1, uid); - state2.bindInteger(2, message.date); + state2.bindInteger(2, message != null ? message.date : 0); state2.bindInteger(3, dialog.unread_count); state2.bindInteger(4, dialog.top_message); state2.bindInteger(5, dialog.read_inbox_max_id); @@ -3898,17 +3968,6 @@ public class MessagesStorage { state4.bindLong(1, uid); state4.bindInteger(2, dialog.notify_settings.mute_until != 0 ? 1 : 0); state4.step(); - - if (SharedMediaQuery.canAddMessageToMedia(message)) { - state3.requery(); - state3.bindLong(1, message.id); - state3.bindInteger(2, uid); - state3.bindInteger(3, message.date); - state3.bindInteger(4, SharedMediaQuery.getMediaType(message)); - state3.bindByteBuffer(5, data.buffer); - state3.step(); - } - buffersStorage.reuseFreeBuffer(data); } state.dispose(); state2.dispose(); diff --git a/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java b/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java index 2092d378c..ffaf321a6 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java +++ b/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java @@ -44,7 +44,6 @@ public class NotificationCenter { public static final int pushMessagesUpdated = totalEvents++; public static final int blockedUsersDidLoaded = totalEvents++; public static final int openedChatChanged = totalEvents++; - public static final int hideEmojiKeyboard = totalEvents++; public static final int stopEncodingService = totalEvents++; public static final int didCreatedNewDeleteTask = totalEvents++; public static final int mainUserInfoChanged = totalEvents++; @@ -62,6 +61,9 @@ public class NotificationCenter { public static final int stickersDidLoaded = totalEvents++; public static final int didReplacedPhotoInMemCache = totalEvents++; public static final int messagesReadContent = totalEvents++; + public static final int botInfoDidLoaded = totalEvents++; + public static final int botKeyboardDidLoaded = totalEvents++; + public static final int chatSearchResultsAvailable = totalEvents++; public static final int httpFileDidLoaded = totalEvents++; public static final int httpFileDidFailedLoad = totalEvents++; @@ -147,7 +149,7 @@ public class NotificationCenter { public void postNotificationName(int id, Object... args) { boolean allowDuringAnimation = false; - if (id == dialogsNeedReload || id == closeChats || id == messagesDidLoaded || id == mediaCountDidLoaded || id == mediaDidLoaded) { + if (id == dialogsNeedReload || id == closeChats || id == messagesDidLoaded || id == mediaCountDidLoaded || id == mediaDidLoaded || id == botInfoDidLoaded || id == botKeyboardDidLoaded) { allowDuringAnimation = true; } postNotificationNameInternal(id, allowDuringAnimation, args); diff --git a/TMessagesProj/src/main/java/org/telegram/android/NotificationDelay.java b/TMessagesProj/src/main/java/org/telegram/android/NotificationDelay.java deleted file mode 100644 index c47af63f3..000000000 --- a/TMessagesProj/src/main/java/org/telegram/android/NotificationDelay.java +++ /dev/null @@ -1,29 +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.android; - -import android.app.IntentService; -import android.content.Intent; - -public class NotificationDelay extends IntentService { - - public NotificationDelay() { - super("NotificationDelay"); - } - - @Override - protected void onHandleIntent(Intent intent) { - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - NotificationsController.getInstance().notificationDelayReached(); - } - }); - } -} diff --git a/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java b/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java index 67fb8fb3f..3283523ab 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java @@ -24,6 +24,7 @@ import android.media.AudioManager; import android.media.SoundPool; import android.net.Uri; import android.os.Build; +import android.os.PowerManager; import android.os.SystemClock; import android.provider.Settings; import android.support.v4.app.NotificationCompat; @@ -75,12 +76,18 @@ public class NotificationsController { private int lastBadgeCount; private String launcherClassName; + private Runnable notificationDelayRunnable; + private PowerManager.WakeLock notificationDelayWakelock; + private long lastSoundPlay; private long lastSoundOutPlay; private SoundPool soundPool; private int soundIn; private int soundOut; + private boolean soundInLoaded; + private boolean soundOutLoaded; protected AudioManager audioManager; + private AlarmManager alarmManager; private static volatile NotificationsController Instance = null; public static NotificationsController getInstance() { @@ -106,6 +113,37 @@ public class NotificationsController { } catch (Exception e) { FileLog.e("tmessages", e); } + try { + alarmManager = (AlarmManager) ApplicationLoader.applicationContext.getSystemService(Context.ALARM_SERVICE); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + + try { + PowerManager pm = (PowerManager) ApplicationLoader.applicationContext.getSystemService(Context.POWER_SERVICE); + notificationDelayWakelock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "lock"); + notificationDelayWakelock.setReferenceCounted(false); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + + notificationDelayRunnable = new Runnable() { + @Override + public void run() { + FileLog.e("tmessages", "delay reached"); + if (!delayedPushMessages.isEmpty()) { + showOrUpdateNotification(true); + delayedPushMessages.clear(); + } + try { + if (notificationDelayWakelock.isHeld()) { + notificationDelayWakelock.release(); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }; } public void cleanup() { @@ -118,8 +156,17 @@ public class NotificationsController { popupMessages.clear(); wearNotificationsIds.clear(); autoNotificationsIds.clear(); + delayedPushMessages.clear(); notifyCheck = false; lastBadgeCount = 0; + try { + if (notificationDelayWakelock.isHeld()) { + notificationDelayWakelock.release(); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + setBadge(0); SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); editor.clear(); @@ -173,9 +220,9 @@ public class NotificationsController { if (preferences.getBoolean("EnablePreviewAll", true)) { if (messageObject.messageOwner instanceof TLRPC.TL_messageService) { if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionUserJoined) { - msg = LocaleController.formatString("NotificationContactJoined", R.string.NotificationContactJoined, ContactsController.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationContactJoined", R.string.NotificationContactJoined, UserObject.getUserName(user)); } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) { - msg = LocaleController.formatString("NotificationContactNewPhoto", R.string.NotificationContactNewPhoto, ContactsController.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationContactNewPhoto", R.string.NotificationContactNewPhoto, UserObject.getUserName(user)); } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionLoginUnknownLocation) { String date = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, LocaleController.formatterYear.format(((long) messageObject.messageOwner.date) * 1000), LocaleController.formatterDay.format(((long) messageObject.messageOwner.date) * 1000)); msg = LocaleController.formatString("NotificationUnrecognizedDevice", R.string.NotificationUnrecognizedDevice, UserConfig.getCurrentUser().first_name, date, messageObject.messageOwner.action.title, messageObject.messageOwner.action.address); @@ -184,33 +231,33 @@ public class NotificationsController { if (messageObject.isMediaEmpty()) { if (!shortMessage) { if (messageObject.messageOwner.message != null && messageObject.messageOwner.message.length() != 0) { - msg = LocaleController.formatString("NotificationMessageText", R.string.NotificationMessageText, ContactsController.formatName(user.first_name, user.last_name), messageObject.messageOwner.message); + msg = LocaleController.formatString("NotificationMessageText", R.string.NotificationMessageText, UserObject.getUserName(user), messageObject.messageOwner.message); } else { - msg = LocaleController.formatString("NotificationMessageNoText", R.string.NotificationMessageNoText, ContactsController.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationMessageNoText", R.string.NotificationMessageNoText, UserObject.getUserName(user)); } } else { - msg = LocaleController.formatString("NotificationMessageNoText", R.string.NotificationMessageNoText, ContactsController.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationMessageNoText", R.string.NotificationMessageNoText, UserObject.getUserName(user)); } } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) { - msg = LocaleController.formatString("NotificationMessagePhoto", R.string.NotificationMessagePhoto, ContactsController.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationMessagePhoto", R.string.NotificationMessagePhoto, UserObject.getUserName(user)); } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) { - msg = LocaleController.formatString("NotificationMessageVideo", R.string.NotificationMessageVideo, ContactsController.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationMessageVideo", R.string.NotificationMessageVideo, UserObject.getUserName(user)); } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaContact) { - msg = LocaleController.formatString("NotificationMessageContact", R.string.NotificationMessageContact, ContactsController.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationMessageContact", R.string.NotificationMessageContact, UserObject.getUserName(user)); } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeo || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVenue) { - msg = LocaleController.formatString("NotificationMessageMap", R.string.NotificationMessageMap, ContactsController.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationMessageMap", R.string.NotificationMessageMap, UserObject.getUserName(user)); } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) { if (messageObject.isSticker()) { - msg = LocaleController.formatString("NotificationMessageSticker", R.string.NotificationMessageSticker, ContactsController.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationMessageSticker", R.string.NotificationMessageSticker, UserObject.getUserName(user)); } else { - msg = LocaleController.formatString("NotificationMessageDocument", R.string.NotificationMessageDocument, ContactsController.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationMessageDocument", R.string.NotificationMessageDocument, UserObject.getUserName(user)); } } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaAudio) { - msg = LocaleController.formatString("NotificationMessageAudio", R.string.NotificationMessageAudio, ContactsController.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationMessageAudio", R.string.NotificationMessageAudio, UserObject.getUserName(user)); } } } else { - msg = LocaleController.formatString("NotificationMessageNoText", R.string.NotificationMessageNoText, ContactsController.formatName(user.first_name, user.last_name)); + msg = LocaleController.formatString("NotificationMessageNoText", R.string.NotificationMessageNoText, UserObject.getUserName(user)); } } else if (chat_id != 0) { SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE); @@ -218,35 +265,35 @@ public class NotificationsController { if (messageObject.messageOwner instanceof TLRPC.TL_messageService) { if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatAddUser) { if (messageObject.messageOwner.action.user_id == UserConfig.getClientUserId()) { - msg = LocaleController.formatString("NotificationInvitedToGroup", R.string.NotificationInvitedToGroup, ContactsController.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationInvitedToGroup", R.string.NotificationInvitedToGroup, UserObject.getUserName(user), chat.title); } else { TLRPC.User u2 = MessagesController.getInstance().getUser(messageObject.messageOwner.action.user_id); if (u2 == null) { return null; } if (user.id == u2.id) { - msg = LocaleController.formatString("NotificationGroupAddSelf", R.string.NotificationGroupAddSelf, ContactsController.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationGroupAddSelf", R.string.NotificationGroupAddSelf, UserObject.getUserName(user), chat.title); } else { - msg = LocaleController.formatString("NotificationGroupAddMember", R.string.NotificationGroupAddMember, ContactsController.formatName(user.first_name, user.last_name), chat.title, ContactsController.formatName(u2.first_name, u2.last_name)); + msg = LocaleController.formatString("NotificationGroupAddMember", R.string.NotificationGroupAddMember, UserObject.getUserName(user), chat.title, UserObject.getUserName(u2)); } } } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatJoinedByLink) { - msg = LocaleController.formatString("NotificationInvitedToGroupByLink", R.string.NotificationInvitedToGroupByLink, ContactsController.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationInvitedToGroupByLink", R.string.NotificationInvitedToGroupByLink, UserObject.getUserName(user), chat.title); } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatEditTitle) { - msg = LocaleController.formatString("NotificationEditedGroupName", R.string.NotificationEditedGroupName, ContactsController.formatName(user.first_name, user.last_name), messageObject.messageOwner.action.title); + msg = LocaleController.formatString("NotificationEditedGroupName", R.string.NotificationEditedGroupName, UserObject.getUserName(user), messageObject.messageOwner.action.title); } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatEditPhoto || messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatDeletePhoto) { - msg = LocaleController.formatString("NotificationEditedGroupPhoto", R.string.NotificationEditedGroupPhoto, ContactsController.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationEditedGroupPhoto", R.string.NotificationEditedGroupPhoto, UserObject.getUserName(user), chat.title); } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatDeleteUser) { if (messageObject.messageOwner.action.user_id == UserConfig.getClientUserId()) { - msg = LocaleController.formatString("NotificationGroupKickYou", R.string.NotificationGroupKickYou, ContactsController.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationGroupKickYou", R.string.NotificationGroupKickYou, UserObject.getUserName(user), chat.title); } else if (messageObject.messageOwner.action.user_id == user.id) { - msg = LocaleController.formatString("NotificationGroupLeftMember", R.string.NotificationGroupLeftMember, ContactsController.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationGroupLeftMember", R.string.NotificationGroupLeftMember, UserObject.getUserName(user), chat.title); } else { TLRPC.User u2 = MessagesController.getInstance().getUser(messageObject.messageOwner.action.user_id); if (u2 == null) { return null; } - msg = LocaleController.formatString("NotificationGroupKickMember", R.string.NotificationGroupKickMember, ContactsController.formatName(user.first_name, user.last_name), chat.title, ContactsController.formatName(u2.first_name, u2.last_name)); + msg = LocaleController.formatString("NotificationGroupKickMember", R.string.NotificationGroupKickMember, UserObject.getUserName(user), chat.title, UserObject.getUserName(u2)); } } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatCreate) { msg = messageObject.messageText.toString(); @@ -254,30 +301,30 @@ public class NotificationsController { } else { if (messageObject.isMediaEmpty()) { if (!shortMessage && messageObject.messageOwner.message != null && messageObject.messageOwner.message.length() != 0) { - msg = LocaleController.formatString("NotificationMessageGroupText", R.string.NotificationMessageGroupText, ContactsController.formatName(user.first_name, user.last_name), chat.title, messageObject.messageOwner.message); + msg = LocaleController.formatString("NotificationMessageGroupText", R.string.NotificationMessageGroupText, UserObject.getUserName(user), chat.title, messageObject.messageOwner.message); } else { - msg = LocaleController.formatString("NotificationMessageGroupNoText", R.string.NotificationMessageGroupNoText, ContactsController.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationMessageGroupNoText", R.string.NotificationMessageGroupNoText, UserObject.getUserName(user), chat.title); } } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) { - msg = LocaleController.formatString("NotificationMessageGroupPhoto", R.string.NotificationMessageGroupPhoto, ContactsController.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationMessageGroupPhoto", R.string.NotificationMessageGroupPhoto, UserObject.getUserName(user), chat.title); } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) { - msg = LocaleController.formatString("NotificationMessageGroupVideo", R.string.NotificationMessageGroupVideo, ContactsController.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationMessageGroupVideo", R.string.NotificationMessageGroupVideo, UserObject.getUserName(user), chat.title); } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaContact) { - msg = LocaleController.formatString("NotificationMessageGroupContact", R.string.NotificationMessageGroupContact, ContactsController.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationMessageGroupContact", R.string.NotificationMessageGroupContact, UserObject.getUserName(user), chat.title); } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeo || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVenue) { - msg = LocaleController.formatString("NotificationMessageGroupMap", R.string.NotificationMessageGroupMap, ContactsController.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationMessageGroupMap", R.string.NotificationMessageGroupMap, UserObject.getUserName(user), chat.title); } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) { if (messageObject.isSticker()) { - msg = LocaleController.formatString("NotificationMessageGroupSticker", R.string.NotificationMessageGroupSticker, ContactsController.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationMessageGroupSticker", R.string.NotificationMessageGroupSticker, UserObject.getUserName(user), chat.title); } else { - msg = LocaleController.formatString("NotificationMessageGroupDocument", R.string.NotificationMessageGroupDocument, ContactsController.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationMessageGroupDocument", R.string.NotificationMessageGroupDocument, UserObject.getUserName(user), chat.title); } } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaAudio) { - msg = LocaleController.formatString("NotificationMessageGroupAudio", R.string.NotificationMessageGroupAudio, ContactsController.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationMessageGroupAudio", R.string.NotificationMessageGroupAudio, UserObject.getUserName(user), chat.title); } } } else { - msg = LocaleController.formatString("NotificationMessageGroupNoText", R.string.NotificationMessageGroupNoText, ContactsController.formatName(user.first_name, user.last_name), chat.title); + msg = LocaleController.formatString("NotificationMessageGroupNoText", R.string.NotificationMessageGroupNoText, UserObject.getUserName(user), chat.title); } } } @@ -286,14 +333,13 @@ public class NotificationsController { private void scheduleNotificationRepeat() { try { - AlarmManager alarm = (AlarmManager) ApplicationLoader.applicationContext.getSystemService(Context.ALARM_SERVICE); PendingIntent pintent = PendingIntent.getService(ApplicationLoader.applicationContext, 0, new Intent(ApplicationLoader.applicationContext, NotificationRepeat.class), 0); 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.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + minutes * 60 * 1000, pintent); + alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + minutes * 60 * 1000, pintent); } else { - alarm.cancel(pintent); + alarmManager.cancel(pintent); } } catch (Exception e) { FileLog.e("tmessages", e); @@ -303,24 +349,12 @@ public class NotificationsController { private void scheduleNotificationDelay(boolean onlineReason) { try { FileLog.e("tmessages", "delay notification start, onlineReason = " + onlineReason); - AlarmManager alarm = (AlarmManager) ApplicationLoader.applicationContext.getSystemService(Context.ALARM_SERVICE); - 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.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 3 * 1000, pintent); - } else { - alarm.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 1000, pintent); - } + notificationDelayWakelock.acquire(10000); + AndroidUtilities.cancelRunOnUIThread(notificationDelayRunnable); + AndroidUtilities.runOnUIThread(notificationDelayRunnable, (onlineReason ? 3 * 1000 : 1000)); } catch (Exception e) { FileLog.e("tmessages", e); - } - } - - protected void notificationDelayReached() { - FileLog.e("tmessages", "delay reached"); - if (!delayedPushMessages.isEmpty()) { - showOrUpdateNotification(true); - delayedPushMessages.clear(); + showOrUpdateNotification(notifyCheck); } } @@ -529,7 +563,7 @@ public class NotificationsController { if (chat != null) { name = chat.title; } else { - name = ContactsController.formatName(user.first_name, user.last_name); + name = UserObject.getUserName(user); } } @@ -673,9 +707,11 @@ public class NotificationsController { if (Build.VERSION.SDK_INT < 19) { return; } + ArrayList sortedDialogs = new ArrayList<>(); HashMap> messagesByDialogs = new HashMap<>(); - for (MessageObject messageObject : pushMessages) { + for (int a = 0; a < pushMessages.size(); a++) { + MessageObject messageObject = pushMessages.get(a); long dialog_id = messageObject.getDialogId(); if ((int)dialog_id == 0) { continue; @@ -698,7 +734,8 @@ public class NotificationsController { oldIdsAuto.putAll(autoNotificationsIds); autoNotificationsIds.clear(); - for (long dialog_id : sortedDialogs) { + for (int b = 0; b < sortedDialogs.size(); b++) { + long dialog_id = sortedDialogs.get(b); ArrayList messageObjects = messagesByDialogs.get(dialog_id); int max_id = messageObjects.get(0).getId(); int max_date = messageObjects.get(0).messageOwner.date; @@ -719,7 +756,7 @@ public class NotificationsController { if (chat != null) { name = chat.title; } else { - name = ContactsController.formatName(user.first_name, user.last_name); + name = UserObject.getUserName(user); } Integer notificationIdWear = oldIdsWear.get(dialog_id); @@ -736,19 +773,6 @@ public class NotificationsController { oldIdsAuto.remove(dialog_id); } - Intent replyIntent = new Intent(ApplicationLoader.applicationContext, WearReplyReceiver.class); - replyIntent.putExtra("dialog_id", dialog_id); - replyIntent.putExtra("max_id", max_id); - PendingIntent replyPendingIntent = PendingIntent.getBroadcast(ApplicationLoader.applicationContext, notificationIdWear, replyIntent, PendingIntent.FLAG_UPDATE_CURRENT); - RemoteInput remoteInputWear = new RemoteInput.Builder(EXTRA_VOICE_REPLY).setLabel(LocaleController.getString("Reply", R.string.Reply)).build(); - String replyToString; - if (chat != null) { - replyToString = LocaleController.formatString("ReplyToGroup", R.string.ReplyToGroup, name); - } else { - replyToString = LocaleController.formatString("ReplyToUser", R.string.ReplyToUser, name); - } - NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.drawable.ic_reply_icon, replyToString, replyPendingIntent).addRemoteInput(remoteInputWear).build(); - Intent msgHeardIntent = new Intent(); msgHeardIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); msgHeardIntent.setAction("org.telegram.messenger.ACTION_MESSAGE_HEARD"); @@ -765,9 +789,22 @@ public class NotificationsController { RemoteInput remoteInputAuto = new RemoteInput.Builder(NotificationsController.EXTRA_VOICE_REPLY).setLabel(LocaleController.getString("Reply", R.string.Reply)).build(); NotificationCompat.CarExtender.UnreadConversation.Builder unreadConvBuilder = new NotificationCompat.CarExtender.UnreadConversation.Builder(name) - .setReadPendingIntent(msgHeardPendingIntent) - .setReplyAction(msgReplyPendingIntent, remoteInputAuto) - .setLatestTimestamp((long) max_date * 1000); + .setReadPendingIntent(msgHeardPendingIntent) + .setReplyAction(msgReplyPendingIntent, remoteInputAuto) + .setLatestTimestamp((long) max_date * 1000); + + Intent replyIntent = new Intent(ApplicationLoader.applicationContext, WearReplyReceiver.class); + replyIntent.putExtra("dialog_id", dialog_id); + replyIntent.putExtra("max_id", max_id); + PendingIntent replyPendingIntent = PendingIntent.getBroadcast(ApplicationLoader.applicationContext, notificationIdWear, replyIntent, PendingIntent.FLAG_UPDATE_CURRENT); + RemoteInput remoteInputWear = new RemoteInput.Builder(EXTRA_VOICE_REPLY).setLabel(LocaleController.getString("Reply", R.string.Reply)).build(); + String replyToString; + if (chat != null) { + replyToString = LocaleController.formatString("ReplyToGroup", R.string.ReplyToGroup, name); + } else { + replyToString = LocaleController.formatString("ReplyToUser", R.string.ReplyToUser, name); + } + NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.drawable.ic_reply_icon, replyToString, replyPendingIntent).addRemoteInput(remoteInputWear).build(); String text = ""; for (int a = messageObjects.size() - 1; a >= 0; a--) { @@ -789,8 +826,6 @@ public class NotificationsController { unreadConvBuilder.addMessage(message); } - - TLRPC.FileLocation photoPath = null; 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) { @@ -801,23 +836,6 @@ public class NotificationsController { photoPath = user.photo.photo_small; } } - //notificationBuilder.extend(new NotificationCompat.CarExtender().setUnreadConversation(unreadConvBuilder.build())); - NotificationCompat.Builder builderAuto = new NotificationCompat.Builder(ApplicationLoader.applicationContext) - .setSmallIcon(R.drawable.notification) - .setColor(0xff2ca5e0) - .setGroup("messages") - .setLocalOnly(true) - //.setGroupSummary(false) - //.setCategory(NotificationCompat.CATEGORY_MESSAGE) - .extend(new NotificationCompat.CarExtender().setUnreadConversation(unreadConvBuilder.build())); - if (photoPath != null) { - BitmapDrawable img = ImageLoader.getInstance().getImageFromMemory(photoPath, null, "50_50"); - if (img != null) { - builderAuto.setLargeIcon(img.getBitmap()); - } - } - notificationManager.notify("android_auto", notificationIdAuto, builderAuto.build()); - autoNotificationsIds.put(dialog_id, notificationIdAuto); Intent intent = new Intent(ApplicationLoader.applicationContext, LaunchActivity.class); intent.setAction("com.tmessages.openchat" + Math.random() + Integer.MAX_VALUE); @@ -838,6 +856,7 @@ public class NotificationsController { .setGroupSummary(false) .setContentIntent(contentIntent) .extend(new NotificationCompat.WearableExtender().addAction(action)) + .extend(new NotificationCompat.CarExtender().setUnreadConversation(unreadConvBuilder.build())) .setCategory(NotificationCompat.CATEGORY_MESSAGE); if (photoPath != null) { BitmapDrawable img = ImageLoader.getInstance().getImageFromMemory(photoPath, null, "50_50"); @@ -854,9 +873,6 @@ public class NotificationsController { wearNotificationsIds.put(dialog_id, notificationIdWear); } - for (HashMap.Entry entry : oldIdsAuto.entrySet()) { - notificationManager.cancel(entry.getValue()); - } for (HashMap.Entry entry : oldIdsWear.entrySet()) { notificationManager.cancel(entry.getValue()); } @@ -919,6 +935,9 @@ public class NotificationsController { } } } + if (pushMessages.isEmpty() && !popupMessages.isEmpty()) { + popupMessages.clear(); + } } if (dialog_id != 0 && (max_id != 0 || max_date != 0)) { for (int a = 0; a < pushMessages.size(); a++) { @@ -952,6 +971,9 @@ public class NotificationsController { } } } + if (pushMessages.isEmpty() && !popupMessages.isEmpty()) { + popupMessages.clear(); + } } if (oldCount != popupMessages.size()) { NotificationCenter.getInstance().postNotificationName(NotificationCenter.pushMessagesUpdated); @@ -984,7 +1006,7 @@ public class NotificationsController { } try { if (soundPool == null) { - soundPool = new SoundPool(4, AudioManager.STREAM_SYSTEM, 0); + soundPool = new SoundPool(2, AudioManager.STREAM_SYSTEM, 0); soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() { @Override public void onLoadComplete(SoundPool soundPool, int sampleId, int status) { @@ -994,10 +1016,13 @@ public class NotificationsController { } }); } - if (soundIn == 0) { + if (soundIn == 0 && !soundInLoaded) { + soundInLoaded = true; soundIn = soundPool.load(ApplicationLoader.applicationContext, R.raw.sound_in, 1); } - soundPool.play(soundIn, 1.0f, 1.0f, 1, 0, 1.0f); + if (soundIn != 0) { + soundPool.play(soundIn, 1.0f, 1.0f, 1, 0, 1.0f); + } } catch (Exception e) { FileLog.e("tmessages", e); } @@ -1028,7 +1053,7 @@ public class NotificationsController { } lastSoundOutPlay = System.currentTimeMillis(); if (soundPool == null) { - soundPool = new SoundPool(4, AudioManager.STREAM_SYSTEM, 0); + soundPool = new SoundPool(2, AudioManager.STREAM_SYSTEM, 0); soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() { @Override public void onLoadComplete(SoundPool soundPool, int sampleId, int status) { @@ -1038,10 +1063,13 @@ public class NotificationsController { } }); } - if (soundOut == 0) { + if (soundOut == 0 && !soundOutLoaded) { + soundOutLoaded = true; soundOut = soundPool.load(ApplicationLoader.applicationContext, R.raw.sound_out, 1); } - soundPool.play(soundOut, 1.0f, 1.0f, 1, 0, 1.0f); + if (soundOut != 0) { + soundPool.play(soundOut, 1.0f, 1.0f, 1, 0, 1.0f); + } } catch (Exception e) { FileLog.e("tmessages", e); } @@ -1071,7 +1099,8 @@ public class NotificationsController { SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE); int popup = 0; - for (MessageObject messageObject : messageObjects) { + for (int a = 0; a < messageObjects.size(); a++) { + MessageObject messageObject = messageObjects.get(a); if (pushMessagesDict.containsKey(messageObject.getId())) { continue; } @@ -1175,6 +1204,9 @@ public class NotificationsController { popupMessages.remove(messageObject); } } + if (pushMessages.isEmpty() && !popupMessages.isEmpty()) { + popupMessages.clear(); + } } else if (canAddValue) { total_unread_count += newCount; pushDialogs.put(dialog_id, newCount); @@ -1190,7 +1222,7 @@ public class NotificationsController { } notifyCheck = false; if (preferences.getBoolean("badgeNumber", true)) { - setBadge(ApplicationLoader.applicationContext, total_unread_count); + setBadge(total_unread_count); } } @@ -1264,15 +1296,15 @@ public class NotificationsController { showOrUpdateNotification(SystemClock.uptimeMillis() / 1000 < 60); if (preferences.getBoolean("badgeNumber", true)) { - setBadge(ApplicationLoader.applicationContext, total_unread_count); + setBadge(total_unread_count); } } public void setBadgeEnabled(boolean enabled) { - setBadge(ApplicationLoader.applicationContext, enabled ? total_unread_count : 0); + setBadge(enabled ? total_unread_count : 0); } - private void setBadge(final Context context, final int count) { + private void setBadge(final int count) { notificationsQueue.postRunnable(new Runnable() { @Override public void run() { @@ -1284,12 +1316,12 @@ public class NotificationsController { 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); + ApplicationLoader.applicationContext.getContentResolver().insert(Uri.parse("content://com.teslacoilsw.notifier/unread_count"), cv); } catch (Throwable e) { //ignore } try { - launcherClassName = getLauncherClassName(context); + launcherClassName = getLauncherClassName(ApplicationLoader.applicationContext); if (launcherClassName == null) { return; } @@ -1299,9 +1331,9 @@ public class NotificationsController { try { 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_package_name", ApplicationLoader.applicationContext.getPackageName()); intent.putExtra("badge_count_class_name", launcherClassName); - context.sendBroadcast(intent); + ApplicationLoader.applicationContext.sendBroadcast(intent); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -1367,7 +1399,7 @@ public class NotificationsController { if (user == null) { return; } - if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { + if (user.access_hash != 0) { ((TLRPC.TL_inputNotifyPeer)req.peer).peer = new TLRPC.TL_inputPeerForeign(); ((TLRPC.TL_inputNotifyPeer)req.peer).peer.access_hash = user.access_hash; } else { diff --git a/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java b/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java index 3aa324556..060d21799 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java @@ -449,7 +449,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVenue || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeo) { sendMessage(messageObject.messageOwner.media, did, messageObject.replyMessageObject); } else if (messageObject.messageOwner.media.phone_number != null) { - TLRPC.User user = new TLRPC.TL_userContact(); + TLRPC.User user = new TLRPC.TL_userContact_old2(); user.phone = messageObject.messageOwner.media.phone_number; user.first_name = messageObject.messageOwner.media.first_name; user.last_name = messageObject.messageOwner.media.last_name; @@ -503,12 +503,14 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter } } } - for (int a = 0; a < document.attributes.size(); a++) { - TLRPC.DocumentAttribute attribute = document.attributes.get(a); - if (attribute instanceof TLRPC.TL_documentAttributeSticker) { - document.attributes.remove(a); - document.attributes.add(new TLRPC.TL_documentAttributeSticker_old()); - break; + if ((int) peer == 0) { + for (int a = 0; a < document.attributes.size(); a++) { + TLRPC.DocumentAttribute attribute = document.attributes.get(a); + if (attribute instanceof TLRPC.TL_documentAttributeSticker) { + document.attributes.remove(a); + document.attributes.add(new TLRPC.TL_documentAttributeSticker_old()); + break; + } } } SendMessagesHelper.getInstance().sendMessage((TLRPC.TL_document) document, null, null, peer, replyingMessageObject); @@ -537,7 +539,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter if (sendToUser == null) { return; } - if (sendToUser instanceof TLRPC.TL_userForeign || sendToUser instanceof TLRPC.TL_userRequest) { + if (sendToUser.access_hash != 0) { sendToPeer = new TLRPC.TL_inputPeerForeign(); sendToPeer.user_id = sendToUser.id; sendToPeer.access_hash = sendToUser.access_hash; @@ -736,6 +738,15 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter ArrayList sendToPeers = null; if (lower_id == 0) { encryptedChat = MessagesController.getInstance().getEncryptedChat(high_id); + if (encryptedChat == null) { + if (msgObj != null) { + MessagesStorage.getInstance().markMessageAsSendError(msgObj.getId()); + msgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR; + NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, msgObj.getId()); + processSentMessage(msgObj.getId()); + } + return; + } } if (retry) { @@ -766,7 +777,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter video = (TLRPC.TL_video) newMsg.media.video; } } else if (msgObj.type == 12) { - user = new TLRPC.TL_userRequest(); + user = new TLRPC.TL_userRequest_old2(); user.phone = newMsg.media.phone_number; user.first_name = newMsg.media.first_name; user.last_name = newMsg.media.last_name; @@ -862,6 +873,12 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter newMsg.media.first_name = user.first_name; newMsg.media.last_name = user.last_name; newMsg.media.user_id = user.id; + if (newMsg.media.first_name == null) { + user.first_name = newMsg.media.first_name = ""; + } + if (newMsg.media.last_name == null) { + user.last_name = newMsg.media.last_name = ""; + } newMsg.message = ""; type = 6; } else if (document != null) { @@ -941,7 +958,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter processSentMessage(newMsg.id); return; } - if (sendToUser instanceof TLRPC.TL_userForeign || sendToUser instanceof TLRPC.TL_userRequest) { + if ((sendToUser.flags & TLRPC.USER_FLAG_BOT) != 0) { + newMsg.flags &= ~TLRPC.MESSAGE_FLAG_UNREAD; + } + if (sendToUser.access_hash != 0) { sendToPeer = new TLRPC.TL_inputPeerForeign(); sendToPeer.user_id = sendToUser.id; sendToPeer.access_hash = sendToUser.access_hash; @@ -1758,6 +1778,8 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter sentMessage.attachPath = newMsg.attachPath; } } + } else if (sentMessage.media instanceof TLRPC.TL_messageMediaContact && newMsg.media instanceof TLRPC.TL_messageMediaContact) { + newMsg.media = sentMessage.media; } } @@ -2162,15 +2184,30 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter return src; } - public static void prepareSendingText(String text, long dialog_id) { - text = getTrimmedString(text); - if (text.length() != 0) { - int count = (int) Math.ceil(text.length() / 4096.0f); - for (int a = 0; a < count; a++) { - String mess = text.substring(a * 4096, Math.min((a + 1) * 4096, text.length())); - SendMessagesHelper.getInstance().sendMessage(mess, dialog_id, null, null, true); + public static void prepareSendingText(final String text, final long dialog_id) { + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { + @Override + public void run() { + Utilities.stageQueue.postRunnable(new Runnable() { + @Override + public void run() { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + String textFinal = getTrimmedString(text); + if (textFinal.length() != 0) { + int count = (int) Math.ceil(textFinal.length() / 4096.0f); + for (int a = 0; a < count; a++) { + String mess = textFinal.substring(a * 4096, Math.min((a + 1) * 4096, textFinal.length())); + SendMessagesHelper.getInstance().sendMessage(mess, dialog_id, null, null, true); + } + } + } + }); + } + }); } - } + }); } public static void prepareSendingPhotos(ArrayList paths, ArrayList uris, final long dialog_id, final MessageObject reply_to_msg, final ArrayList captions) { diff --git a/TMessagesProj/src/main/java/org/telegram/android/UserObject.java b/TMessagesProj/src/main/java/org/telegram/android/UserObject.java new file mode 100644 index 000000000..1fe80d039 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/android/UserObject.java @@ -0,0 +1,45 @@ +/* + * This is the source code of Telegram for Android v. 2.x.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2015. + */ + +package org.telegram.android; + +import org.telegram.messenger.R; +import org.telegram.messenger.TLRPC; + +public class UserObject { + + public static boolean isDeleted(TLRPC.User user) { + return user == null || user instanceof TLRPC.TL_userDeleted_old2 || user instanceof TLRPC.TL_userEmpty || (user.flags & TLRPC.USER_FLAG_DELETED) != 0; + } + + public static boolean isContact(TLRPC.User user) { + return user instanceof TLRPC.TL_userContact_old2 || (user.flags & TLRPC.USER_FLAG_CONTACT) != 0 || (user.flags & TLRPC.USER_FLAG_MUTUAL_CONTACT) != 0; + } + + public static boolean isUserSelf(TLRPC.User user) { + return user instanceof TLRPC.TL_userSelf_old3 || (user.flags & TLRPC.USER_FLAG_SELF) != 0; + } + + public static String getUserName(TLRPC.User user) { + if (user == null || isDeleted(user)) { + return LocaleController.getString("HiddenName", R.string.HiddenName); + } + return ContactsController.formatName(user.first_name, user.last_name); + } + + public static String getFirstName(TLRPC.User user) { + if (user == null || isDeleted(user)) { + return "DELETED"; + } + String name = user.first_name; + if (name == null || name.length() == 0) { + name = user.last_name; + } + return name != null && name.length() > 0 ? name : "DELETED"; + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/android/query/BotQuery.java b/TMessagesProj/src/main/java/org/telegram/android/query/BotQuery.java new file mode 100644 index 000000000..fb778b131 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/android/query/BotQuery.java @@ -0,0 +1,205 @@ +/* + * This is the source code of Telegram for Android v. 2.x.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2015. + */ + +package org.telegram.android.query; + +import org.telegram.SQLite.SQLiteCursor; +import org.telegram.SQLite.SQLitePreparedStatement; +import org.telegram.android.AndroidUtilities; +import org.telegram.android.MessagesStorage; +import org.telegram.android.NotificationCenter; +import org.telegram.messenger.ByteBufferDesc; +import org.telegram.messenger.FileLog; +import org.telegram.messenger.TLRPC; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Locale; + +public class BotQuery { + + private static HashMap botInfos = new HashMap<>(); + private static HashMap botKeyboards = new HashMap<>(); + private static HashMap botKeyboardsByMids = new HashMap<>(); + + public static void cleanup() { + botInfos.clear(); + } + + public static void clearBotKeyboard(final long did, final ArrayList messages) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (messages != null) { + for (int a = 0; a < messages.size(); a++) { + Long did = botKeyboardsByMids.get(messages.get(a)); + if (did != null) { + botKeyboards.remove(did); + botKeyboardsByMids.remove(messages.get(a)); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.botKeyboardDidLoaded, null, did); + } + } + } else { + botKeyboards.remove(did); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.botKeyboardDidLoaded, null, did); + } + } + }); + } + + public static void loadBotKeyboard(final long did) { + TLRPC.Message keyboard = botKeyboards.get(did); + if (keyboard != null) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.botKeyboardDidLoaded, keyboard, did); + return; + } + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { + @Override + public void run() { + try { + TLRPC.Message botKeyboard = null; + SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT info FROM bot_keyboard WHERE uid = %d", did)); + if (cursor.next()) { + ByteBufferDesc data; + + if (!cursor.isNull(0)) { + data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0)); + if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { + botKeyboard = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false); + } + MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data); + } + } + cursor.dispose(); + + if (botKeyboard != null) { + final TLRPC.Message botKeyboardFinal = botKeyboard; + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.botKeyboardDidLoaded, botKeyboardFinal, did); + } + }); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + } + + public static void loadBotInfo(final int uid, boolean cache, final int classGuid) { + if (cache) { + TLRPC.BotInfo botInfo = botInfos.get(uid); + if (botInfo != null) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.botInfoDidLoaded, botInfo, classGuid); + return; + } + } + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { + @Override + public void run() { + try { + TLRPC.BotInfo botInfo = null; + SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT info FROM bot_info WHERE uid = %d", uid)); + if (cursor.next()) { + ByteBufferDesc data; + + if (!cursor.isNull(0)) { + data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0)); + if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { + botInfo = TLRPC.BotInfo.TLdeserialize(data, data.readInt32(false), false); + } + MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data); + } + } + cursor.dispose(); + + if (botInfo != null) { + final TLRPC.BotInfo botInfoFinal = botInfo; + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.botInfoDidLoaded, botInfoFinal, classGuid); + } + }); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + } + + public static void putBotKeyboard(final long did, final TLRPC.Message message) { + if (message == null) { + return; + } + try { + int mid = 0; + SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT mid FROM bot_keyboard WHERE uid = %d", did)); + if (cursor.next()) { + mid = cursor.intValue(0); + } + cursor.dispose(); + if (mid >= message.id) { + return; + } + + SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO bot_keyboard VALUES(?, ?, ?)"); + state.requery(); + ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(message.getObjectSize()); + message.serializeToStream(data); + state.bindLong(1, did); + state.bindInteger(2, message.id); + state.bindByteBuffer(3, data.buffer); + state.step(); + MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data); + state.dispose(); + + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + TLRPC.Message old = botKeyboards.put(did, message); + if (old != null) { + botKeyboardsByMids.remove(old.id); + } + botKeyboardsByMids.put(message.id, did); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.botKeyboardDidLoaded, message, did); + } + }); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + + public static void putBotInfo(final TLRPC.BotInfo botInfo) { + if (botInfo == null || botInfo instanceof TLRPC.TL_botInfoEmpty) { + return; + } + botInfos.put(botInfo.user_id, botInfo); + MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { + @Override + public void run() { + try { + SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO bot_info(uid, info) VALUES(?, ?)"); + state.requery(); + ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(botInfo.getObjectSize()); + botInfo.serializeToStream(data); + state.bindInteger(1, botInfo.user_id); + state.bindByteBuffer(2, data.buffer); + state.step(); + MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data); + state.dispose(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/android/query/MessagesSearchQuery.java b/TMessagesProj/src/main/java/org/telegram/android/query/MessagesSearchQuery.java new file mode 100644 index 000000000..c1f9f39c7 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/android/query/MessagesSearchQuery.java @@ -0,0 +1,137 @@ +/* + * This is the source code of Telegram for Android v. 2.x.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2015. + */ + +package org.telegram.android.query; + +import org.telegram.android.AndroidUtilities; +import org.telegram.android.MessageObject; +import org.telegram.android.MessagesController; +import org.telegram.android.MessagesStorage; +import org.telegram.android.NotificationCenter; +import org.telegram.messenger.ConnectionsManager; +import org.telegram.messenger.RPCRequest; +import org.telegram.messenger.TLObject; +import org.telegram.messenger.TLRPC; + +import java.util.ArrayList; + +public class MessagesSearchQuery { + + private static long reqId; + private static int lastReqId; + private static boolean messagesSearchEndReached; + private static ArrayList searchResultMessages = new ArrayList<>(); + private static String lastSearchQuery; + private static int lastReturnedNum; + + private static int getMask() { + int mask = 0; + if (lastReturnedNum < searchResultMessages.size() - 1) { + mask |= 1; + } + if (lastReturnedNum > 0) { + mask |= 2; + } + return mask; + } + + public static void searchMessagesInChat(String query, long dialog_id, final int guid, int direction) { + if (reqId != 0) { + ConnectionsManager.getInstance().cancelRpc(reqId, true); + reqId = 0; + } + int max_id = 0; + if (query == null || query.length() == 0) { + if (direction == 1) { + lastReturnedNum++; + if (lastReturnedNum < searchResultMessages.size()) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, searchResultMessages.get(lastReturnedNum).getId(), getMask()); + return; + } else { + if (messagesSearchEndReached) { + lastReturnedNum--; + return; + } + query = lastSearchQuery; + max_id = searchResultMessages.get(searchResultMessages.size() - 1).getId(); + } + } else if (direction == 2) { + lastReturnedNum--; + if (lastReturnedNum < 0) { + lastReturnedNum = 0; + return; + } + NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, searchResultMessages.get(lastReturnedNum).getId(), getMask()); + return; + } else { + return; + } + } + final TLRPC.TL_messages_search req = new TLRPC.TL_messages_search(); + req.limit = 21; + int lower_part = (int) dialog_id; + if (lower_part < 0) { + req.peer = new TLRPC.TL_inputPeerChat(); + req.peer.chat_id = -lower_part; + } else { + TLRPC.User user = MessagesController.getInstance().getUser(lower_part); + if (user == null) { + return; + } + if (user.access_hash != 0) { + req.peer = new TLRPC.TL_inputPeerForeign(); + req.peer.access_hash = user.access_hash; + } else { + req.peer = new TLRPC.TL_inputPeerContact(); + } + req.peer.user_id = lower_part; + } + req.q = query; + req.max_id = max_id; + req.filter = new TLRPC.TL_inputMessagesFilterEmpty(); + final int currentReqId = ++lastReqId; + lastSearchQuery = query; + reqId = ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(final TLObject response, final TLRPC.TL_error error) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + if (currentReqId == lastReqId) { + if (error == null) { + TLRPC.messages_Messages res = (TLRPC.messages_Messages) response; + MessagesStorage.getInstance().putUsersAndChats(res.users, res.chats, true, true); + MessagesController.getInstance().putUsers(res.users, false); + MessagesController.getInstance().putChats(res.chats, false); + if (req.max_id == 0) { + lastReturnedNum = 0; + searchResultMessages.clear(); + } + boolean added = false; + for (int a = 0; a < Math.min(res.messages.size(), 20); a++) { + TLRPC.Message message = res.messages.get(a); + added = true; + searchResultMessages.add(new MessageObject(message, null, false)); + } + messagesSearchEndReached = res.messages.size() != 21; + if (searchResultMessages.isEmpty()) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, 0, getMask()); + } else { + if (added) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, searchResultMessages.get(lastReturnedNum).getId(), getMask()); + } + } + } + } + reqId = 0; + } + }); + } + }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/android/query/SharedMediaQuery.java b/TMessagesProj/src/main/java/org/telegram/android/query/SharedMediaQuery.java index 345b0e49d..f1acd0285 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/query/SharedMediaQuery.java +++ b/TMessagesProj/src/main/java/org/telegram/android/query/SharedMediaQuery.java @@ -55,7 +55,10 @@ public class SharedMediaQuery { req.peer.chat_id = -lower_part; } else { TLRPC.User user = MessagesController.getInstance().getUser(lower_part); - if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { + if (user == null) { + return; + } + if (user.access_hash != 0) { req.peer = new TLRPC.TL_inputPeerForeign(); req.peer.access_hash = user.access_hash; } else { @@ -98,7 +101,10 @@ public class SharedMediaQuery { req.peer.chat_id = -lower_part; } else { TLRPC.User user = MessagesController.getInstance().getUser(lower_part); - if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { + if (user == null) { + return; + } + if (user.access_hash != 0) { req.peer = new TLRPC.TL_inputPeerForeign(); req.peer.access_hash = user.access_hash; } else { diff --git a/TMessagesProj/src/main/java/org/telegram/android/query/StickersQuery.java b/TMessagesProj/src/main/java/org/telegram/android/query/StickersQuery.java index 9b247d8e8..d4187165f 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/query/StickersQuery.java +++ b/TMessagesProj/src/main/java/org/telegram/android/query/StickersQuery.java @@ -33,23 +33,31 @@ import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.Components.StickersAlert; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; public class StickersQuery { - private static String hash; + private static String loadHash; private static int loadDate; - private static ArrayList stickers = new ArrayList<>(); - private static HashMap> allStickers = new HashMap<>(); - private static ArrayList stickerPacks = new ArrayList<>(); - private static ArrayList stickerSets = new ArrayList<>(); - private static HashMap> stickersBySets = new HashMap<>(); + private static ArrayList stickerSets = new ArrayList<>(); + private static HashMap stickerSetsById = new HashMap<>(); private static HashMap stickersByEmoji = new HashMap<>(); + private static HashMap stickersById = new HashMap<>(); + private static HashMap> allStickers = new HashMap<>(); + private static boolean loadingStickers; private static boolean stickersLoaded; - private static boolean hideMainStickersPack; + + public static void cleanup() { + loadHash = null; + loadDate = 0; + allStickers.clear(); + stickerSets.clear(); + stickersByEmoji.clear(); + stickerSetsById.clear(); + loadingStickers = false; + stickersLoaded = false; + } public static void checkStickers() { if (!loadingStickers && (!stickersLoaded || loadDate < (System.currentTimeMillis() / 1000 - 60 * 60))) { @@ -61,28 +69,28 @@ public class StickersQuery { return loadingStickers; } + public static TLRPC.Document getStickerById(long id) { + TLRPC.Document document = stickersById.get(id); + if (document != null) { + long setId = getStickerSetId(document); + TLRPC.TL_messages_stickerSet stickerSet = stickerSetsById.get(setId); + if (stickerSet != null && (stickerSet.set.flags & 2) != 0) { + return null; + } + } + return document; + } + public static HashMap> getAllStickers() { return allStickers; } - public static ArrayList getStickersForSet(long id) { - return stickersBySets.get(id); - } - - public static ArrayList getStickerPacks() { - return stickerPacks; - } - - public static ArrayList getStickers() { - return stickers; - } - - public static ArrayList getStickerSets() { + public static ArrayList getStickerSets() { return stickerSets; } public static boolean isStickerPackInstalled(long id) { - return stickersBySets.containsKey(id); + return stickerSetsById.containsKey(id); } public static String getEmojiForSticker(long id) { @@ -99,43 +107,91 @@ public class StickersQuery { MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { - TLRPC.messages_AllStickers result = null; + ArrayList newStickerArray = null; int date = 0; + String hash = null; try { - SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT value FROM keyvalue WHERE id = 'hide_stickers'"); - if (cursor.next()) { - int value = Utilities.parseInt(cursor.stringValue(0)); - hideMainStickersPack = value == 1; - } - cursor.dispose(); - - cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT data, date FROM stickers WHERE 1"); - ArrayList loadedUsers = new ArrayList<>(); + SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT data, date, hash FROM stickers_v2 WHERE 1"); if (cursor.next()) { ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0)); if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { - result = TLRPC.messages_AllStickers.TLdeserialize(data, data.readInt32(false), false); + if (newStickerArray == null) { + newStickerArray = new ArrayList<>(); + } + int count = data.readInt32(false); + for (int a = 0; a < count; a++) { + TLRPC.TL_messages_stickerSet stickerSet = TLRPC.TL_messages_stickerSet.TLdeserialize(data, data.readInt32(false), false); + newStickerArray.add(stickerSet); + } } date = cursor.intValue(1); + hash = cursor.stringValue(2); MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data); } cursor.dispose(); } catch (Exception e) { FileLog.e("tmessages", e); } - processLoadedStickers(result, true, date); + processLoadedStickers(newStickerArray, true, date, hash); } }); } else { TLRPC.TL_messages_getAllStickers req = new TLRPC.TL_messages_getAllStickers(); - req.hash = hash == null || force ? "" : hash; + req.hash = loadHash == null || force ? "" : loadHash; 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() { - processLoadedStickers((TLRPC.messages_AllStickers) response, false, (int) (System.currentTimeMillis() / 1000)); + if (response instanceof TLRPC.TL_messages_allStickers) { + final HashMap newStickerSets = new HashMap<>(); + final ArrayList newStickerArray = new ArrayList<>(); + final TLRPC.TL_messages_allStickers res = (TLRPC.TL_messages_allStickers) response; + + for (int a = 0; a < res.sets.size(); a++) { + final TLRPC.StickerSet stickerSet = res.sets.get(a); + + TLRPC.TL_messages_stickerSet oldSet = stickerSetsById.get(stickerSet.id); + if (oldSet != null && oldSet.set.hash == stickerSet.hash) { + oldSet.set.flags = stickerSet.flags; + newStickerSets.put(oldSet.set.id, oldSet); + newStickerArray.add(oldSet); + + if (newStickerSets.size() == res.sets.size()) { + processLoadedStickers(newStickerArray, false, (int) (System.currentTimeMillis() / 1000), res.hash); + } + continue; + } + + newStickerArray.add(null); + final int index = a; + + TLRPC.TL_messages_getStickerSet req = new TLRPC.TL_messages_getStickerSet(); + req.stickerset = new TLRPC.TL_inputStickerSetID(); + req.stickerset.id = stickerSet.id; + req.stickerset.access_hash = stickerSet.access_hash; + + ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(final TLObject response, final TLRPC.TL_error error) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + TLRPC.TL_messages_stickerSet res1 = (TLRPC.TL_messages_stickerSet) response; + newStickerArray.set(index, res1); + newStickerSets.put(stickerSet.id, res1); + if (newStickerSets.size() == res.sets.size()) { + processLoadedStickers(newStickerArray, false, (int) (System.currentTimeMillis() / 1000), res.hash); + } + } + }); + } + }); + } + } else { + processLoadedStickers(null, false, (int) (System.currentTimeMillis() / 1000), error == null ? "" : null); + } } }); } @@ -143,18 +199,26 @@ public class StickersQuery { } } - private static void putStickersToCache(final TLRPC.TL_messages_allStickers stickers) { + private static void putStickersToCache(final ArrayList stickers, final int date, final String hash) { MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { @Override public void run() { try { - SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO stickers VALUES(?, ?, ?)"); + SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO stickers_v2 VALUES(?, ?, ?, ?)"); state.requery(); - ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(stickers.getObjectSize()); - stickers.serializeToStream(data); + int size = 4; + for (int a = 0; a < stickers.size(); a++) { + size += stickers.get(a).getObjectSize(); + } + ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(size); + data.writeInt32(stickers.size()); + for (int a = 0; a < stickers.size(); a++) { + stickers.get(a).serializeToStream(data); + } state.bindInteger(1, 1); state.bindByteBuffer(2, data.buffer); - state.bindInteger(3, (int) (System.currentTimeMillis() / 1000)); + state.bindInteger(3, date); + state.bindString(4, hash); state.step(); MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data); state.dispose(); @@ -177,7 +241,7 @@ public class StickersQuery { return -1; } - private static void processLoadedStickers(final TLRPC.messages_AllStickers res, final boolean cache, final int date) { + private static void processLoadedStickers(final ArrayList res, final boolean cache, final int date, final String hash) { AndroidUtilities.runOnUIThread(new Runnable() { @Override public void run() { @@ -188,104 +252,77 @@ public class StickersQuery { Utilities.stageQueue.postRunnable(new Runnable() { @Override public void run() { - if ((res == null || date < (int) (System.currentTimeMillis() / 1000 - 60 * 60)) && cache) { + if (cache && (res == null || date < (int) (System.currentTimeMillis() / 1000 - 60 * 60)) || !cache && res == null && hash == null) { AndroidUtilities.runOnUIThread(new Runnable() { @Override public void run() { + if (res != null && cache && hash != null) { + loadHash = hash; + } loadStickers(false, false); } - }); + }, res == null && !cache ? 1000 : 0); if (res == null) { return; } } - if (res instanceof TLRPC.TL_messages_allStickers) { - HashMap documents = new HashMap<>(); - final HashMap> sets = new HashMap<>(); - final ArrayList allDocuments = new ArrayList<>(); - final HashMap stickersEmoji = new HashMap<>(); - for (TLRPC.Document document : res.documents) { - if (document == null) { + if (res != null) { + final ArrayList stickerSetsNew = new ArrayList<>(); + final HashMap stickerSetsByIdNew = new HashMap<>(); + final HashMap stickersByEmojiNew = new HashMap<>(); + final HashMap stickersByIdNew = new HashMap<>(); + final HashMap> allStickersNew = new HashMap<>(); + + for (int a = 0; a < res.size(); a++) { + TLRPC.TL_messages_stickerSet stickerSet = res.get(a); + if (stickerSet == null) { continue; } + stickerSetsNew.add(stickerSet); + stickerSetsByIdNew.put(stickerSet.set.id, stickerSet); - documents.put(document.id, document); - long setId = getStickerSetId(document); - if (setId != -1 || setId == -1 && !hideMainStickersPack) { - allDocuments.add(document); - } - ArrayList docs = sets.get(setId); - if (docs == null) { - docs = new ArrayList<>(); - sets.put(setId, docs); - if (setId == -1) { - boolean contain = false; - for (TLRPC.TL_stickerSet set : res.sets) { - if (set.id == setId) { - contain = true; - break; - } - } - if (!contain) { - TLRPC.TL_stickerSet set = new TLRPC.TL_stickerSet(); - set.title = set.short_name = ""; - set.id = -1; - res.sets.add(0, set); - } + for (int b = 0; b < stickerSet.documents.size(); b++) { + TLRPC.Document document = stickerSet.documents.get(b); + if (document == null || document instanceof TLRPC.TL_documentEmpty) { + continue; } + stickersByIdNew.put(document.id, document); } - docs.add(document); - } - final HashMap> result = new HashMap<>(); - for (TLRPC.TL_stickerPack stickerPack : res.packs) { - if (stickerPack != null && stickerPack.emoticon != null) { - stickerPack.emoticon = stickerPack.emoticon.replace("\uFE0F", ""); - ArrayList arrayList = result.get(stickerPack.emoticon); - for (Long id : stickerPack.documents) { - if (!stickersEmoji.containsKey(id)) { - stickersEmoji.put(id, stickerPack.emoticon); + if ((stickerSet.set.flags & 2) == 0) { + for (int b = 0; b < stickerSet.packs.size(); b++) { + TLRPC.TL_stickerPack stickerPack = stickerSet.packs.get(b); + if (stickerPack == null || stickerPack.emoticon == null) { + continue; } - TLRPC.Document document = documents.get(id); - if (document != null) { - long setId = getStickerSetId(document); - if (setId == -1 && hideMainStickersPack) { - continue; + stickerPack.emoticon = stickerPack.emoticon.replace("\uFE0F", ""); + ArrayList arrayList = allStickersNew.get(stickerPack.emoticon); + if (arrayList == null) { + arrayList = new ArrayList<>(); + allStickersNew.put(stickerPack.emoticon, arrayList); + } + for (int c = 0; c < stickerPack.documents.size(); c++) { + Long id = stickerPack.documents.get(c); + if (!stickersByEmojiNew.containsKey(id)) { + stickersByEmojiNew.put(id, stickerPack.emoticon); } - - if (arrayList == null) { - arrayList = new ArrayList<>(); - result.put(stickerPack.emoticon, arrayList); - } - arrayList.add(document); + arrayList.add(stickersByIdNew.get(id)); } } } } - Collections.sort(allDocuments, new Comparator() { - @Override - public int compare(TLRPC.Document lhs, TLRPC.Document rhs) { - long lid = getStickerSetId(lhs); - long rid = getStickerSetId(rhs); - if (lid < rid) { - return -1; - } else if (lid > rid) { - return 1; - } - return 0; - } - }); + if (!cache) { - putStickersToCache((TLRPC.TL_messages_allStickers) res); + putStickersToCache(stickerSetsNew, date, hash); } AndroidUtilities.runOnUIThread(new Runnable() { @Override public void run() { - stickerSets = res.sets; - allStickers = result; - stickers = allDocuments; - stickersBySets = sets; - stickersByEmoji = stickersEmoji; - hash = res.hash; + stickersById = stickersByIdNew; + stickerSetsById = stickerSetsByIdNew; + stickerSets = stickerSetsNew; + allStickers = allStickersNew; + stickersByEmoji = stickersByEmojiNew; + loadHash = hash; loadDate = date; NotificationCenter.getInstance().postNotificationName(NotificationCenter.stickersDidLoaded); } @@ -323,7 +360,7 @@ public class StickersQuery { if (error == null) { final TLRPC.TL_messages_stickerSet res = (TLRPC.TL_messages_stickerSet) response; - StickersAlert alert = new StickersAlert(fragment.getParentActivity(), res.set, res.documents); + StickersAlert alert = new StickersAlert(fragment.getParentActivity(), res); if (res.set == null || !StickersQuery.isStickerPackInstalled(res.set.id)) { alert.setButton(AlertDialog.BUTTON_POSITIVE, LocaleController.getString("AddStickers", R.string.AddStickers), new DialogInterface.OnClickListener() { @Override @@ -354,7 +391,7 @@ public class StickersQuery { alert.setButton(AlertDialog.BUTTON_NEUTRAL, LocaleController.getString("StickersRemove", R.string.StickersRemove), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - removeStickersSet(fragment.getParentActivity(), res.set); + removeStickersSet(fragment.getParentActivity(), res.set, 0); } }); } @@ -385,53 +422,54 @@ public class StickersQuery { progressDialog.show(); } - public static void setHideMainStickersPack(final boolean value) { - hideMainStickersPack = value; - MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() { - @Override - public void run() { - try { - SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO keyvalue VALUES(?, ?)"); - state.requery(); - state.bindString(1, "hide_stickers"); - state.bindString(2, value ? "1" : "0"); - state.step(); - state.dispose(); - } catch (Exception e) { - FileLog.e("tmessages", e); - } + public static void removeStickersSet(final Context context, TLRPC.StickerSet stickerSet, int hide) { + TLRPC.TL_inputStickerSetID stickerSetID = new TLRPC.TL_inputStickerSetID(); + stickerSetID.access_hash = stickerSet.access_hash; + stickerSetID.id = stickerSet.id; + if (hide != 0) { + if (hide == 1) { + stickerSet.flags |= 2; + } else { + stickerSet.flags &= ~2; } - }); - } - - public static void removeStickersSet(final Context context, TLRPC.TL_stickerSet stickerSet) { - TLRPC.TL_messages_uninstallStickerSet req = new TLRPC.TL_messages_uninstallStickerSet(); - req.stickerset = new TLRPC.TL_inputStickerSetID(); - req.stickerset.access_hash = stickerSet.access_hash; - req.stickerset.id = stickerSet.id; - ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { - @Override - public void run(TLObject response, final TLRPC.TL_error error) { - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - try { - if (error == null) { - Toast.makeText(context, LocaleController.getString("StickersRemoved", R.string.StickersRemoved), Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(context, LocaleController.getString("ErrorOccurred", R.string.ErrorOccurred), Toast.LENGTH_SHORT).show(); - } - } catch (Exception e) { - FileLog.e("tmessages", e); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.stickersDidLoaded); + TLRPC.TL_messages_installStickerSet req = new TLRPC.TL_messages_installStickerSet(); + req.stickerset = stickerSetID; + req.disabled = hide == 1; + ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, final TLRPC.TL_error error) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + loadStickers(false, true); } - loadStickers(false, true); - } - }); - } - }); - } - - public static boolean getHideMainStickersPack() { - return hideMainStickersPack; + }, 1000); + } + }); + } else { + TLRPC.TL_messages_uninstallStickerSet req = new TLRPC.TL_messages_uninstallStickerSet(); + req.stickerset = stickerSetID; + ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, final TLRPC.TL_error error) { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + try { + if (error == null) { + Toast.makeText(context, LocaleController.getString("StickersRemoved", R.string.StickersRemoved), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(context, LocaleController.getString("ErrorOccurred", R.string.ErrorOccurred), Toast.LENGTH_SHORT).show(); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + loadStickers(false, true); + } + }); + } + }); + } } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/support/widget/RecyclerView.java b/TMessagesProj/src/main/java/org/telegram/android/support/widget/RecyclerView.java index c5a0fe725..f6a17a1d8 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/support/widget/RecyclerView.java +++ b/TMessagesProj/src/main/java/org/telegram/android/support/widget/RecyclerView.java @@ -5030,7 +5030,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView { * @see #notifyItemRangeInserted(int, int) * @see #notifyItemRangeRemoved(int, int) */ - public final void notifyDataSetChanged() { + public void notifyDataSetChanged() { mObservable.notifyChanged(); } @@ -5045,7 +5045,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView { * * @see #notifyItemRangeChanged(int, int) */ - public final void notifyItemChanged(int position) { + public void notifyItemChanged(int position) { mObservable.notifyItemRangeChanged(position, 1); } @@ -5062,7 +5062,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView { * * @see #notifyItemChanged(int) */ - public final void notifyItemRangeChanged(int positionStart, int itemCount) { + public void notifyItemRangeChanged(int positionStart, int itemCount) { mObservable.notifyItemRangeChanged(positionStart, itemCount); } @@ -5079,7 +5079,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView { * * @see #notifyItemRangeInserted(int, int) */ - public final void notifyItemInserted(int position) { + public void notifyItemInserted(int position) { mObservable.notifyItemRangeInserted(position, 1); } @@ -5094,7 +5094,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView { * @param fromPosition Previous position of the item. * @param toPosition New position of the item. */ - public final void notifyItemMoved(int fromPosition, int toPosition) { + public void notifyItemMoved(int fromPosition, int toPosition) { mObservable.notifyItemMoved(fromPosition, toPosition); } @@ -5113,7 +5113,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView { * * @see #notifyItemInserted(int) */ - public final void notifyItemRangeInserted(int positionStart, int itemCount) { + public void notifyItemRangeInserted(int positionStart, int itemCount) { mObservable.notifyItemRangeInserted(positionStart, itemCount); } @@ -5130,7 +5130,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView { * * @see #notifyItemRangeRemoved(int, int) */ - public final void notifyItemRemoved(int position) { + public void notifyItemRemoved(int position) { mObservable.notifyItemRangeRemoved(position, 1); } @@ -5147,7 +5147,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView { * @param positionStart Previous position of the first item that was removed * @param itemCount Number of items removed from the data set */ - public final void notifyItemRangeRemoved(int positionStart, int itemCount) { + public void notifyItemRangeRemoved(int positionStart, int itemCount) { mObservable.notifyItemRangeRemoved(positionStart, itemCount); } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java index 38c0e7ca0..15c858b24 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java @@ -10,7 +10,7 @@ package org.telegram.messenger; public class BuildVars { public static boolean DEBUG_VERSION = false; - public static int BUILD_VERSION = 542; + public static int BUILD_VERSION = 572; public static int APP_ID = 0; //obtain your own APP_ID at https://core.telegram.org/api/obtaining_api_id public static String APP_HASH = ""; //obtain your own APP_HASH at https://core.telegram.org/api/obtaining_api_id public static String HOCKEY_APP_HASH = "your-hockeyapp-api-key-here"; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java b/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java index 658896f07..928d5e572 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java @@ -33,6 +33,7 @@ import java.net.NetworkInterface; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; @@ -132,7 +133,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. if (lastPauseTime != 0 && lastPauseTime < currentTime - nextSleepTimeout) { boolean dontSleep = !pushMessagesReceived; if (!dontSleep) { - for (RPCRequest request : runningRequests) { + for (int a = 0; a < runningRequests.size(); a++) { + RPCRequest request = runningRequests.get(a); if (request.rawRequest instanceof TLRPC.TL_get_future_salts) { dontSleep = true; } else if (request.retryCount < 10 && (request.runningStartTime + 60 > (int) (currentTime / 1000)) && ((request.flags & RPCRequest.RPCRequestClassDownloadMedia) != 0 || (request.flags & RPCRequest.RPCRequestClassUploadMedia) != 0)) { @@ -142,7 +144,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } } if (!dontSleep) { - for (RPCRequest request : requestQueue) { + for (int a = 0; a < requestQueue.size(); a++) { + RPCRequest request = requestQueue.get(a); if (request.rawRequest instanceof TLRPC.TL_get_future_salts) { dontSleep = true; } else if ((request.flags & RPCRequest.RPCRequestClassDownloadMedia) != 0 || (request.flags & RPCRequest.RPCRequestClassUploadMedia) != 0) { @@ -190,7 +193,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. processRequestQueue(0, 0); } else { boolean notFound = true; - for (Action actor : actionQueue) { + for (int a = 0; a < actionQueue.size(); a++) { + Action actor = actionQueue.get(a); if (actor instanceof HandshakeAction) { HandshakeAction eactor = (HandshakeAction) actor; if (eactor.datacenter.datacenterId == datacenter.datacenterId) { @@ -536,7 +540,9 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. continue; } FileLog.e("tmessages", "valid interface: " + networkInterface); - for (InterfaceAddress address : networkInterface.getInterfaceAddresses()) { + List interfaceAddresses = networkInterface.getInterfaceAddresses(); + for (int a = 0; a < interfaceAddresses.size(); a++) { + InterfaceAddress address = interfaceAddresses.get(a); InetAddress inetAddress = address.getAddress(); if (BuildVars.DEBUG_VERSION) { FileLog.e("tmessages", "address: " + inetAddress.getHostAddress()); @@ -553,20 +559,22 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. FileLog.e("tmessages", e); } } - if (Build.VERSION.SDK_INT < 50) { + if (Build.VERSION.SDK_INT < 19) { return false; } try { NetworkInterface networkInterface; Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); + boolean hasIpv4 = false; + boolean hasIpv6 = false; while (networkInterfaces.hasMoreElements()) { networkInterface = networkInterfaces.nextElement(); if (!networkInterface.isUp() || networkInterface.isLoopback()) { continue; } - boolean hasIpv4 = false; - boolean hasIpv6 = false; - for (InterfaceAddress address : networkInterface.getInterfaceAddresses()) { + List interfaceAddresses = networkInterface.getInterfaceAddresses(); + for (int a = 0; a < interfaceAddresses.size(); a++) { + InterfaceAddress address = interfaceAddresses.get(a); InetAddress inetAddress = address.getAddress(); if (inetAddress.isLinkLocalAddress() || inetAddress.isLoopbackAddress() || inetAddress.isMulticastAddress()) { continue; @@ -574,12 +582,15 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. if (inetAddress instanceof Inet6Address) { hasIpv6 = true; } else if (inetAddress instanceof Inet4Address) { - hasIpv4 = true; + String addrr = inetAddress.getHostAddress(); + if (!addrr.startsWith("192.0.0.")) { + hasIpv4 = true; + } } } - if (!hasIpv4 && hasIpv6) { - return true; - } + } + if (!hasIpv4 && hasIpv6) { + return true; } } catch (Throwable e) { FileLog.e("tmessages", e); @@ -609,8 +620,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. if (!sessions.isEmpty()) { SerializedData data = new SerializedData(sessions.size() * 8 + 4); data.writeInt32(sessions.size()); - for (long session : sessions) { - data.writeInt64(session); + for (int a = 0; a < sessions.size(); a++) { + data.writeInt64(sessions.get(a)); } editor.putString("sessionsToDestroy", Base64.encodeToString(data.toByteArray(), Base64.DEFAULT)); data.cleanup(); @@ -648,7 +659,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } void clearRequestsForRequestClass(int requestClass, Datacenter datacenter) { - for (RPCRequest request : runningRequests) { + for (int a = 0; a < runningRequests.size(); a++) { + RPCRequest request = runningRequests.get(a); Datacenter dcenter = datacenterWithId(request.runningDatacenterId); if ((request.flags & requestClass) != 0 && dcenter != null && dcenter.datacenterId == datacenter.datacenterId) { request.runningMessageId = 0; @@ -736,7 +748,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. public void cancelRpcsForClassGuid(int guid) { ArrayList requests = requestsByGuids.get(guid); if (requests != null) { - for (Long request : requests) { + for (int a = 0; a < requests.size(); a++) { + Long request = requests.get(a); cancelRpc(request, true); } requestsByGuids.remove(guid); @@ -858,7 +871,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. lastDcUpdateTime = (int) (System.currentTimeMillis() / 1000) - DC_UPDATE_TIME + updateIn; ArrayList datacentersArr = new ArrayList<>(); HashMap datacenterMap = new HashMap<>(); - for (TLRPC.TL_dcOption datacenterDesc : config.dc_options) { + for (int a = 0; a < config.dc_options.size(); a++) { + TLRPC.TL_dcOption datacenterDesc = config.dc_options.get(a); Datacenter existing = datacenterMap.get(datacenterDesc.id); if (existing == null) { existing = new Datacenter(); @@ -870,7 +884,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } if (!datacentersArr.isEmpty()) { - for (Datacenter datacenter : datacentersArr) { + for (int a = 0; a < datacentersArr.size(); a++) { + Datacenter datacenter = datacentersArr.get(a); Datacenter exist = datacenterWithId(datacenter.datacenterId); if (exist == null) { datacenters.put(datacenter.datacenterId, datacenter); @@ -1281,7 +1296,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. if (genericConnection != null && genericConnection.channelToken != 0) { Datacenter currentDatacenter = datacenterWithId(currentDatacenterId); - for (Long it : sessionsToDestroy) { + for (int a = 0; a < sessionsToDestroy.size(); a++) { + Long it = sessionsToDestroy.get(a); if (destroyingSessions.contains(it)) { continue; } @@ -1304,7 +1320,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. int uploadRunningRequestCount = 0; int downloadRunningRequestCount = 0; - for (RPCRequest request : runningRequests) { + for (int a = 0; a < runningRequests.size(); a++) { + RPCRequest request = runningRequests.get(a); if ((request.flags & RPCRequest.RPCRequestClassGeneric) != 0) { genericRunningRequestCount++; } else if ((request.flags & RPCRequest.RPCRequestClassUploadMedia) != 0) { @@ -1481,7 +1498,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. boolean hasSendMessage = false; ArrayList arr = genericMessagesToDatacenters.get(iter); - for (NetworkMessage networkMessage : arr) { + for (int b = 0; b < arr.size(); b++) { + NetworkMessage networkMessage = arr.get(b); TLRPC.TL_protoMessage message = networkMessage.protoMessage; Object rawRequest = networkMessage.rawRequest; @@ -1502,7 +1520,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. scannedPreviousRequests = true; ArrayList currentRequests = new ArrayList<>(); - for (NetworkMessage currentNetworkMessage : arr) { + for (int a = 0; a < arr.size(); a++) { + NetworkMessage currentNetworkMessage = arr.get(a); TLRPC.TL_protoMessage currentMessage = currentNetworkMessage.protoMessage; Object currentRawRequest = currentNetworkMessage.rawRequest; @@ -1519,7 +1538,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } long maxRequestId = 0; - for (RPCRequest request : runningRequests) { + for (int a = 0; a < runningRequests.size(); a++) { + RPCRequest request = runningRequests.get(a); if (request.rawRequest instanceof TLRPC.TL_messages_sendMessage || request.rawRequest instanceof TLRPC.TL_messages_sendMedia || request.rawRequest instanceof TLRPC.TL_messages_forwardMessages || @@ -1564,10 +1584,12 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. updateDcSettings(0); } - for (int num : neededDatacenterIds) { + for (int a = 0; a < neededDatacenterIds.size(); a++) { + int num = neededDatacenterIds.get(a); if (num != movingToDatacenterId) { boolean notFound = true; - for (Action actor : actionQueue) { + for (int b = 0; b < actionQueue.size(); b++) { + Action actor = actionQueue.get(b); if (actor instanceof HandshakeAction) { HandshakeAction eactor = (HandshakeAction) actor; if (eactor.datacenter.datacenterId == num) { @@ -1584,10 +1606,12 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } } - for (int num : unauthorizedDatacenterIds) { + for (int a = 0; a < unauthorizedDatacenterIds.size(); a++) { + int num = unauthorizedDatacenterIds.get(a); if (num != currentDatacenterId && num != movingToDatacenterId && UserConfig.isClientActivated()) { boolean notFound = true; - for (Action actor : actionQueue) { + for (int b = 0; b < actionQueue.size(); b++) { + Action actor = actionQueue.get(b); if (actor instanceof ExportAuthorizationAction) { ExportAuthorizationAction eactor = (ExportAuthorizationAction) actor; if (eactor.datacenter.datacenterId == num) { @@ -1677,7 +1701,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. if (reportAck && quickAckId.size() != 0) { ArrayList requestIds = new ArrayList<>(); - for (NetworkMessage message : messagesToSend) { + for (int b = 0; b < messagesToSend.size(); b++) { + NetworkMessage message = messagesToSend.get(b); if (message.requestId != 0) { requestIds.add(message.requestId); } @@ -1756,7 +1781,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. ArrayList containerMessages = new ArrayList<>(messages.size()); - for (NetworkMessage networkMessage : messages) { + for (int a = 0; a < messages.size(); a++) { + NetworkMessage networkMessage = messages.get(a); TLRPC.TL_protoMessage message = networkMessage.protoMessage; containerMessages.add(message); if (BuildVars.DEBUG_VERSION) { @@ -1841,7 +1867,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. Utilities.stageQueue.postRunnable(new Runnable() { @Override public void run() { - for (RPCRequest request : requestQueue) { + for (int a = 0; a < requestQueue.size(); a++) { + RPCRequest request = requestQueue.get(a); if (request.rawRequest instanceof TLRPC.TL_get_future_salts) { Datacenter requestDatacenter = datacenterWithId(request.runningDatacenterId); if (requestDatacenter.datacenterId == datacenter.datacenterId) { @@ -1850,7 +1877,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } } - for (RPCRequest request : runningRequests) { + for (int a = 0; a < runningRequests.size(); a++) { + RPCRequest request = runningRequests.get(a); if (request.rawRequest instanceof TLRPC.TL_get_future_salts) { Datacenter requestDatacenter = datacenterWithId(request.runningDatacenterId); if (requestDatacenter.datacenterId == datacenter.datacenterId) { @@ -1881,7 +1909,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. Utilities.stageQueue.postRunnable(new Runnable() { @Override public void run() { - for (RPCRequest request : runningRequests) { + for (int a = 0; a < runningRequests.size(); a++) { + RPCRequest request = runningRequests.get(a); if (requestMsgId == request.runningMessageId) { request.confirmed = true; } @@ -1991,7 +2020,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. serverSaltDesc.value = serverSalt; datacenter.addServerSalt(serverSaltDesc); - for (RPCRequest request : runningRequests) { + for (int a = 0; a < runningRequests.size(); a++) { + RPCRequest request = runningRequests.get(a); Datacenter dcenter = datacenterWithId(request.runningDatacenterId); if (request.runningMessageId < newSession.first_msg_id && (request.flags & connection.transportRequestClass) != 0 && dcenter != null && dcenter.datacenterId == datacenter.datacenterId) { request.runningMessageId = 0; @@ -2021,7 +2051,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. }*/ TLRPC.TL_msg_container messageContainer = (TLRPC.TL_msg_container) message; - for (TLRPC.TL_protoMessage innerMessage : messageContainer.messages) { + for (int a = 0; a < messageContainer.messages.size(); a++) { + TLRPC.TL_protoMessage innerMessage = messageContainer.messages.get(a); long innerMessageId = innerMessage.msg_id; if (innerMessage.seqno % 2 != 0) { connection.addMessageToConfirm(innerMessageId); @@ -2060,8 +2091,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. itemsToDelete.add(pid); } } - for (Long pid : itemsToDelete) { - pingIdToDate.remove(pid); + for (int a = 0; a < itemsToDelete.size(); a++) { + pingIdToDate.remove(itemsToDelete.get(a)); } } else { FileLog.e("tmessages", "received push ping"); @@ -2070,7 +2101,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } else if (message instanceof TLRPC.TL_futuresalts) { TLRPC.TL_futuresalts futureSalts = (TLRPC.TL_futuresalts) message; long requestMid = futureSalts.req_msg_id; - for (RPCRequest request : runningRequests) { + for (int a = 0; a < runningRequests.size(); a++) { + RPCRequest request = runningRequests.get(a); if (request.respondsToMessageId(requestMid)) { if (request.completionBlock != null) { request.completionBlock.run(futureSalts, null); @@ -2090,7 +2122,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. ArrayList lst = new ArrayList<>(); lst.addAll(sessionsToDestroy); destroyingSessions.remove(res.session_id); - for (long session : lst) { + for (int a = 0; a < lst.size(); a++) { + long session = lst.get(a); if (session == res.session_id) { sessionsToDestroy.remove(session); FileLog.d("tmessages", String.format("Destroyed session %d (%s)", res.session_id, res instanceof TLRPC.TL_destroy_session_ok ? "ok" : "not found")); @@ -2114,7 +2147,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. migrateErrors.add("NETWORK_MIGRATE_"); migrateErrors.add("PHONE_MIGRATE_"); migrateErrors.add("USER_MIGRATE_"); - for (String possibleError : migrateErrors) { + for (int a = 0; a < migrateErrors.size(); a++) { + String possibleError = migrateErrors.get(a); if (errorMessage.contains(possibleError)) { String errorMsg = errorMessage.replace(possibleError, ""); @@ -2152,7 +2186,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. if (!ignoreResult) { boolean found = false; - for (RPCRequest request : runningRequests) { + for (int a = 0; a < runningRequests.size(); a++) { + RPCRequest request = runningRequests.get(a); if (request.respondsToMessageId(resultMid)) { found = true; @@ -2356,7 +2391,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } long resultMid = ((TLRPC.TL_bad_server_salt) message).bad_msg_id; if (resultMid != 0) { - for (RPCRequest request : runningRequests) { + for (int a = 0; a < runningRequests.size(); a++) { + RPCRequest request = runningRequests.get(a); if ((request.flags & RPCRequest.RPCRequestClassDownloadMedia) == 0) { continue; } @@ -2389,7 +2425,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. boolean confirm = true; if (detailedInfo instanceof TLRPC.TL_msg_detailed_info) { - for (RPCRequest request : runningRequests) { + for (int a = 0; a < runningRequests.size(); a++) { + RPCRequest request = runningRequests.get(a); if (request.respondsToMessageId(detailedInfo.msg_id)) { if (request.completed) { break; @@ -2486,8 +2523,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. itemsToDelete.add(pid); } } - for (Long pid : itemsToDelete) { - pingIdToDate.remove(pid); + for (int a = 0; a < itemsToDelete.size(); a++) { + pingIdToDate.remove(itemsToDelete.get(a)); } } } @@ -2605,7 +2642,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. public void tcpConnectionQuiackAckReceived(TcpConnection connection, int ack) { ArrayList arr = quickAckIdToRequestIds.get(ack); if (arr != null) { - for (RPCRequest request : runningRequests) { + for (int a = 0; a < runningRequests.size(); a++) { + RPCRequest request = runningRequests.get(a); if (arr.contains(request.token)) { if (request.quickAckBlock != null) { request.quickAckBlock.quickAck(); @@ -2699,14 +2737,6 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. int messageSeqNo = data.readInt32(false); int messageLength = data.readInt32(false); - if (connection.isMessageIdProcessed(messageId)) { - doNotProcess = true; - } - - if (messageSeqNo % 2 != 0) { - connection.addMessageToConfirm(messageId); - } - byte[] realMessageKeyFull = Utilities.computeSHA1(data.buffer, 24, Math.min(messageLength + 32 + 24, data.limit())); if (realMessageKeyFull == null) { return; @@ -2720,6 +2750,14 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. return; } + if (connection.isMessageIdProcessed(messageId)) { + doNotProcess = true; + } + + if (messageSeqNo % 2 != 0) { + connection.addMessageToConfirm(messageId); + } + if (!doNotProcess) { TLObject message = deserialize(getRequestWithMessageId(messageId), data, true); if (message != null) { @@ -2776,7 +2814,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } public TLObject getRequestWithMessageId(long msgId) { - for (RPCRequest request : runningRequests) { + for (int a = 0; a < runningRequests.size(); a++) { + RPCRequest request = runningRequests.get(a); if (msgId == request.runningMessageId) { return request.rawRequest; } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/HandshakeAction.java b/TMessagesProj/src/main/java/org/telegram/messenger/HandshakeAction.java index eb225c09c..7043dca59 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/HandshakeAction.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/HandshakeAction.java @@ -297,6 +297,9 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti } } else if (message instanceof TLRPC.Server_DH_Params) { if (message instanceof TLRPC.TL_server_DH_params_ok) { + if (authNewNonce == null) { + return; + } TLRPC.TL_server_DH_params_ok serverDhParams = (TLRPC.TL_server_DH_params_ok)message; SerializedData tmpAesKey = new SerializedData(); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java b/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java index 32d39df40..5de616dc4 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java @@ -13,13 +13,33 @@ import java.util.ArrayList; @SuppressWarnings("unchecked") public class TLRPC { - public static final int MESSAGE_FLAG_UNREAD = 1; - public static final int MESSAGE_FLAG_OUT = 2; - public static final int MESSAGE_FLAG_FWD = 4; - public static final int MESSAGE_FLAG_REPLY = 8; - public static final int MESSAGE_FLAG_MENTION = 16; - public static final int MESSAGE_FLAG_CONTENT_UNREAD = 32; - public static final int LAYER = 30; + public static final int USER_FLAG_ACCESS_HASH = 0x00000001; + public static final int USER_FLAG_FIRST_NAME = 0x00000002; + public static final int USER_FLAG_LAST_NAME = 0x00000004; + public static final int USER_FLAG_USERNAME = 0x00000008; + public static final int USER_FLAG_PHONE = 0x00000010; + public static final int USER_FLAG_PHOTO = 0x00000020; + public static final int USER_FLAG_STATUS = 0x00000040; + public static final int USER_FLAG_UNUSED = 0x00000080; + public static final int USER_FLAG_UNUSED2 = 0x00000100; + public static final int USER_FLAG_UNUSED3 = 0x00000200; + public static final int USER_FLAG_SELF = 0x00000400; + public static final int USER_FLAG_CONTACT = 0x00000800; + public static final int USER_FLAG_MUTUAL_CONTACT = 0x00001000; + public static final int USER_FLAG_DELETED = 0x00002000; + public static final int USER_FLAG_BOT = 0x00004000; + public static final int USER_FLAG_BOT_READING_HISTORY = 0x00008000; + public static final int USER_FLAG_BOT_CANT_JOIN_GROUP = 0x00010000; + + + public static final int MESSAGE_FLAG_UNREAD = 0x00000001; + public static final int MESSAGE_FLAG_OUT = 0x00000002; + public static final int MESSAGE_FLAG_FWD = 0x00000004; + public static final int MESSAGE_FLAG_REPLY = 0x00000008; + public static final int MESSAGE_FLAG_MENTION = 0x00000010; + public static final int MESSAGE_FLAG_CONTENT_UNREAD = 0x00000020; + + public static final int LAYER = 32; public static class TL_inputEncryptedChat extends TLObject { public static int constructor = 0xf141b5e1; @@ -555,7 +575,7 @@ public class TLRPC { public static class TL_messages_stickerSet extends TLObject { public static int constructor = 0xb60a24a6; - public TL_stickerSet set; + public StickerSet set; public ArrayList packs = new ArrayList<>(); public ArrayList documents = new ArrayList<>(); @@ -573,7 +593,7 @@ public class TLRPC { } public void readParams(AbsSerializedData stream, boolean exception) { - set = TL_stickerSet.TLdeserialize(stream, stream.readInt32(exception), exception); + set = StickerSet.TLdeserialize(stream, stream.readInt32(exception), exception); int magic = stream.readInt32(exception); if (magic != 0x1cb5c415) { if (exception) { @@ -655,6 +675,53 @@ public class TLRPC { } } + public static class TL_keyboardButtonRow extends TLObject { + public static int constructor = 0x77608b83; + + public ArrayList buttons = new ArrayList<>(); + + public static TL_keyboardButtonRow TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { + if (TL_keyboardButtonRow.constructor != constructor) { + if (exception) { + throw new RuntimeException(String.format("can't parse magic %x in TL_keyboardButtonRow", constructor)); + } else { + return null; + } + } + TL_keyboardButtonRow result = new TL_keyboardButtonRow(); + result.readParams(stream, exception); + return result; + } + + public void readParams(AbsSerializedData stream, boolean exception) { + int magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + int count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + TL_keyboardButton object = TL_keyboardButton.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + buttons.add(object); + } + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(0x1cb5c415); + int count = buttons.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + buttons.get(a).serializeToStream(stream); + } + } + } + public static class InputDocument extends TLObject { public long id; public long access_hash; @@ -704,10 +771,86 @@ public class TLRPC { } } - public static class TL_auth_authorization extends TLObject { - public static int constructor = 0xf6b673a4; + public static class BotInfo extends TLObject { + public int user_id; + public int version; + public String share_text; + public String description; + public ArrayList commands = new ArrayList<>(); + + public static BotInfo TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { + BotInfo result = null; + switch(constructor) { + case 0xbb2e37ce: + result = new TL_botInfoEmpty(); + break; + case 0x9cf585d: + result = new TL_botInfo(); + break; + } + if (result == null && exception) { + throw new RuntimeException(String.format("can't parse magic %x in BotInfo", constructor)); + } + if (result != null) { + result.readParams(stream, exception); + } + return result; + } + } + + public static class TL_botInfoEmpty extends BotInfo { + public static int constructor = 0xbb2e37ce; + + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + } + } + + public static class TL_botInfo extends BotInfo { + public static int constructor = 0x9cf585d; + + + public void readParams(AbsSerializedData stream, boolean exception) { + user_id = stream.readInt32(exception); + version = stream.readInt32(exception); + share_text = stream.readString(exception); + description = stream.readString(exception); + int magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + int count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + TL_botCommand object = TL_botCommand.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + commands.add(object); + } + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(user_id); + stream.writeInt32(version); + stream.writeString(share_text); + stream.writeString(description); + stream.writeInt32(0x1cb5c415); + int count = commands.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + commands.get(a).serializeToStream(stream); + } + } + } + + public static class TL_auth_authorization extends TLObject { + public static int constructor = 0xff036af1; - public int expires; public User user; public static TL_auth_authorization TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { @@ -724,13 +867,11 @@ public class TLRPC { } public void readParams(AbsSerializedData stream, boolean exception) { - expires = stream.readInt32(exception); user = User.TLdeserialize(stream, stream.readInt32(exception), exception); } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); - stream.writeInt32(expires); user.serializeToStream(stream); } } @@ -1964,15 +2105,14 @@ public class TLRPC { } public static class TL_userFull extends TLObject { - public static int constructor = 0x771095da; + public static int constructor = 0x5a89ac5b; public User user; public TL_contacts_link link; public Photo profile_photo; public PeerNotifySettings notify_settings; public boolean blocked; - public String real_first_name; - public String real_last_name; + public BotInfo bot_info; public static TL_userFull TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { if (TL_userFull.constructor != constructor) { @@ -1993,8 +2133,7 @@ public class TLRPC { profile_photo = Photo.TLdeserialize(stream, stream.readInt32(exception), exception); notify_settings = PeerNotifySettings.TLdeserialize(stream, stream.readInt32(exception), exception); blocked = stream.readBool(exception); - real_first_name = stream.readString(exception); - real_last_name = stream.readString(exception); + bot_info = BotInfo.TLdeserialize(stream, stream.readInt32(exception), exception); } public void serializeToStream(AbsSerializedData stream) { @@ -2004,8 +2143,7 @@ public class TLRPC { profile_photo.serializeToStream(stream); notify_settings.serializeToStream(stream); stream.writeBool(blocked); - stream.writeString(real_first_name); - stream.writeString(real_last_name); + bot_info.serializeToStream(stream); } } @@ -2980,30 +3118,32 @@ public class TLRPC { public int id; public String first_name; public String last_name; + public String username; public long access_hash; public String phone; public UserProfilePhoto photo; public UserStatus status; public boolean inactive; - public String username; + public int flags; + public int bot_info_version; public static User TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { User result = null; switch(constructor) { + case 0xcab35e18: + result = new TL_userContact_old2(); + break; case 0xf2fb8319: result = new TL_userContact_old(); break; case 0x720535ec: result = new TL_userSelf_old(); break; - case 0xcab35e18: - result = new TL_userContact(); - break; case 0x1c60e608: - result = new TL_userSelf(); + result = new TL_userSelf_old3(); break; - case 0x75cf7a8: - result = new TL_userForeign(); + case 0xd6016d7a: + result = new TL_userDeleted_old2(); break; case 0x200250ba: result = new TL_userEmpty(); @@ -3014,17 +3154,20 @@ public class TLRPC { case 0x5214c89d: result = new TL_userForeign_old(); break; - case 0xd9ccc4ef: - result = new TL_userRequest(); + case 0x75cf7a8: + result = new TL_userForeign_old2(); break; - case 0x7007b451: - result = new TL_userSelf_old2(); + case 0xd9ccc4ef: + result = new TL_userRequest_old2(); break; case 0xb29ad7cc: result = new TL_userDeleted_old(); break; - case 0xd6016d7a: - result = new TL_userDeleted(); + case 0x7007b451: + result = new TL_userSelf_old2(); + break; + case 0x22e49072: + result = new TL_user(); break; } if (result == null && exception) { @@ -3037,59 +3180,7 @@ public class TLRPC { } } - public static class TL_userContact_old extends TL_userContact { - public static int constructor = 0xf2fb8319; - - - public void readParams(AbsSerializedData stream, boolean exception) { - id = stream.readInt32(exception); - first_name = stream.readString(exception); - last_name = stream.readString(exception); - access_hash = stream.readInt64(exception); - phone = stream.readString(exception); - photo = UserProfilePhoto.TLdeserialize(stream, stream.readInt32(exception), exception); - status = UserStatus.TLdeserialize(stream, stream.readInt32(exception), exception); - } - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - stream.writeInt32(id); - stream.writeString(first_name); - stream.writeString(last_name); - stream.writeInt64(access_hash); - stream.writeString(phone); - photo.serializeToStream(stream); - status.serializeToStream(stream); - } - } - - public static class TL_userSelf_old extends TL_userSelf { - public static int constructor = 0x720535ec; - - - public void readParams(AbsSerializedData stream, boolean exception) { - id = stream.readInt32(exception); - first_name = stream.readString(exception); - last_name = stream.readString(exception); - phone = stream.readString(exception); - photo = UserProfilePhoto.TLdeserialize(stream, stream.readInt32(exception), exception); - status = UserStatus.TLdeserialize(stream, stream.readInt32(exception), exception); - inactive = stream.readBool(exception); - } - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - stream.writeInt32(id); - stream.writeString(first_name); - stream.writeString(last_name); - stream.writeString(phone); - photo.serializeToStream(stream); - status.serializeToStream(stream); - stream.writeBool(inactive); - } - } - - public static class TL_userContact extends User { + public static class TL_userContact_old2 extends User { public static int constructor = 0xcab35e18; @@ -3117,7 +3208,59 @@ public class TLRPC { } } - public static class TL_userSelf extends User { + public static class TL_userContact_old extends TL_userContact_old2 { + public static int constructor = 0xf2fb8319; + + + public void readParams(AbsSerializedData stream, boolean exception) { + id = stream.readInt32(exception); + first_name = stream.readString(exception); + last_name = stream.readString(exception); + access_hash = stream.readInt64(exception); + phone = stream.readString(exception); + photo = UserProfilePhoto.TLdeserialize(stream, stream.readInt32(exception), exception); + status = UserStatus.TLdeserialize(stream, stream.readInt32(exception), exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(id); + stream.writeString(first_name); + stream.writeString(last_name); + stream.writeInt64(access_hash); + stream.writeString(phone); + photo.serializeToStream(stream); + status.serializeToStream(stream); + } + } + + public static class TL_userSelf_old extends TL_userSelf_old2 { + public static int constructor = 0x720535ec; + + + public void readParams(AbsSerializedData stream, boolean exception) { + id = stream.readInt32(exception); + first_name = stream.readString(exception); + last_name = stream.readString(exception); + phone = stream.readString(exception); + photo = UserProfilePhoto.TLdeserialize(stream, stream.readInt32(exception), exception); + status = UserStatus.TLdeserialize(stream, stream.readInt32(exception), exception); + inactive = stream.readBool(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(id); + stream.writeString(first_name); + stream.writeString(last_name); + stream.writeString(phone); + photo.serializeToStream(stream); + status.serializeToStream(stream); + stream.writeBool(inactive); + } + } + + public static class TL_userSelf_old3 extends User { public static int constructor = 0x1c60e608; @@ -3143,8 +3286,8 @@ public class TLRPC { } } - public static class TL_userForeign extends User { - public static int constructor = 0x75cf7a8; + public static class TL_userDeleted_old2 extends User { + public static int constructor = 0xd6016d7a; public void readParams(AbsSerializedData stream, boolean exception) { @@ -3152,9 +3295,6 @@ public class TLRPC { first_name = stream.readString(exception); last_name = stream.readString(exception); username = stream.readString(exception); - access_hash = stream.readInt64(exception); - photo = UserProfilePhoto.TLdeserialize(stream, stream.readInt32(exception), exception); - status = UserStatus.TLdeserialize(stream, stream.readInt32(exception), exception); } public void serializeToStream(AbsSerializedData stream) { @@ -3163,13 +3303,24 @@ public class TLRPC { stream.writeString(first_name); stream.writeString(last_name); stream.writeString(username); - stream.writeInt64(access_hash); - photo.serializeToStream(stream); - status.serializeToStream(stream); } } - public static class TL_userRequest_old extends TL_userRequest { + public static class TL_userEmpty extends User { + public static int constructor = 0x200250ba; + + + public void readParams(AbsSerializedData stream, boolean exception) { + id = stream.readInt32(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(id); + } + } + + public static class TL_userRequest_old extends TL_userRequest_old2 { public static int constructor = 0x22e8ceb0; @@ -3195,7 +3346,7 @@ public class TLRPC { } } - public static class TL_userForeign_old extends TL_userForeign { + public static class TL_userForeign_old extends TL_userForeign_old2 { public static int constructor = 0x5214c89d; @@ -3219,7 +3370,33 @@ public class TLRPC { } } - public static class TL_userRequest extends User { + public static class TL_userForeign_old2 extends User { + public static int constructor = 0x75cf7a8; + + + public void readParams(AbsSerializedData stream, boolean exception) { + id = stream.readInt32(exception); + first_name = stream.readString(exception); + last_name = stream.readString(exception); + username = stream.readString(exception); + access_hash = stream.readInt64(exception); + photo = UserProfilePhoto.TLdeserialize(stream, stream.readInt32(exception), exception); + status = UserStatus.TLdeserialize(stream, stream.readInt32(exception), exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(id); + stream.writeString(first_name); + stream.writeString(last_name); + stream.writeString(username); + stream.writeInt64(access_hash); + photo.serializeToStream(stream); + status.serializeToStream(stream); + } + } + + public static class TL_userRequest_old2 extends User { public static int constructor = 0xd9ccc4ef; @@ -3247,7 +3424,25 @@ public class TLRPC { } } - public static class TL_userSelf_old2 extends TL_userSelf { + public static class TL_userDeleted_old extends TL_userDeleted_old2 { + public static int constructor = 0xb29ad7cc; + + + public void readParams(AbsSerializedData stream, boolean exception) { + id = stream.readInt32(exception); + first_name = stream.readString(exception); + last_name = stream.readString(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(id); + stream.writeString(first_name); + stream.writeString(last_name); + } + } + + public static class TL_userSelf_old2 extends TL_userSelf_old3 { public static int constructor = 0x7007b451; @@ -3275,41 +3470,67 @@ public class TLRPC { } } - public static class TL_userDeleted_old extends TL_userDeleted { - public static int constructor = 0xb29ad7cc; + public static class TL_user extends User { + public static int constructor = 0x22e49072; public void readParams(AbsSerializedData stream, boolean exception) { + flags = stream.readInt32(exception); id = stream.readInt32(exception); - first_name = stream.readString(exception); - last_name = stream.readString(exception); + if ((flags & 1) != 0) { + access_hash = stream.readInt64(exception); + } + if ((flags & 2) != 0) { + first_name = stream.readString(exception); + } + if ((flags & 4) != 0) { + last_name = stream.readString(exception); + } + if ((flags & 8) != 0) { + username = stream.readString(exception); + } + if ((flags & 16) != 0) { + phone = stream.readString(exception); + } + if ((flags & 32) != 0) { + photo = UserProfilePhoto.TLdeserialize(stream, stream.readInt32(exception), exception); + } + if ((flags & 64) != 0) { + status = UserStatus.TLdeserialize(stream, stream.readInt32(exception), exception); + } + if ((flags & 16384) != 0) { + bot_info_version = stream.readInt32(exception); + } } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); + stream.writeInt32(flags); stream.writeInt32(id); - stream.writeString(first_name); - stream.writeString(last_name); - } - } - - public static class TL_userDeleted extends User { - public static int constructor = 0xd6016d7a; - - - public void readParams(AbsSerializedData stream, boolean exception) { - id = stream.readInt32(exception); - first_name = stream.readString(exception); - last_name = stream.readString(exception); - username = stream.readString(exception); - } - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - stream.writeInt32(id); - stream.writeString(first_name); - stream.writeString(last_name); - stream.writeString(username); + if ((flags & 1) != 0) { + stream.writeInt64(access_hash); + } + if ((flags & 2) != 0) { + stream.writeString(first_name); + } + if ((flags & 4) != 0) { + stream.writeString(last_name); + } + if ((flags & 8) != 0) { + stream.writeString(username); + } + if ((flags & 16) != 0) { + stream.writeString(phone); + } + if ((flags & 32) != 0) { + photo.serializeToStream(stream); + } + if ((flags & 64) != 0) { + status.serializeToStream(stream); + } + if ((flags & 16384) != 0) { + stream.writeInt32(bot_info_version); + } } } @@ -5595,26 +5816,38 @@ public class TLRPC { } } - public static class TL_stickerSet extends TLObject { - public static int constructor = 0xa7a43b17; - + public static class StickerSet extends TLObject { public long id; public long access_hash; public String title; public String short_name; + public int flags; + public int count; + public int hash; - public static TL_stickerSet TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { - if (TL_stickerSet.constructor != constructor) { - if (exception) { - throw new RuntimeException(String.format("can't parse magic %x in TL_stickerSet", constructor)); - } else { - return null; - } + public static StickerSet TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { + StickerSet result = null; + switch(constructor) { + case 0xa7a43b17: + result = new TL_stickerSet_old(); + break; + case 0xcd303b41: + result = new TL_stickerSet(); + break; + } + if (result == null && exception) { + throw new RuntimeException(String.format("can't parse magic %x in StickerSet", constructor)); + } + if (result != null) { + result.readParams(stream, exception); } - TL_stickerSet result = new TL_stickerSet(); - result.readParams(stream, exception); return result; } + } + + public static class TL_stickerSet_old extends TL_stickerSet { + public static int constructor = 0xa7a43b17; + public void readParams(AbsSerializedData stream, boolean exception) { id = stream.readInt64(exception); @@ -5632,6 +5865,32 @@ public class TLRPC { } } + public static class TL_stickerSet extends StickerSet { + public static int constructor = 0xcd303b41; + + + public void readParams(AbsSerializedData stream, boolean exception) { + flags = stream.readInt32(exception); + id = stream.readInt64(exception); + access_hash = stream.readInt64(exception); + title = stream.readString(exception); + short_name = stream.readString(exception); + count = stream.readInt32(exception); + hash = stream.readInt32(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(flags); + stream.writeInt64(id); + stream.writeInt64(access_hash); + stream.writeString(title); + stream.writeString(short_name); + stream.writeInt32(count); + stream.writeInt32(hash); + } + } + public static class TL_pong extends TLObject { public static int constructor = 0x347773c5; @@ -6546,6 +6805,37 @@ public class TLRPC { } } + public static class TL_botCommand extends TLObject { + public static int constructor = 0xc27ac8c7; + + public String command; + public String description; + + public static TL_botCommand TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { + if (TL_botCommand.constructor != constructor) { + if (exception) { + throw new RuntimeException(String.format("can't parse magic %x in TL_botCommand", constructor)); + } else { + return null; + } + } + TL_botCommand result = new TL_botCommand(); + result.readParams(stream, exception); + return result; + } + + public void readParams(AbsSerializedData stream, boolean exception) { + command = stream.readString(exception); + description = stream.readString(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeString(command); + stream.writeString(description); + } + } + public static class InputFileLocation extends TLObject { public long id; public long access_hash; @@ -6665,13 +6955,14 @@ public class TLRPC { } public static class TL_chatFull extends TLObject { - public static int constructor = 0xcade0791; + public static int constructor = 0x2e02a614; public int id; public ChatParticipants participants; public Photo chat_photo; public PeerNotifySettings notify_settings; public ExportedChatInvite exported_invite; + public ArrayList bot_info = new ArrayList<>(); public static TL_chatFull TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { if (TL_chatFull.constructor != constructor) { @@ -6692,6 +6983,21 @@ public class TLRPC { chat_photo = Photo.TLdeserialize(stream, stream.readInt32(exception), exception); notify_settings = PeerNotifySettings.TLdeserialize(stream, stream.readInt32(exception), exception); exported_invite = ExportedChatInvite.TLdeserialize(stream, stream.readInt32(exception), exception); + int magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + int count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + BotInfo object = BotInfo.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + bot_info.add(object); + } } public void serializeToStream(AbsSerializedData stream) { @@ -6701,6 +7007,12 @@ public class TLRPC { chat_photo.serializeToStream(stream); notify_settings.serializeToStream(stream); exported_invite.serializeToStream(stream); + stream.writeInt32(0x1cb5c415); + int count = bot_info.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + bot_info.get(a).serializeToStream(stream); + } } } @@ -8012,22 +8324,25 @@ public class TLRPC { public static class messages_AllStickers extends TLObject { public String hash; + public ArrayList sets = new ArrayList<>(); public ArrayList packs = new ArrayList<>(); - public ArrayList sets = new ArrayList<>(); public ArrayList documents = new ArrayList<>(); public static messages_AllStickers TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { messages_AllStickers result = null; switch(constructor) { - case 0x5ce352ec: + case 0xd51dafdb: result = new TL_messages_allStickers(); break; - case 0xe86602c3: - result = new TL_messages_allStickersNotModified(); - break; case 0xdcef3102: result = new TL_messages_allStickers_old(); break; + case 0x5ce352ec: + result = new TL_messages_allStickers_old2(); + break; + case 0xe86602c3: + result = new TL_messages_allStickersNotModified(); + break; } if (result == null && exception) { throw new RuntimeException(String.format("can't parse magic %x in messages_AllStickers", constructor)); @@ -8040,7 +8355,7 @@ public class TLRPC { } public static class TL_messages_allStickers extends messages_AllStickers { - public static int constructor = 0x5ce352ec; + public static int constructor = 0xd51dafdb; public void readParams(AbsSerializedData stream, boolean exception) { @@ -8054,74 +8369,23 @@ public class TLRPC { } int count = stream.readInt32(exception); for (int a = 0; a < count; a++) { - TL_stickerPack object = TL_stickerPack.TLdeserialize(stream, stream.readInt32(exception), exception); - if (object == null) { - return; - } - packs.add(object); - } - magic = stream.readInt32(exception); - if (magic != 0x1cb5c415) { - if (exception) { - throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); - } - return; - } - count = stream.readInt32(exception); - for (int a = 0; a < count; a++) { - TL_stickerSet object = TL_stickerSet.TLdeserialize(stream, stream.readInt32(exception), exception); + StickerSet object = StickerSet.TLdeserialize(stream, stream.readInt32(exception), exception); if (object == null) { return; } sets.add(object); } - magic = stream.readInt32(exception); - if (magic != 0x1cb5c415) { - if (exception) { - throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); - } - return; - } - count = stream.readInt32(exception); - for (int a = 0; a < count; a++) { - Document object = Document.TLdeserialize(stream, stream.readInt32(exception), exception); - if (object == null) { - return; - } - documents.add(object); - } } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); stream.writeString(hash); stream.writeInt32(0x1cb5c415); - int count = packs.size(); - stream.writeInt32(count); - for (int a = 0; a < count; a++) { - packs.get(a).serializeToStream(stream); - } - stream.writeInt32(0x1cb5c415); - count = sets.size(); + int count = sets.size(); stream.writeInt32(count); for (int a = 0; a < count; a++) { sets.get(a).serializeToStream(stream); } - stream.writeInt32(0x1cb5c415); - count = documents.size(); - stream.writeInt32(count); - for (int a = 0; a < count; a++) { - documents.get(a).serializeToStream(stream); - } - } - } - - public static class TL_messages_allStickersNotModified extends messages_AllStickers { - public static int constructor = 0xe86602c3; - - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); } } @@ -8181,6 +8445,92 @@ public class TLRPC { } } + public static class TL_messages_allStickers_old2 extends TL_messages_allStickers { + public static int constructor = 0x5ce352ec; + + + public void readParams(AbsSerializedData stream, boolean exception) { + hash = stream.readString(exception); + int magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + int count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + TL_stickerPack object = TL_stickerPack.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + packs.add(object); + } + magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + StickerSet object = StickerSet.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + sets.add(object); + } + magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + Document object = Document.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + documents.add(object); + } + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeString(hash); + stream.writeInt32(0x1cb5c415); + int count = packs.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + packs.get(a).serializeToStream(stream); + } + stream.writeInt32(0x1cb5c415); + count = sets.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + sets.get(a).serializeToStream(stream); + } + stream.writeInt32(0x1cb5c415); + count = documents.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + documents.get(a).serializeToStream(stream); + } + } + } + + public static class TL_messages_allStickersNotModified extends messages_AllStickers { + public static int constructor = 0xe86602c3; + + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + } + } + public static class TL_auth_checkedPhone extends TLObject { public static int constructor = 0x811ea28e; @@ -9468,6 +9818,34 @@ public class TLRPC { } } + public static class TL_keyboardButton extends TLObject { + public static int constructor = 0xa2fa4880; + + public String text; + + public static TL_keyboardButton TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { + if (TL_keyboardButton.constructor != constructor) { + if (exception) { + throw new RuntimeException(String.format("can't parse magic %x in TL_keyboardButton", constructor)); + } else { + return null; + } + } + TL_keyboardButton result = new TL_keyboardButton(); + result.readParams(stream, exception); + return result; + } + + public void readParams(AbsSerializedData stream, boolean exception) { + text = stream.readString(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeString(text); + } + } + public static class TL_disabledFeature extends TLObject { public static int constructor = 0xae636f24; @@ -10326,6 +10704,96 @@ public class TLRPC { } } + public static class ReplyMarkup extends TLObject { + public int flags; + public ArrayList rows = new ArrayList<>(); + + public static ReplyMarkup TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { + ReplyMarkup result = null; + switch(constructor) { + case 0xa03e5b85: + result = new TL_replyKeyboardHide(); + break; + case 0x3502758c: + result = new TL_replyKeyboardMarkup(); + break; + case 0xf4108aa0: + result = new TL_replyKeyboardForceReply(); + break; + } + if (result == null && exception) { + throw new RuntimeException(String.format("can't parse magic %x in ReplyMarkup", constructor)); + } + if (result != null) { + result.readParams(stream, exception); + } + return result; + } + } + + public static class TL_replyKeyboardHide extends ReplyMarkup { + public static int constructor = 0xa03e5b85; + + + public void readParams(AbsSerializedData stream, boolean exception) { + flags = stream.readInt32(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(flags); + } + } + + public static class TL_replyKeyboardMarkup extends ReplyMarkup { + public static int constructor = 0x3502758c; + + + public void readParams(AbsSerializedData stream, boolean exception) { + flags = stream.readInt32(exception); + int magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + int count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + TL_keyboardButtonRow object = TL_keyboardButtonRow.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + rows.add(object); + } + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(flags); + stream.writeInt32(0x1cb5c415); + int count = rows.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + rows.get(a).serializeToStream(stream); + } + } + } + + public static class TL_replyKeyboardForceReply extends ReplyMarkup { + public static int constructor = 0xf4108aa0; + + + public void readParams(AbsSerializedData stream, boolean exception) { + flags = stream.readInt32(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(flags); + } + } + public static class TL_msgs_state_info extends TLObject { public static int constructor = 0x04deb57d; @@ -12027,10 +12495,12 @@ public class TLRPC { public static class DocumentAttribute extends TLObject { public int w; public int h; - public String file_name; + public int duration; public String alt; public InputStickerSet stickerset; - public int duration; + public String title; + public String performer; + public String file_name; public static DocumentAttribute TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { DocumentAttribute result = null; @@ -12044,8 +12514,8 @@ public class TLRPC { case 0x6c37c15c: result = new TL_documentAttributeImageSize(); break; - case 0x15590068: - result = new TL_documentAttributeFilename(); + case 0x51448e5: + result = new TL_documentAttributeAudio_old(); break; case 0x3a556302: result = new TL_documentAttributeSticker(); @@ -12053,12 +12523,15 @@ public class TLRPC { case 0x5910cccb: result = new TL_documentAttributeVideo(); break; - case 0x51448e5: + case 0xded218e0: result = new TL_documentAttributeAudio(); break; case 0x994c9882: result = new TL_documentAttributeSticker_old2(); break; + case 0x15590068: + result = new TL_documentAttributeFilename(); + break; } if (result == null && exception) { throw new RuntimeException(String.format("can't parse magic %x in DocumentAttribute", constructor)); @@ -12106,6 +12579,20 @@ public class TLRPC { } } + public static class TL_documentAttributeAudio_old extends TL_documentAttributeAudio { + public static int constructor = 0x51448e5; + + + public void readParams(AbsSerializedData stream, boolean exception) { + duration = stream.readInt32(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(duration); + } + } + public static class TL_documentAttributeFilename extends DocumentAttribute { public static int constructor = 0x15590068; @@ -12155,16 +12642,20 @@ public class TLRPC { } public static class TL_documentAttributeAudio extends DocumentAttribute { - public static int constructor = 0x51448e5; + public static int constructor = 0xded218e0; public void readParams(AbsSerializedData stream, boolean exception) { duration = stream.readInt32(exception); + title = stream.readString(exception); + performer = stream.readString(exception); } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); stream.writeInt32(duration); + stream.writeString(title); + stream.writeString(performer); } } @@ -13314,13 +13805,14 @@ public class TLRPC { } public static class TL_messages_sendMessage extends TLObject { - public static int constructor = 0x9add8f26; + public static int constructor = 0xfc55e6b5; public int flags; public InputPeer peer; public int reply_to_msg_id; public String message; public long random_id; + public ReplyMarkup reply_markup; public TLObject deserializeResponse(AbsSerializedData stream, int constructor, boolean exception) { return messages_SentMessage.TLdeserialize(stream, constructor, exception); @@ -13335,17 +13827,21 @@ public class TLRPC { } stream.writeString(message); stream.writeInt64(random_id); + if ((flags & 4) != 0) { + reply_markup.serializeToStream(stream); + } } } public static class TL_messages_sendMedia extends TLObject { - public static int constructor = 0x2d7923b1; + public static int constructor = 0xc8f16791; public int flags; public InputPeer peer; public int reply_to_msg_id; public InputMedia media; public long random_id; + public ReplyMarkup reply_markup; public TLObject deserializeResponse(AbsSerializedData stream, int constructor, boolean exception) { return Updates.TLdeserialize(stream, constructor, exception); @@ -13360,6 +13856,9 @@ public class TLRPC { } media.serializeToStream(stream); stream.writeInt64(random_id); + if ((flags & 4) != 0) { + reply_markup.serializeToStream(stream); + } } } @@ -14603,9 +15102,10 @@ public class TLRPC { } public static class TL_messages_installStickerSet extends TLObject { - public static int constructor = 0xefbbfae9; + public static int constructor = 0x7b30c3a6; public InputStickerSet stickerset; + public boolean disabled; public TLObject deserializeResponse(AbsSerializedData stream, int constructor, boolean exception) { return Bool.TLdeserialize(stream, constructor, exception); @@ -14614,6 +15114,7 @@ public class TLRPC { public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); stickerset.serializeToStream(stream); + stream.writeBool(disabled); } } @@ -14632,6 +15133,27 @@ public class TLRPC { } } + public static class TL_messages_startBot extends TLObject { + public static int constructor = 0x1b3e0ffc; + + public InputUser bot; + public int chat_id; + public long random_id; + public String start_param; + + public TLObject deserializeResponse(AbsSerializedData stream, int constructor, boolean exception) { + return Updates.TLdeserialize(stream, constructor, exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + bot.serializeToStream(stream); + stream.writeInt32(chat_id); + stream.writeInt64(random_id); + stream.writeString(start_param); + } + } + //manually created //EncryptedChat start @@ -14709,6 +15231,7 @@ public class TLRPC { public String message; public MessageMedia media; public int flags; + public ReplyMarkup reply_markup; public int send_state = 0; //custom public int fwd_msg_id = 0; //custom public String attachPath = ""; //custom @@ -14729,6 +15252,9 @@ public class TLRPC { result = new TL_messageService(); break; case 0xa7ab1991: + result = new TL_message_old3(); + break; + case 0xc3060325: result = new TL_message(); break; case 0x83e5de54: @@ -14805,6 +15331,66 @@ public class TLRPC { } public static class TL_message extends Message { + public static int constructor = 0xc3060325; + + + public void readParams(AbsSerializedData stream, boolean exception) { + flags = stream.readInt32(exception); + id = stream.readInt32(exception); + from_id = stream.readInt32(exception); + to_id = Peer.TLdeserialize(stream, stream.readInt32(exception), exception); + if ((flags & 4) != 0) { + fwd_from_id = stream.readInt32(exception); + } + if ((flags & 4) != 0) { + fwd_date = stream.readInt32(exception); + } + if ((flags & 8) != 0) { + reply_to_msg_id = stream.readInt32(exception); + } + date = stream.readInt32(exception); + message = stream.readString(exception); + media = MessageMedia.TLdeserialize(stream, stream.readInt32(exception), exception); + if ((flags & 64) != 0) { + reply_markup = ReplyMarkup.TLdeserialize(stream, stream.readInt32(exception), exception); + } + if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && !(media instanceof TL_messageMediaWebPage) && message != null && message.length() != 0 && message.startsWith("-1"))) { + attachPath = stream.readString(exception); + } + if ((flags & MESSAGE_FLAG_FWD) != 0 && id < 0) { + fwd_msg_id = stream.readInt32(exception); + } + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(flags); + stream.writeInt32(id); + stream.writeInt32(from_id); + to_id.serializeToStream(stream); + if ((flags & 4) != 0) { + stream.writeInt32(fwd_from_id); + } + if ((flags & 4) != 0) { + stream.writeInt32(fwd_date); + } + if ((flags & 8) != 0) { + stream.writeInt32(reply_to_msg_id); + } + stream.writeInt32(date); + stream.writeString(message); + media.serializeToStream(stream); + if ((flags & 64) != 0) { + reply_markup.serializeToStream(stream); + } + stream.writeString(attachPath); + if ((flags & MESSAGE_FLAG_FWD) != 0 && id < 0) { + stream.writeInt32(fwd_msg_id); + } + } + } + + public static class TL_message_old3 extends TL_message { public static int constructor = 0xa7ab1991; public void readParams(AbsSerializedData stream, boolean exception) { @@ -14824,7 +15410,7 @@ public class TLRPC { date = stream.readInt32(exception); message = stream.readString(exception); media = MessageMedia.TLdeserialize(stream, stream.readInt32(exception), exception); - if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && message != null && message.length() != 0 && message.startsWith("-1"))) { + if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && !(media instanceof TL_messageMediaWebPage) && message != null && message.length() != 0 && message.startsWith("-1"))) { attachPath = stream.readString(exception); } if ((flags & MESSAGE_FLAG_FWD) != 0 && id < 0) { @@ -14869,7 +15455,7 @@ public class TLRPC { date = stream.readInt32(exception); message = stream.readString(exception); media = MessageMedia.TLdeserialize(stream, stream.readInt32(exception), exception); - if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && message != null && message.length() != 0 && message.startsWith("-1"))) { + if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && !(media instanceof TL_messageMediaWebPage) && message != null && message.length() != 0 && message.startsWith("-1"))) { attachPath = stream.readString(exception); } } @@ -14932,7 +15518,7 @@ public class TLRPC { if (id < 0) { fwd_msg_id = stream.readInt32(exception); } - if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && message != null && message.length() != 0 && message.startsWith("-1"))) { + if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && !(media instanceof TL_messageMediaWebPage) && message != null && message.length() != 0 && message.startsWith("-1"))) { attachPath = stream.readString(exception); } } @@ -14968,7 +15554,7 @@ public class TLRPC { date = stream.readInt32(exception); message = stream.readString(exception); media = MessageMedia.TLdeserialize(stream, stream.readInt32(exception), exception); - if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && message != null && message.length() != 0 && message.startsWith("-1"))) { + if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && !(media instanceof TL_messageMediaWebPage) && message != null && message.length() != 0 && message.startsWith("-1"))) { attachPath = stream.readString(exception); } } @@ -14999,7 +15585,7 @@ public class TLRPC { date = stream.readInt32(exception); message = stream.readString(exception); media = MessageMedia.TLdeserialize(stream, stream.readInt32(exception), exception); - if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && message != null && message.length() != 0 && message.startsWith("-1"))) { + if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && !(media instanceof TL_messageMediaWebPage) && message != null && message.length() != 0 && message.startsWith("-1"))) { attachPath = stream.readString(exception); } } @@ -15064,27 +15650,6 @@ public class TLRPC { } //TL_dialog end - //User start - public static class TL_userEmpty extends User { - public static int constructor = 0x200250ba; - - - public void readParams(AbsSerializedData stream, boolean exception) { - id = stream.readInt32(exception); - - first_name = "DELETED"; - last_name = ""; - phone = ""; - status = new TL_userStatusEmpty(); - } - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - stream.writeInt32(id); - } - } - //User end - //Chat start public static class TL_chatEmpty extends Chat { public static int constructor = 0x9ba2d800; @@ -15385,7 +15950,8 @@ public class TLRPC { stream.writeInt32(constructor); int count = session_ids.size(); stream.writeInt32(count); - for (Long session_id : session_ids) { + for (int a = 0; a < session_ids.size(); a++) { + Long session_id = session_ids.get(a); stream.writeInt64(session_id); } } @@ -15544,7 +16110,8 @@ public class TLRPC { public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); stream.writeInt32(messages.size()); - for (TLObject obj : messages) { + for (int a = 0; a < messages.size(); a++) { + TLObject obj = messages.get(a); TL_protoMessage proto = (TL_protoMessage) obj; stream.writeInt64(proto.msg_id); stream.writeInt32(proto.seqno); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java index 31b0ffce5..38e3ff667 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java @@ -132,7 +132,7 @@ public class UserConfig { int ver = data.readInt32(false); if (ver == 1) { int constructor = data.readInt32(false); - currentUser = TLRPC.TL_userSelf.TLdeserialize(data, constructor, false); + currentUser = TLRPC.User.TLdeserialize(data, constructor, false); MessagesStorage.lastDateValue = data.readInt32(false); MessagesStorage.lastPtsValue = data.readInt32(false); MessagesStorage.lastSeqValue = data.readInt32(false); @@ -159,7 +159,7 @@ public class UserConfig { }); } else if (ver == 2) { int constructor = data.readInt32(false); - currentUser = TLRPC.TL_userSelf.TLdeserialize(data, constructor, false); + currentUser = TLRPC.User.TLdeserialize(data, constructor, false); SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("userconfing", Context.MODE_PRIVATE); registeredForPush = preferences.getBoolean("registeredForPush", false); @@ -211,7 +211,7 @@ public class UserConfig { byte[] userBytes = Base64.decode(user, Base64.DEFAULT); if (userBytes != null) { SerializedData data = new SerializedData(userBytes); - currentUser = TLRPC.TL_userSelf.TLdeserialize(data, data.readInt32(false), false); + currentUser = TLRPC.User.TLdeserialize(data, data.readInt32(false), false); data.cleanup(); } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java b/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java index 73326ac0c..bb1831cc2 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java @@ -270,7 +270,7 @@ public class Utilities { } public static boolean arraysEquals(byte[] arr1, int offset1, byte[] arr2, int offset2) { - if (arr1 == null || arr2 == null || arr1.length - offset1 != arr2.length - offset2 || arr1.length - offset1 < 0) { + if (arr1 == null || arr2 == null || offset1 < 0 || offset2 < 0 || arr1.length - offset1 != arr2.length - offset2 || arr1.length - offset1 < 0 || arr2.length - offset2 < 0) { return false; } boolean result = true; 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 b14f21bfe..68b3b28be 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java @@ -28,7 +28,6 @@ import android.widget.FrameLayout; import android.widget.LinearLayout; import org.telegram.android.AndroidUtilities; -import org.telegram.android.NotificationCenter; import org.telegram.messenger.R; import org.telegram.android.AnimationCompat.AnimatorListenerAdapterProxy; import org.telegram.android.AnimationCompat.AnimatorSetProxy; @@ -184,6 +183,13 @@ public class ActionBarLayout extends FrameLayout { } } + public void drawHeaderShadow(Canvas canvas, int y) { + if (headerShadowDrawable != null) { + headerShadowDrawable.setBounds(0, y, getMeasuredWidth(), y + headerShadowDrawable.getIntrinsicHeight()); + headerShadowDrawable.draw(canvas); + } + } + public void setInnerTranslationX(float value) { innerTranslationX = value; invalidate(); @@ -264,7 +270,10 @@ public class ActionBarLayout extends FrameLayout { layerShadowDrawable.setAlpha((int) (0xff * alpha)); layerShadowDrawable.draw(canvas); } else if (child == containerViewBack) { - final float opacity = Math.min(0.8f, (width - translationX) / (float)width); + float opacity = Math.min(0.8f, (width - translationX) / (float)width); + if (opacity < 0) { + opacity = 0; + } scrimPaint.setColor((int) (((0x99000000 & 0xff000000) >>> 24) * opacity) << 24); canvas.drawRect(clipLeft, 0, clipRight, getHeight(), scrimPaint); } @@ -293,6 +302,7 @@ public class ActionBarLayout extends FrameLayout { lastFragment = fragmentsStack.get(fragmentsStack.size() - 1); currentActionBar = lastFragment.actionBar; lastFragment.onResume(); + lastFragment.onBecomeFullyVisible(); } else { BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 2); lastFragment.onPause(); @@ -309,7 +319,7 @@ public class ActionBarLayout extends FrameLayout { } } } - containerViewBack.setVisibility(View.INVISIBLE); + containerViewBack.setVisibility(View.GONE); //AndroidUtilities.unlockOrientation(parentActivity); startedTracking = false; animationInProgress = false; @@ -428,13 +438,13 @@ public class ActionBarLayout extends FrameLayout { if (!backAnimation) { distToMove = containerView.getMeasuredWidth() - x; animatorSet.playTogether( - ObjectAnimatorProxy.ofFloat(containerView, "x", containerView.getMeasuredWidth()), + ObjectAnimatorProxy.ofFloat(containerView, "translationX", containerView.getMeasuredWidth()), ObjectAnimatorProxy.ofFloat(this, "innerTranslationX", (float)containerView.getMeasuredWidth()) ); } else { distToMove = x; animatorSet.playTogether( - ObjectAnimatorProxy.ofFloat(containerView, "x", 0), + ObjectAnimatorProxy.ofFloat(containerView, "translationX", 0), ObjectAnimatorProxy.ofFloat(this, "innerTranslationX", 0.0f) ); } @@ -545,7 +555,7 @@ public class ActionBarLayout extends FrameLayout { } } } - containerViewBack.setVisibility(View.INVISIBLE); + containerViewBack.setVisibility(View.GONE); } public boolean presentFragment(BaseFragment fragment) { @@ -560,6 +570,13 @@ public class ActionBarLayout extends FrameLayout { if (first) { animationProgress = 0.0f; lastFrameTime = System.nanoTime() / 1000000; + if (Build.VERSION.SDK_INT >= 11) { + if (open) { + containerView.setLayerType(LAYER_TYPE_HARDWARE, null); + } else { + containerViewBack.setLayerType(LAYER_TYPE_HARDWARE, null); + } + } } AndroidUtilities.runOnUIThread(new Runnable() { @Override @@ -600,7 +617,6 @@ public class ActionBarLayout extends FrameLayout { } if (parentActivity.getCurrentFocus() != null) { AndroidUtilities.hideKeyboard(parentActivity.getCurrentFocus()); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.hideEmojiKeyboard); } boolean needAnimation = Build.VERSION.SDK_INT > 10 && !forceWithoutAnimation && parentActivity.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).getBoolean("view_animations", true); @@ -665,6 +681,7 @@ public class ActionBarLayout extends FrameLayout { @Override public void run() { fragment.onOpenAnimationEnd(); + fragment.onBecomeFullyVisible(); } }; ArrayList animators = new ArrayList<>(); @@ -697,8 +714,12 @@ public class ActionBarLayout extends FrameLayout { onOpenAnimationEndRunnable = new Runnable() { @Override public void run() { + if (Build.VERSION.SDK_INT >= 18) { + containerView.setLayerType(LAYER_TYPE_NONE, null); + } presentFragmentInternalRemoveOld(removeLast, currentFragment); fragment.onOpenAnimationEnd(); + fragment.onBecomeFullyVisible(); ViewProxy.setTranslationX(containerView, 0); } }; @@ -737,6 +758,7 @@ public class ActionBarLayout extends FrameLayout { } fragment.onOpenAnimationStart(); fragment.onOpenAnimationEnd(); + fragment.onBecomeFullyVisible(); } return true; } @@ -779,7 +801,7 @@ public class ActionBarLayout extends FrameLayout { fragment.onFragmentDestroy(); fragment.setParentLayout(null); fragmentsStack.remove(fragment); - containerViewBack.setVisibility(View.INVISIBLE); + containerViewBack.setVisibility(View.GONE); bringChildToFront(containerView); } @@ -830,6 +852,7 @@ public class ActionBarLayout extends FrameLayout { layoutParams.width = LayoutHelper.MATCH_PARENT; layoutParams.height = LayoutHelper.MATCH_PARENT; fragmentView.setLayoutParams(layoutParams); + previousFragment.onOpenAnimationStart(); previousFragment.onResume(); currentActionBar = previousFragment.actionBar; if (!previousFragment.hasOwnBackground && fragmentView.getBackground() == null) { @@ -843,11 +866,17 @@ public class ActionBarLayout extends FrameLayout { if (needAnimation) { transitionAnimationStartTime = System.currentTimeMillis(); transitionAnimationInProgress = true; + final BaseFragment previousFragmentFinal = previousFragment; onCloseAnimationEndRunnable = new Runnable() { @Override public void run() { + if (Build.VERSION.SDK_INT >= 18) { + containerViewBack.setLayerType(LAYER_TYPE_NONE, null); + } closeLastFragmentInternalRemoveOld(currentFragment); ViewProxy.setTranslationX(containerViewBack, 0); + previousFragmentFinal.onOpenAnimationEnd(); + previousFragmentFinal.onBecomeFullyVisible(); } }; startLayoutAnimation(false, true); @@ -875,6 +904,9 @@ public class ActionBarLayout extends FrameLayout { } }); currentAnimation.start();*/ + } else { + previousFragment.onOpenAnimationEnd(); + previousFragment.onBecomeFullyVisible(); } } else { if (useAlphaAnimations) { @@ -885,9 +917,9 @@ public class ActionBarLayout extends FrameLayout { @Override public void run() { removeFragmentFromStack(currentFragment); - setVisibility(INVISIBLE); + setVisibility(GONE); if (backgroundView != null) { - backgroundView.setVisibility(INVISIBLE); + backgroundView.setVisibility(GONE); } if (drawerLayoutContainer != null) { drawerLayoutContainer.setAllowOpenDrawer(true, false); @@ -924,9 +956,9 @@ public class ActionBarLayout extends FrameLayout { currentAnimation.start(); } else { removeFragmentFromStack(currentFragment); - setVisibility(INVISIBLE); + setVisibility(GONE); if (backgroundView != null) { - backgroundView.setVisibility(INVISIBLE); + backgroundView.setVisibility(GONE); } } } @@ -986,7 +1018,7 @@ public class ActionBarLayout extends FrameLayout { public void rebuildAllFragmentViews(boolean last) { for (int a = 0; a < fragmentsStack.size() - (last ? 0 : 1); a++) { - fragmentsStack.get(a).setParentLayout(null); + fragmentsStack.get(a).clearViews(); fragmentsStack.get(a).setParentLayout(this); } if (delegate != null) { 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 6d152b6a2..ad5fc1d9b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenuItem.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarMenuItem.java @@ -45,10 +45,14 @@ public class ActionBarMenuItem extends FrameLayoutFixed { public void onSearchExpand() { } - public boolean onSearchCollapse() { + public boolean canCollapseSearch() { return true; } + public void onSearchCollapse() { + + } + public void onTextChanged(EditText editText) { } @@ -77,6 +81,7 @@ public class ActionBarMenuItem extends FrameLayoutFixed { private int menuHeight = AndroidUtilities.dp(16); private int subMenuOpenSide = 0; private ActionBarMenuItemDelegate delegate; + private boolean allowCloseAnimation = true; public ActionBarMenuItem(Context context, ActionBarMenu menu, int background) { super(context); @@ -154,8 +159,10 @@ public class ActionBarMenuItem extends FrameLayoutFixed { } else if (delegate != null) { delegate.onItemClick((Integer) selectedMenuView.getTag()); } + popupWindow.dismiss(allowCloseAnimation); + } else { + popupWindow.dismiss(); } - popupWindow.dismiss(); } else { if (selectedMenuView != null) { selectedMenuView.setSelected(false); @@ -171,6 +178,9 @@ public class ActionBarMenuItem extends FrameLayoutFixed { public void setShowFromBottom(boolean value) { showFromBottom = value; + if (popupLayout != null) { + popupLayout.setShowedFromBotton(showFromBottom); + } } public void setSubMenuOpenSide(int side) { @@ -183,7 +193,8 @@ public class ActionBarMenuItem extends FrameLayoutFixed { location = new int[2]; popupLayout = new ActionBarPopupWindow.ActionBarPopupWindowLayout(getContext()); popupLayout.setOrientation(LinearLayout.VERTICAL); - popupLayout.setBackgroundResource(R.drawable.popup_fixed); + popupLayout.setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(8), AndroidUtilities.dp(8), AndroidUtilities.dp(8)); + //popupLayout.setBackgroundResource(R.drawable.popup_fixed); popupLayout.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { @@ -228,6 +239,7 @@ public class ActionBarMenuItem extends FrameLayoutFixed { textView.setCompoundDrawablesWithIntrinsicBounds(null, null, getResources().getDrawable(icon), null); } } + popupLayout.setShowedFromBotton(showFromBottom); popupLayout.addView(textView); LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams(); if (LocaleController.isRTL) { @@ -239,14 +251,14 @@ public class ActionBarMenuItem extends FrameLayoutFixed { textView.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { + if (popupWindow != null && popupWindow.isShowing()) { + popupWindow.dismiss(allowCloseAnimation); + } if (parentMenu != null) { parentMenu.onItemClick((Integer) view.getTag()); } else if (delegate != null) { delegate.onItemClick((Integer) view.getTag()); } - if (popupWindow != null && popupWindow.isShowing()) { - popupWindow.dismiss(); - } } }); menuHeight += layoutParams.height; @@ -272,7 +284,11 @@ public class ActionBarMenuItem extends FrameLayoutFixed { if (popupWindow == null) { popupWindow = new ActionBarPopupWindow(popupLayout, LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT); //popupWindow.setBackgroundDrawable(new BitmapDrawable()); - popupWindow.setAnimationStyle(R.style.PopupAnimation); + if (Build.VERSION.SDK_INT >= 19) { + popupWindow.setAnimationStyle(0); + } else { + popupWindow.setAnimationStyle(R.style.PopupAnimation); + } popupWindow.setOutsideTouchable(true); popupWindow.setClippingEnabled(true); popupWindow.setInputMethodMode(ActionBarPopupWindow.INPUT_METHOD_NOT_NEEDED); @@ -292,54 +308,11 @@ public class ActionBarMenuItem extends FrameLayoutFixed { } popupWindow.setFocusable(true); if (popupLayout.getMeasuredWidth() == 0) { - if (subMenuOpenSide == 0) { - if (showFromBottom) { - popupWindow.showAsDropDown(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth(), getOffsetY()); - popupWindow.update(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth(), getOffsetY(), -1, -1); - } else { - if (parentMenu != null) { - popupWindow.showAsDropDown(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), getOffsetY()); - popupWindow.update(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), getOffsetY(), -1, -1); - } else if (getParent() != null) { - View parent = (View) getParent(); - popupWindow.showAsDropDown(this, parent.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parent.getLeft(), getOffsetY()); - popupWindow.update(this, parent.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parent.getLeft(), getOffsetY(), -1, -1); - } - } - } else { - popupWindow.showAsDropDown(this, -AndroidUtilities.dp(8), getOffsetY()); - popupWindow.update(this, -AndroidUtilities.dp(8), getOffsetY(), -1, -1); - } + updateOrShowPopup(true, true); } else { - if (subMenuOpenSide == 0) { - if (showFromBottom) { - popupWindow.showAsDropDown(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth(), getOffsetY()); - } else { - if (parentMenu != null) { - popupWindow.showAsDropDown(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), getOffsetY()); - } else { - View parent = (View) getParent(); - popupWindow.showAsDropDown(this, parent.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parent.getLeft(), getOffsetY()); - } - } - } else { - popupWindow.showAsDropDown(this, -AndroidUtilities.dp(8), getOffsetY()); - } - } - } - - private int getOffsetY() { - if (showFromBottom) { - getLocationOnScreen(location); - int diff = location[1] - AndroidUtilities.statusBarHeight + getMeasuredHeight() - menuHeight; - int y = -menuHeight; - if (diff < 0) { - y -= diff; - } - return y; - } else { - return -getMeasuredHeight(); + updateOrShowPopup(true, false); } + popupWindow.startAnimation(); } public void openSearch() { @@ -354,10 +327,13 @@ public class ActionBarMenuItem extends FrameLayoutFixed { return false; } if (searchContainer.getVisibility() == VISIBLE) { - if (listener == null || listener != null && listener.onSearchCollapse()) { + if (listener == null || listener != null && listener.canCollapseSearch()) { searchContainer.setVisibility(GONE); setVisibility(VISIBLE); AndroidUtilities.hideKeyboard(searchField); + if (listener != null) { + listener.onSearchCollapse(); + } } return false; } else { @@ -388,6 +364,10 @@ public class ActionBarMenuItem extends FrameLayoutFixed { } public ActionBarMenuItem setIsSearchField(boolean value) { + return setIsSearchField(value, true); + } + + public ActionBarMenuItem setIsSearchField(boolean value, boolean needClearButton) { if (parentMenu == null) { return this; } @@ -423,6 +403,7 @@ public class ActionBarMenuItem extends FrameLayoutFixed { } public void onDestroyActionMode(ActionMode mode) { + } public boolean onCreateActionMode(ActionMode mode, Menu menu) { @@ -457,7 +438,9 @@ public class ActionBarMenuItem extends FrameLayoutFixed { if (listener != null) { listener.onTextChanged(searchField); } - ViewProxy.setAlpha(clearButton, s == null || s.length() == 0 ? 0.6f : 1.0f); + if (clearButton != null) { + ViewProxy.setAlpha(clearButton, s == null || s.length() == 0 ? 0.6f : 1.0f); + } } @Override @@ -487,22 +470,24 @@ public class ActionBarMenuItem extends FrameLayoutFixed { layoutParams2.rightMargin = AndroidUtilities.dp(48); searchField.setLayoutParams(layoutParams2); - clearButton = new ImageView(getContext()); - clearButton.setImageResource(R.drawable.ic_close_white); - clearButton.setScaleType(ImageView.ScaleType.CENTER); - clearButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - searchField.setText(""); - AndroidUtilities.showKeyboard(searchField); - } - }); - searchContainer.addView(clearButton); - layoutParams2 = (FrameLayout.LayoutParams) clearButton.getLayoutParams(); - layoutParams2.width = AndroidUtilities.dp(48); - layoutParams2.gravity = Gravity.CENTER_VERTICAL | Gravity.RIGHT; - layoutParams2.height = LayoutHelper.MATCH_PARENT; - clearButton.setLayoutParams(layoutParams2); + if (needClearButton) { + clearButton = new ImageView(getContext()); + clearButton.setImageResource(R.drawable.ic_close_white); + clearButton.setScaleType(ImageView.ScaleType.CENTER); + clearButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + searchField.setText(""); + AndroidUtilities.showKeyboard(searchField); + } + }); + searchContainer.addView(clearButton); + layoutParams2 = (FrameLayout.LayoutParams) clearButton.getLayoutParams(); + layoutParams2.width = AndroidUtilities.dp(48); + layoutParams2.gravity = Gravity.CENTER_VERTICAL | Gravity.RIGHT; + layoutParams2.height = LayoutHelper.MATCH_PARENT; + clearButton.setLayoutParams(layoutParams2); + } } isSearchField = value; return this; @@ -517,23 +502,69 @@ public class ActionBarMenuItem extends FrameLayoutFixed { return this; } + public ActionBarMenuItem setAllowCloseAnimation(boolean value) { + allowCloseAnimation = value; + return this; + } + @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); if (popupWindow != null && popupWindow.isShowing()) { - if (subMenuOpenSide == 0) { - if (showFromBottom) { - popupWindow.update(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth(), getOffsetY(), -1, -1); - } else { - if (parentMenu != null) { - popupWindow.update(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), getOffsetY(), -1, -1); - } else { - View parent = (View) getParent(); - popupWindow.update(this, parent.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parent.getLeft(), getOffsetY(), -1, -1); - } + updateOrShowPopup(false, true); + } + } + + private void updateOrShowPopup(boolean show, boolean update) { + int offsetY; + if (showFromBottom) { + getLocationOnScreen(location); + int diff = location[1] - AndroidUtilities.statusBarHeight + getMeasuredHeight() - menuHeight; + offsetY = -menuHeight; + if (diff < 0) { + offsetY -= diff; + } + } else { + if (parentMenu != null && subMenuOpenSide == 0) { + offsetY = -parentMenu.parentActionBar.getMeasuredHeight() + parentMenu.getTop(); + } else { + offsetY = -getMeasuredHeight(); + } + } + + if (subMenuOpenSide == 0) { + if (showFromBottom) { + if (show) { + popupWindow.showAsDropDown(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth(), offsetY); + } + if (update) { + popupWindow.update(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth(), offsetY, -1, -1); } } else { - popupWindow.update(this, -AndroidUtilities.dp(8), getOffsetY(), -1, -1); + if (parentMenu != null) { + View parent = parentMenu.parentActionBar; + if (show) { + popupWindow.showAsDropDown(parent, getLeft() + parentMenu.getLeft() + getMeasuredWidth() - popupLayout.getMeasuredWidth(), offsetY); + } + if (update) { + popupWindow.update(parent, getLeft() + parentMenu.getLeft() + getMeasuredWidth() - popupLayout.getMeasuredWidth(), offsetY, -1, -1); + } + } else if (getParent() != null) { + View parent = (View) getParent(); + if (show) { + popupWindow.showAsDropDown(parent, parent.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parent.getLeft(), offsetY); + } + if (update) { + popupWindow.update(parent, parent.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parent.getLeft(), offsetY, -1, -1); + } + } + } + } else { + if (show) { + popupWindow.showAsDropDown(this, -AndroidUtilities.dp(8), offsetY); + } + if (update) { + popupWindow.update(this, -AndroidUtilities.dp(8), offsetY, -1, -1); } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarPopupWindow.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarPopupWindow.java index 759222d1c..7d6816f25 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarPopupWindow.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarPopupWindow.java @@ -10,20 +10,33 @@ package org.telegram.ui.ActionBar; +import android.animation.Animator; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; import android.content.Context; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.os.Build; import android.view.KeyEvent; import android.view.View; import android.view.ViewTreeObserver; +import android.view.animation.DecelerateInterpolator; import android.widget.LinearLayout; import android.widget.PopupWindow; +import org.telegram.android.AndroidUtilities; import org.telegram.messenger.FileLog; +import org.telegram.messenger.R; import java.lang.reflect.Field; +import java.util.HashMap; public class ActionBarPopupWindow extends PopupWindow { private static final Field superListenerField; + private static final boolean animationEnabled = Build.VERSION.SDK_INT >= 18; + private static DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator(); + private AnimatorSet windowAnimatorSet; static { Field f = null; try { @@ -52,15 +65,104 @@ public class ActionBarPopupWindow extends PopupWindow { public static class ActionBarPopupWindowLayout extends LinearLayout { private OnDispatchKeyEventListener mOnDispatchKeyEventListener; + protected static Drawable backgroundDrawable; + private float backScaleX = 1; + private float backScaleY = 1; + private int backAlpha = 255; + private int lastStartedChild = 0; + private boolean showedFromBotton; + private HashMap positions = new HashMap<>(); public ActionBarPopupWindowLayout(Context context) { super(context); + setWillNotDraw(false); + + if (backgroundDrawable == null) { + backgroundDrawable = getResources().getDrawable(R.drawable.popup_fixed); + } + } + + public void setShowedFromBotton(boolean value) { + showedFromBotton = value; } public void setDispatchKeyEventListener(OnDispatchKeyEventListener listener) { mOnDispatchKeyEventListener = listener; } + public void setBackAlpha(int value) { + backAlpha = value; + } + + public int getBackAlpha() { + return backAlpha; + } + + public void setBackScaleX(float value) { + backScaleX = value; + invalidate(); + } + + public void setBackScaleY(float value) { + backScaleY = value; + if (animationEnabled) { + int count = getChildCount(); + int visibleCount = 0; + for (int a = 0; a < count; a++) { + visibleCount += getChildAt(a).getVisibility() == VISIBLE ? 1 : 0; + } + int height = getMeasuredHeight() - AndroidUtilities.dp(16); + if (showedFromBotton) { + for (int a = lastStartedChild; a >= 0; a--) { + View child = getChildAt(a); + if (child.getVisibility() != VISIBLE) { + continue; + } + int position = positions.get(child); + if (height - (position * AndroidUtilities.dp(48) + AndroidUtilities.dp(32)) > value * height) { + break; + } + lastStartedChild = a - 1; + startChildAnimation(child); + } + } else { + for (int a = lastStartedChild; a < count; a++) { + View child = getChildAt(a); + if (child.getVisibility() != VISIBLE) { + continue; + } + int position = positions.get(child); + if ((position + 1) * AndroidUtilities.dp(48) - AndroidUtilities.dp(24) > value * height) { + break; + } + lastStartedChild = a + 1; + startChildAnimation(child); + } + } + } + invalidate(); + } + + private void startChildAnimation(View child) { + if (animationEnabled) { + AnimatorSet animatorSet = new AnimatorSet(); + animatorSet.playTogether( + ObjectAnimator.ofFloat(child, "alpha", 0.0f, 1.0f), + ObjectAnimator.ofFloat(child, "translationY", AndroidUtilities.dp(showedFromBotton ? 6 : -6), 0)); + animatorSet.setDuration(180); + animatorSet.setInterpolator(decelerateInterpolator); + animatorSet.start(); + } + } + + public float getBackScaleX() { + return backScaleX; + } + + public float getBackScaleY() { + return backScaleY; + } + @Override public boolean dispatchKeyEvent(KeyEvent event) { if (mOnDispatchKeyEventListener != null) { @@ -68,6 +170,19 @@ public class ActionBarPopupWindow extends PopupWindow { } return super.dispatchKeyEvent(event); } + + @Override + protected void onDraw(Canvas canvas) { + if (backgroundDrawable != null) { + backgroundDrawable.setAlpha(backAlpha); + if (showedFromBotton) { + backgroundDrawable.setBounds(0, (int) (getMeasuredHeight() * (1.0f - backScaleY)), (int) (getMeasuredWidth() * backScaleX), getMeasuredHeight()); + } else { + backgroundDrawable.setBounds(0, 0, (int) (getMeasuredWidth() * backScaleX), (int) (getMeasuredHeight() * backScaleY)); + } + backgroundDrawable.draw(canvas); + } + } } public ActionBarPopupWindow() { @@ -109,15 +224,6 @@ public class ActionBarPopupWindow extends PopupWindow { mSuperScrollListener = null; } } - /*if (Build.VERSION.SDK_INT >= 21) { - try { - Field field = PopupWindow.class.getDeclaredField("mWindowLayoutType"); - field.setAccessible(true); - field.set(this, WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); - } catch (Exception e) { - //ignored - } - }*/ } private void unregisterListener() { @@ -153,6 +259,63 @@ public class ActionBarPopupWindow extends PopupWindow { } } + public void startAnimation() { + if (animationEnabled) { + if (windowAnimatorSet != null) { + return; + } + ActionBarPopupWindowLayout content = (ActionBarPopupWindowLayout) getContentView(); + content.setTranslationY(0); + content.setAlpha(1.0f); + content.setPivotX(content.getMeasuredWidth()); + content.setPivotY(0); + int count = content.getChildCount(); + content.positions.clear(); + int visibleCount = 0; + for (int a = 0; a < count; a++) { + View child = content.getChildAt(a); + if (child.getVisibility() != View.VISIBLE) { + continue; + } + content.positions.put(child, visibleCount); + child.setAlpha(0.0f); + visibleCount++; + } + if (content.showedFromBotton) { + content.lastStartedChild = count - 1; + } else { + content.lastStartedChild = 0; + } + windowAnimatorSet = new AnimatorSet(); + windowAnimatorSet.playTogether( + ObjectAnimator.ofFloat(content, "backScaleY", 0.0f, 1.0f), + ObjectAnimator.ofInt(content, "backAlpha", 0, 255)); + windowAnimatorSet.setDuration(150 + 16 * visibleCount); + windowAnimatorSet.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + windowAnimatorSet = null; + } + + @Override + public void onAnimationCancel(Animator animation) { + onAnimationEnd(animation); + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + }); + windowAnimatorSet.start(); + } + } + @Override public void update(View anchor, int xoff, int yoff, int width, int height) { super.update(anchor, xoff, yoff, width, height); @@ -173,12 +336,57 @@ public class ActionBarPopupWindow extends PopupWindow { @Override public void dismiss() { - setFocusable(false); - try { - super.dismiss(); - } catch (Exception e) { - //don't promt + dismiss(true); + } + + public void dismiss(boolean animated) { + if (animationEnabled && animated) { + if (windowAnimatorSet != null) { + windowAnimatorSet.cancel(); + } + ActionBarPopupWindowLayout content = (ActionBarPopupWindowLayout) getContentView(); + windowAnimatorSet = new AnimatorSet(); + windowAnimatorSet.playTogether( + ObjectAnimator.ofFloat(content, "translationY", AndroidUtilities.dp(content.showedFromBotton ? 5 : -5)), + ObjectAnimator.ofFloat(content, "alpha", 0.0f)); + windowAnimatorSet.setDuration(150); + windowAnimatorSet.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + windowAnimatorSet = null; + setFocusable(false); + try { + ActionBarPopupWindow.super.dismiss(); + } catch (Exception e) { + //don't promt + } + unregisterListener(); + } + + @Override + public void onAnimationCancel(Animator animation) { + onAnimationEnd(animation); + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + }); + windowAnimatorSet.start(); + } else { + setFocusable(false); + try { + super.dismiss(); + } catch (Exception e) { + //don't promt + } + unregisterListener(); } - unregisterListener(); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BaseFragment.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BaseFragment.java index c4414cc87..dad03f246 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BaseFragment.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BaseFragment.java @@ -52,6 +52,32 @@ public class BaseFragment { return arguments; } + protected void clearViews() { + if (fragmentView != null) { + ViewGroup parent = (ViewGroup) fragmentView.getParent(); + if (parent != null) { + try { + parent.removeView(fragmentView); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + fragmentView = null; + } + if (actionBar != null) { + ViewGroup parent = (ViewGroup) actionBar.getParent(); + if (parent != null) { + try { + parent.removeView(actionBar); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + actionBar = null; + } + parentLayout = null; + } + protected void setParentLayout(ActionBarLayout layout) { if (parentLayout != layout) { parentLayout = layout; @@ -64,7 +90,9 @@ public class BaseFragment { FileLog.e("tmessages", e); } } - fragmentView = null; + if (parentLayout != null && parentLayout.getContext() != fragmentView.getContext()) { + fragmentView = null; + } } if (actionBar != null) { ViewGroup parent = (ViewGroup) actionBar.getParent(); @@ -75,8 +103,11 @@ public class BaseFragment { FileLog.e("tmessages", e); } } + if (parentLayout != null && parentLayout.getContext() != actionBar.getContext()) { + actionBar = null; + } } - if (parentLayout != null) { + if (parentLayout != null && actionBar == null) { actionBar = new ActionBar(parentLayout.getContext()); actionBar.parentFragment = this; actionBar.setBackgroundColor(0xff54759e); @@ -200,6 +231,10 @@ public class BaseFragment { } + protected void onBecomeFullyVisible() { + + } + public void onLowMemory() { } @@ -209,7 +244,7 @@ public class BaseFragment { } public Dialog showDialog(Dialog dialog) { - if (parentLayout == null || parentLayout.animationInProgress || parentLayout.startedTracking || parentLayout.checkTransitionAnimation()) { + if (dialog == null || parentLayout == null || parentLayout.animationInProgress || parentLayout.startedTracking || parentLayout.checkTransitionAnimation()) { return null; } try { @@ -242,6 +277,10 @@ public class BaseFragment { } + public Dialog getVisibleDialog() { + return visibleDialog; + } + public void setVisibleDialog(Dialog dialog) { visibleDialog = dialog; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BottomSheet.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BottomSheet.java index 39ca1cf64..dd00b928b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BottomSheet.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/BottomSheet.java @@ -8,21 +8,26 @@ package org.telegram.ui.ActionBar; +import android.animation.Animator; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; +import android.graphics.drawable.ColorDrawable; import android.os.Build; import android.os.Bundle; +import android.text.TextUtils; import android.util.TypedValue; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; +import android.view.ViewAnimationUtils; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; 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.TextView; @@ -30,48 +35,104 @@ import org.telegram.android.AndroidUtilities; import org.telegram.android.AnimationCompat.AnimatorListenerAdapterProxy; import org.telegram.android.AnimationCompat.AnimatorSetProxy; import org.telegram.android.AnimationCompat.ObjectAnimatorProxy; +import org.telegram.android.AnimationCompat.ViewProxy; import org.telegram.android.LocaleController; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.ui.Components.LayoutHelper; +import java.util.ArrayList; + public class BottomSheet extends Dialog { private LinearLayout linearLayout; private FrameLayout container; + private boolean dismissed; + private int tag; private DialogInterface.OnClickListener onClickListener; private CharSequence[] items; + private int[] itemIcons; private View customView; + private CharSequence title; private boolean overrideTabletWidth = true; + private boolean isGrid; + private ColorDrawable backgroundDrawable = new ColorDrawable(0xff000000); + + private int revealX; + private int revealY; + private boolean useRevealAnimation; + + private DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator(); + private AccelerateInterpolator accelerateInterpolator = new AccelerateInterpolator(); + + private ArrayList itemViews = new ArrayList<>(); private BottomSheetDelegate delegate; public interface BottomSheetDelegate { + void onOpenAnimationStart(); void onOpenAnimationEnd(); } - private static class BottomSheetRow extends FrameLayout { + private static class BottomSheetCell extends FrameLayout { private TextView textView; + private ImageView imageView; + private boolean isGrid; - public BottomSheetRow(Context context) { + public BottomSheetCell(Context context, boolean grid) { super(context); + isGrid = grid; setBackgroundResource(R.drawable.list_selector); - setPadding(AndroidUtilities.dp(16), 0, AndroidUtilities.dp(16), 0); + if (!grid) { + setPadding(AndroidUtilities.dp(16), 0, AndroidUtilities.dp(16), 0); + } + + imageView = new ImageView(context); + imageView.setScaleType(ImageView.ScaleType.CENTER); + if (grid) { + addView(imageView, LayoutHelper.createFrame(48, 48, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 0, 8, 0, 0)); + } else { + addView(imageView, LayoutHelper.createFrame(24, 24, Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT))); + } textView = new TextView(context); - textView.setTextColor(0xff212121); - textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); - addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL)); + textView.setLines(1); + textView.setSingleLine(true); + textView.setGravity(Gravity.CENTER_HORIZONTAL); + textView.setEllipsize(TextUtils.TruncateAt.END); + if (grid) { + textView.setTextColor(0xff757575); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12); + addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 0, 60, 0, 0)); + } else { + textView.setTextColor(0xff212121); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL)); + } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(48), MeasureSpec.EXACTLY)); + super.onMeasure(isGrid ? MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(96), MeasureSpec.EXACTLY) : widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(isGrid ? 80 : 48), MeasureSpec.EXACTLY)); + } + + public void setTextAndIcon(CharSequence text, int icon) { + textView.setText(text); + if (icon != 0) { + imageView.setImageResource(icon); + imageView.setVisibility(VISIBLE); + if (!isGrid) { + textView.setPadding(LocaleController.isRTL ? 0 : AndroidUtilities.dp(56), 0, LocaleController.isRTL ? AndroidUtilities.dp(56) : 0, 0); + } + } else { + imageView.setVisibility(INVISIBLE); + textView.setPadding(0, 0, 0, 0); + } } } @@ -86,29 +147,17 @@ public class BottomSheet extends Dialog { return false; } }); + container.setBackgroundDrawable(backgroundDrawable); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - /* - @null - @null - fill_parent - @android:color/transparent - true - @null - true - @style/BottomSheet.Animation - #DD000000 - #8A000000 - #42000000 - */ - Window window = getWindow(); window.setBackgroundDrawableResource(R.drawable.transparent); window.requestFeature(Window.FEATURE_NO_TITLE); + window.setWindowAnimations(R.style.DialogNoAnimation); setContentView(container); @@ -127,34 +176,94 @@ public class BottomSheet extends Dialog { LinearLayout containerView = new LinearLayout(getContext()); containerView.setBackgroundColor(0xffffffff); containerView.setOrientation(LinearLayout.VERTICAL); - containerView.setPadding(0, AndroidUtilities.dp(8), 0, AndroidUtilities.dp(8)); + containerView.setPadding(0, AndroidUtilities.dp(8), 0, AndroidUtilities.dp(isGrid ? 16 : 8)); linearLayout.addView(containerView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); + if (title != null) { + TextView titleView = new TextView(getContext()); + titleView.setLines(1); + titleView.setSingleLine(true); + titleView.setText(title); + titleView.setTextColor(0xff757575); + titleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + titleView.setPadding(AndroidUtilities.dp(16), 0, AndroidUtilities.dp(16), AndroidUtilities.dp(8)); + titleView.setGravity(Gravity.CENTER_VERTICAL); + containerView.addView(titleView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48)); + titleView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + } + + if (customView != null) { + if (customView.getParent() != null) { + ViewGroup viewGroup = (ViewGroup) customView.getParent(); + viewGroup.removeView(customView); + } + containerView.addView(customView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); + } + if (items != null) { + if (customView != null) { + FrameLayout frameLayout = new FrameLayout(getContext()); + frameLayout.setPadding(0, AndroidUtilities.dp(8), 0, 0); + containerView.addView(frameLayout, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 16)); + + View lineView = new View(getContext()); + lineView.setBackgroundColor(0xffd2d2d2); + frameLayout.addView(lineView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1)); + } + FrameLayout rowLayout = null; + int lastRowLayoutNum = 0; for (int a = 0; a < items.length; a++) { - CharSequence charSequence = items[a]; - BottomSheetRow row = new BottomSheetRow(getContext()); - row.textView.setText(charSequence); - containerView.addView(row, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48)); - row.setTag(a); - row.setOnClickListener(new View.OnClickListener() { + BottomSheetCell cell = new BottomSheetCell(getContext(), isGrid); + cell.setTextAndIcon(items[a], itemIcons != null ? itemIcons[a] : 0); + if (isGrid) { + int row = a / 3; + if (rowLayout == null || lastRowLayoutNum != row) { + rowLayout = new FrameLayout(getContext()); + lastRowLayoutNum = row; + containerView.addView(rowLayout, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 80, 0, lastRowLayoutNum != 0 ? 8 : 0, 0, 0)); + rowLayout.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + } + int col = a % 3; + int gravity; + if (col == 0) { + gravity = Gravity.LEFT | Gravity.TOP; + } else if (col == 1) { + gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP; + } else { + gravity = Gravity.RIGHT | Gravity.TOP; + } + rowLayout.addView(cell, LayoutHelper.createFrame(96, 80, gravity)); + } else { + containerView.addView(cell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48)); + } + cell.setTag(a); + cell.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dismissWithButtonClick((Integer) v.getTag()); } }); + itemViews.add(cell); } } - if (customView != null) { - containerView.addView(customView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); - } WindowManager.LayoutParams params = getWindow().getAttributes(); params.height = ViewGroup.LayoutParams.MATCH_PARENT; params.width = ViewGroup.LayoutParams.MATCH_PARENT; params.gravity = Gravity.TOP | Gravity.LEFT; - params.dimAmount = 0.2f; - params.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; + params.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; + params.dimAmount = 0; + params.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND; if (Build.VERSION.SDK_INT >= 21) { params.flags |= WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR; @@ -164,20 +273,102 @@ public class BottomSheet extends Dialog { setOnShowListener(new OnShowListener() { @Override public void onShow(DialogInterface dialog) { - AnimatorSetProxy animatorSetProxy = new AnimatorSetProxy(); - animatorSetProxy.playTogether( - ObjectAnimatorProxy.ofFloat(linearLayout, "translationY", linearLayout.getHeight(), 0)); - animatorSetProxy.setDuration(180); - animatorSetProxy.setInterpolator(new DecelerateInterpolator()); - animatorSetProxy.addListener(new AnimatorListenerAdapterProxy() { - @Override - public void onAnimationEnd(Object animation) { - if (delegate != null) { - delegate.onOpenAnimationEnd(); + if (useRevealAnimation) { + int finalRadius = Math.max(AndroidUtilities.displaySize.x, container.getHeight()); + Animator anim = ViewAnimationUtils.createCircularReveal(container, revealX, revealY, 0, finalRadius); + anim.setDuration(400); + anim.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + if (delegate != null) { + delegate.onOpenAnimationStart(); + } } + + @Override + public void onAnimationEnd(Animator animation) { + if (delegate != null) { + delegate.onOpenAnimationEnd(); + } + } + + @Override + public void onAnimationCancel(Animator animation) { + + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + }); + anim.start(); + } else { + //startLayoutAnimation(true, true); + ViewProxy.setTranslationY(linearLayout, linearLayout.getHeight()); + backgroundDrawable.setAlpha(0); + AnimatorSetProxy animatorSetProxy = new AnimatorSetProxy(); + animatorSetProxy.playTogether( + ObjectAnimatorProxy.ofFloat(linearLayout, "translationY", 0), + ObjectAnimatorProxy.ofInt(backgroundDrawable, "alpha", 51)); + animatorSetProxy.setDuration(200); + animatorSetProxy.setStartDelay(20); + animatorSetProxy.setInterpolator(new DecelerateInterpolator()); + animatorSetProxy.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + if (delegate != null) { + delegate.onOpenAnimationEnd(); + } + } + }); + animatorSetProxy.start(); + } + } + }); + } + + private float animationProgress; + private long lastFrameTime; + private void startLayoutAnimation(final boolean open, final boolean first) { + if (first) { + animationProgress = 0.0f; + lastFrameTime = System.nanoTime() / 1000000; + if (Build.VERSION.SDK_INT >= 11) { + container.setLayerType(View.LAYER_TYPE_HARDWARE, null); + } + } + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + long newTime = System.nanoTime() / 1000000; + long dt = newTime - lastFrameTime; + FileLog.e("tmessages", "dt = " + dt); + if (dt > 16) { + dt = 16; + } + lastFrameTime = newTime; + animationProgress += dt / 200.0f; + if (animationProgress > 1.0f) { + animationProgress = 1.0f; + } + + if (open) { + float interpolated = decelerateInterpolator.getInterpolation(animationProgress); + ViewProxy.setTranslationY(linearLayout, linearLayout.getHeight() * (1.0f - interpolated)); + backgroundDrawable.setAlpha((int) (51 * interpolated)); + } else { + float interpolated = accelerateInterpolator.getInterpolation(animationProgress); + ViewProxy.setTranslationY(linearLayout, linearLayout.getHeight() * interpolated); + backgroundDrawable.setAlpha((int) (51 * (1.0f - interpolated))); + } + if (animationProgress < 1) { + startLayoutAnimation(open, false); + } else { + if (open && delegate != null) { + delegate.onOpenAnimationEnd(); } - }); - animatorSetProxy.start(); + } } }); } @@ -194,13 +385,26 @@ public class BottomSheet extends Dialog { return linearLayout; } + public int getTag() { + return tag; + } + + public void setItemText(int item, CharSequence text) { + if (item < 0 || item >= itemViews.size()) { + return; + } + BottomSheetCell cell = itemViews.get(item); + cell.textView.setText(text); + } + private void dismissWithButtonClick(final int item) { if (dismissed) { return; } AnimatorSetProxy animatorSetProxy = new AnimatorSetProxy(); animatorSetProxy.playTogether( - ObjectAnimatorProxy.ofFloat(linearLayout, "translationY", linearLayout.getHeight() + AndroidUtilities.dp(10)) + ObjectAnimatorProxy.ofFloat(linearLayout, "translationY", linearLayout.getHeight() + AndroidUtilities.dp(10)), + ObjectAnimatorProxy.ofInt(backgroundDrawable, "alpha", 0) ); animatorSetProxy.setDuration(180); animatorSetProxy.setInterpolator(new AccelerateInterpolator()); @@ -238,7 +442,8 @@ public class BottomSheet extends Dialog { dismissed = true; AnimatorSetProxy animatorSetProxy = new AnimatorSetProxy(); animatorSetProxy.playTogether( - ObjectAnimatorProxy.ofFloat(linearLayout, "translationY", linearLayout.getHeight() + AndroidUtilities.dp(10)) + ObjectAnimatorProxy.ofFloat(linearLayout, "translationY", linearLayout.getHeight() + AndroidUtilities.dp(10)), + ObjectAnimatorProxy.ofInt(backgroundDrawable, "alpha", 0) ); animatorSetProxy.setDuration(180); animatorSetProxy.setInterpolator(new AccelerateInterpolator()); @@ -279,11 +484,23 @@ public class BottomSheet extends Dialog { return this; } + public Builder setItems(CharSequence[] items, int[] icons, final OnClickListener onClickListener) { + bottomSheet.items = items; + bottomSheet.itemIcons = icons; + bottomSheet.onClickListener = onClickListener; + return this; + } + public Builder setCustomView(View view) { bottomSheet.customView = view; return this; } + public Builder setTitle(CharSequence title) { + bottomSheet.title = title; + return this; + } + public BottomSheet create() { return bottomSheet; } @@ -293,6 +510,28 @@ public class BottomSheet extends Dialog { return bottomSheet; } + public Builder setTag(int tag) { + bottomSheet.tag = tag; + return this; + } + + public Builder setRevealAnimation(int x, int y) { + bottomSheet.revealX = x; + bottomSheet.revealY = y; + bottomSheet.useRevealAnimation = true; + return this; + } + + public Builder setDelegate(BottomSheetDelegate delegate) { + bottomSheet.setDelegate(delegate); + return this; + } + + public Builder setIsGrid(boolean value) { + bottomSheet.isGrid = value; + return this; + } + public BottomSheet setOverrideTabletWidth(boolean value) { bottomSheet.overrideTabletWidth = value; return bottomSheet; 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 3596048d4..ce43585cc 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/DrawerLayoutContainer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/DrawerLayoutContainer.java @@ -25,6 +25,7 @@ import android.widget.FrameLayout; import android.widget.ListView; import org.telegram.android.AndroidUtilities; +import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.android.AnimationCompat.AnimatorListenerAdapterProxy; import org.telegram.android.AnimationCompat.AnimatorSetProxy; @@ -147,7 +148,7 @@ public class DrawerLayoutContainer extends FrameLayout { } requestLayout(); - final int newVisibility = drawerPosition > 0 ? VISIBLE : INVISIBLE; + final int newVisibility = drawerPosition > 0 ? VISIBLE : GONE; if (drawerLayout.getVisibility() != newVisibility) { drawerLayout.setVisibility(newVisibility); } @@ -393,10 +394,14 @@ public class DrawerLayoutContainer extends FrameLayout { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - if (drawerLayout != child) { - child.layout(lp.leftMargin, lp.topMargin, lp.leftMargin + child.getMeasuredWidth(), lp.topMargin + child.getMeasuredHeight()); - } else { - child.layout(-child.getMeasuredWidth() + (int)drawerPosition, lp.topMargin, (int)drawerPosition, lp.topMargin + child.getMeasuredHeight()); + try { + if (drawerLayout != child) { + child.layout(lp.leftMargin, lp.topMargin, lp.leftMargin + child.getMeasuredWidth(), lp.topMargin + child.getMeasuredHeight()); + } else { + child.layout(-child.getMeasuredWidth() + (int)drawerPosition, lp.topMargin, (int)drawerPosition, lp.topMargin + child.getMeasuredHeight()); + } + } catch (Exception e) { + FileLog.e("tmessages", e); } } inLayout = false; 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 56508d07a..6619e5902 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsAdapter.java @@ -19,10 +19,12 @@ import org.telegram.messenger.TLRPC; import org.telegram.ui.Cells.DialogCell; import org.telegram.ui.Cells.LoadingCell; +import java.util.ArrayList; + public class DialogsAdapter extends RecyclerView.Adapter { private Context mContext; - private boolean serverOnly; + private int dialogsType; private long openedDialogId; private int currentCount; @@ -33,9 +35,9 @@ public class DialogsAdapter extends RecyclerView.Adapter { } } - public DialogsAdapter(Context context, boolean onlyFromServer) { + public DialogsAdapter(Context context, int type) { mContext = context; - serverOnly = onlyFromServer; + dialogsType = type; } public void setOpenedDialogId(long id) { @@ -47,14 +49,20 @@ public class DialogsAdapter extends RecyclerView.Adapter { return current != getItemCount(); } + private ArrayList getDialogsArray() { + if (dialogsType == 0) { + return MessagesController.getInstance().dialogs; + } else if (dialogsType == 1) { + return MessagesController.getInstance().dialogsServerOnly; + } else if (dialogsType == 2) { + return MessagesController.getInstance().dialogsGroupsOnly; + } + return null; + } + @Override public int getItemCount() { - int count; - if (serverOnly) { - count = MessagesController.getInstance().dialogsServerOnly.size(); - } else { - count = MessagesController.getInstance().dialogs.size(); - } + int count = getDialogsArray().size(); if (count == 0 && MessagesController.getInstance().loadingDialogs) { return 0; } @@ -66,17 +74,11 @@ public class DialogsAdapter extends RecyclerView.Adapter { } public TLRPC.TL_dialog getItem(int i) { - if (serverOnly) { - if (i < 0 || i >= MessagesController.getInstance().dialogsServerOnly.size()) { - return null; - } - return MessagesController.getInstance().dialogsServerOnly.get(i); - } else { - if (i < 0 || i >= MessagesController.getInstance().dialogs.size()) { - return null; - } - return MessagesController.getInstance().dialogs.get(i); + ArrayList arrayList = getDialogsArray(); + if (i < 0 || i >= arrayList.size()) { + return null; } + return arrayList.get(i); } @Override @@ -100,22 +102,19 @@ public class DialogsAdapter extends RecyclerView.Adapter { if (viewHolder.getItemViewType() == 0) { DialogCell cell = (DialogCell) viewHolder.itemView; cell.useSeparator = (i != getItemCount() - 1); - TLRPC.TL_dialog dialog; - if (serverOnly) { - dialog = MessagesController.getInstance().dialogsServerOnly.get(i); - } else { - dialog = MessagesController.getInstance().dialogs.get(i); + TLRPC.TL_dialog dialog = getItem(i); + if (dialogsType == 0) { if (AndroidUtilities.isTablet()) { cell.setDialogSelected(dialog.id == openedDialogId); } } - cell.setDialog(dialog, i, serverOnly); + cell.setDialog(dialog, i, dialogsType); } } @Override public int getItemViewType(int i) { - if (serverOnly && i == MessagesController.getInstance().dialogsServerOnly.size() || !serverOnly && i == MessagesController.getInstance().dialogs.size()) { + if (i == getDialogsArray().size()) { return 1; } return 0; 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 0aae2b086..cf5a0d4f6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsSearchAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsSearchAdapter.java @@ -160,7 +160,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler { }, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors); } - private void searchDialogsInternal(final String query, final boolean serverOnly, final int searchId) { + private void searchDialogsInternal(final String query, final int dialogsType, final int searchId) { if (needMessagesSearch == 2) { return; } @@ -202,12 +202,12 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler { int high_id = (int) (id >> 32); if (lower_id != 0) { if (high_id == 1) { - if (!serverOnly && !chatsToLoad.contains(lower_id)) { + if (dialogsType == 0 && !chatsToLoad.contains(lower_id)) { chatsToLoad.add(lower_id); } } else { if (lower_id > 0) { - if (!usersToLoad.contains(lower_id)) { + if (dialogsType != 2 && !usersToLoad.contains(lower_id)) { usersToLoad.add(lower_id); } } else { @@ -216,7 +216,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler { } } } - } else if (!serverOnly) { + } else if (dialogsType == 0) { if (!encryptedToLoad.contains(high_id)) { encryptedToLoad.add(high_id); } @@ -394,49 +394,51 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler { resultArrayNames.add(dialogSearchResult.name); } - cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT u.data, u.status, u.name, u.uid FROM users as u INNER JOIN contacts as c ON u.uid = c.uid"); - while (cursor.next()) { - int uid = cursor.intValue(3); - if (dialogsResult.containsKey((long) uid)) { - continue; - } - String name = cursor.stringValue(2); - String tName = LocaleController.getInstance().getTranslitString(name); - if (name.equals(tName)) { - tName = null; - } - String username = null; - int usernamePos = name.lastIndexOf(";;;"); - if (usernamePos != -1) { - username = name.substring(usernamePos + 3); - } - int found = 0; - for (String q : search) { - 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; + if (dialogsType != 2) { + cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT u.data, u.status, u.name, u.uid FROM users as u INNER JOIN contacts as c ON u.uid = c.uid"); + while (cursor.next()) { + int uid = cursor.intValue(3); + if (dialogsResult.containsKey((long) uid)) { + continue; } - if (found != 0) { - ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0)); - if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { - TLRPC.User user = TLRPC.User.TLdeserialize(data, data.readInt32(false), false); - if (user.status != null) { - user.status.expires = cursor.intValue(1); - } - if (found == 1) { - resultArrayNames.add(AndroidUtilities.generateSearchName(user.first_name, user.last_name, q)); - } else { - resultArrayNames.add(AndroidUtilities.generateSearchName("@" + user.username, null, "@" + q)); - } - resultArray.add(user); + 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) { + username = name.substring(usernamePos + 3); + } + int found = 0; + for (String q : search) { + 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; + } + if (found != 0) { + ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0)); + if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { + TLRPC.User user = TLRPC.User.TLdeserialize(data, data.readInt32(false), false); + if (user.status != null) { + user.status.expires = cursor.intValue(1); + } + if (found == 1) { + resultArrayNames.add(AndroidUtilities.generateSearchName(user.first_name, user.last_name, q)); + } else { + resultArrayNames.add(AndroidUtilities.generateSearchName("@" + user.username, null, "@" + q)); + } + resultArray.add(user); + } + MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data); + break; } - MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data); - break; } } + cursor.dispose(); } - cursor.dispose(); updateSearchResults(resultArray, resultArrayNames, encUsers, searchId); } catch (Exception e) { @@ -502,13 +504,14 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler { notifyDataSetChanged(); } - public void searchDialogs(final String query, final boolean serverOnly) { + public void searchDialogs(final String query, final int dialogsType) { if (query != null && lastSearchText != null && query.equals(lastSearchText)) { return; } try { if (searchTimer != null) { searchTimer.cancel(); + searchTimer = null; } } catch (Exception e) { FileLog.e("tmessages", e); @@ -524,7 +527,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler { searchMessagesInternal(null); notifyDataSetChanged(); } else { - if (query.startsWith("#") && query.length() == 1) { + if (needMessagesSearch != 2 && (query.startsWith("#") && query.length() == 1)) { messagesSearchEndReached = true; if (!hashtagsLoadedFromDb) { loadRecentHashtags(); @@ -553,12 +556,13 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler { @Override public void run() { try { + cancel(); searchTimer.cancel(); searchTimer = null; } catch (Exception e) { FileLog.e("tmessages", e); } - searchDialogsInternal(query, serverOnly, searchId); + searchDialogsInternal(query, dialogsType, searchId); AndroidUtilities.runOnUIThread(new Runnable() { @Override public void run() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DrawerLayoutAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DrawerLayoutAdapter.java index 8304f7f7e..7e70d45cd 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DrawerLayoutAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DrawerLayoutAdapter.java @@ -13,6 +13,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; +import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; import org.telegram.android.MessagesController; import org.telegram.messenger.R; @@ -70,7 +71,7 @@ public class DrawerLayoutAdapter extends BaseAdapter { ((DrawerProfileCell) view).setUser(MessagesController.getInstance().getUser(UserConfig.getClientUserId())); } else if (type == 1) { if (view == null) { - view = new EmptyCell(mContext, 8); + view = new EmptyCell(mContext, AndroidUtilities.dp(8)); } } else if (type == 2) { if (view == null) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/MentionsAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/MentionsAdapter.java index 312038997..952216990 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/MentionsAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/MentionsAdapter.java @@ -14,6 +14,7 @@ import android.view.ViewGroup; import org.telegram.android.MessageObject; import org.telegram.android.MessagesController; +import org.telegram.android.UserObject; import org.telegram.messenger.TLRPC; import org.telegram.ui.Cells.MentionCell; @@ -32,7 +33,11 @@ public class MentionsAdapter extends BaseSearchAdapter { private TLRPC.ChatParticipants info; private ArrayList searchResultUsernames; private ArrayList searchResultHashtags; + private ArrayList searchResultCommands; + private ArrayList searchResultCommandsHelp; + private ArrayList searchResultCommandsUsers; private MentionsAdapterDelegate delegate; + private HashMap botInfo; private int resultStartPosition; private int resultLength; private String lastText; @@ -40,6 +45,7 @@ public class MentionsAdapter extends BaseSearchAdapter { private ArrayList messages; private boolean needUsernames = true; private boolean isDarkTheme; + private int botsCount; public MentionsAdapter(Context context, boolean isDarkTheme, MentionsAdapterDelegate delegate) { mContext = context; @@ -58,6 +64,14 @@ public class MentionsAdapter extends BaseSearchAdapter { needUsernames = value; } + public void setBotInfo(HashMap info) { + botInfo = info; + } + + public void setBotsCount(int count) { + botsCount = count; + } + @Override public void clearRecentHashtags() { super.clearRecentHashtags(); @@ -126,6 +140,11 @@ public class MentionsAdapter extends BaseSearchAdapter { resultLength = result.length() + 1; result.insert(0, ch); break; + } else if (a == 0 && botInfo != null && ch == '/') { + foundType = 2; + resultStartPosition = a; + resultLength = result.length() + 1; + break; } } if (!(ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch == '_')) { @@ -149,7 +168,7 @@ public class MentionsAdapter extends BaseSearchAdapter { ArrayList newResult = new ArrayList<>(); for (TLRPC.TL_chatParticipant chatParticipant : info.participants) { TLRPC.User user = MessagesController.getInstance().getUser(chatParticipant.user_id); - if (user == null || user instanceof TLRPC.TL_userSelf) { + if (user == null || UserObject.isUserSelf(user)) { continue; } if (user.username != null && user.username.length() > 0 && (usernameString.length() > 0 && user.username.toLowerCase().startsWith(usernameString) || usernameString.length() == 0)) { @@ -157,6 +176,9 @@ public class MentionsAdapter extends BaseSearchAdapter { } } searchResultHashtags = null; + searchResultCommands = null; + searchResultCommandsHelp = null; + searchResultCommandsUsers = null; searchResultUsernames = newResult; Collections.sort(searchResultUsernames, new Comparator() { @Override @@ -175,16 +197,40 @@ public class MentionsAdapter extends BaseSearchAdapter { }); notifyDataSetChanged(); delegate.needChangePanelVisibility(!newResult.isEmpty()); - } else { + } else if (foundType == 1) { ArrayList newResult = new ArrayList<>(); String hashtagString = result.toString().toLowerCase(); for (HashtagObject hashtagObject : hashtags) { - if (hashtagString != null && hashtagObject.hashtag != null && hashtagObject.hashtag.startsWith(hashtagString)) { + if (hashtagObject != null && hashtagObject.hashtag != null && hashtagObject.hashtag.startsWith(hashtagString)) { newResult.add(hashtagObject.hashtag); } } searchResultHashtags = newResult; searchResultUsernames = null; + searchResultCommands = null; + searchResultCommandsHelp = null; + searchResultCommandsUsers = null; + notifyDataSetChanged(); + delegate.needChangePanelVisibility(!newResult.isEmpty()); + } else if (foundType == 2) { + ArrayList newResult = new ArrayList<>(); + ArrayList newResultHelp = new ArrayList<>(); + ArrayList newResultUsers = new ArrayList<>(); + String command = result.toString().toLowerCase(); + for (HashMap.Entry entry : botInfo.entrySet()) { + for (TLRPC.TL_botCommand botCommand : entry.getValue().commands) { + if (botCommand != null && botCommand.command != null && botCommand.command.startsWith(command)) { + newResult.add("/" + botCommand.command); + newResultHelp.add(botCommand.description); + newResultUsers.add(MessagesController.getInstance().getUser(entry.getValue().user_id)); + } + } + } + searchResultHashtags = null; + searchResultUsernames = null; + searchResultCommands = newResult; + searchResultCommandsHelp = newResultHelp; + searchResultCommandsUsers = newResultUsers; notifyDataSetChanged(); delegate.needChangePanelVisibility(!newResult.isEmpty()); } @@ -209,6 +255,8 @@ public class MentionsAdapter extends BaseSearchAdapter { return searchResultUsernames.size(); } else if (searchResultHashtags != null) { return searchResultHashtags.size(); + } else if (searchResultCommands != null) { + return searchResultCommands.size(); } return 0; } @@ -219,6 +267,8 @@ public class MentionsAdapter extends BaseSearchAdapter { return searchResultUsernames.isEmpty(); } else if (searchResultHashtags != null) { return searchResultHashtags.isEmpty(); + } else if (searchResultCommands != null) { + return searchResultCommands.isEmpty(); } return true; } @@ -255,10 +305,26 @@ public class MentionsAdapter extends BaseSearchAdapter { return null; } return searchResultHashtags.get(i); + } else if (searchResultCommands != null) { + if (i < 0 || i >= searchResultCommands.size()) { + return null; + } + if (searchResultCommandsUsers != null && botsCount != 1) { + return String.format("%s@%s", searchResultCommands.get(i), searchResultCommandsUsers.get(i).username); + } + return searchResultCommands.get(i); } return null; } + public boolean isLongClickEnabled() { + return searchResultHashtags != null; + } + + public boolean isBotCommands() { + return searchResultCommands != null; + } + @Override public View getView(int i, View view, ViewGroup viewGroup) { if (view == null) { @@ -269,6 +335,8 @@ public class MentionsAdapter extends BaseSearchAdapter { ((MentionCell) view).setUser(searchResultUsernames.get(i)); } else if (searchResultHashtags != null) { ((MentionCell) view).setText(searchResultHashtags.get(i)); + } else if (searchResultCommands != null) { + ((MentionCell) view).setBotCommand(searchResultCommands.get(i), searchResultCommandsHelp.get(i), searchResultCommandsUsers.get(i)); } return view; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/PhotoAttachAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/PhotoAttachAdapter.java new file mode 100644 index 000000000..d1f497b7b --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/PhotoAttachAdapter.java @@ -0,0 +1,123 @@ +/* + * This is the source code of Telegram for Android v. 2.x.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2015. + */ + +package org.telegram.ui.Adapters; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; + +import org.telegram.android.MediaController; +import org.telegram.android.NotificationCenter; +import org.telegram.android.support.widget.RecyclerView; +import org.telegram.ui.Cells.PhotoAttachPhotoCell; + +import java.util.HashMap; + +public class PhotoAttachAdapter extends RecyclerView.Adapter implements NotificationCenter.NotificationCenterDelegate { + + private Context mContext; + private PhotoAttachAdapterDelegate delegate; + private HashMap selectedPhotos = new HashMap<>(); + + public interface PhotoAttachAdapterDelegate { + void selectedPhotosChanged(); + } + + private class Holder extends RecyclerView.ViewHolder { + + public Holder(View itemView) { + super(itemView); + } + } + + public PhotoAttachAdapter(Context context) { + mContext = context; + NotificationCenter.getInstance().addObserver(this, NotificationCenter.albumsDidLoaded); + if (MediaController.allPhotosAlbumEntry == null) { + MediaController.loadGalleryPhotosAlbums(0); + } + } + + public void onDestroy() { + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.albumsDidLoaded); + } + + public void clearSelectedPhotos() { + if (!selectedPhotos.isEmpty()) { + selectedPhotos.clear(); + delegate.selectedPhotosChanged(); + notifyDataSetChanged(); + } + } + + public HashMap getSelectedPhotos() { + return selectedPhotos; + } + + public void setDelegate(PhotoAttachAdapterDelegate photoAttachAdapterDelegate) { + delegate = photoAttachAdapterDelegate; + } + + @Override + public void didReceivedNotification(int id, Object... args) { + if (id == NotificationCenter.albumsDidLoaded) { + notifyDataSetChanged(); + } + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + //if (position != 0) { + PhotoAttachPhotoCell cell = (PhotoAttachPhotoCell) holder.itemView; + MediaController.PhotoEntry photoEntry = MediaController.allPhotosAlbumEntry.photos.get(position/* - 1*/); + cell.setPhotoEntry(photoEntry, position == MediaController.allPhotosAlbumEntry.photos.size()); + cell.setChecked(selectedPhotos.containsKey(photoEntry.imageId), false); + //} + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view; + /*if (viewType == 0) { + view = new PhotoAttachCameraCell(mContext); + } else {*/ + PhotoAttachPhotoCell cell = new PhotoAttachPhotoCell(mContext); + cell.setOnCheckClickLisnener(new View.OnClickListener() { + @Override + public void onClick(View v) { + PhotoAttachPhotoCell cell = (PhotoAttachPhotoCell) v.getParent(); + MediaController.PhotoEntry photoEntry = cell.getPhotoEntry(); + if (selectedPhotos.containsKey(photoEntry.imageId)) { + selectedPhotos.remove(photoEntry.imageId); + cell.setChecked(false, true); + } else { + selectedPhotos.put(photoEntry.imageId, photoEntry); + cell.setChecked(true, true); + } + delegate.selectedPhotosChanged(); + } + }); + view = cell; + //} + return new Holder(view); + } + + @Override + public int getItemCount() { + return /*1 + */(MediaController.allPhotosAlbumEntry != null ? MediaController.allPhotosAlbumEntry.photos.size() : 0); + } + + @Override + public int getItemViewType(int position) { + //if (position == 0) { + return 0; + //} + //return 1; + } +} 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 38bb738f5..00206cf9b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/StickersAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/StickersAdapter.java @@ -51,7 +51,7 @@ public class StickersAdapter extends RecyclerView.Adapter implements Notificatio NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidFailedLoad); } - public void destroy() { + public void onDestroy() { NotificationCenter.getInstance().removeObserver(this, NotificationCenter.FileDidLoaded); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.FileDidFailedLoad); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/AddMemberCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/AddMemberCell.java index a4cff7ad0..4f6760572 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/AddMemberCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/AddMemberCell.java @@ -21,6 +21,8 @@ import org.telegram.ui.Components.SimpleTextView; public class AddMemberCell extends FrameLayout { + private SimpleTextView textView; + public AddMemberCell(Context context) { super(context); @@ -29,10 +31,9 @@ public class AddMemberCell extends FrameLayout { imageView.setScaleType(ImageView.ScaleType.CENTER); addView(imageView, LayoutHelper.createFrame(48, 48, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 68, 8, LocaleController.isRTL ? 68 : 0, 0)); - SimpleTextView textView = new SimpleTextView(context); + textView = new SimpleTextView(context); textView.setTextColor(0xff212121); textView.setTextSize(17); - textView.setText(LocaleController.getString("AddMember", R.string.AddMember)); textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP); addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 20, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 28 : 129, 22.5f, LocaleController.isRTL ? 129 : 28, 0)); } @@ -41,4 +42,8 @@ public class AddMemberCell extends FrameLayout { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(64), MeasureSpec.EXACTLY)); } + + public void setText(String text) { + textView.setText(text); + } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/BaseCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/BaseCell.java index c0170b66f..df37101dd 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/BaseCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/BaseCell.java @@ -80,6 +80,11 @@ public class BaseCell extends View { } } + @Override + public boolean hasOverlappingRendering() { + return false; + } + protected void onLongPress() { } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/BotHelpCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/BotHelpCell.java new file mode 100644 index 000000000..6c05ae107 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/BotHelpCell.java @@ -0,0 +1,196 @@ +/* + * This is the source code of Telegram for Android v. 2.x.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2015. + */ + +package org.telegram.ui.Cells; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.text.Layout; +import android.text.Spannable; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.StaticLayout; +import android.text.TextPaint; +import android.text.style.ClickableSpan; +import android.view.MotionEvent; +import android.view.View; + +import org.telegram.android.AndroidUtilities; +import org.telegram.android.LocaleController; +import org.telegram.android.MessageObject; +import org.telegram.messenger.FileLog; +import org.telegram.messenger.R; +import org.telegram.ui.Components.LinkPath; +import org.telegram.ui.Components.ResourceLoader; +import org.telegram.ui.Components.TypefaceSpan; +import org.telegram.ui.Components.URLSpanNoUnderline; + +public class BotHelpCell extends View { + + private StaticLayout textLayout; + private TextPaint textPaint; + private Paint urlPaint; + private String oldText; + + private int width; + private int height; + private int textX; + private int textY; + + private ClickableSpan pressedLink; + private LinkPath urlPath = new LinkPath(); + + private BotHelpCellDelegate delegate; + + public interface BotHelpCellDelegate { + void didPressUrl(String url); + } + + public BotHelpCell(Context context) { + super(context); + + textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); + textPaint.setTextSize(AndroidUtilities.dp(16)); + textPaint.setColor(0xff000000); + textPaint.linkColor = 0xff316f9f; + + urlPaint = new Paint(); + urlPaint.setColor(0x33316f9f); + } + + public void setDelegate(BotHelpCellDelegate botHelpCellDelegate) { + delegate = botHelpCellDelegate; + } + + private void resetPressedLink() { + if (pressedLink != null) { + pressedLink = null; + } + invalidate(); + } + + public void setText(String text) { + if (text == null || text.length() == 0) { + setVisibility(GONE); + return; + } + if (text != null && oldText != null && text.equals(oldText)) { + return; + } + oldText = text; + setVisibility(VISIBLE); + if (AndroidUtilities.isTablet()) { + width = (int) (AndroidUtilities.getMinTabletSide() * 0.7f); + } else { + width = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.7f); + } + SpannableStringBuilder stringBuilder = new SpannableStringBuilder(); + String help = LocaleController.getString("BotInfoTitle", R.string.BotInfoTitle); + stringBuilder.append(help); + stringBuilder.append("\n\n"); + stringBuilder.append(text); + MessageObject.addLinks(stringBuilder); + stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), 0, help.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + textLayout = new StaticLayout(stringBuilder, textPaint, width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); + width = 0; + height = textLayout.getHeight() + AndroidUtilities.dp(4 + 18); + int count = textLayout.getLineCount(); + for (int a = 0; a < count; a++) { + width = (int) Math.ceil(Math.max(width, textLayout.getLineWidth(a) - textLayout.getLineLeft(a))); + } + width += AndroidUtilities.dp(4 + 18); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + float x = event.getX(); + float y = event.getY(); + + boolean result = false; + int side = AndroidUtilities.dp(48); + if (textLayout != null) { + if (event.getAction() == MotionEvent.ACTION_DOWN || pressedLink != null && event.getAction() == MotionEvent.ACTION_UP) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + resetPressedLink(); + try { + int x2 = (int) (x - textX); + int y2 = (int) (y - textY); + final int line = textLayout.getLineForVertical(y2); + final int off = textLayout.getOffsetForHorizontal(line, x2); + + final float left = textLayout.getLineLeft(line); + if (left <= x2 && left + textLayout.getLineWidth(line) >= x2) { + Spannable buffer = (Spannable) textLayout.getText(); + ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class); + if (link.length != 0) { + resetPressedLink(); + pressedLink = link[0]; + result = true; + try { + int start = buffer.getSpanStart(pressedLink); + urlPath.setCurrentLayout(textLayout, start); + textLayout.getSelectionPath(start, buffer.getSpanEnd(pressedLink), urlPath); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } else { + resetPressedLink(); + } + } else { + resetPressedLink(); + } + } catch (Exception e) { + resetPressedLink(); + FileLog.e("tmessages", e); + } + } else if (pressedLink != null) { + try { + if (pressedLink instanceof URLSpanNoUnderline) { + String url = ((URLSpanNoUnderline) pressedLink).getURL(); + if (url.startsWith("@") || url.startsWith("#") || url.startsWith("/")) { + if (delegate != null) { + delegate.didPressUrl(url); + } + } + } else { + pressedLink.onClick(this); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + resetPressedLink(); + result = true; + } + } else if (event.getAction() == MotionEvent.ACTION_CANCEL) { + resetPressedLink(); + } + } + return result || super.onTouchEvent(event); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), height + AndroidUtilities.dp(8)); + } + + @Override + protected void onDraw(Canvas canvas) { + int x = (canvas.getWidth() - width) / 2; + int y = AndroidUtilities.dp(4); + ResourceLoader.backgroundMediaDrawableIn.setBounds(x, y, width + x, height + y); + ResourceLoader.backgroundMediaDrawableIn.draw(canvas); + canvas.save(); + canvas.translate(textX = AndroidUtilities.dp(2 + 9) + x, textY = AndroidUtilities.dp(2 + 9) + y); + if (pressedLink != null) { + canvas.drawPath(urlPath, urlPaint); + } + textLayout.draw(canvas); + canvas.restore(); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatAudioCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatAudioCell.java index 66862c623..1b7a9db99 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatAudioCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatAudioCell.java @@ -144,14 +144,14 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega buttonState = 3; invalidate(); } else if (buttonState == 3) { + FileLoader.getInstance().cancelLoadFile(currentMessageObject.messageOwner.media.audio); + buttonState = 2; + invalidate(); + } else if (buttonState == 4) { if (currentMessageObject.isOut() && currentMessageObject.isSending()) { if (delegate != null) { delegate.didPressedCancelSendButton(this); } - } else { - FileLoader.getInstance().cancelLoadFile(currentMessageObject.messageOwner.media.audio); - buttonState = 2; - invalidate(); } } } @@ -194,8 +194,16 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega if (currentMessageObject.isOut() && currentMessageObject.isSending()) { buttonState = 4; } else { - String fileName = currentMessageObject.getFileName(); - File cacheFile = FileLoader.getPathToMessage(currentMessageObject.messageOwner); + File cacheFile = null; + if (currentMessageObject.messageOwner.attachPath != null && currentMessageObject.messageOwner.attachPath.length() > 0) { + cacheFile = new File(currentMessageObject.messageOwner.attachPath); + if(!cacheFile.exists()) { + cacheFile = null; + } + } + if (cacheFile == null) { + cacheFile = FileLoader.getPathToMessage(currentMessageObject.messageOwner); + } if (cacheFile.exists()) { MediaController.getInstance().removeLoadingFileObserver(this); boolean playing = MediaController.getInstance().isPlayingAudio(currentMessageObject); @@ -206,6 +214,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega } progressView.setProgress(0); } else { + String fileName = currentMessageObject.getFileName(); MediaController.getInstance().addLoadingFileObserver(fileName, this); if (!FileLoader.getInstance().isLoadingFile(fileName)) { buttonState = 2; 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 5b8f96c46..8e28d5163 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java @@ -13,7 +13,6 @@ import android.content.Context; import android.content.res.Configuration; import android.graphics.Canvas; import android.graphics.Paint; -import android.graphics.Path; import android.graphics.drawable.Drawable; import android.text.Layout; import android.text.StaticLayout; @@ -24,9 +23,9 @@ import android.view.MotionEvent; import android.view.SoundEffectConstants; import org.telegram.android.AndroidUtilities; -import org.telegram.android.ContactsController; import org.telegram.android.Emoji; import org.telegram.android.LocaleController; +import org.telegram.android.UserObject; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; @@ -36,6 +35,7 @@ import org.telegram.messenger.R; import org.telegram.android.MessageObject; import org.telegram.android.ImageReceiver; import org.telegram.ui.Components.AvatarDrawable; +import org.telegram.ui.Components.LinkPath; import org.telegram.ui.Components.ResourceLoader; import org.telegram.ui.Components.StaticLayoutEx; @@ -46,49 +46,14 @@ public class ChatBaseCell extends BaseCell { void didPressedCancelSendButton(ChatBaseCell cell); void didLongPressed(ChatBaseCell cell); void didPressReplyMessage(ChatBaseCell cell, int id); - void didPressUrl(String url); + void didPressUrl(MessageObject messageObject, String url); void needOpenWebView(String url, String title, String originalUrl, int w, int h); boolean canPerformActions(); } - protected class MyPath extends Path { - - private StaticLayout currentLayout; - private int currentLine; - private float lastTop = -1; - - public void setCurrentLayout(StaticLayout layout, int start) { - currentLayout = layout; - currentLine = layout.getLineForOffset(start); - lastTop = -1; - } - - @Override - public void addRect(float left, float top, float right, float bottom, Direction dir) { - if (lastTop == -1) { - lastTop = top; - } else if (lastTop != top) { - lastTop = top; - currentLine++; - } - float lineRight = currentLayout.getLineRight(currentLine); - float lineLeft = currentLayout.getLineLeft(currentLine); - if (left >= lineRight) { - return; - } - if (right > lineRight) { - right = lineRight; - } - if (left < lineLeft) { - left = lineLeft; - } - super.addRect(left, top, right, bottom, dir); - } - } - protected ClickableSpan pressedLink; protected boolean linkPreviewPressed; - protected MyPath urlPath = new MyPath(); + protected LinkPath urlPath = new LinkPath(); protected static Paint urlPaint; public boolean isChat = false; @@ -294,7 +259,7 @@ public class ChatBaseCell extends BaseCell { String newNameString = null; if (drawName && isChat && newUser != null && !currentMessageObject.isOut()) { - newNameString = ContactsController.formatName(newUser.first_name, newUser.last_name); + newNameString = UserObject.getUserName(newUser); } if (currentNameString == null && newNameString != null || currentNameString != null && newNameString == null || currentNameString != null && newNameString != null && !currentNameString.equals(newNameString)) { @@ -304,7 +269,7 @@ public class ChatBaseCell extends BaseCell { newUser = MessagesController.getInstance().getUser(currentMessageObject.messageOwner.fwd_from_id); newNameString = null; if (newUser != null && drawForwardedName && currentMessageObject.messageOwner.fwd_from_id != 0) { - newNameString = ContactsController.formatName(newUser.first_name, newUser.last_name); + newNameString = UserObject.getUserName(newUser); } return currentForwardNameString == null && newNameString != null || currentForwardNameString != null && newNameString == null || currentForwardNameString != null && newNameString != null && !currentForwardNameString.equals(newNameString); } @@ -370,7 +335,7 @@ public class ChatBaseCell extends BaseCell { namesOffset = 0; if (drawName && isChat && currentUser != null && !currentMessageObject.isOut()) { - currentNameString = ContactsController.formatName(currentUser.first_name, currentUser.last_name); + currentNameString = UserObject.getUserName(currentUser); nameWidth = getMaxNameWidth(); CharSequence nameStringFinal = TextUtils.ellipsize(currentNameString.replace("\n", " "), namePaint, nameWidth - AndroidUtilities.dp(12), TextUtils.TruncateAt.END); @@ -391,7 +356,7 @@ public class ChatBaseCell extends BaseCell { if (drawForwardedName && messageObject.isForwarded()) { currentForwardUser = MessagesController.getInstance().getUser(messageObject.messageOwner.fwd_from_id); if (currentForwardUser != null) { - currentForwardNameString = ContactsController.formatName(currentForwardUser.first_name, currentForwardUser.last_name); + currentForwardNameString = UserObject.getUserName(currentForwardUser); forwardedNameWidth = getMaxNameWidth(); @@ -472,7 +437,7 @@ public class ChatBaseCell extends BaseCell { TLRPC.User user = MessagesController.getInstance().getUser(messageObject.replyMessageObject.messageOwner.from_id); if (user != null) { - stringFinalName = TextUtils.ellipsize(ContactsController.formatName(user.first_name, user.last_name).replace("\n", " "), replyNamePaint, maxWidth - AndroidUtilities.dp(8), TextUtils.TruncateAt.END); + stringFinalName = TextUtils.ellipsize(UserObject.getUserName(user).replace("\n", " "), replyNamePaint, maxWidth - AndroidUtilities.dp(8), TextUtils.TruncateAt.END); } if (messageObject.replyMessageObject.messageText != null && messageObject.replyMessageObject.messageText.length() > 0) { String mess = messageObject.replyMessageObject.messageText.toString(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatLoadingCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatLoadingCell.java new file mode 100644 index 000000000..0dfb3026c --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatLoadingCell.java @@ -0,0 +1,51 @@ +/* + * This is the source code of Telegram for Android v. 2.x.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.view.Gravity; +import android.widget.FrameLayout; +import android.widget.ProgressBar; + +import org.telegram.android.AndroidUtilities; +import org.telegram.messenger.ApplicationLoader; +import org.telegram.messenger.R; +import org.telegram.ui.Components.LayoutHelper; + +public class ChatLoadingCell extends FrameLayout { + + private FrameLayout frameLayout; + + public ChatLoadingCell(Context context) { + super(context); + + frameLayout = new FrameLayout(context); + frameLayout.setBackgroundResource(ApplicationLoader.isCustomTheme() ? R.drawable.system_loader2 : R.drawable.system_loader1); + addView(frameLayout, LayoutHelper.createFrame(36, 36, Gravity.CENTER)); + + ProgressBar progressBar = new ProgressBar(context); + try { + progressBar.setIndeterminateDrawable(getResources().getDrawable(R.drawable.loading_animation)); + } catch (Exception e) { + //don't promt + } + progressBar.setIndeterminate(true); + AndroidUtilities.setProgressBarAnimationDuration(progressBar, 1500); + frameLayout.addView(progressBar, LayoutHelper.createFrame(32, 32, Gravity.CENTER)); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(44), MeasureSpec.EXACTLY)); + } + + public void setProgressVisible(boolean value) { + frameLayout.setVisibility(value ? VISIBLE : INVISIBLE); + } +} 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 df409c4b7..23f72ec76 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java @@ -172,7 +172,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD boolean result = false; int side = AndroidUtilities.dp(48); - if (currentMessageObject.caption instanceof Spannable && !isPressed) { + if (currentMessageObject.caption instanceof Spannable && delegate.canPerformActions()) { if (event.getAction() == MotionEvent.ACTION_DOWN || (linkPreviewPressed || pressedLink != null) && event.getAction() == MotionEvent.ACTION_UP) { if (nameLayout != null && x >= captionX && x <= captionX + backgroundWidth && y >= captionY && y <= captionY + captionHeight) { if (event.getAction() == MotionEvent.ACTION_DOWN) { @@ -213,9 +213,9 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD try { if (pressedLink instanceof URLSpanNoUnderline) { String url = ((URLSpanNoUnderline) pressedLink).getURL(); - if (url.startsWith("@") || url.startsWith("#")) { + if (url.startsWith("@") || url.startsWith("#") || url.startsWith("/")) { if (delegate != null) { - delegate.didPressUrl(url); + delegate.didPressUrl(currentMessageObject, url); } } } else { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java index 8e5924c37..aac1b324d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java @@ -79,7 +79,7 @@ public class ChatMessageCell extends ChatBaseCell { @Override public boolean onTouchEvent(MotionEvent event) { boolean result = false; - if (currentMessageObject != null && currentMessageObject.textLayoutBlocks != null && !currentMessageObject.textLayoutBlocks.isEmpty() && currentMessageObject.messageText instanceof Spannable && !isPressed) { + if (currentMessageObject != null && currentMessageObject.textLayoutBlocks != null && !currentMessageObject.textLayoutBlocks.isEmpty() && currentMessageObject.messageText instanceof Spannable && delegate.canPerformActions()) { if (event.getAction() == MotionEvent.ACTION_DOWN || (linkPreviewPressed || pressedLink != null) && event.getAction() == MotionEvent.ACTION_UP) { int x = (int) event.getX(); int y = (int) event.getY(); @@ -116,9 +116,9 @@ public class ChatMessageCell extends ChatBaseCell { try { if (pressedLink instanceof URLSpanNoUnderline) { String url = ((URLSpanNoUnderline) pressedLink).getURL(); - if (url.startsWith("@") || url.startsWith("#")) { + if (url.startsWith("@") || url.startsWith("#") || url.startsWith("/")) { if (delegate != null) { - delegate.didPressUrl(url); + delegate.didPressUrl(currentMessageObject, url); } } } else { @@ -618,7 +618,7 @@ public class ChatMessageCell extends ChatBaseCell { } } - if (webPage.duration != 0) { + if (webPage.type != null && webPage.type.equals("video") && webPage.duration != 0) { if (durationPaint == null) { durationPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); durationPaint.setTextSize(AndroidUtilities.dp(12)); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatUnreadCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatUnreadCell.java new file mode 100644 index 000000000..a40e5e8e9 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatUnreadCell.java @@ -0,0 +1,53 @@ +/* + * This is the source code of Telegram for Android v. 2.x.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.ImageView; +import android.widget.TextView; + +import org.telegram.android.AndroidUtilities; +import org.telegram.messenger.R; +import org.telegram.ui.Components.LayoutHelper; + +public class ChatUnreadCell extends FrameLayout { + + private TextView textView; + + public ChatUnreadCell(Context context) { + super(context); + + FrameLayout frameLayout = new FrameLayout(context); + frameLayout.setBackgroundResource(R.drawable.newmsg_divider); + addView(frameLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 27, Gravity.LEFT | Gravity.TOP, 0, 7, 0, 0)); + + ImageView imageView = new ImageView(context); + imageView.setImageResource(R.drawable.ic_ab_new); + imageView.setPadding(0, AndroidUtilities.dp(2), 0, 0); + frameLayout.addView(imageView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.RIGHT | Gravity.CENTER_VERTICAL, 0, 0, 10, 0)); + + textView = new TextView(context); + textView.setPadding(0, 0, 0, AndroidUtilities.dp(1)); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + textView.setTextColor(0xff4a7297); + addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER)); + } + + public void setText(String text) { + textView.setText(text); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(40), MeasureSpec.EXACTLY)); + } +} 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 41a469e9e..b163ec918 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java @@ -23,6 +23,7 @@ import org.telegram.android.AndroidUtilities; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.LocaleController; import org.telegram.android.MessageObject; +import org.telegram.android.UserObject; import org.telegram.messenger.FileLog; import org.telegram.messenger.TLRPC; import org.telegram.android.ContactsController; @@ -33,6 +34,8 @@ import org.telegram.messenger.UserConfig; import org.telegram.android.ImageReceiver; import org.telegram.ui.Components.AvatarDrawable; +import java.util.ArrayList; + public class DialogCell extends BaseCell { private static TextPaint namePaint; @@ -65,7 +68,7 @@ public class DialogCell extends BaseCell { private boolean dialogMuted; private MessageObject message; private int index; - private boolean isServerOnly; + private int dialogsType; private ImageReceiver avatarImage; private AvatarDrawable avatarDrawable; @@ -176,11 +179,11 @@ public class DialogCell extends BaseCell { avatarDrawable = new AvatarDrawable(); } - public void setDialog(TLRPC.TL_dialog dialog, int i, boolean server) { + public void setDialog(TLRPC.TL_dialog dialog, int i, int type) { currentDialogId = dialog.id; isDialogCell = true; index = i; - isServerOnly = server; + dialogsType = type; update(0); } @@ -349,12 +352,14 @@ public class DialogCell extends BaseCell { currentMessagePaint = messagePrintingPaint; } else { if (chat != null && chat.id > 0) { - String name = ""; + String name; if (message.isOut()) { name = LocaleController.getString("FromYou", R.string.FromYou); } else { - if (fromUser != null) { - if (fromUser.first_name.length() > 0) { + if (UserObject.isDeleted(fromUser)) { + name = "Deleted"; + } else { + if (fromUser.first_name != null && fromUser.first_name.length() > 0) { name = fromUser.first_name; } else { name = fromUser.last_name; @@ -368,11 +373,11 @@ public class DialogCell extends BaseCell { mess = mess.substring(0, 150); } mess = mess.replace("\n", " "); - messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("%s: %s", name, mess)), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20)); + messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("%s: %s", name, mess), AndroidUtilities.FLAG_TAG_COLOR), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20)); } else { if (message.messageOwner.media != null && !message.isMediaEmpty()) { currentMessagePaint = messagePrintingPaint; - messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("%s: %s", name, message.messageText)), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20)); + messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("%s: %s", name, message.messageText), AndroidUtilities.FLAG_TAG_COLOR), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20)); } else { if (message.messageOwner.message != null) { String mess = message.messageOwner.message; @@ -380,7 +385,7 @@ public class DialogCell extends BaseCell { mess = mess.substring(0, 150); } mess = mess.replace("\n", " "); - messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("%s: %s", name, mess)), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20)); + messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("%s: %s", name, mess), AndroidUtilities.FLAG_TAG_COLOR), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20)); } } } @@ -448,17 +453,17 @@ public class DialogCell extends BaseCell { } else if (user != null) { if (user.id / 1000 != 777 && user.id / 1000 != 333 && ContactsController.getInstance().contactsDict.get(user.id) == null) { if (ContactsController.getInstance().contactsDict.size() == 0 && (!ContactsController.getInstance().contactsLoaded || ContactsController.getInstance().isLoadingContacts())) { - nameString = ContactsController.formatName(user.first_name, user.last_name); + nameString = UserObject.getUserName(user); } else { if (user.phone != null && user.phone.length() != 0) { nameString = PhoneFormat.getInstance().format("+" + user.phone); } else { currentNamePaint = nameUnknownPaint; - nameString = ContactsController.formatName(user.first_name, user.last_name); + nameString = UserObject.getUserName(user); } } } else { - nameString = ContactsController.formatName(user.first_name, user.last_name); + nameString = UserObject.getUserName(user); } if (encryptedChat != null) { currentNamePaint = nameEncryptedPaint; @@ -641,18 +646,20 @@ public class DialogCell extends BaseCell { isSelected = value; } - public void checkCurrentDialogIndex() { - TLRPC.TL_dialog dialog = null; - if (isServerOnly) { - if (index < MessagesController.getInstance().dialogsServerOnly.size()) { - dialog = MessagesController.getInstance().dialogsServerOnly.get(index); - } - } else { - if (index < MessagesController.getInstance().dialogs.size()) { - dialog = MessagesController.getInstance().dialogs.get(index); - } + private ArrayList getDialogsArray() { + if (dialogsType == 0) { + return MessagesController.getInstance().dialogs; + } else if (dialogsType == 1) { + return MessagesController.getInstance().dialogsServerOnly; + } else if (dialogsType == 2) { + return MessagesController.getInstance().dialogsGroupsOnly; } - if (dialog != null) { + return null; + } + + public void checkCurrentDialogIndex() { + if (index < getDialogsArray().size()) { + TLRPC.TL_dialog dialog = getDialogsArray().get(index); if (currentDialogId != dialog.id || message != null && message.getId() != dialog.top_message || unreadCount != dialog.unread_count) { currentDialogId = dialog.id; update(0); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DrawerProfileCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DrawerProfileCell.java index 1d2692c6a..a3977bdbc 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DrawerProfileCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DrawerProfileCell.java @@ -25,7 +25,7 @@ import android.widget.TextView; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.AndroidUtilities; -import org.telegram.android.ContactsController; +import org.telegram.android.UserObject; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; @@ -128,7 +128,7 @@ public class DrawerProfileCell extends FrameLayout { if (user.photo != null) { photo = user.photo.photo_small; } - nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name)); + nameTextView.setText(UserObject.getUserName(user)); phoneTextView.setText(PhoneFormat.getInstance().format("+" + user.phone)); AvatarDrawable avatarDrawable = new AvatarDrawable(user); avatarDrawable.setColor(0xff5c98cd); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/MentionCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/MentionCell.java index 7a477eafb..eae727cb3 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/MentionCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/MentionCell.java @@ -16,7 +16,7 @@ import android.widget.LinearLayout; import android.widget.TextView; import org.telegram.android.AndroidUtilities; -import org.telegram.android.ContactsController; +import org.telegram.android.UserObject; import org.telegram.messenger.TLRPC; import org.telegram.ui.Components.AvatarDrawable; import org.telegram.ui.Components.BackupImageView; @@ -55,7 +55,7 @@ public class MentionCell extends LinearLayout { usernameTextView.setSingleLine(true); usernameTextView.setGravity(Gravity.LEFT); usernameTextView.setEllipsize(TextUtils.TruncateAt.END); - addView(usernameTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL, 12, 0, 0, 0)); + addView(usernameTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL, 12, 0, 8, 0)); } @Override @@ -76,7 +76,7 @@ public class MentionCell extends LinearLayout { } else { imageView.setImageDrawable(avatarDrawable); } - nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name)); + nameTextView.setText(UserObject.getUserName(user)); usernameTextView.setText("@" + user.username); imageView.setVisibility(VISIBLE); usernameTextView.setVisibility(VISIBLE); @@ -88,6 +88,23 @@ public class MentionCell extends LinearLayout { nameTextView.setText(text); } + public void setBotCommand(String command, String help, TLRPC.User user) { + if (user != null) { + imageView.setVisibility(VISIBLE); + avatarDrawable.setInfo(user); + if (user.photo != null && user.photo.photo_small != null) { + imageView.setImage(user.photo.photo_small, "50_50", avatarDrawable); + } else { + imageView.setImageDrawable(avatarDrawable); + } + } else { + imageView.setVisibility(INVISIBLE); + } + usernameTextView.setVisibility(VISIBLE); + nameTextView.setText(command); + usernameTextView.setText(help); + } + public void setIsDarkTheme(boolean isDarkTheme) { if (isDarkTheme) { nameTextView.setTextColor(0xffffffff); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoAttachCameraCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoAttachCameraCell.java new file mode 100644 index 000000000..54414ebc2 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoAttachCameraCell.java @@ -0,0 +1,35 @@ +/* + * This is the source code of Telegram for Android v. 2.x.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.widget.FrameLayout; +import android.widget.ImageView; + +import org.telegram.android.AndroidUtilities; +import org.telegram.messenger.R; +import org.telegram.ui.Components.LayoutHelper; + +public class PhotoAttachCameraCell extends FrameLayout { + + public PhotoAttachCameraCell(Context context) { + super(context); + + ImageView imageView = new ImageView(context); + imageView.setScaleType(ImageView.ScaleType.CENTER); + imageView.setImageResource(R.drawable.ic_attach_photobig); + imageView.setBackgroundColor(0xff777777); + addView(imageView, LayoutHelper.createFrame(80, 80)); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(86), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(80), MeasureSpec.EXACTLY)); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoAttachPhotoCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoAttachPhotoCell.java new file mode 100644 index 000000000..bf00964c4 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoAttachPhotoCell.java @@ -0,0 +1,85 @@ +/* + * This is the source code of Telegram for Android v. 2.x.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.view.Gravity; +import android.view.View; +import android.widget.FrameLayout; + +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.CheckBox; +import org.telegram.ui.Components.LayoutHelper; +import org.telegram.ui.PhotoViewer; + +public class PhotoAttachPhotoCell extends FrameLayout { + + private BackupImageView imageView; + private FrameLayout checkFrame; + private CheckBox checkBox; + private boolean isLast; + + private MediaController.PhotoEntry photoEntry; + + public PhotoAttachPhotoCell(Context context) { + super(context); + + imageView = new BackupImageView(context); + addView(imageView, LayoutHelper.createFrame(80, 80)); + + checkFrame = new FrameLayout(context); + //addView(checkFrame, LayoutHelper.createFrame(42, 42, Gravity.LEFT | Gravity.TOP, 38, 0, 0, 0)); + addView(checkFrame, LayoutHelper.createFrame(80, 80, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 0)); + + checkBox = new CheckBox(context, R.drawable.checkbig); + checkBox.setSize(30); + checkBox.setCheckOffset(AndroidUtilities.dp(1)); + checkBox.setDrawBackground(true); + checkBox.setColor(0xff3ccaef); + addView(checkBox, LayoutHelper.createFrame(30, 30, Gravity.LEFT | Gravity.TOP, 46, 4, 0, 0)); + checkBox.setVisibility(VISIBLE); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(80 + (isLast ? 0 : 6)), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(80), MeasureSpec.EXACTLY)); + } + + public MediaController.PhotoEntry getPhotoEntry() { + return photoEntry; + } + + public void setPhotoEntry(MediaController.PhotoEntry entry, boolean last) { + photoEntry = entry; + isLast = last; + if (photoEntry.thumbPath != null) { + imageView.setImage(photoEntry.thumbPath, null, getResources().getDrawable(R.drawable.nophotos)); + } else if (photoEntry.path != null) { + imageView.setOrientation(photoEntry.orientation, true); + imageView.setImage("thumb://" + photoEntry.imageId + ":" + photoEntry.path, null, getResources().getDrawable(R.drawable.nophotos)); + } else { + imageView.setImageResource(R.drawable.nophotos); + } + boolean showing = PhotoViewer.getInstance().isShowingImage(photoEntry.path); + imageView.getImageReceiver().setVisible(!showing, true); + checkBox.setVisibility(showing ? View.INVISIBLE : View.VISIBLE); + requestLayout(); + } + + public void setChecked(boolean value, boolean animated) { + checkBox.setChecked(value, animated); + } + + public void setOnCheckClickLisnener(OnClickListener onCheckClickLisnener) { + checkFrame.setOnClickListener(onCheckClickLisnener); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java index cc7537594..8aaa67bea 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ProfileSearchCell.java @@ -21,10 +21,10 @@ import android.view.MotionEvent; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.AndroidUtilities; -import org.telegram.android.ContactsController; import org.telegram.android.ImageReceiver; import org.telegram.android.LocaleController; import org.telegram.android.MessagesController; +import org.telegram.android.UserObject; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; @@ -172,7 +172,6 @@ public class ProfileSearchCell extends BaseCell { nameLockTop = AndroidUtilities.dp(16.5f); } else { if (chat != null) { - if (chat.id < 0) { drawNameBroadcast = true; nameLockTop = AndroidUtilities.dp(28.5f); @@ -203,7 +202,7 @@ public class ProfileSearchCell extends BaseCell { if (chat != null) { nameString2 = chat.title; } else if (user != null) { - nameString2 = ContactsController.formatName(user.first_name, user.last_name); + nameString2 = UserObject.getUserName(user); } nameString = nameString2.replace("\n", " "); } @@ -251,10 +250,14 @@ public class ProfileSearchCell extends BaseCell { if (subLabel != null) { onlineString = subLabel; } else { - onlineString = LocaleController.formatUserStatus(user); - if (user != null && (user.id == UserConfig.getClientUserId() || user.status != null && user.status.expires > ConnectionsManager.getInstance().getCurrentTime())) { - currentOnlinePaint = onlinePaint; - onlineString = LocaleController.getString("Online", R.string.Online); + if ((user.flags & TLRPC.USER_FLAG_BOT) != 0) { + onlineString = LocaleController.getString("Bot", R.string.Bot); + } else { + onlineString = LocaleController.formatUserStatus(user); + if (user != null && (user.id == UserConfig.getClientUserId() || user.status != null && user.status.expires > ConnectionsManager.getInstance().getCurrentTime())) { + currentOnlinePaint = onlinePaint; + onlineString = LocaleController.getString("Online", R.string.Online); + } } } 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 4c2e46a36..7cc059b68 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedDocumentCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedDocumentCell.java @@ -212,7 +212,7 @@ public class SharedDocumentCell extends FrameLayout implements MediaController.F 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.messageOwner.media.document.thumb instanceof TLRPC.TL_photoSizeEmpty || document.messageOwner.media.document.thumb == null) { thumbImageView.setVisibility(INVISIBLE); thumbImageView.setImageBitmap(null); } else { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedPhotoVideoCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedPhotoVideoCell.java index 879043844..93059d1fd 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedPhotoVideoCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedPhotoVideoCell.java @@ -83,7 +83,7 @@ public class SharedPhotoVideoCell extends FrameLayoutFixed { checkBox = new CheckBox(context, R.drawable.round_check2); checkBox.setVisibility(INVISIBLE); - addView(checkBox, LayoutHelper.createFrame(22, 22, Gravity.RIGHT | Gravity.TOP, 6, 0, 6, 0)); + addView(checkBox, LayoutHelper.createFrame(22, 22, Gravity.RIGHT | Gravity.TOP, 0, 6, 6, 0)); } @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/StickerSetCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/StickerSetCell.java index 03699a64a..9ebd05c48 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/StickerSetCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/StickerSetCell.java @@ -21,7 +21,6 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.android.AnimationCompat.ViewProxy; import org.telegram.android.LocaleController; -import org.telegram.android.query.StickersQuery; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.ui.Components.BackupImageView; @@ -36,7 +35,7 @@ public class StickerSetCell extends FrameLayout { private BackupImageView imageView; private boolean needDivider; private ImageView optionsButton; - private TLRPC.TL_stickerSet stickersSet; + private TLRPC.TL_messages_stickerSet stickersSet; private static Paint paint; @@ -56,7 +55,7 @@ public class StickerSetCell extends FrameLayout { textView.setSingleLine(true); textView.setEllipsize(TextUtils.TruncateAt.END); textView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); - addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT, LocaleController.isRTL ? 40 : 71, 10, LocaleController.isRTL ? 40 : 71, 0)); + addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT, LocaleController.isRTL ? 40 : 71, 10, LocaleController.isRTL ? 71 : 40, 0)); valueTextView = new TextView(context); valueTextView.setTextColor(0xff8a8a8a); @@ -65,7 +64,7 @@ public class StickerSetCell extends FrameLayout { valueTextView.setMaxLines(1); valueTextView.setSingleLine(true); valueTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); - addView(valueTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT, LocaleController.isRTL ? 40 : 71, 35, LocaleController.isRTL ? 40 : 71, 0)); + addView(valueTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT, LocaleController.isRTL ? 40 : 71, 35, LocaleController.isRTL ? 71 : 40, 0)); imageView = new BackupImageView(context); imageView.setAspectFit(true); @@ -94,29 +93,22 @@ public class StickerSetCell extends FrameLayout { super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(64) + (needDivider ? 1 : 0), MeasureSpec.EXACTLY)); } - public void setStickersSet(TLRPC.TL_stickerSet set, boolean divider) { + public void setStickersSet(TLRPC.TL_messages_stickerSet set, boolean divider) { needDivider = divider; stickersSet = set; - if (stickersSet.id == -1) { - textView.setText(LocaleController.getString("GeniusStickerPackName", R.string.GeniusStickerPackName)); - if (StickersQuery.getHideMainStickersPack()) { - ViewProxy.setAlpha(textView, 0.5f); - ViewProxy.setAlpha(valueTextView, 0.5f); - ViewProxy.setAlpha(imageView, 0.5f); - } else { - ViewProxy.setAlpha(textView, 1.0f); - ViewProxy.setAlpha(valueTextView, 1.0f); - ViewProxy.setAlpha(imageView, 1.0f); - } + textView.setText(stickersSet.set.title); + if ((stickersSet.set.flags & 2) != 0) { + ViewProxy.setAlpha(textView, 0.5f); + ViewProxy.setAlpha(valueTextView, 0.5f); + ViewProxy.setAlpha(imageView, 0.5f); } else { - textView.setText(stickersSet.title); ViewProxy.setAlpha(textView, 1.0f); ViewProxy.setAlpha(valueTextView, 1.0f); ViewProxy.setAlpha(imageView, 1.0f); } - ArrayList documents = StickersQuery.getStickersForSet(stickersSet.id); - if (documents != null) { + ArrayList documents = set.documents; + if (documents != null && !documents.isEmpty()) { valueTextView.setText(LocaleController.formatPluralString("Stickers", documents.size())); TLRPC.Document document = documents.get(0); if (document.thumb != null && document.thumb.location != null) { @@ -131,7 +123,7 @@ public class StickerSetCell extends FrameLayout { optionsButton.setOnClickListener(listener); } - public TLRPC.TL_stickerSet getStickersSet() { + public TLRPC.TL_messages_stickerSet getStickersSet() { return stickersSet; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextCell.java index d43cb7580..8827b1ba8 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/TextCell.java @@ -28,6 +28,8 @@ public class TextCell extends FrameLayout { private ImageView imageView; private ImageView valueImageView; + private boolean multiline; + public TextCell(Context context) { super(context); @@ -61,7 +63,7 @@ public class TextCell extends FrameLayout { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(48), MeasureSpec.EXACTLY)); + super.onMeasure(widthMeasureSpec, multiline ? MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED) : MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(48), MeasureSpec.EXACTLY)); } public void setTextColor(int color) { @@ -83,6 +85,22 @@ public class TextCell extends FrameLayout { valueImageView.setVisibility(INVISIBLE); } + public void setMultiline(boolean value) { + if (multiline == value) { + return; + } + multiline = value; + if (value) { + textView.setSingleLine(false); + textView.setPadding(0, AndroidUtilities.dp(6), 0, AndroidUtilities.dp(6)); + } else { + textView.setLines(1); + textView.setMaxLines(1); + textView.setSingleLine(true); + } + requestLayout(); + } + public void setTextAndValue(String text, String value) { textView.setText(text); valueTextView.setText(value); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/UserCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/UserCell.java index 116721b01..0c420a0f0 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/UserCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/UserCell.java @@ -14,9 +14,9 @@ import android.widget.FrameLayout; import android.widget.ImageView; import org.telegram.android.AndroidUtilities; -import org.telegram.android.ContactsController; import org.telegram.android.LocaleController; import org.telegram.android.MessagesController; +import org.telegram.android.UserObject; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; @@ -140,7 +140,7 @@ public class UserCell extends FrameLayout { } } if (!continueUpdate && currentName == null && lastName != null && (mask & MessagesController.UPDATE_MASK_NAME) != 0) { - newName = ContactsController.formatName(currentUser.first_name, currentUser.last_name); + newName = UserObject.getUserName(currentUser); if (!newName.equals(lastName)) { continueUpdate = true; } @@ -161,19 +161,28 @@ public class UserCell extends FrameLayout { lastName = null; nameTextView.setText(currentName); } else { - lastName = newName == null ? ContactsController.formatName(currentUser.first_name, currentUser.last_name) : newName; + lastName = newName == null ? UserObject.getUserName(currentUser) : newName; nameTextView.setText(lastName); } if (currrntStatus != null) { statusTextView.setTextColor(statusColor); statusTextView.setText(currrntStatus); } else { - if (currentUser.id == UserConfig.getClientUserId() || currentUser.status != null && currentUser.status.expires > ConnectionsManager.getInstance().getCurrentTime()) { - statusTextView.setTextColor(statusOnlineColor); - statusTextView.setText(LocaleController.getString("Online", R.string.Online)); - } else { + if ((currentUser.flags & TLRPC.USER_FLAG_BOT) != 0) { statusTextView.setTextColor(statusColor); - statusTextView.setText(LocaleController.formatUserStatus(currentUser)); + if ((currentUser.flags & TLRPC.USER_FLAG_BOT_READING_HISTORY) != 0) { + statusTextView.setText(LocaleController.getString("BotStatusRead", R.string.BotStatusRead)); + } else { + statusTextView.setText(LocaleController.getString("BotStatusCantRead", R.string.BotStatusCantRead)); + } + } else { + if (currentUser.id == UserConfig.getClientUserId() || currentUser.status != null && currentUser.status.expires > ConnectionsManager.getInstance().getCurrentTime() || MessagesController.getInstance().onlinePrivacy.containsKey(currentUser.id)) { + statusTextView.setTextColor(statusOnlineColor); + statusTextView.setText(LocaleController.getString("Online", R.string.Online)); + } else { + statusTextView.setTextColor(statusColor); + statusTextView.setText(LocaleController.formatUserStatus(currentUser)); + } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java index 1887a03b0..bc6040073 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChangePhoneActivity.java @@ -497,7 +497,7 @@ public class ChangePhoneActivity extends BaseFragment { }); textView = new TextView(context); - textView.setText(LocaleController.getString("StartText", R.string.StartText)); + textView.setText(LocaleController.getString("ChangePhoneHelp", R.string.ChangePhoneHelp)); textView.setTextColor(0xff757575); textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); textView.setGravity(Gravity.LEFT); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index 133143686..8e59129c3 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -17,6 +17,7 @@ import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; +import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Rect; import android.graphics.drawable.Drawable; @@ -24,6 +25,7 @@ import android.media.ExifInterface; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.provider.ContactsContract; import android.provider.MediaStore; import android.text.TextUtils; import android.util.Base64; @@ -55,7 +57,10 @@ import org.telegram.android.MessagesStorage; import org.telegram.android.NotificationsController; import org.telegram.android.SecretChatHelper; import org.telegram.android.SendMessagesHelper; +import org.telegram.android.UserObject; import org.telegram.android.VideoEditedInfo; +import org.telegram.android.query.BotQuery; +import org.telegram.android.query.MessagesSearchQuery; import org.telegram.android.query.ReplyMessageQuery; import org.telegram.android.query.StickersQuery; import org.telegram.android.support.widget.LinearLayoutManager; @@ -85,16 +90,21 @@ import org.telegram.ui.Cells.ChatActionCell; import org.telegram.ui.Cells.ChatAudioCell; import org.telegram.ui.Cells.ChatBaseCell; import org.telegram.ui.Cells.ChatContactCell; +import org.telegram.ui.Cells.ChatLoadingCell; import org.telegram.ui.Cells.ChatMediaCell; import org.telegram.ui.ActionBar.ActionBar; import org.telegram.ui.ActionBar.ActionBarMenu; import org.telegram.ui.ActionBar.ActionBarMenuItem; import org.telegram.ui.Cells.ChatMessageCell; +import org.telegram.ui.Cells.ChatUnreadCell; +import org.telegram.ui.Components.AlertsCreator; import org.telegram.ui.Components.AvatarDrawable; import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.ActionBar.BaseFragment; +import org.telegram.ui.Cells.BotHelpCell; import org.telegram.ui.Components.ChatActivityEnterView; import org.telegram.android.ImageReceiver; +import org.telegram.ui.Components.ChatAttachView; import org.telegram.ui.Components.FrameLayoutFixed; import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.RecordStatusDrawable; @@ -107,6 +117,7 @@ import org.telegram.ui.Components.TypingDotsDrawable; import org.telegram.ui.Components.WebFrameLayout; import java.io.File; +import java.net.URLDecoder; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -132,6 +143,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private ActionBarMenuItem menuItem; private ActionBarMenuItem attachItem; private ActionBarMenuItem headerItem; + private ActionBarMenuItem searchItem; + private ActionBarMenuItem searchUpItem; + private ActionBarMenuItem searchDownItem; private TextView addContactItem; private RecyclerListView chatListView; private LinearLayoutManager chatLayoutManager; @@ -162,6 +176,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private MentionsAdapter mentionsAdapter; private ListView mentionListView; private AnimatorSetProxy mentionListAnimation; + private ChatAttachView chatAttachView; private boolean allowStickersPanel; private AnimatorSetProxy runningAnimation; @@ -227,6 +242,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not protected TLRPC.ChatParticipants info = null; private int onlineCount = -1; + private HashMap botInfo = new HashMap<>(); + private String botUser; + private MessageObject botButtons; + private MessageObject botReplyButtons; + private int botsCount; + private boolean hasBotsCommands; + private CharSequence lastPrintString; private String lastStatus; private int lastStatusDrawable; @@ -240,21 +262,32 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private float startX = 0; private float startY = 0; - private final static int copy = 1; - private final static int forward = 2; - private final static int delete = 3; - private final static int chat_enc_timer = 4; - private final static int chat_menu_attach = 5; - private final static int attach_photo = 6; - private final static int attach_gallery = 7; - private final static int attach_video = 8; - private final static int attach_document = 9; - private final static int attach_location = 10; - private final static int clear_history = 11; - private final static int delete_chat = 12; - private final static int share_contact = 13; - private final static int mute = 14; - private final static int reply = 15; + private final static int copy = 10; + private final static int forward = 11; + private final static int delete = 12; + private final static int chat_enc_timer = 13; + private final static int chat_menu_attach = 14; + private final static int clear_history = 15; + private final static int delete_chat = 16; + private final static int share_contact = 17; + private final static int mute = 18; + private final static int reply = 19; + + private final static int bot_help = 30; + private final static int bot_settings = 31; + + private final static int attach_photo = 0; + private final static int attach_gallery = 1; + private final static int attach_video = 2; + private final static int attach_audio = 3; + private final static int attach_document = 4; + private final static int attach_contact = 5; + private final static int attach_location = 6; + + private final static int search = 40; + private final static int search_up = 41; + private final static int search_down = 42; + private final static int id_chat_compose_panel = 1000; @@ -353,6 +386,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } dialog_id = userId; + botUser = arguments.getString("botUser"); } else if (encId != 0) { currentEncryptedChat = MessagesController.getInstance().getEncryptedChat(encId); if (currentEncryptedChat == null) { @@ -433,9 +467,28 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not NotificationCenter.getInstance().addObserver(this, NotificationCenter.didReceivedWebpages); NotificationCenter.getInstance().addObserver(this, NotificationCenter.didReceivedWebpagesInUpdates); NotificationCenter.getInstance().addObserver(this, NotificationCenter.messagesReadContent); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.botInfoDidLoaded); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.botKeyboardDidLoaded); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.chatSearchResultsAvailable); super.onFragmentCreate(); + if (currentEncryptedChat == null && !isBroadcast) { + BotQuery.loadBotKeyboard(dialog_id); + } + + if (userId != 0 && (currentUser.flags & TLRPC.USER_FLAG_BOT) != 0) { + BotQuery.loadBotInfo(userId, true, classGuid); + } else if (info != null) { + for (int a = 0; a < info.participants.size(); a++) { + TLRPC.TL_chatParticipant participant = info.participants.get(a); + TLRPC.User user = MessagesController.getInstance().getUser(participant.user_id); + if (user != null && (user.flags & TLRPC.USER_FLAG_BOT) != 0) { + BotQuery.loadBotInfo(user.id, true, classGuid); + } + } + } + loading = true; if (startLoadFromMessageId != 0) { @@ -502,6 +555,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not NotificationCenter.getInstance().removeObserver(this, NotificationCenter.didReceivedWebpages); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.didReceivedWebpagesInUpdates); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.messagesReadContent); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.botInfoDidLoaded); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.botKeyboardDidLoaded); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.chatSearchResultsAvailable); if (AndroidUtilities.isTablet()) { NotificationCenter.getInstance().postNotificationName(NotificationCenter.openedChatChanged, dialog_id, true); @@ -516,7 +572,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not getParentActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); } if (stickersAdapter != null) { - stickersAdapter.destroy(); + stickersAdapter.onDestroy(); + } + if (chatAttachView != null) { + chatAttachView.onDestroy(); } AndroidUtilities.unlockOrientation(getParentActivity()); MediaController.getInstance().stopAudio(); @@ -535,6 +594,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not lastPrintString = null; lastStatus = null; hasOwnBackground = true; + chatAttachView = null; ResourceLoader.loadRecources(context); @@ -542,150 +602,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { @Override public void onItemClick(final int id) { - if (id == attach_photo || id == attach_gallery || id == attach_document || id == attach_video) { - String action; - if (currentChat != null) { - if (currentChat.participants_count > MessagesController.getInstance().groupBigSize) { - if (id == attach_photo || id == attach_gallery) { - action = "bigchat_upload_photo"; - } else { - action = "bigchat_upload_document"; - } - } else { - if (id == attach_photo || id == attach_gallery) { - action = "chat_upload_photo"; - } else { - action = "chat_upload_document"; - } - } - } else { - if (id == attach_photo || id == attach_gallery) { - action = "pm_upload_photo"; - } else { - action = "pm_upload_document"; - } - } - if (action != null && !MessagesController.isFeatureEnabled(action, ChatActivity.this)) { - return; - } - } if (id == -1) { - if (chatActivityEnterView != null) { - chatActivityEnterView.hideEmojiPopup(); - } finishFragment(); } else if (id == -2) { selectedMessagesIds.clear(); selectedMessagesCanCopyIds.clear(); actionBar.hideActionMode(); updateVisibleRows(); - } else if (id == attach_photo) { - try { - Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - File image = AndroidUtilities.generatePicturePath(); - if (image != null) { - takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image)); - currentPicturePath = image.getAbsolutePath(); - } - startActivityForResult(takePictureIntent, 0); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } else if (id == attach_gallery) { - PhotoAlbumPickerActivity fragment = new PhotoAlbumPickerActivity(false, ChatActivity.this); - fragment.setDelegate(new PhotoAlbumPickerActivity.PhotoAlbumPickerActivityDelegate() { - @Override - public void didSelectPhotos(ArrayList photos, ArrayList captions, ArrayList webPhotos) { - SendMessagesHelper.prepareSendingPhotos(photos, null, dialog_id, replyingMessageObject, captions); - SendMessagesHelper.prepareSendingPhotosSearch(webPhotos, dialog_id, replyingMessageObject); - showReplyPanel(false, null, null, null, false, true); - } - - @Override - public void startPhotoSelectActivity() { - try { - Intent videoPickerIntent = new Intent(); - videoPickerIntent.setType("video/*"); - videoPickerIntent.setAction(Intent.ACTION_GET_CONTENT); - videoPickerIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, (long) (1024 * 1024 * 1536)); - - Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); - photoPickerIntent.setType("image/*"); - Intent chooserIntent = Intent.createChooser(photoPickerIntent, null); - chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{videoPickerIntent}); - - startActivityForResult(chooserIntent, 1); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } - - @Override - public boolean didSelectVideo(String path) { - if (Build.VERSION.SDK_INT >= 16) { - return !openVideoEditor(path, true, true); - } else { - SendMessagesHelper.prepareSendingVideo(path, 0, 0, 0, 0, null, dialog_id, replyingMessageObject); - showReplyPanel(false, null, null, null, false, true); - return true; - } - } - }); - presentFragment(fragment); - } else if (id == attach_video) { - try { - Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); - File video = AndroidUtilities.generateVideoPath(); - if (video != null) { - if (Build.VERSION.SDK_INT >= 18) { - takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(video)); - } - takeVideoIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, (long) (1024 * 1024 * 1536)); - currentPicturePath = video.getAbsolutePath(); - } - startActivityForResult(takeVideoIntent, 2); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } else if (id == attach_location) { - if (!isGoogleMapsInstalled()) { - return; - } - LocationActivity fragment = new LocationActivity(); - fragment.setDelegate(new LocationActivity.LocationActivityDelegate() { - @Override - public void didSelectLocation(TLRPC.MessageMedia location) { - SendMessagesHelper.getInstance().sendMessage(location, dialog_id, replyingMessageObject); - moveScrollToLastMessage(); - showReplyPanel(false, null, null, null, false, true); - if (paused) { - scrollToTopOnResume = true; - } - } - }); - presentFragment(fragment); - } else if (id == attach_document) { - DocumentSelectActivity fragment = new DocumentSelectActivity(); - fragment.setDelegate(new DocumentSelectActivity.DocumentSelectActivityDelegate() { - @Override - public void didSelectFiles(DocumentSelectActivity activity, ArrayList files) { - activity.finishFragment(); - SendMessagesHelper.prepareSendingDocuments(files, files, null, null, dialog_id, replyingMessageObject); - showReplyPanel(false, null, null, null, false, true); - } - - @Override - public void startDocumentSelectActivity() { - try { - Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); - photoPickerIntent.setType("*/*"); - startActivityForResult(photoPickerIntent, 21); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } - }); - presentFragment(fragment); } else if (id == copy) { String str = ""; ArrayList ids = new ArrayList<>(selectedMessagesCanCopyIds.keySet()); @@ -749,7 +672,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } else if (id == forward) { Bundle args = new Bundle(); args.putBoolean("onlySelect", true); - args.putBoolean("serverOnly", true); + args.putInt("dialogsType", 1); MessagesActivity fragment = new MessagesActivity(args); fragment.setDelegate(ChatActivity.this); presentFragment(fragment); @@ -822,52 +745,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } else if (id == mute) { boolean muted = MessagesController.getInstance().isDialogMuted(dialog_id); if (!muted) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("Notifications", R.string.Notifications)); - CharSequence[] items = new CharSequence[]{ - LocaleController.formatString("MuteFor", R.string.MuteFor, LocaleController.formatPluralString("Hours", 1)), - LocaleController.formatString("MuteFor", R.string.MuteFor, LocaleController.formatPluralString("Hours", 8)), - LocaleController.formatString("MuteFor", R.string.MuteFor, LocaleController.formatPluralString("Days", 2)), - LocaleController.getString("MuteDisable", R.string.MuteDisable) - }; - builder.setItems(items, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - int untilTime = ConnectionsManager.getInstance().getCurrentTime(); - if (i == 0) { - untilTime += 60 * 60; - } else if (i == 1) { - untilTime += 60 * 60 * 8; - } else if (i == 2) { - untilTime += 60 * 60 * 48; - } else if (i == 3) { - untilTime = Integer.MAX_VALUE; - } - - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - long flags; - if (i == 3) { - editor.putInt("notify2_" + dialog_id, 2); - flags = 1; - } else { - editor.putInt("notify2_" + dialog_id, 3); - editor.putInt("notifyuntil_" + dialog_id, untilTime); - flags = ((long) untilTime << 32) | 1; - } - MessagesStorage.getInstance().setDialogFlags(dialog_id, flags); - editor.commit(); - TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(dialog_id); - if (dialog != null) { - dialog.notify_settings = new TLRPC.TL_peerNotifySettings(); - dialog.notify_settings.mute_until = untilTime; - } - NotificationsController.updateServerNotificationsSettings(dialog_id); - } - } - ); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showDialog(builder.create()); + showDialog(AlertsCreator.createMuteAlert(getParentActivity(), dialog_id)); } else { SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); @@ -892,6 +770,74 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not selectedMessagesCanCopyIds.clear(); actionBar.hideActionMode(); updateVisibleRows(); + }/* else if (id == chat_menu_attach) { + if (getParentActivity() == null) { + return; + } + BottomSheet.Builder builder = new BottomSheet.Builder(getParentActivity()); + if (chatAttachView == null) { + chatAttachView = new ChatAttachView(getParentActivity()); + chatAttachView.setDelegate(new ChatAttachView.ChatAttachViewDelegate() { + @Override + public void didPressedButton(int button) { + if (visibleDialog != null) { + visibleDialog.dismiss(); + } + if (button == 7) { + HashMap selectedPhotos = chatAttachView.getSelectedPhotos(); + if (!selectedPhotos.isEmpty()) { + ArrayList photos = new ArrayList<>(); + ArrayList captions = new ArrayList<>(); + for (HashMap.Entry entry : selectedPhotos.entrySet()) { + photos.add(entry.getValue().path); + captions.add(""); + } + SendMessagesHelper.prepareSendingPhotos(photos, null, dialog_id, replyingMessageObject, captions); + showReplyPanel(false, null, null, null, false, true); + } + return; + } + processSelectedAttach(button); + } + }); + } + builder.setCustomView(chatAttachView); + final int coords[] = new int[2]; + menuItem.getLocationInWindow(coords); + builder.setRevealAnimation(coords[0] + menuItem.getWidth() / 2, coords[1] + menuItem.getHeight() / 2); + builder.setDelegate(new BottomSheet.BottomSheetDelegate() { + @Override + public void onOpenAnimationStart() { + chatAttachView.startAnimations(coords[1] > AndroidUtilities.displaySize.y - AndroidUtilities.dp(100)); + } + + @Override + public void onOpenAnimationEnd() { + + } + }); + chatAttachView.init(ChatActivity.this); + showDialog(builder.create()); + }*/ else if (id == attach_gallery || id == attach_video || id == attach_document || id == attach_location || id == attach_photo || id == attach_audio || id == attach_contact) { + processSelectedAttach(id); + } else if (id == bot_help) { + SendMessagesHelper.getInstance().sendMessage("/help", dialog_id, null, null, false); + } else if (id == bot_settings) { + SendMessagesHelper.getInstance().sendMessage("/settings", dialog_id, null, null, false); + } else if (id == search) { + avatarContainer.setVisibility(View.GONE); + headerItem.setVisibility(View.GONE); + attachItem.setVisibility(View.GONE); + searchItem.setVisibility(View.VISIBLE); + searchUpItem.setVisibility(View.VISIBLE); + searchDownItem.setVisibility(View.VISIBLE); + updateSearchButtons(0); + //chatActivityEnterView.setVisibility(View.GONE); + searchItem.openSearch(); + } else if (id == search_up) { + MessagesSearchQuery.searchMessagesInChat(null, dialog_id, classGuid, 1); + } else if (id == search_down) { + MessagesSearchQuery.searchMessagesInChat(null, dialog_id, classGuid, 2); } } }); @@ -975,7 +921,52 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not ActionBarMenu menu = actionBar.createMenu(); + if (currentEncryptedChat == null && !isBroadcast) { + /*searchItem = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true, false).setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() { + + @Override + public void onSearchCollapse() { + avatarContainer.setVisibility(View.VISIBLE); + headerItem.setVisibility(View.VISIBLE); + searchItem.setVisibility(View.GONE); + //chatActivityEnterView.setVisibility(View.VISIBLE); + searchUpItem.clearAnimation(); + searchDownItem.clearAnimation(); + searchUpItem.setVisibility(View.GONE); + searchDownItem.setVisibility(View.GONE); + scrollToLastMessage(); + } + + @Override + public void onSearchExpand() { + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + searchItem.getSearchField().requestFocus(); + AndroidUtilities.showKeyboard(searchItem.getSearchField()); + } + }, 200); //TODO find a better way to open keyboard + } + + @Override + public void onSearchPressed(EditText editText) { + updateSearchButtons(0); + MessagesSearchQuery.searchMessagesInChat(editText.getText().toString(), dialog_id, classGuid, 0); + } + }); + searchItem.getSearchField().setHint(LocaleController.getString("Search", R.string.Search)); + searchItem.setVisibility(View.GONE); + + searchUpItem = menu.addItem(search_up, R.drawable.search_up); + searchUpItem.setVisibility(View.GONE); + searchDownItem = menu.addItem(search_down, R.drawable.search_down); + searchDownItem.setVisibility(View.GONE);*/ + } + headerItem = menu.addItem(0, R.drawable.ic_ab_other); + if (searchItem != null) { + headerItem.addSubItem(search, LocaleController.getString("Search", R.string.Search), 0); + } if (currentUser != null) { addContactItem = headerItem.addSubItem(share_contact, "", 0); } @@ -989,27 +980,32 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not headerItem.addSubItem(delete_chat, LocaleController.getString("DeleteChatUser", R.string.DeleteChatUser), 0); } muteItem = headerItem.addSubItem(mute, null, 0); - ((LinearLayout.LayoutParams) headerItem.getLayoutParams()).setMargins(0, 0, AndroidUtilities.dp(-48), 0); + if (currentUser != null && currentEncryptedChat == null && (currentUser.flags & TLRPC.USER_FLAG_BOT) != 0) { + headerItem.addSubItem(bot_settings, LocaleController.getString("BotSettings", R.string.BotSettings), 0); + headerItem.addSubItem(bot_help, LocaleController.getString("BotHelp", R.string.BotHelp), 0); + updateBotButtons(); + } updateTitle(); updateSubtitle(); updateTitleIcons(); - attachItem = menu.addItem(chat_menu_attach, R.drawable.ic_ab_other); + attachItem = menu.addItem(chat_menu_attach, R.drawable.ic_ab_other).setAllowCloseAnimation(false); attachItem.addSubItem(attach_photo, LocaleController.getString("ChatTakePhoto", R.string.ChatTakePhoto), R.drawable.ic_attach_photo); attachItem.addSubItem(attach_gallery, LocaleController.getString("ChatGallery", R.string.ChatGallery), R.drawable.ic_attach_gallery); attachItem.addSubItem(attach_video, LocaleController.getString("ChatVideo", R.string.ChatVideo), R.drawable.ic_attach_video); attachItem.addSubItem(attach_document, LocaleController.getString("ChatDocument", R.string.ChatDocument), R.drawable.ic_ab_doc); attachItem.addSubItem(attach_location, LocaleController.getString("ChatLocation", R.string.ChatLocation), R.drawable.ic_attach_location); - attachItem.setVisibility(View.INVISIBLE); + attachItem.setVisibility(View.GONE); - menuItem = menu.addItem(chat_menu_attach, R.drawable.ic_ab_attach); + menuItem = menu.addItem(chat_menu_attach, R.drawable.ic_ab_attach).setAllowCloseAnimation(false); menuItem.addSubItem(attach_photo, LocaleController.getString("ChatTakePhoto", R.string.ChatTakePhoto), R.drawable.ic_attach_photo); menuItem.addSubItem(attach_gallery, LocaleController.getString("ChatGallery", R.string.ChatGallery), R.drawable.ic_attach_gallery); menuItem.addSubItem(attach_video, LocaleController.getString("ChatVideo", R.string.ChatVideo), R.drawable.ic_attach_video); menuItem.addSubItem(attach_document, LocaleController.getString("ChatDocument", R.string.ChatDocument), R.drawable.ic_ab_doc); menuItem.addSubItem(attach_location, LocaleController.getString("ChatLocation", R.string.ChatLocation), R.drawable.ic_attach_location); menuItem.setShowFromBottom(true); + menuItem.setBackgroundDrawable(null); actionModeViews.clear(); @@ -1052,6 +1048,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not checkActionBarMenu(); fragmentView = new SizeNotifierFrameLayout(context) { + + int inputFieldHeight = 0; + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); @@ -1060,9 +1059,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not int heightSize = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(widthSize, heightSize); - heightSize -= getPaddingBottom(); - int inputFieldHeight = 0; + int keyboardSize = getKeyboardHeight(); + + if (keyboardSize <= AndroidUtilities.dp(20)) { + heightSize -= chatActivityEnterView.getEmojiPadding(); + } int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { @@ -1078,12 +1080,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (child.getVisibility() == GONE || child == chatActivityEnterView) { continue; } - - LayoutParams lp = (LayoutParams) child.getLayoutParams(); - if (child == chatListView) { + if (child == chatListView || child == progressView) { int contentWidthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY); int contentHeightSpec = MeasureSpec.makeMeasureSpec(Math.max(AndroidUtilities.dp(10), heightSize - inputFieldHeight + AndroidUtilities.dp(2)), MeasureSpec.EXACTLY); child.measure(contentWidthSpec, contentHeightSpec); + } else if (child == emptyViewContainer) { + int contentWidthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY); + int contentHeightSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY); + child.measure(contentWidthSpec, contentHeightSpec); + } else if (chatActivityEnterView.isPopupView(child)) { + child.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(child.getLayoutParams().height, MeasureSpec.EXACTLY)); } else { measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0); } @@ -1094,6 +1100,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = getChildCount(); + int paddingBottom = getKeyboardHeight() <= AndroidUtilities.dp(20) ? chatActivityEnterView.getEmojiPadding() : 0; + setBottomClip(paddingBottom); + for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() == GONE) { @@ -1132,10 +1141,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not childTop = lp.topMargin; break; case Gravity.CENTER_VERTICAL: - childTop = ((b - getPaddingBottom()) - t - height) / 2 + lp.topMargin - lp.bottomMargin; + childTop = ((b - paddingBottom) - t - height) / 2 + lp.topMargin - lp.bottomMargin; break; case Gravity.BOTTOM: - childTop = ((b - getPaddingBottom()) - t) - height - lp.bottomMargin; + childTop = ((b - paddingBottom) - t) - height - lp.bottomMargin; break; default: childTop = lp.topMargin; @@ -1145,6 +1154,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not childTop -= chatActivityEnterView.getMeasuredHeight() - AndroidUtilities.dp(2); } else if (child == pagedownButton) { childTop -= chatActivityEnterView.getMeasuredHeight(); + } else if (child == emptyViewContainer) { + childTop -= inputFieldHeight / 2; + } else if (chatActivityEnterView.isPopupView(child)) { + childTop = chatActivityEnterView.getBottom(); } child.layout(childLeft, childTop, childLeft + width, childTop + height); } @@ -1153,15 +1166,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } }; - SizeNotifierFrameLayout contentView = (SizeNotifierFrameLayout) fragmentView; contentView.setBackgroundImage(ApplicationLoader.getCachedWallpaper()); emptyViewContainer = new FrameLayout(context); - emptyViewContainer.setPadding(0, 0, 0, AndroidUtilities.dp(48)); emptyViewContainer.setVisibility(View.INVISIBLE); - contentView.addView(emptyViewContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); + contentView.addView(emptyViewContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER)); emptyViewContainer.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { @@ -1195,17 +1206,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not secretViewStatusTextView.setGravity(Gravity.CENTER_HORIZONTAL); secretViewStatusTextView.setMaxWidth(AndroidUtilities.dp(210)); if (currentEncryptedChat.admin_id == UserConfig.getClientUserId()) { - if (currentUser.first_name.length() > 0) { - secretViewStatusTextView.setText(LocaleController.formatString("EncryptedPlaceholderTitleOutgoing", R.string.EncryptedPlaceholderTitleOutgoing, currentUser.first_name)); - } else { - secretViewStatusTextView.setText(LocaleController.formatString("EncryptedPlaceholderTitleOutgoing", R.string.EncryptedPlaceholderTitleOutgoing, currentUser.last_name)); - } + secretViewStatusTextView.setText(LocaleController.formatString("EncryptedPlaceholderTitleOutgoing", R.string.EncryptedPlaceholderTitleOutgoing, UserObject.getFirstName(currentUser))); } 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)); - } + secretViewStatusTextView.setText(LocaleController.formatString("EncryptedPlaceholderTitleIncoming", R.string.EncryptedPlaceholderTitleIncoming, UserObject.getFirstName(currentUser))); } secretChatPlaceholder.addView(secretViewStatusTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.TOP)); @@ -1260,7 +1263,26 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not chatActivityEnterView.onDestroy(); } - chatListView = new RecyclerListView(context); + chatListView = new RecyclerListView(context) { + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + super.onLayout(changed, l, t, r, b); + if (chatAdapter.isBot) { + int childCount = getChildCount(); + for (int a = 0; a < childCount; a++) { + View child = getChildAt(a); + if (child instanceof BotHelpCell) { + int height = b - t; + int top = height / 2 - child.getMeasuredHeight() / 2; + if (child.getTop() > top) { + child.layout(0, top, r - l, top + child.getMeasuredHeight()); + } + break; + } + } + } + } + }; chatListView.setVerticalScrollBarEnabled(true); chatListView.setAdapter(chatAdapter = new ChatActivityAdapter(context)); chatListView.setClipToPadding(false); @@ -1292,7 +1314,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { int firstVisibleItem = chatLayoutManager.findFirstVisibleItemPosition(); - int visibleItemCount = Math.abs(chatLayoutManager.findLastVisibleItemPosition() - firstVisibleItem) + 1; + int visibleItemCount = firstVisibleItem == RecyclerView.NO_POSITION ? 0 : Math.abs(chatLayoutManager.findLastVisibleItemPosition() - firstVisibleItem) + 1; if (visibleItemCount > 0) { int totalItemCount = chatAdapter.getItemCount(); if (firstVisibleItem <= 10) { @@ -1429,7 +1451,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not progressView = new FrameLayout(context); progressView.setVisibility(View.INVISIBLE); - contentView.addView(progressView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, 0, 0, 0, 48)); + contentView.addView(progressView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT)); View view = new View(context); view.setBackgroundResource(ApplicationLoader.isCustomTheme() ? R.drawable.system_loader2 : R.drawable.system_loader1); @@ -1532,8 +1554,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } })); + mentionsAdapter.setBotInfo(botInfo); mentionsAdapter.setChatInfo(info); mentionsAdapter.setNeedUsernames(currentChat != null); + mentionsAdapter.setBotsCount(currentChat != null ? botsCount : 1); mentionListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override @@ -1547,7 +1571,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not chatActivityEnterView.replaceWithText(start, len, "@" + user.username + " "); } } else if (object instanceof String) { - chatActivityEnterView.replaceWithText(start, len, object + " "); + if (mentionsAdapter.isBotCommands()) { + SendMessagesHelper.getInstance().sendMessage((String) object, dialog_id, null, null, false); + chatActivityEnterView.setFieldText(""); + } else { + chatActivityEnterView.replaceWithText(start, len, object + " "); + } } } }); @@ -1555,6 +1584,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not mentionListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { + if (!mentionsAdapter.isLongClickEnabled()) { + return false; + } Object object = mentionsAdapter.getItem(position); if (object instanceof String) { AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); @@ -1579,6 +1611,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not chatActivityEnterView.setDialogId(dialog_id); chatActivityEnterView.addToAttachLayout(menuItem); chatActivityEnterView.setId(id_chat_compose_panel); + chatActivityEnterView.setBotsCount(botsCount, hasBotsCommands); contentView.addView(chatActivityEnterView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.BOTTOM)); chatActivityEnterView.setDelegate(new ChatActivityEnterView.ChatActivityEnterViewDelegate() { @Override @@ -1631,14 +1664,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not attachItem.setVisibility(View.VISIBLE); } if (headerItem != null) { - headerItem.setVisibility(View.INVISIBLE); + headerItem.setVisibility(View.GONE); } } @Override public void onAttachButtonShow() { if (attachItem != null) { - attachItem.setVisibility(View.INVISIBLE); + attachItem.setVisibility(View.GONE); } if (headerItem != null) { headerItem.setVisibility(View.VISIBLE); @@ -1674,7 +1707,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not FrameLayout replyLayout = new FrameLayout(context); replyLayout.setClickable(true); - chatActivityEnterView.addTopView(replyLayout, AndroidUtilities.dp(48)); + chatActivityEnterView.addTopView(replyLayout, 48); View lineView = new View(context); lineView.setBackgroundColor(0xffe8e8e8); @@ -1735,7 +1768,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (currentEncryptedChat == null || currentEncryptedChat != null && AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 23) { chatActivityEnterView.setAllowStickers(true); if (stickersAdapter != null) { - stickersAdapter.destroy(); + stickersAdapter.onDestroy(); } stickersListView.setPadding(AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18), 0); stickersListView.setAdapter(stickersAdapter = new StickersAdapter(context, new StickersAdapter.StickersAdapterDelegate() { @@ -1818,9 +1851,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (getParentActivity() == null) { return; } - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + AlertDialog.Builder builder = null; if (currentUser != null && userBlocked) { + builder = new AlertDialog.Builder(getParentActivity()); builder.setMessage(LocaleController.getString("AreYouSureUnblockContact", R.string.AreYouSureUnblockContact)); builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { @Override @@ -1828,7 +1861,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not MessagesController.getInstance().unblockUser(currentUser.id); } }); + } else if (currentUser != null && botUser != null) { + if (botUser.length() != 0) { + MessagesController.getInstance().sendBotStart(currentUser, botUser); + } else { + SendMessagesHelper.getInstance().sendMessage("/start", dialog_id, null, null, false); + } + botUser = null; + updateBottomOverlay(); } else { + builder = new AlertDialog.Builder(getParentActivity()); builder.setMessage(LocaleController.getString("AreYouSureDeleteThisChat", R.string.AreYouSureDeleteThisChat)); builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { @Override @@ -1838,8 +1880,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } }); } - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showDialog(builder.create()); + if (builder != null) { + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showDialog(builder.create()); + } } }); @@ -1871,6 +1916,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not chatListView.setEmptyView(emptyViewContainer); } + chatActivityEnterView.setButtons(botButtons); + updateContactStatus(); updateBottomOverlay(); updateSecretStatus(); @@ -1905,6 +1952,160 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not return false; } + private void processSelectedAttach(int which) { + if (which == attach_photo || which == attach_gallery || which == attach_document || which == attach_video) { + String action; + if (currentChat != null) { + if (currentChat.participants_count > MessagesController.getInstance().groupBigSize) { + if (which == attach_photo || which == attach_gallery) { + action = "bigchat_upload_photo"; + } else { + action = "bigchat_upload_document"; + } + } else { + if (which == attach_photo || which == attach_gallery) { + action = "chat_upload_photo"; + } else { + action = "chat_upload_document"; + } + } + } else { + if (which == attach_photo || which == attach_gallery) { + action = "pm_upload_photo"; + } else { + action = "pm_upload_document"; + } + } + if (action != null && !MessagesController.isFeatureEnabled(action, ChatActivity.this)) { + return; + } + } + + if (which == attach_photo) { + try { + Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + File image = AndroidUtilities.generatePicturePath(); + if (image != null) { + takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image)); + currentPicturePath = image.getAbsolutePath(); + } + startActivityForResult(takePictureIntent, 0); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } else if (which == attach_gallery) { + PhotoAlbumPickerActivity fragment = new PhotoAlbumPickerActivity(false, ChatActivity.this); + fragment.setDelegate(new PhotoAlbumPickerActivity.PhotoAlbumPickerActivityDelegate() { + @Override + public void didSelectPhotos(ArrayList photos, ArrayList captions, ArrayList webPhotos) { + SendMessagesHelper.prepareSendingPhotos(photos, null, dialog_id, replyingMessageObject, captions); + SendMessagesHelper.prepareSendingPhotosSearch(webPhotos, dialog_id, replyingMessageObject); + showReplyPanel(false, null, null, null, false, true); + } + + @Override + public void startPhotoSelectActivity() { + try { + Intent videoPickerIntent = new Intent(); + videoPickerIntent.setType("video/*"); + videoPickerIntent.setAction(Intent.ACTION_GET_CONTENT); + videoPickerIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, (long) (1024 * 1024 * 1536)); + + Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); + photoPickerIntent.setType("image/*"); + Intent chooserIntent = Intent.createChooser(photoPickerIntent, null); + chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{videoPickerIntent}); + + startActivityForResult(chooserIntent, 1); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + + @Override + public boolean didSelectVideo(String path) { + if (Build.VERSION.SDK_INT >= 16) { + return !openVideoEditor(path, true, true); + } else { + SendMessagesHelper.prepareSendingVideo(path, 0, 0, 0, 0, null, dialog_id, replyingMessageObject); + showReplyPanel(false, null, null, null, false, true); + return true; + } + } + }); + presentFragment(fragment); + } else if (which == attach_video) { + try { + Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); + File video = AndroidUtilities.generateVideoPath(); + if (video != null) { + if (Build.VERSION.SDK_INT >= 18) { + takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(video)); + } + takeVideoIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, (long) (1024 * 1024 * 1536)); + currentPicturePath = video.getAbsolutePath(); + } + startActivityForResult(takeVideoIntent, 2); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } else if (which == attach_location) { + if (!isGoogleMapsInstalled()) { + return; + } + LocationActivity fragment = new LocationActivity(); + fragment.setDelegate(new LocationActivity.LocationActivityDelegate() { + @Override + public void didSelectLocation(TLRPC.MessageMedia location) { + SendMessagesHelper.getInstance().sendMessage(location, dialog_id, replyingMessageObject); + moveScrollToLastMessage(); + showReplyPanel(false, null, null, null, false, true); + if (paused) { + scrollToTopOnResume = true; + } + } + }); + presentFragment(fragment); + } else if (which == attach_document) { + DocumentSelectActivity fragment = new DocumentSelectActivity(); + fragment.setDelegate(new DocumentSelectActivity.DocumentSelectActivityDelegate() { + @Override + public void didSelectFiles(DocumentSelectActivity activity, ArrayList files) { + activity.finishFragment(); + SendMessagesHelper.prepareSendingDocuments(files, files, null, null, dialog_id, replyingMessageObject); + showReplyPanel(false, null, null, null, false, true); + } + + @Override + public void startDocumentSelectActivity() { + try { + Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); + photoPickerIntent.setType("*/*"); + startActivityForResult(photoPickerIntent, 21); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + presentFragment(fragment); + } else if (which == attach_audio) { + try { + Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI); + startActivityForResult(intent, 32); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } else if (which == attach_contact) { + try { + Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI); + intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE); + startActivityForResult(intent, 31); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + } + private void searchLinks(CharSequence charSequence, boolean force) { if (currentEncryptedChat != null) { return; @@ -2008,7 +2209,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not return; } replyIconImageView.setImageResource(R.drawable.reply); - replyNameTextView.setText(ContactsController.formatName(user.first_name, user.last_name)); + replyNameTextView.setText(UserObject.getUserName(user)); if (messageObject.messageText != null) { String mess = messageObject.messageText.toString(); if (mess.length() > 150) { @@ -2050,7 +2251,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not continue; } if (uids.size() == 1) { - userNames.append(ContactsController.formatName(user.first_name, user.last_name)); + userNames.append(UserObject.getUserName(user)); } else if (uids.size() == 2 || userNames.length() == 0) { if (userNames.length() > 0) { userNames.append(", "); @@ -2155,6 +2356,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (replyingMessageObject == null && forwardingMessages == null && foundWebPage == null) { return; } + if (replyingMessageObject != null && replyingMessageObject.messageOwner.reply_markup instanceof TLRPC.TL_replyKeyboardForceReply) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + preferences.edit().putInt("answered_" + dialog_id, replyingMessageObject.getId()).commit(); + } if (foundWebPage != null) { foundWebPage = null; chatActivityEnterView.setWebPage(null, !cancel); @@ -2211,6 +2416,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not maxDate = Integer.MIN_VALUE; minDate = 0; forward_end_reached = true; + first = true; + firstLoading = true; loading = true; startLoadFromMessageId = 0; needSelectFromMessageId = false; @@ -2361,7 +2568,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not bottomOverlay.setVisibility(View.INVISIBLE); } if (hideKeyboard) { - chatActivityEnterView.hideEmojiPopup(); + chatActivityEnterView.hidePopup(); if (getParentActivity() != null) { AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); } @@ -2372,7 +2579,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private void checkActionBarMenu() { if (currentEncryptedChat != null && !(currentEncryptedChat instanceof TLRPC.TL_encryptedChat) || currentChat != null && (currentChat instanceof TLRPC.TL_chatForbidden || currentChat.left) || - currentUser != null && (currentUser instanceof TLRPC.TL_userDeleted || currentUser instanceof TLRPC.TL_userEmpty)) { + currentUser != null && UserObject.isDeleted(currentUser)) { if (menuItem != null) { menuItem.setVisibility(View.GONE); @@ -2608,18 +2815,48 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (currentUser.phone != null && currentUser.phone.length() != 0) { nameTextView.setText(PhoneFormat.getInstance().format("+" + currentUser.phone)); } else { - if (currentUser instanceof TLRPC.TL_userDeleted) { - nameTextView.setText(LocaleController.getString("HiddenName", R.string.HiddenName)); - } else { - nameTextView.setText(ContactsController.formatName(currentUser.first_name, currentUser.last_name)); - } + nameTextView.setText(UserObject.getUserName(currentUser)); } } else { - nameTextView.setText(ContactsController.formatName(currentUser.first_name, currentUser.last_name)); + nameTextView.setText(UserObject.getUserName(currentUser)); } } } + private void updateBotButtons() { + if (headerItem == null || currentUser == null || currentEncryptedChat != null || (currentUser.flags & TLRPC.USER_FLAG_BOT) == 0) { + return; + } + boolean hasHelp = false; + boolean hasSettings = false; + if (!botInfo.isEmpty()) { + for (HashMap.Entry entry : botInfo.entrySet()) { + TLRPC.BotInfo info = entry.getValue(); + for (int a = 0; a < info.commands.size(); a++) { + TLRPC.TL_botCommand command = info.commands.get(a); + if (command.command.toLowerCase().equals("help")) { + hasHelp = true; + } else if (command.command.toLowerCase().equals("settings")) { + hasSettings = true; + } + if (hasSettings && hasHelp) { + break; + } + } + } + } + if (hasHelp) { + headerItem.showSubItem(bot_help); + } else { + headerItem.hideSubItem(bot_help); + } + if (hasSettings) { + headerItem.showSubItem(bot_settings); + } else { + headerItem.hideSubItem(bot_settings); + } + } + private void updateTitleIcons() { int leftIcon = currentEncryptedChat != null ? R.drawable.ic_lock_header : 0; int rightIcon = MessagesController.getInstance().isDialogMuted(dialog_id) ? R.drawable.mute_fixed : 0; @@ -2663,9 +2900,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (user != null) { currentUser = user; } - String newStatus = LocaleController.formatUserStatus(currentUser); + String newStatus; if (currentUser.id == 333000 || currentUser.id == 777000) { newStatus = LocaleController.getString("ServiceNotifications", R.string.ServiceNotifications); + } else if ((currentUser.flags & TLRPC.USER_FLAG_BOT) != 0) { + newStatus = LocaleController.getString("Bot", R.string.Bot); + } else { + newStatus = LocaleController.formatUserStatus(currentUser); } if (lastStatus == null || lastPrintString != null || lastStatus != null && !lastStatus.equals(newStatus)) { lastStatus = newStatus; @@ -2919,7 +3160,22 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not showAttachmentError(); return; } - String tempPath = AndroidUtilities.getPath(data.getData()); + Uri uri = data.getData(); + + String extractUriFrom = uri.toString(); + if (extractUriFrom.contains("com.google.android.apps.photos.contentprovider")) { + try { + String firstExtraction = extractUriFrom.split("/1/")[1]; + if (firstExtraction.contains("/ACTUAL")) { + firstExtraction = firstExtraction.replace("/ACTUAL", ""); + String secondExtraction = URLDecoder.decode(firstExtraction, "UTF-8"); + uri = Uri.parse(secondExtraction); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + String tempPath = AndroidUtilities.getPath(uri); String originalPath = tempPath; if (tempPath == null) { originalPath = data.toString(); @@ -2931,6 +3187,56 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } SendMessagesHelper.prepareSendingDocument(tempPath, originalPath, null, null, dialog_id, replyingMessageObject); showReplyPanel(false, null, null, null, false, true); + } else if (requestCode == 31) { + if (data == null || data.getData() == null) { + showAttachmentError(); + return; + } + Uri uri = data.getData(); + Cursor c = null; + try { + c = getParentActivity().getContentResolver().query(uri, new String[]{ContactsContract.Data.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}, null, null, null); + if (c != null) { + boolean sent = false; + while (c.moveToNext()) { + sent = true; + String name = c.getString(0); + String number = c.getString(1); + TLRPC.User user = new TLRPC.User(); + user.first_name = name; + user.last_name = ""; + user.phone = number; + SendMessagesHelper.getInstance().sendMessage(user, dialog_id, replyingMessageObject); + } + if (sent) { + showReplyPanel(false, null, null, null, false, true); + } + } + } finally { + try { + if (c != null && !c.isClosed()) { + c.close(); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + } else if (requestCode == 32) { + if (data == null || data.getData() == null) { + showAttachmentError(); + return; + } + Uri uri = data.getData(); + String path = AndroidUtilities.getPath(uri); + if (path != null) { + TLRPC.TL_audio audio = new TLRPC.TL_audio(); + audio.dc_id = Integer.MIN_VALUE; + audio.id = Integer.MIN_VALUE; + audio.user_id = UserConfig.getClientUserId(); + audio.mime_type = "audio/mp3"; + SendMessagesHelper.getInstance().sendMessage(audio, path, dialog_id, replyingMessageObject); + showReplyPanel(false, null, null, null, false, true); + } } } } @@ -3125,11 +3431,18 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not last_message_id = 0; first_message_id = 0; startLoadFromMessageId = 0; - chatAdapter.notifyItemChanged(chatAdapter.getItemCount() - 1); + chatAdapter.notifyItemRemoved(chatAdapter.getItemCount() - 1); newRowsCount--; } if (newRowsCount != 0) { - chatAdapter.notifyItemRangeInserted(chatAdapter.getItemCount() - 2, newRowsCount); + int firstVisPos = chatLayoutManager.findLastVisibleItemPosition(); + if (firstVisPos == RecyclerView.NO_POSITION) { + firstVisPos = 0; + } + View firstVisView = chatListView.getChildAt(chatListView.getChildCount() - 1); + int top = ((firstVisView == null) ? 0 : firstVisView.getTop()) - chatListView.getPaddingTop(); + chatAdapter.notifyItemRangeInserted(chatAdapter.getItemCount() - 1, newRowsCount); + chatLayoutManager.scrollToPositionWithOffset(firstVisPos, top); } loadingForward = false; } else { @@ -3157,21 +3470,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } else { chatLayoutManager.scrollToPositionWithOffset(messages.size() - messages.indexOf(scrollToMessage), AndroidUtilities.dp(-11) + yOffset); } - ViewTreeObserver obs = chatListView.getViewTreeObserver(); - obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { //TODO remove it? - if (!messages.isEmpty()) { - if (messages.get(messages.size() - 1) == scrollToMessage) { - chatLayoutManager.scrollToPositionWithOffset(0, AndroidUtilities.dp(-11) + yOffset); - } else { - chatLayoutManager.scrollToPositionWithOffset(messages.size() - messages.indexOf(scrollToMessage), AndroidUtilities.dp(-11) + yOffset); - } - } - chatListView.getViewTreeObserver().removeOnPreDrawListener(this); - return true; - } - }); } chatListView.invalidate(); showPagedownButton(true, true); @@ -3180,13 +3478,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } else { if (endReached) { - chatAdapter.notifyItemRemoved(0); + chatAdapter.notifyItemRemoved(chatAdapter.isBot ? 1 : 0); } if (newRowsCount != 0) { int firstVisPos = chatLayoutManager.findLastVisibleItemPosition(); + if (firstVisPos == RecyclerView.NO_POSITION) { + firstVisPos = 0; + } View firstVisView = chatListView.getChildAt(chatListView.getChildCount() - 1); int top = ((firstVisView == null) ? 0 : firstVisView.getTop()) - chatListView.getPaddingTop(); - chatAdapter.notifyItemRangeInserted(1, newRowsCount); + chatAdapter.notifyItemRangeInserted(chatAdapter.isBot ? 2 : 1, newRowsCount); chatLayoutManager.scrollToPositionWithOffset(firstVisPos + newRowsCount - (endReached ? 1 : 0), top); } } @@ -3225,6 +3526,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not }, 700); first = false; } + if (messages.isEmpty() && currentEncryptedChat == null && currentUser != null && (currentUser.flags & TLRPC.USER_FLAG_BOT) != 0 && botUser == null) { + botUser = ""; + updateBottomOverlay(); + } if (progressView != null) { progressView.setVisibility(View.INVISIBLE); @@ -3293,6 +3598,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } + ReplyMessageQuery.loadReplyMessagesForMessages(arr, dialog_id); if (!forward_end_reached) { int currentMaxDate = Integer.MIN_VALUE; int currentMinMsgId = Integer.MIN_VALUE; @@ -3345,10 +3651,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } updateVisibleRows(); } else { - ReplyMessageQuery.loadReplyMessagesForMessages(arr, dialog_id); boolean markAsRead = false; boolean unreadUpdated = true; int oldCount = messages.size(); + int addedCount = 0; for (MessageObject obj : arr) { if (currentEncryptedChat != null && obj.messageOwner.action != null && obj.messageOwner.action instanceof TLRPC.TL_messageEncryptedAction && obj.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL && timerDrawable != null) { @@ -3388,6 +3694,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not dateObj.type = 10; dateObj.contentType = 4; messages.add(0, dateObj); + addedCount++; } if (!obj.isOut()) { if (paused) { @@ -3412,6 +3719,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not unreadUpdated = false; unread_to_load = 0; scrollToTopUnReadOnResume = true; + addedCount++; } } if (unreadMessageObject != null) { @@ -3425,12 +3733,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not markAsRead = true; } } + dayArray.add(0, obj); messages.add(0, obj); + addedCount++; if (obj.type == 10 || obj.type == 11) { updateChat = true; } } + if (progressView != null) { progressView.setVisibility(View.INVISIBLE); } @@ -3438,8 +3749,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (unreadUpdated) { chatAdapter.updateRowWithMessageObject(unreadMessageObject); } - if (messages.size() - oldCount != 0) { - chatAdapter.notifyItemRangeInserted(chatAdapter.getItemCount(), messages.size() - oldCount); + if (addedCount != 0) { + chatAdapter.notifyItemRangeInserted(chatAdapter.getItemCount(), addedCount); } } else { scrollToTopOnResume = true; @@ -3447,9 +3758,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (chatListView != null && chatAdapter != null) { int lastVisible = chatLayoutManager.findLastVisibleItemPosition(); + if (lastVisible == RecyclerView.NO_POSITION) { + lastVisible = 0; + } if (endReached) { lastVisible++; } + if (chatAdapter.isBot) { + oldCount++; + } if (lastVisible == oldCount || hasFromMe) { if (!firstLoading) { if (paused) { @@ -3475,6 +3792,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } } + if (!messages.isEmpty() && botUser != null && botUser.length() == 0) { + botUser = null; + updateBottomOverlay(); + } if (updateChat) { updateTitle(); checkAndUpdateAvatar(); @@ -3552,8 +3873,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } if (messages.isEmpty()) { if (!endReached && !loading) { - progressView.setVisibility(View.INVISIBLE); - chatListView.setEmptyView(null); + if (progressView != null) { + progressView.setVisibility(View.INVISIBLE); + } + if (chatListView != null) { + chatListView.setEmptyView(null); + } if (currentEncryptedChat == null) { maxMessageId = Integer.MAX_VALUE; minMessageId = Integer.MIN_VALUE; @@ -3565,6 +3890,17 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not minDate = 0; MessagesController.getInstance().loadMessages(dialog_id, 30, 0, !cacheEndReaced, minDate, classGuid, 0, 0, 0, true); loading = true; + } else { + if (botButtons != null) { + botButtons = null; + if (chatActivityEnterView != null) { + chatActivityEnterView.setButtons(null, false); + } + } + if (currentEncryptedChat == null && currentUser != null && (currentUser.flags & TLRPC.USER_FLAG_BOT) != 0 && botUser == null) { + botUser = ""; + updateBottomOverlay(); + } } } if (updated && chatAdapter != null) { @@ -3582,11 +3918,28 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not obj.messageOwner.media = newMsgObj.media; obj.generateThumbs(true); } - messagesDict.remove(msgId); + int oldCount = messagesDict.size(); + MessageObject removed = messagesDict.remove(msgId); messagesDict.put(newMsgId, obj); obj.messageOwner.id = newMsgId; obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENT; + ArrayList messArr = new ArrayList<>(); + messArr.add(obj); + ReplyMessageQuery.loadReplyMessagesForMessages(messArr, dialog_id); updateVisibleRows(); + if (oldCount != messagesDict.size()) { + int index = messages.indexOf(removed); + messages.remove(index); + ArrayList dayArr = messagesByDays.get(removed.dateKey); + dayArr.remove(obj); + if (dayArr.isEmpty()) { + messagesByDays.remove(obj.dateKey); + if (index >= 0 && index < messages.size()) { + messages.remove(index); + } + } + chatAdapter.notifyDataSetChanged(); + } if (mediaUpdated && chatLayoutManager.findLastVisibleItemPosition() >= messages.size() - 1) { moveScrollToLastMessage(); } @@ -3618,6 +3971,25 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (isBroadcast) { SendMessagesHelper.getInstance().setCurrentChatInfo(info); } + if (info != null) { + hasBotsCommands = false; + botInfo.clear(); + botsCount = 0; + for (int a = 0; a < info.participants.size(); a++) { + TLRPC.TL_chatParticipant participant = info.participants.get(a); + TLRPC.User user = MessagesController.getInstance().getUser(participant.user_id); + if (user != null && (user.flags & TLRPC.USER_FLAG_BOT) != 0) { + botsCount++; + BotQuery.loadBotInfo(user.id, true, classGuid); + } + } + } + if (chatActivityEnterView != null) { + chatActivityEnterView.setBotsCount(botsCount, hasBotsCommands); + } + if (mentionsAdapter != null) { + mentionsAdapter.setBotsCount(botsCount); + } } } else if (id == NotificationCenter.contactsDidLoaded) { updateContactStatus(); @@ -3697,6 +4069,17 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not selectedMessagesCanCopyIds.clear(); actionBar.hideActionMode(); chatAdapter.notifyDataSetChanged(); + + if (messages.isEmpty()) { + if (botButtons != null) { + botButtons = null; + chatActivityEnterView.setButtons(null, false); + } + if (currentEncryptedChat == null && currentUser != null && (currentUser.flags & TLRPC.USER_FLAG_BOT) != 0 && botUser == null) { + botUser = ""; + updateBottomOverlay(); + } + } } } else if (id == NotificationCenter.screenshotTook) { updateInformationForScreenshotDetector(); @@ -3759,16 +4142,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not mediaUpdated = true; } messagesDict.put(old.getId(), messageObject); - int idx = messages.indexOf(old); - if (idx >= 0) { - messages.set(idx, messageObject); - chatAdapter.notifyItemChanged(messages.size() - (!endReached ? 0 : 1) - idx); + int index = messages.indexOf(old); + if (index >= 0) { + messages.set(index, messageObject); + chatAdapter.notifyItemChanged(chatAdapter.messagesStartRow + messages.size() - index - 1); changed = true; } } } if (changed) { - if (mediaUpdated && chatLayoutManager.findLastVisibleItemPosition() >= messages.size() - 1) { + if (mediaUpdated && chatLayoutManager.findLastVisibleItemPosition() >= messages.size() - (chatAdapter.isBot ? 2 : 1)) { moveScrollToLastMessage(); } } @@ -3820,12 +4203,83 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (updated) { updateVisibleRows(); } + } else if (id == NotificationCenter.botInfoDidLoaded) { + int guid = (Integer) args[1]; + if (classGuid == guid) { + TLRPC.BotInfo info = (TLRPC.BotInfo) args[0]; + if (currentEncryptedChat == null) { + if (!info.commands.isEmpty()) { + hasBotsCommands = true; + } + botInfo.put(info.user_id, info); + if (chatAdapter != null) { + chatAdapter.notifyItemChanged(0); + } + if (mentionsAdapter != null) { + mentionsAdapter.setBotInfo(botInfo); + } + if (chatActivityEnterView != null) { + chatActivityEnterView.setBotsCount(botsCount, hasBotsCommands); + } + } + updateBotButtons(); + } + } else if (id == NotificationCenter.botKeyboardDidLoaded) { + if (dialog_id == (Long) args[1]) { + TLRPC.Message message = (TLRPC.Message) args[0]; + if (message != null) { + botButtons = new MessageObject(message, null, false); + if (chatActivityEnterView != null) { + if (botButtons.messageOwner.reply_markup instanceof TLRPC.TL_replyKeyboardForceReply) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + if (preferences.getInt("answered_" + dialog_id, 0) != botButtons.getId() && (replyingMessageObject == null || chatActivityEnterView.getFieldText() == null)) { + botReplyButtons = botButtons; + chatActivityEnterView.setButtons(botButtons); + showReplyPanel(true, botButtons, null, null, false, true); + } + } else { + if (replyingMessageObject != null && botReplyButtons == replyingMessageObject) { + botReplyButtons = null; + showReplyPanel(false, null, null, null, false, true); + } + chatActivityEnterView.setButtons(botButtons); + } + } + } else { + botButtons = null; + if (chatActivityEnterView != null) { + if (replyingMessageObject != null && botReplyButtons == replyingMessageObject) { + botReplyButtons = null; + showReplyPanel(false, null, null, null, false, true); + } + chatActivityEnterView.setButtons(botButtons); + } + } + } + } else if (id == NotificationCenter.chatSearchResultsAvailable) { + if (classGuid == (Integer) args[0]) { + int messageId = (Integer) args[1]; + if (messageId != 0) { + scrollToMessageId(messageId, 0, true); + } + updateSearchButtons((Integer) args[2]); + } + } + } + + private void updateSearchButtons(int mask) { + if (searchUpItem != null) { + searchUpItem.setEnabled((mask & 1) != 0); + searchDownItem.setEnabled((mask & 2) != 0); + ViewProxy.setAlpha(searchUpItem, searchUpItem.isEnabled() ? 1.0f : 0.6f); + ViewProxy.setAlpha(searchDownItem, searchDownItem.isEnabled() ? 1.0f : 0.6f); } } @Override protected void onOpenAnimationStart() { NotificationCenter.getInstance().setAnimationInProgress(true); + openAnimationEnded = false; } @Override @@ -3847,23 +4301,39 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } private void updateBottomOverlay() { + if (bottomOverlayChatText == null) { + return; + } if (currentUser == null) { bottomOverlayChatText.setText(LocaleController.getString("DeleteThisGroup", R.string.DeleteThisGroup)); } else { if (userBlocked) { bottomOverlayChatText.setText(LocaleController.getString("Unblock", R.string.Unblock)); + } else if (botUser != null) { + bottomOverlayChatText.setText(LocaleController.getString("BotStart", R.string.BotStart)); + chatActivityEnterView.hidePopup(); + if (getParentActivity() != null) { + AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); + } } else { bottomOverlayChatText.setText(LocaleController.getString("DeleteThisChat", R.string.DeleteThisChat)); } } if (currentChat != null && (currentChat instanceof TLRPC.TL_chatForbidden || currentChat.left) || - currentUser != null && (currentUser instanceof TLRPC.TL_userDeleted || currentUser instanceof TLRPC.TL_userEmpty || userBlocked)) { + currentUser != null && (UserObject.isDeleted(currentUser) || userBlocked)) { bottomOverlayChat.setVisibility(View.VISIBLE); muteItem.setVisibility(View.GONE); chatActivityEnterView.setFieldFocused(false); + chatActivityEnterView.setVisibility(View.INVISIBLE); } else { + if (botUser != null) { + bottomOverlayChat.setVisibility(View.VISIBLE); + chatActivityEnterView.setVisibility(View.INVISIBLE); + } else { + chatActivityEnterView.setVisibility(View.VISIBLE); + bottomOverlayChat.setVisibility(View.INVISIBLE); + } muteItem.setVisibility(View.VISIBLE); - bottomOverlayChat.setVisibility(View.INVISIBLE); } } @@ -3880,7 +4350,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } if (currentEncryptedChat != null && !(currentEncryptedChat instanceof TLRPC.TL_encryptedChat) || currentUser.id / 1000 == 333 || currentUser.id / 1000 == 777 - || currentUser instanceof TLRPC.TL_userEmpty || currentUser instanceof TLRPC.TL_userDeleted + || UserObject.isDeleted(currentUser) || ContactsController.getInstance().isLoadingContacts() || (currentUser.phone != null && currentUser.phone.length() != 0 && ContactsController.getInstance().contactsDict.get(currentUser.id) != null && (ContactsController.getInstance().contactsDict.size() != 0 || !ContactsController.getInstance().isLoadingContacts()))) { addContactItem.setVisibility(View.GONE); @@ -3944,31 +4414,40 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not fixLayout(true); SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); - String lastMessageText = preferences.getString("dialog_" + dialog_id, null); - if (lastMessageText != null) { - preferences.edit().remove("dialog_" + dialog_id).commit(); - chatActivityEnterView.setFieldText(lastMessageText); - } - String lastReplyMessage = preferences.getString("reply_" + dialog_id, null); - if (lastReplyMessage != null && lastReplyMessage.length() != 0) { - preferences.edit().remove("reply_" + dialog_id).commit(); - try { - byte[] bytes = Base64.decode(lastReplyMessage, Base64.DEFAULT); - if (bytes != null) { - SerializedData data = new SerializedData(bytes); - TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false); - if (message != null) { - replyingMessageObject = new MessageObject(message, MessagesController.getInstance().getUsers(), false); - showReplyPanel(true, replyingMessageObject, null, null, false, false); - } - } - } catch (Exception e) { - FileLog.e("tmessages", e); + if (chatActivityEnterView.getFieldText() == null) { + String lastMessageText = preferences.getString("dialog_" + dialog_id, null); + if (lastMessageText != null) { + preferences.edit().remove("dialog_" + dialog_id).commit(); + chatActivityEnterView.setFieldText(lastMessageText); } + } else { + preferences.edit().remove("dialog_" + dialog_id).commit(); + } + if (replyingMessageObject == null) { + String lastReplyMessage = preferences.getString("reply_" + dialog_id, null); + if (lastReplyMessage != null && lastReplyMessage.length() != 0) { + preferences.edit().remove("reply_" + dialog_id).commit(); + try { + byte[] bytes = Base64.decode(lastReplyMessage, Base64.DEFAULT); + if (bytes != null) { + SerializedData data = new SerializedData(bytes); + TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false); + if (message != null) { + replyingMessageObject = new MessageObject(message, MessagesController.getInstance().getUsers(), false); + showReplyPanel(true, replyingMessageObject, null, null, false, false); + } + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + } else { + preferences.edit().remove("reply_" + dialog_id).commit(); } if (bottomOverlayChat.getVisibility() != View.VISIBLE) { chatActivityEnterView.setFieldFocused(true); } + chatActivityEnterView.onResume(); if (currentEncryptedChat != null) { chatEnterTime = System.currentTimeMillis(); chatLeaveTime = 0; @@ -3989,12 +4468,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not chatListView.setLongClickable(true); } - @Override - public void onBeginSlide() { - super.onBeginSlide(); - chatActivityEnterView.hideEmojiPopup(); - } - @Override public void onPause() { super.onPause(); @@ -4005,7 +4478,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not wasPaused = true; NotificationsController.getInstance().setOpennedDialogId(0); if (chatActivityEnterView != null) { - chatActivityEnterView.hideEmojiPopup(); + chatActivityEnterView.onPause(); String text = chatActivityEnterView.getFieldText(); if (text != null) { SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); @@ -4070,16 +4543,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (avatarContainer != null) { avatarContainer.getViewTreeObserver().removeOnPreDrawListener(this); } - if (getParentActivity() == null) { - return false; - } - if (!AndroidUtilities.isTablet() && getParentActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + if (!AndroidUtilities.isTablet() && ApplicationLoader.applicationContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { selectedMessagesCountTextView.setTextSize(18); } else { selectedMessagesCountTextView.setTextSize(20); } if (AndroidUtilities.isTablet()) { - if (AndroidUtilities.isSmallTablet() && getParentActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { + if (AndroidUtilities.isSmallTablet() && ApplicationLoader.applicationContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); } else { actionBar.setBackButtonImage(R.drawable.ic_close_white); @@ -4090,7 +4560,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) avatarContainer.getLayoutParams(); layoutParams.topMargin = (Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0); avatarContainer.setLayoutParams(layoutParams); - return false; + return true; } }); } @@ -4299,18 +4769,22 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not forwaringMessage = selectedObject; Bundle args = new Bundle(); args.putBoolean("onlySelect", true); - args.putBoolean("serverOnly", true); + args.putInt("dialogsType", 1); MessagesActivity fragment = new MessagesActivity(args); fragment.setDelegate(this); presentFragment(fragment); } else if (option == 3) { - if (Build.VERSION.SDK_INT < 11) { - android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); - clipboard.setText(selectedObject.messageText); - } else { - android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); - android.content.ClipData clip = android.content.ClipData.newPlainText("label", selectedObject.messageText); - clipboard.setPrimaryClip(clip); + try { + if (Build.VERSION.SDK_INT < 11) { + android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); + clipboard.setText(selectedObject.messageText); + } else { + android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); + android.content.ClipData clip = android.content.ClipData.newPlainText("label", selectedObject.messageText); + clipboard.setPrimaryClip(clip); + } + } catch (Exception e) { + FileLog.e("tmessages", e); } } else if (option == 4) { String fileName = selectedObject.getFileName(); @@ -4478,8 +4952,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not actionBar.hideActionMode(); updateVisibleRows(); return false; - } else if (chatActivityEnterView.isEmojiPopupShowing()) { - chatActivityEnterView.hideEmojiPopup(); + } else if (chatActivityEnterView.isPopupShowing()) { + chatActivityEnterView.hidePopup(); return false; } return true; @@ -4645,9 +5119,46 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not public class ChatActivityAdapter extends RecyclerView.Adapter { private Context mContext; + private boolean isBot; + private int rowCount; + private int botInfoRow; + private int loadingUpRow; + private int loadingDownRow; + private int messagesStartRow; + private int messagesEndRow; public ChatActivityAdapter(Context context) { mContext = context; + isBot = currentUser != null && (currentUser.flags & TLRPC.USER_FLAG_BOT) != 0; + } + + public void updateRows() { + rowCount = 0; + if (currentUser != null && (currentUser.flags & TLRPC.USER_FLAG_BOT) != 0) { + botInfoRow = rowCount++; + } else { + botInfoRow = -1; + } + if (!messages.isEmpty()) { + if (!endReached) { + loadingUpRow = rowCount++; + } else { + loadingUpRow = -1; + } + messagesStartRow = rowCount; + rowCount += messages.size(); + messagesEndRow = rowCount; + if (!forward_end_reached) { + loadingDownRow = rowCount++; + } else { + loadingDownRow = -1; + } + } else { + loadingUpRow = -1; + loadingDownRow = -1; + messagesStartRow = -1; + messagesEndRow = -1; + } } private class Holder extends RecyclerView.ViewHolder { @@ -4659,16 +5170,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not @Override public int getItemCount() { - int count = messages.size(); - if (count != 0) { - if (!endReached) { - count++; - } - if (!forward_end_reached) { - count++; - } - } - return count; + return rowCount; } @Override @@ -4700,12 +5202,25 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } else if (viewType == 4) { view = new ChatActionCell(mContext); } else if (viewType == 5) { - LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - view = li.inflate(R.layout.chat_loading_layout, parent, false); - view.findViewById(R.id.progressLayout).setBackgroundResource(ApplicationLoader.isCustomTheme() ? R.drawable.system_loader2 : R.drawable.system_loader1); + view = new ChatLoadingCell(mContext); } else if (viewType == 6) { - LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - view = li.inflate(R.layout.chat_unread_layout, parent, false); + view = new ChatUnreadCell(mContext); + } else if (viewType == 7) { + view = new BotHelpCell(mContext); + ((BotHelpCell) view).setDelegate(new BotHelpCell.BotHelpCellDelegate() { + @Override + public void didPressUrl(String url) { + if (url.startsWith("@")) { + MessagesController.openByUserName(url.substring(1), ChatActivity.this, 0); + } else if (url.startsWith("#")) { + MessagesActivity fragment = new MessagesActivity(null); + fragment.setSearchString(url); + presentFragment(fragment); + } else if (url.startsWith("/")) { + chatActivityEnterView.setCommand(null, url); + } + } + }); } if (view instanceof ChatBaseCell) { @@ -4742,13 +5257,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } @Override - public void didPressUrl(String url) { + public void didPressUrl(MessageObject messageObject, String url) { if (url.startsWith("@")) { MessagesController.openByUserName(url.substring(1), ChatActivity.this, 0); } else if (url.startsWith("#")) { MessagesActivity fragment = new MessagesActivity(null); fragment.setSearchString(url); presentFragment(fragment); + } else if (url.startsWith("/")) { + chatActivityEnterView.setCommand(messageObject, url); } } @@ -4898,13 +5415,17 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not FileLog.e("tmessages", e); } } else if (i == 0) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); - clipboard.setText(messageObject.messageOwner.media.phone_number); - } else { - android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); - android.content.ClipData clip = android.content.ClipData.newPlainText("label", messageObject.messageOwner.media.phone_number); - clipboard.setPrimaryClip(clip); + try { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { + android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); + clipboard.setText(messageObject.messageOwner.media.phone_number); + } else { + android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); + android.content.ClipData clip = android.content.ClipData.newPlainText("label", messageObject.messageOwner.media.phone_number); + clipboard.setPrimaryClip(clip); + } + } catch (Exception e) { + FileLog.e("tmessages", e); } } } @@ -4944,63 +5465,59 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { - int viewType = holder.getItemViewType(); - if (viewType == 5) { - holder.itemView.findViewById(R.id.progressLayout).setVisibility(loadsCount > 1 ? View.VISIBLE : View.INVISIBLE); - return; - } + if (position == botInfoRow) { + BotHelpCell helpView = (BotHelpCell) holder.itemView; + helpView.setText(!botInfo.isEmpty() ? botInfo.get(currentUser.id).description : null); + } else if (position == loadingDownRow || position == loadingUpRow) { + ChatLoadingCell loadingCell = (ChatLoadingCell) holder.itemView; + loadingCell.setProgressVisible(loadsCount > 1); + } else if (position >= messagesStartRow && position < messagesEndRow) { + MessageObject message = messages.get(messages.size() - (position - messagesStartRow) - 1); + View view = holder.itemView; - MessageObject message = messages.get(messages.size() - position - (!endReached ? 0 : 1)); - View view = holder.itemView; - - int type = message.contentType; - - boolean selected = false; - boolean disableSelection = false; - if (actionBar.isActionModeShowed()) { - if (selectedMessagesIds.containsKey(message.getId())) { - view.setBackgroundColor(0x6633b5e5); - selected = true; + boolean selected = false; + boolean disableSelection = false; + if (actionBar.isActionModeShowed()) { + if (selectedMessagesIds.containsKey(message.getId())) { + view.setBackgroundColor(0x6633b5e5); + selected = true; + } else { + view.setBackgroundColor(0); + } + disableSelection = true; } else { view.setBackgroundColor(0); } - disableSelection = true; - } else { - view.setBackgroundColor(0); - } - if (view instanceof ChatBaseCell) { - ChatBaseCell baseCell = (ChatBaseCell) view; - baseCell.isChat = currentChat != null; - baseCell.setMessageObject(message); - baseCell.setCheckPressed(!disableSelection, disableSelection && selected); - if (view instanceof ChatAudioCell && MediaController.getInstance().canDownloadMedia(MediaController.AUTODOWNLOAD_MASK_AUDIO)) { - ((ChatAudioCell) view).downloadAudioIfNeed(); + if (view instanceof ChatBaseCell) { + ChatBaseCell baseCell = (ChatBaseCell) view; + baseCell.isChat = currentChat != null; + baseCell.setMessageObject(message); + baseCell.setCheckPressed(!disableSelection, disableSelection && selected); + if (view instanceof ChatAudioCell && MediaController.getInstance().canDownloadMedia(MediaController.AUTODOWNLOAD_MASK_AUDIO)) { + ((ChatAudioCell) view).downloadAudioIfNeed(); + } + baseCell.setHighlighted(highlightMessageId != Integer.MAX_VALUE && message.getId() == highlightMessageId); + } else if (view instanceof ChatActionCell) { + ChatActionCell actionCell = (ChatActionCell) view; + actionCell.setMessageObject(message); + } else if (view instanceof ChatUnreadCell) { + ChatUnreadCell unreadCell = (ChatUnreadCell) view; + unreadCell.setText(LocaleController.formatPluralString("NewMessages", unread_to_load)); } - baseCell.setHighlighted(highlightMessageId != Integer.MAX_VALUE && message.getId() == highlightMessageId); - } else if (view instanceof ChatActionCell) { - ChatActionCell actionCell = (ChatActionCell) view; - actionCell.setMessageObject(message); - } else if (type == 6) { - TextView messageTextView = (TextView) view.findViewById(R.id.chat_message_text); - messageTextView.setText(LocaleController.formatPluralString("NewMessages", unread_to_load)); } } @Override public int getItemViewType(int position) { - int offset = 1; - if (!endReached && messages.size() != 0) { - offset = 0; - if (position == 0) { - return 5; - } - } - if (!forward_end_reached && position == (messages.size() + 1 - offset)) { + if (position == loadingUpRow || position == loadingDownRow) { return 5; + } else if (position == botInfoRow) { + return 7; + } else if (position >= messagesStartRow && position < messagesEndRow) { + return messages.get(messages.size() - (position - messagesStartRow) - 1).contentType; } - MessageObject message = messages.get(messages.size() - position - offset); - return message.contentType; + return 5; } @Override @@ -5028,7 +5545,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (index == -1) { return; } - notifyItemChanged(messages.size() - (!endReached ? 0 : 1) - index); + notifyItemChanged(messagesStartRow + messages.size() - index - 1); } public void removeMessageObject(MessageObject messageObject) { @@ -5037,7 +5554,55 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not return; } messages.remove(index); - notifyItemRemoved(messages.size() - (!endReached ? 0 : 1) - index); + notifyItemRemoved(messagesStartRow + messages.size() - index - 1); + } + + @Override + public void notifyDataSetChanged() { + updateRows(); + super.notifyDataSetChanged(); + } + + @Override + public void notifyItemChanged(int position) { + updateRows(); + super.notifyItemChanged(position); + } + + @Override + public void notifyItemRangeChanged(int positionStart, int itemCount) { + updateRows(); + super.notifyItemRangeChanged(positionStart, itemCount); + } + + @Override + public void notifyItemInserted(int position) { + updateRows(); + super.notifyItemInserted(position); + } + + @Override + public void notifyItemMoved(int fromPosition, int toPosition) { + updateRows(); + super.notifyItemMoved(fromPosition, toPosition); + } + + @Override + public void notifyItemRangeInserted(int positionStart, int itemCount) { + updateRows(); + super.notifyItemRangeInserted(positionStart, itemCount); + } + + @Override + public void notifyItemRemoved(int position) { + updateRows(); + super.notifyItemRemoved(position); + } + + @Override + public void notifyItemRangeRemoved(int positionStart, int itemCount) { + updateRows(); + super.notifyItemRangeRemoved(positionStart, itemCount); } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java new file mode 100644 index 000000000..31520751c --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java @@ -0,0 +1,80 @@ +/* + * This is the source code of Telegram for Android v. 2.x.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.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.SharedPreferences; + +import org.telegram.android.LocaleController; +import org.telegram.android.MessagesController; +import org.telegram.android.MessagesStorage; +import org.telegram.android.NotificationsController; +import org.telegram.messenger.ApplicationLoader; +import org.telegram.messenger.ConnectionsManager; +import org.telegram.messenger.R; +import org.telegram.messenger.TLRPC; +import org.telegram.ui.ActionBar.BottomSheet; + +public class AlertsCreator { + + public static Dialog createMuteAlert(Context context, final long dialog_id) { + if (context == null) { + return null; + } + + BottomSheet.Builder builder = new BottomSheet.Builder(context); + builder.setTitle(LocaleController.getString("Notifications", R.string.Notifications)); + CharSequence[] items = new CharSequence[]{ + LocaleController.formatString("MuteFor", R.string.MuteFor, LocaleController.formatPluralString("Hours", 1)), + LocaleController.formatString("MuteFor", R.string.MuteFor, LocaleController.formatPluralString("Hours", 8)), + LocaleController.formatString("MuteFor", R.string.MuteFor, LocaleController.formatPluralString("Days", 2)), + LocaleController.getString("MuteDisable", R.string.MuteDisable) + }; + builder.setItems(items, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + int untilTime = ConnectionsManager.getInstance().getCurrentTime(); + if (i == 0) { + untilTime += 60 * 60; + } else if (i == 1) { + untilTime += 60 * 60 * 8; + } else if (i == 2) { + untilTime += 60 * 60 * 48; + } else if (i == 3) { + untilTime = Integer.MAX_VALUE; + } + + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + long flags; + if (i == 3) { + editor.putInt("notify2_" + dialog_id, 2); + flags = 1; + } else { + editor.putInt("notify2_" + dialog_id, 3); + editor.putInt("notifyuntil_" + dialog_id, untilTime); + flags = ((long) untilTime << 32) | 1; + } + MessagesStorage.getInstance().setDialogFlags(dialog_id, flags); + editor.commit(); + TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(dialog_id); + if (dialog != null) { + dialog.notify_settings = new TLRPC.TL_peerNotifySettings(); + dialog.notify_settings.mute_until = untilTime; + } + NotificationsController.updateServerNotificationsSettings(dialog_id); + } + } + ); + return builder.create(); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/BotKeyboardView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/BotKeyboardView.java new file mode 100644 index 000000000..cb8164d78 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/BotKeyboardView.java @@ -0,0 +1,126 @@ +/* + * This is the source code of Telegram for Android v. 2.x.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.util.TypedValue; +import android.view.Gravity; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ScrollView; +import android.widget.TextView; + +import org.telegram.android.AndroidUtilities; +import org.telegram.android.Emoji; +import org.telegram.messenger.R; +import org.telegram.messenger.TLRPC; + +import java.util.ArrayList; + +public class BotKeyboardView extends LinearLayout { + + private LinearLayout container; + private TLRPC.TL_replyKeyboardMarkup botButtons; + private BotKeyboardViewDelegate delegate; + private int panelHeight; + private boolean isFullSize; + private int buttonHeight; + private ArrayList buttonViews = new ArrayList<>(); + + public interface BotKeyboardViewDelegate { + void didPressedButton(CharSequence text); + } + + public BotKeyboardView(Context context) { + super(context); + + setOrientation(VERTICAL); + + ScrollView scrollView = new ScrollView(context); + addView(scrollView); + container = new LinearLayout(context); + container.setOrientation(VERTICAL); + scrollView.addView(container); + + setBackgroundColor(0xfff5f6f7); + } + + public void setDelegate(BotKeyboardViewDelegate botKeyboardViewDelegate) { + delegate = botKeyboardViewDelegate; + } + + public void setPanelHeight(int height) { + panelHeight = height; + if (isFullSize && botButtons != null) { + buttonHeight = !isFullSize ? 42 : (int) Math.max(42, (panelHeight - AndroidUtilities.dp(30) - (botButtons.rows.size() - 1) * AndroidUtilities.dp(10)) / botButtons.rows.size() / AndroidUtilities.density); + int count = container.getChildCount(); + int newHeight = AndroidUtilities.dp(buttonHeight); + for (int a = 0; a < count; a++) { + View v = container.getChildAt(a); + LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) v.getLayoutParams(); + if (layoutParams.height != newHeight) { + layoutParams.height = newHeight; + v.setLayoutParams(layoutParams); + } + } + } + } + + public void invalidateViews() { + for (int a = 0; a < buttonViews.size(); a++) { + buttonViews.get(a).invalidate(); + } + } + + public boolean isFullSize() { + return isFullSize; + } + + public void setButtons(TLRPC.TL_replyKeyboardMarkup buttons) { + botButtons = buttons; + container.removeAllViews(); + buttonViews.clear(); + + if (buttons != null) { + isFullSize = (buttons.flags & 1) == 0; + buttonHeight = !isFullSize ? 42 : (int) Math.max(42, (panelHeight - AndroidUtilities.dp(30) - (botButtons.rows.size() - 1) * AndroidUtilities.dp(10)) / botButtons.rows.size() / AndroidUtilities.density); + for (int a = 0; a < buttons.rows.size(); a++) { + TLRPC.TL_keyboardButtonRow row = buttons.rows.get(a); + + LinearLayout layout = new LinearLayout(getContext()); + layout.setOrientation(LinearLayout.HORIZONTAL); + container.addView(layout, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, buttonHeight, 15, a == 0 ? 15 : 10, 15, a == buttons.rows.size() - 1 ? 15 : 0)); + + float weight = 1.0f / row.buttons.size(); + for (int b = 0; b < row.buttons.size(); b++) { + TLRPC.TL_keyboardButton button = row.buttons.get(b); + TextView textView = new TextView(getContext()); + textView.setTextColor(0xff36474f); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); + textView.setGravity(Gravity.CENTER); + textView.setBackgroundResource(R.drawable.bot_keyboard_states); + textView.setPadding(AndroidUtilities.dp(4), 0, AndroidUtilities.dp(4), 0); + textView.setText(Emoji.replaceEmoji(button.text, textView.getPaint().getFontMetricsInt(), AndroidUtilities.dp(16))); + layout.addView(textView, LayoutHelper.createLinear(0, LayoutHelper.MATCH_PARENT, weight, 0, 0, b != row.buttons.size() - 1 ? 10 : 0, 0)); + textView.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + delegate.didPressedButton(((TextView) v).getText()); + } + }); + buttonViews.add(textView); + } + } + } + } + + public int getKeyboardHeight() { + return isFullSize ? panelHeight : botButtons.rows.size() * AndroidUtilities.dp(buttonHeight) + AndroidUtilities.dp(30) + (botButtons.rows.size() - 1) * AndroidUtilities.dp(10); + } +} 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 4d6580a2e..6fc40e4a8 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java @@ -22,8 +22,6 @@ import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import android.view.ViewTreeObserver; -import android.view.WindowManager; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.inputmethod.EditorInfo; import android.widget.EditText; @@ -53,7 +51,9 @@ import org.telegram.android.AnimationCompat.ObjectAnimatorProxy; import org.telegram.android.AnimationCompat.ViewProxy; import org.telegram.messenger.ApplicationLoader; -public class ChatActivityEnterView extends FrameLayoutFixed implements NotificationCenter.NotificationCenterDelegate, SizeNotifierRelativeLayout.SizeNotifierRelativeLayoutDelegate { +import java.util.Locale; + +public class ChatActivityEnterView extends FrameLayoutFixed implements NotificationCenter.NotificationCenterDelegate, SizeNotifierFrameLayout.SizeNotifierFrameLayoutDelegate { public interface ChatActivityEnterViewDelegate { void onMessageSend(String message); @@ -66,23 +66,29 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat private EditText messageEditText; private ImageView sendButton; - private PopupWindow emojiPopup; private ImageView emojiButton; private EmojiView emojiView; private TextView recordTimeText; private ImageView audioSendButton; private FrameLayout recordPanel; private LinearLayout slideText; - private View sizeNotifierLayout; - private FrameLayout attachButton; + private SizeNotifierFrameLayout sizeNotifierLayout; + private LinearLayout attachButton; + private ImageView botButton; private LinearLayout textFieldContainer; private View topView; + private PopupWindow botKeyboardPopup; + private BotKeyboardView botKeyboardView; - private int framesDroped; + private int currentPopupContentType = -1; - private int keyboardTransitionState; - private boolean showKeyboardOnEmojiButton; - private ViewTreeObserver.OnPreDrawListener onPreDrawListener; + private boolean isPaused; + private boolean showKeyboardOnResume; + + private MessageObject botButtonsMessageObject; + private TLRPC.TL_replyKeyboardMarkup botReplyMarkup; + private int botCount; + private boolean hasBotCommands; private PowerManager.WakeLock mWakeLock; private AnimatorSetProxy runningAnimation; @@ -94,6 +100,7 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat private int keyboardHeight; private int keyboardHeightLand; private boolean keyboardVisible; + private int emojiPadding; private boolean sendByEnter; private long lastTypingTimeSend; private String lastTimeString; @@ -103,11 +110,15 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat private boolean forceShowSendButton; private boolean allowStickers; + private int lastSizeChangeValue1; + private boolean lastSizeChangeValue2; + private Activity parentActivity; private BaseFragment parentFragment; private long dialog_id; private boolean ignoreTextChange; private MessageObject replyingMessageObject; + private MessageObject botMessageObject; private TLRPC.WebPage messageWebPage; private boolean messageWebPageSearch = true; private ChatActivityEnterViewDelegate delegate; @@ -118,7 +129,20 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat private boolean allowShowTopView; private AnimatorSetProxy currentTopViewAnimation; - public ChatActivityEnterView(Activity context, View parent, BaseFragment fragment, boolean isChat) { + private boolean waitingForKeyboardOpen; + private Runnable openKeyboardRunnable = new Runnable() { + @Override + public void run() { + if (messageEditText != null && waitingForKeyboardOpen && !keyboardVisible && !AndroidUtilities.usingHardwareInput) { + messageEditText.requestFocus(); + AndroidUtilities.showKeyboard(messageEditText); + AndroidUtilities.cancelRunOnUIThread(openKeyboardRunnable); + AndroidUtilities.runOnUIThread(openKeyboardRunnable, 100); + } + } + }; + + public ChatActivityEnterView(Activity context, SizeNotifierFrameLayout parent, BaseFragment fragment, boolean isChat) { super(context); setBackgroundResource(R.drawable.compose_panel); setFocusable(true); @@ -131,85 +155,34 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat NotificationCenter.getInstance().addObserver(this, NotificationCenter.closeChats); NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioDidSent); NotificationCenter.getInstance().addObserver(this, NotificationCenter.emojiDidLoaded); - NotificationCenter.getInstance().addObserver(this, NotificationCenter.hideEmojiKeyboard); NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioRouteChanged); parentActivity = context; parentFragment = fragment; sizeNotifierLayout = parent; - if (sizeNotifierLayout instanceof SizeNotifierRelativeLayout) { - ((SizeNotifierRelativeLayout) sizeNotifierLayout).setDelegate(this); - } else if (sizeNotifierLayout instanceof SizeNotifierFrameLayout) { - ((SizeNotifierFrameLayout) sizeNotifierLayout).setDelegate(this); - } + sizeNotifierLayout.setDelegate(this); SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); sendByEnter = preferences.getBoolean("send_by_enter", false); - parent.getViewTreeObserver().addOnPreDrawListener(onPreDrawListener = new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { - if (keyboardTransitionState == 1) { - if (keyboardVisible || framesDroped >= 60) { - showEmojiPopup(false, false); - keyboardTransitionState = 0; - } else { - openKeyboard(); - } - framesDroped++; - return false; - } else if (keyboardTransitionState == 2) { - if (!keyboardVisible || framesDroped >= 60) { - int currentHeight = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y ? keyboardHeightLand : keyboardHeight; - sizeNotifierLayout.setPadding(0, 0, 0, currentHeight); - keyboardTransitionState = 0; - } - framesDroped++; - return false; - } - return true; - } - }); - textFieldContainer = new LinearLayout(context); textFieldContainer.setBackgroundColor(0xffffffff); textFieldContainer.setOrientation(LinearLayout.HORIZONTAL); - addView(textFieldContainer); - LayoutParams layoutParams2 = (LayoutParams) textFieldContainer.getLayoutParams(); - layoutParams2.gravity = Gravity.LEFT | Gravity.TOP; - layoutParams2.width = LayoutHelper.MATCH_PARENT; - layoutParams2.height = LayoutHelper.WRAP_CONTENT; - layoutParams2.topMargin = AndroidUtilities.dp(2); - textFieldContainer.setLayoutParams(layoutParams2); + addView(textFieldContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 0, 2, 0, 0)); FrameLayoutFixed frameLayout = new FrameLayoutFixed(context); - textFieldContainer.addView(frameLayout); - LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) frameLayout.getLayoutParams(); - layoutParams.width = 0; - layoutParams.height = LayoutHelper.WRAP_CONTENT; - layoutParams.weight = 1; - frameLayout.setLayoutParams(layoutParams); + textFieldContainer.addView(frameLayout, LayoutHelper.createLinear(0, LayoutHelper.WRAP_CONTENT, 1.0f)); emojiButton = new ImageView(context); emojiButton.setImageResource(R.drawable.ic_msg_panel_smiles); emojiButton.setScaleType(ImageView.ScaleType.CENTER_INSIDE); emojiButton.setPadding(AndroidUtilities.dp(4), AndroidUtilities.dp(1), 0, 0); - frameLayout.addView(emojiButton); - FrameLayout.LayoutParams layoutParams1 = (FrameLayout.LayoutParams) emojiButton.getLayoutParams(); - layoutParams1.width = AndroidUtilities.dp(48); - layoutParams1.height = AndroidUtilities.dp(48); - layoutParams1.gravity = Gravity.BOTTOM; - emojiButton.setLayoutParams(layoutParams1); + frameLayout.addView(emojiButton, LayoutHelper.createFrame(48, 48, Gravity.BOTTOM)); emojiButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - if (showKeyboardOnEmojiButton) { - setKeyboardTransitionState(1); - int selection = messageEditText.getSelectionStart(); - MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0); - messageEditText.onTouchEvent(event); - event.recycle(); - messageEditText.setSelection(selection); + if (!isPopupShowing() || currentPopupContentType != 0) { + showPopup(1, 0); } else { - showEmojiPopup(emojiPopup == null || !emojiPopup.isShowing(), true); + openKeyboardInternal(); } } }); @@ -227,20 +200,13 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat AndroidUtilities.clearCursorDrawable(messageEditText); messageEditText.setTextColor(0xff000000); messageEditText.setHintTextColor(0xffb2b2b2); - frameLayout.addView(messageEditText); - layoutParams1 = (FrameLayout.LayoutParams) messageEditText.getLayoutParams(); - layoutParams1.width = LayoutHelper.MATCH_PARENT; - layoutParams1.height = LayoutHelper.WRAP_CONTENT; - layoutParams1.gravity = Gravity.BOTTOM; - layoutParams1.leftMargin = AndroidUtilities.dp(52); - layoutParams1.rightMargin = AndroidUtilities.dp(isChat ? 50 : 2); - messageEditText.setLayoutParams(layoutParams1); + frameLayout.addView(messageEditText, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM, 52, 0, isChat ? 50 : 2, 0)); messageEditText.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View view, int i, KeyEvent keyEvent) { - if (i == 4 && !keyboardVisible && emojiPopup != null && emojiPopup.isShowing()) { + if (i == KeyEvent.KEYCODE_BACK && !keyboardVisible && isPopupShowing()) { if (keyEvent.getAction() == 1) { - showEmojiPopup(false, true); + showPopup(0, 0); } return true; } else if (i == KeyEvent.KEYCODE_ENTER && sendByEnter && keyEvent.getAction() == KeyEvent.ACTION_DOWN) { @@ -253,8 +219,8 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat messageEditText.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - if (emojiPopup != null && emojiPopup.isShowing()) { - setKeyboardTransitionState(1); + if (isPopupShowing()) { + showPopup(AndroidUtilities.usingHardwareInput ? 0 : 2, 0); } } }); @@ -327,99 +293,71 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat }); if (isChat) { - attachButton = new FrameLayout(context); + attachButton = new LinearLayout(context); + attachButton.setOrientation(LinearLayout.HORIZONTAL); attachButton.setEnabled(false); ViewProxy.setPivotX(attachButton, AndroidUtilities.dp(48)); - frameLayout.addView(attachButton); - layoutParams1 = (FrameLayout.LayoutParams) attachButton.getLayoutParams(); - layoutParams1.width = AndroidUtilities.dp(48); - layoutParams1.height = AndroidUtilities.dp(48); - layoutParams1.gravity = Gravity.BOTTOM | Gravity.RIGHT; - attachButton.setLayoutParams(layoutParams1); + frameLayout.addView(attachButton, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, 48, Gravity.BOTTOM | Gravity.RIGHT)); + + botButton = new ImageView(context); + botButton.setImageResource(R.drawable.bot_keyboard2); + botButton.setScaleType(ImageView.ScaleType.CENTER); + botButton.setVisibility(GONE); + attachButton.addView(botButton, LayoutHelper.createLinear(48, 48)); + botButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (botReplyMarkup != null) { + if (!isPopupShowing() || currentPopupContentType != 1) { + showPopup(1, 1); + } else { + openKeyboardInternal(); + } + } else if (hasBotCommands) { + setFieldText("/"); + openKeyboard(); + } + } + }); } recordPanel = new FrameLayoutFixed(context); recordPanel.setVisibility(GONE); recordPanel.setBackgroundColor(0xffffffff); - frameLayout.addView(recordPanel); - layoutParams1 = (FrameLayout.LayoutParams) recordPanel.getLayoutParams(); - layoutParams1.width = LayoutHelper.MATCH_PARENT; - layoutParams1.height = AndroidUtilities.dp(48); - layoutParams1.gravity = Gravity.BOTTOM; - recordPanel.setLayoutParams(layoutParams1); + frameLayout.addView(recordPanel, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.BOTTOM)); slideText = new LinearLayout(context); slideText.setOrientation(LinearLayout.HORIZONTAL); - recordPanel.addView(slideText); - layoutParams1 = (FrameLayout.LayoutParams) slideText.getLayoutParams(); - layoutParams1.width = LayoutHelper.WRAP_CONTENT; - layoutParams1.height = LayoutHelper.WRAP_CONTENT; - layoutParams1.gravity = Gravity.CENTER; - layoutParams1.leftMargin = AndroidUtilities.dp(30); - slideText.setLayoutParams(layoutParams1); + recordPanel.addView(slideText, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER, 30, 0, 0, 0)); ImageView imageView = new ImageView(context); imageView.setImageResource(R.drawable.slidearrow); - slideText.addView(imageView); - layoutParams = (LinearLayout.LayoutParams) imageView.getLayoutParams(); - layoutParams.width = LayoutHelper.WRAP_CONTENT; - layoutParams.height = LayoutHelper.WRAP_CONTENT; - layoutParams.gravity = Gravity.CENTER_VERTICAL; - layoutParams.topMargin = AndroidUtilities.dp(1); - imageView.setLayoutParams(layoutParams); + slideText.addView(imageView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL, 0, 1, 0, 0)); TextView textView = new TextView(context); textView.setText(LocaleController.getString("SlideToCancel", R.string.SlideToCancel)); textView.setTextColor(0xff999999); textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12); - slideText.addView(textView); - layoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams(); - layoutParams.width = LayoutHelper.WRAP_CONTENT; - layoutParams.height = LayoutHelper.WRAP_CONTENT; - layoutParams.gravity = Gravity.CENTER_VERTICAL; - layoutParams.leftMargin = AndroidUtilities.dp(6); - textView.setLayoutParams(layoutParams); + slideText.addView(textView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL, 6, 0, 0, 0)); LinearLayout linearLayout = new LinearLayout(context); linearLayout.setOrientation(LinearLayout.HORIZONTAL); linearLayout.setPadding(AndroidUtilities.dp(13), 0, 0, 0); linearLayout.setBackgroundColor(0xffffffff); - recordPanel.addView(linearLayout); - layoutParams1 = (FrameLayout.LayoutParams) linearLayout.getLayoutParams(); - layoutParams1.width = LayoutHelper.WRAP_CONTENT; - layoutParams1.height = LayoutHelper.WRAP_CONTENT; - layoutParams1.gravity = Gravity.CENTER_VERTICAL; - linearLayout.setLayoutParams(layoutParams1); + recordPanel.addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL)); imageView = new ImageView(context); imageView.setImageResource(R.drawable.rec); - linearLayout.addView(imageView); - layoutParams = (LinearLayout.LayoutParams) imageView.getLayoutParams(); - layoutParams.width = LayoutHelper.WRAP_CONTENT; - layoutParams.height = LayoutHelper.WRAP_CONTENT; - layoutParams.gravity = Gravity.CENTER_VERTICAL; - layoutParams.topMargin = AndroidUtilities.dp(1); - imageView.setLayoutParams(layoutParams); + linearLayout.addView(imageView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL, 0, 1, 0, 0)); recordTimeText = new TextView(context); recordTimeText.setText("00:00"); recordTimeText.setTextColor(0xff4d4c4b); recordTimeText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); - linearLayout.addView(recordTimeText); - layoutParams = (LinearLayout.LayoutParams) recordTimeText.getLayoutParams(); - layoutParams.width = LayoutHelper.WRAP_CONTENT; - layoutParams.height = LayoutHelper.WRAP_CONTENT; - layoutParams.gravity = Gravity.CENTER_VERTICAL; - layoutParams.leftMargin = AndroidUtilities.dp(6); - recordTimeText.setLayoutParams(layoutParams); + linearLayout.addView(recordTimeText, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL, 6, 0, 0, 0)); FrameLayout frameLayout1 = new FrameLayout(context); - textFieldContainer.addView(frameLayout1); - layoutParams = (LinearLayout.LayoutParams) frameLayout1.getLayoutParams(); - layoutParams.width = AndroidUtilities.dp(48); - layoutParams.height = AndroidUtilities.dp(48); - layoutParams.gravity = Gravity.BOTTOM; - frameLayout1.setLayoutParams(layoutParams); + textFieldContainer.addView(frameLayout1, LayoutHelper.createLinear(48, 48, Gravity.BOTTOM)); audioSendButton = new ImageView(context); audioSendButton.setScaleType(ImageView.ScaleType.CENTER_INSIDE); @@ -427,11 +365,7 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat audioSendButton.setBackgroundColor(0xffffffff); audioSendButton.setSoundEffectsEnabled(false); audioSendButton.setPadding(0, 0, AndroidUtilities.dp(4), 0); - frameLayout1.addView(audioSendButton); - layoutParams1 = (FrameLayout.LayoutParams) audioSendButton.getLayoutParams(); - layoutParams1.width = AndroidUtilities.dp(48); - layoutParams1.height = AndroidUtilities.dp(48); - audioSendButton.setLayoutParams(layoutParams1); + frameLayout1.addView(audioSendButton, LayoutHelper.createFrame(48, 48)); audioSendButton.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { @@ -516,11 +450,7 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat 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); + frameLayout1.addView(sendButton, LayoutHelper.createFrame(48, 48)); sendButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { @@ -528,43 +458,21 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat } }); + SharedPreferences sharedPreferences = ApplicationLoader.applicationContext.getSharedPreferences("emoji", Context.MODE_PRIVATE); + keyboardHeight = sharedPreferences.getInt("kbd_height", AndroidUtilities.dp(200)); + keyboardHeightLand = sharedPreferences.getInt("kbd_height_land3", AndroidUtilities.dp(200)); + checkSendButton(false); } - private void setKeyboardTransitionState(int state) { - if (AndroidUtilities.usingHardwareInput) { - if (state == 1) { - showEmojiPopup(false, false); - keyboardTransitionState = 0; - - } else if (state == 2) { - int currentHeight = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y ? keyboardHeightLand : keyboardHeight; - sizeNotifierLayout.setPadding(0, 0, 0, currentHeight); - keyboardTransitionState = 0; - } - } else { - framesDroped = 0; - keyboardTransitionState = state; - if (state == 1) { - sizeNotifierLayout.setPadding(0, 0, 0, 0); - } - } - } - public void addTopView(View view, int height) { if (view == null) { return; } - addView(view, 0); topView = view; topView.setVisibility(GONE); + addView(topView, 0, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, height, Gravity.TOP | Gravity.LEFT, 0, 2, 0, 0)); needShowTopView = false; - LayoutParams layoutParams = (LayoutParams) topView.getLayoutParams(); - layoutParams.width = LayoutHelper.MATCH_PARENT; - layoutParams.height = height; - layoutParams.topMargin = AndroidUtilities.dp(2); - layoutParams.gravity = Gravity.TOP | Gravity.LEFT; - topView.setLayoutParams(layoutParams); } public void setTopViewAnimation(float progress) { @@ -600,7 +508,7 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat currentTopViewAnimation = null; } if (animated) { - if (keyboardVisible || emojiPopup != null && emojiPopup.isShowing()) { + if (keyboardVisible || isPopupShowing()) { currentTopViewAnimation = new AnimatorSetProxy(); currentTopViewAnimation.playTogether( ObjectAnimatorProxy.ofFloat(ChatActivityEnterView.this, "topViewAnimation", 1.0f) @@ -673,7 +581,11 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat return topView != null && topView.getVisibility() == VISIBLE; } - private void onWindowSizeChanged(int size) { + private void onWindowSizeChanged() { + int size = sizeNotifierLayout.getHeight(); + if (!keyboardVisible) { + size -= emojiPadding; + } if (delegate != null) { delegate.onWindowSizeChanged(size); } @@ -706,9 +618,7 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat 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); - sizeNotifierLayout.getViewTreeObserver().removeOnPreDrawListener(onPreDrawListener); if (mWakeLock != null) { try { mWakeLock.release(); @@ -718,10 +628,24 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat } } if (sizeNotifierLayout != null) { - if (sizeNotifierLayout instanceof SizeNotifierRelativeLayout) { - ((SizeNotifierRelativeLayout) sizeNotifierLayout).setDelegate(null); - } else if (sizeNotifierLayout instanceof SizeNotifierFrameLayout) { - ((SizeNotifierFrameLayout) sizeNotifierLayout).setDelegate(null); + sizeNotifierLayout.setDelegate(null); + } + } + + public void onPause() { + isPaused = true; + } + + public void onResume() { + isPaused = false; + if (showKeyboardOnResume) { + showKeyboardOnResume = false; + messageEditText.requestFocus(); + AndroidUtilities.showKeyboard(messageEditText); + if (!AndroidUtilities.usingHardwareInput && !keyboardVisible) { + waitingForKeyboardOpen = true; + AndroidUtilities.cancelRunOnUIThread(openKeyboardRunnable); + AndroidUtilities.runOnUIThread(openKeyboardRunnable, 100); } } } @@ -731,7 +655,19 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat } public void setReplyingMessageObject(MessageObject messageObject) { - replyingMessageObject = messageObject; + if (messageObject != null) { + if (botMessageObject == null && botButtonsMessageObject != replyingMessageObject) { + botMessageObject = botButtonsMessageObject; + } + replyingMessageObject = messageObject; + setButtons(replyingMessageObject, true); + } else if (messageObject == null && replyingMessageObject == botButtonsMessageObject) { + replyingMessageObject = null; + setButtons(botMessageObject, false); + botMessageObject = null; + } else { + replyingMessageObject = messageObject; + } } public void setWebPage(TLRPC.WebPage webPage, boolean searchWebPages) { @@ -1051,122 +987,28 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat } } - private void showEmojiPopup(boolean show, boolean post) { - if (show) { - if (emojiPopup == null) { - if (parentActivity == null) { - return; - } - emojiView = new EmojiView(allowStickers, parentActivity); - emojiView.setListener(new EmojiView.Listener() { - public boolean onBackspace() { - if (messageEditText.length() == 0) { - return false; - } - messageEditText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL)); - return true; - } - - public void onEmojiSelected(String symbol) { - int i = messageEditText.getSelectionEnd(); - if (i < 0) { - i = 0; - } - try {//TODO check - CharSequence localCharSequence = Emoji.replaceEmoji(symbol/* + "\uFE0F"*/, messageEditText.getPaint().getFontMetricsInt(), AndroidUtilities.dp(20)); - messageEditText.setText(messageEditText.getText().insert(i, localCharSequence)); - int j = i + localCharSequence.length(); - messageEditText.setSelection(j, j); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } - - public void onStickerSelected(TLRPC.Document sticker) { - SendMessagesHelper.getInstance().sendSticker(sticker, dialog_id, replyingMessageObject); - if (delegate != null) { - delegate.onMessageSend(null); - } - } - }); - emojiPopup = new PopupWindow(emojiView); - } - - if (keyboardHeight <= 0) { - keyboardHeight = ApplicationLoader.applicationContext.getSharedPreferences("emoji", 0).getInt("kbd_height", AndroidUtilities.dp(200)); - } - if (keyboardHeightLand <= 0) { - keyboardHeightLand = ApplicationLoader.applicationContext.getSharedPreferences("emoji", 0).getInt("kbd_height_land3", AndroidUtilities.dp(200)); - } - int currentHeight = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y ? keyboardHeightLand : keyboardHeight; - FileLog.e("tmessages", "show emoji with height = " + currentHeight); - emojiPopup.setHeight(View.MeasureSpec.makeMeasureSpec(currentHeight, View.MeasureSpec.EXACTLY)); - if (sizeNotifierLayout != null) { - emojiPopup.setWidth(View.MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.x, View.MeasureSpec.EXACTLY)); - } - - emojiPopup.showAtLocation(parentActivity.getWindow().getDecorView(), Gravity.BOTTOM | Gravity.LEFT, 0, 0); - - if (!keyboardVisible) { - if (sizeNotifierLayout != null) { - sizeNotifierLayout.setPadding(0, 0, 0, currentHeight); - emojiButton.setImageResource(R.drawable.ic_msg_panel_hide); - showKeyboardOnEmojiButton = false; - onWindowSizeChanged(sizeNotifierLayout.getHeight() - sizeNotifierLayout.getPaddingBottom()); - } - return; - } else { - setKeyboardTransitionState(2); - AndroidUtilities.hideKeyboard(messageEditText); - } - emojiButton.setImageResource(R.drawable.ic_msg_panel_kb); - showKeyboardOnEmojiButton = true; - return; - } - if (emojiButton != null) { - showKeyboardOnEmojiButton = false; - emojiButton.setImageResource(R.drawable.ic_msg_panel_smiles); - } - if (emojiPopup != null) { - try { - emojiPopup.dismiss(); - } catch (Exception e) { - //don't promt - } - } - if (keyboardTransitionState == 0) { - if (sizeNotifierLayout != null) { - if (post) { - sizeNotifierLayout.post(new Runnable() { - public void run() { - if (sizeNotifierLayout != null) { - sizeNotifierLayout.setPadding(0, 0, 0, 0); - onWindowSizeChanged(sizeNotifierLayout.getHeight()); - } - } - }); - } else { - sizeNotifierLayout.setPadding(0, 0, 0, 0); - onWindowSizeChanged(sizeNotifierLayout.getHeight()); - } - } - } - } - - public void hideEmojiPopup() { - if (emojiPopup != null && emojiPopup.isShowing()) { - showEmojiPopup(false, true); - } - } - - public void openKeyboard() { - AndroidUtilities.showKeyboard(messageEditText); - } - public void setDelegate(ChatActivityEnterViewDelegate delegate) { this.delegate = delegate; } + public void setCommand(MessageObject messageObject, String command) { + if (command == null) { + return; + } + TLRPC.User user = messageObject != null && (int) dialog_id < 0 ? MessagesController.getInstance().getUser(messageObject.messageOwner.from_id) : null; + if (botCount != 1 && user != null && (user.flags & TLRPC.USER_FLAG_BOT) != 0 && !command.contains("@")) { + SendMessagesHelper.getInstance().sendMessage(String.format(Locale.US, "%s@%s", command, user.username), dialog_id, null, null, false); + } else { + SendMessagesHelper.getInstance().sendMessage(command, dialog_id, null, null, false); + } + /*String text = messageEditText.getText().toString(); + text = command + " " + text.replaceFirst("^/[a-zA-Z@\\d_]{1,255}(\\s|$)", ""); + ignoreTextChange = true; + messageEditText.setText(text); + messageEditText.setSelection(messageEditText.getText().length()); + ignoreTextChange = false;*/ + } + public void setFieldText(String text) { if (messageEditText == null) { return; @@ -1235,10 +1077,6 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat return null; } - public boolean isEmojiPopupShowing() { - return emojiPopup != null && emojiPopup.isShowing(); - } - public void addToAttachLayout(View view) { if (attachButton == null) { return; @@ -1247,12 +1085,241 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat ViewGroup viewGroup = (ViewGroup) view.getParent(); viewGroup.removeView(view); } - attachButton.addView(view); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) view.getLayoutParams(); - layoutParams.gravity = Gravity.CENTER; - layoutParams.width = AndroidUtilities.dp(48); - layoutParams.height = LayoutHelper.MATCH_PARENT; - view.setLayoutParams(layoutParams); + attachButton.addView(view, LayoutHelper.createLinear(48, 48)); + } + + private void updateBotButton() { + if (botButton == null) { + return; + } + if (hasBotCommands || botReplyMarkup != null) { + if (botButton.getVisibility() != VISIBLE) { + botButton.setVisibility(VISIBLE); + } + if (botReplyMarkup != null) { + if (isPopupShowing() && currentPopupContentType == 1) { + botButton.setImageResource(R.drawable.ic_msg_panel_kb); + } else { + botButton.setImageResource(R.drawable.bot_keyboard2); + } + } else { + botButton.setImageResource(R.drawable.bot_keyboard); + } + } else { + botButton.setVisibility(GONE); + } + ViewProxy.setPivotX(attachButton, AndroidUtilities.dp(botButton.getVisibility() == GONE ? 48 : 96)); + attachButton.clearAnimation(); + } + + public void setBotsCount(int count, boolean hasCommands) { + botCount = count; + if (hasBotCommands != hasCommands) { + hasBotCommands = hasCommands; + updateBotButton(); + } + } + + public void setButtons(MessageObject messageObject) { + setButtons(messageObject, true); + } + + public void setButtons(MessageObject messageObject, boolean openKeyboard) { + if (replyingMessageObject != null && replyingMessageObject == botButtonsMessageObject && replyingMessageObject != messageObject) { + botMessageObject = messageObject; + return; + } + if (botButton == null || botButtonsMessageObject != null && botButtonsMessageObject == messageObject || botButtonsMessageObject == null && messageObject == null) { + return; + } + if (botKeyboardView == null) { + botKeyboardView = new BotKeyboardView(parentActivity); + botKeyboardView.setVisibility(GONE); + botKeyboardView.setDelegate(new BotKeyboardView.BotKeyboardViewDelegate() { + @Override + public void didPressedButton(CharSequence text) { + MessageObject object = replyingMessageObject != null ? replyingMessageObject : ((int) dialog_id < 0 ? botButtonsMessageObject : null); + SendMessagesHelper.getInstance().sendMessage(text.toString(), dialog_id, object, null, false); + if (replyingMessageObject != null) { + openKeyboardInternal(); + setButtons(botMessageObject, false); + } else if ((botButtonsMessageObject.messageOwner.reply_markup.flags & 2) != 0) { + openKeyboardInternal(); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + preferences.edit().putInt("answered_" + dialog_id, botButtonsMessageObject.getId()).commit(); + } + if (delegate != null) { + delegate.onMessageSend(null); + } + } + }); + sizeNotifierLayout.addView(botKeyboardView); + } + botButtonsMessageObject = messageObject; + botReplyMarkup = messageObject != null && messageObject.messageOwner.reply_markup instanceof TLRPC.TL_replyKeyboardMarkup ? (TLRPC.TL_replyKeyboardMarkup) messageObject.messageOwner.reply_markup : null; + + botKeyboardView.setPanelHeight(AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y ? keyboardHeightLand : keyboardHeight); + botKeyboardView.setButtons(botReplyMarkup != null ? botReplyMarkup : null); + if (botReplyMarkup != null) { + if (botButtonsMessageObject != replyingMessageObject && (botReplyMarkup.flags & 2) != 0) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + if (preferences.getInt("answered_" + dialog_id, 0) == messageObject.getId()) { + return; + } + } + if (messageEditText.length() == 0 && !isPopupShowing()) { + showPopup(1, 1); + } + } else { + if (isPopupShowing() && currentPopupContentType == 1) { + if (openKeyboard) { + openKeyboardInternal(); + } else { + showPopup(0, 1); + } + } + } + updateBotButton(); + } + + public boolean isPopupView(View view) { + return view == botKeyboardView || view == emojiView; + } + + private void showPopup(int show, int contentType) { + if (show == 1) { + if (contentType == 0 && emojiView == null) { + if (parentActivity == null) { + return; + } + emojiView = new EmojiView(allowStickers, parentActivity); + emojiView.setVisibility(GONE); + emojiView.setListener(new EmojiView.Listener() { + public boolean onBackspace() { + if (messageEditText.length() == 0) { + return false; + } + messageEditText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL)); + return true; + } + + public void onEmojiSelected(String symbol) { + int i = messageEditText.getSelectionEnd(); + if (i < 0) { + i = 0; + } + try { + CharSequence localCharSequence = Emoji.replaceEmoji(symbol/* + "\uFE0F"*/, messageEditText.getPaint().getFontMetricsInt(), AndroidUtilities.dp(20)); + messageEditText.setText(messageEditText.getText().insert(i, localCharSequence)); + int j = i + localCharSequence.length(); + messageEditText.setSelection(j, j); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + + public void onStickerSelected(TLRPC.Document sticker) { + SendMessagesHelper.getInstance().sendSticker(sticker, dialog_id, replyingMessageObject); + if (delegate != null) { + delegate.onMessageSend(null); + } + } + }); + sizeNotifierLayout.addView(emojiView); + } + + View currentView = null; + if (contentType == 0) { + emojiView.setVisibility(VISIBLE); + if (botKeyboardView != null && botKeyboardView.getVisibility() != GONE) { + botKeyboardView.setVisibility(GONE); + } + currentView = emojiView; + } else if (contentType == 1) { + if (emojiView != null && emojiView.getVisibility() != GONE) { + emojiView.setVisibility(GONE); + } + botKeyboardView.setVisibility(VISIBLE); + currentView = botKeyboardView; + } + currentPopupContentType = contentType; + + if (keyboardHeight <= 0) { + keyboardHeight = ApplicationLoader.applicationContext.getSharedPreferences("emoji", Context.MODE_PRIVATE).getInt("kbd_height", AndroidUtilities.dp(200)); + } + if (keyboardHeightLand <= 0) { + keyboardHeightLand = ApplicationLoader.applicationContext.getSharedPreferences("emoji", Context.MODE_PRIVATE).getInt("kbd_height_land3", AndroidUtilities.dp(200)); + } + int currentHeight = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y ? keyboardHeightLand : keyboardHeight; + if (contentType == 1) { + currentHeight = Math.min(botKeyboardView.getKeyboardHeight(), currentHeight); + } + if (botKeyboardView != null) { + botKeyboardView.setPanelHeight(currentHeight); + } + + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) currentView.getLayoutParams(); + layoutParams.width = AndroidUtilities.displaySize.x; + layoutParams.height = currentHeight; + currentView.setLayoutParams(layoutParams); + AndroidUtilities.hideKeyboard(messageEditText); + if (sizeNotifierLayout != null) { + emojiPadding = currentHeight; + sizeNotifierLayout.requestLayout(); + if (contentType == 0) { + emojiButton.setImageResource(R.drawable.ic_msg_panel_kb); + } else if (contentType == 1) { + emojiButton.setImageResource(R.drawable.ic_msg_panel_smiles); + } + updateBotButton(); + onWindowSizeChanged(); + } + } else { + if (emojiButton != null) { + emojiButton.setImageResource(R.drawable.ic_msg_panel_smiles); + } + if (emojiView != null) { + emojiView.setVisibility(GONE); + } + if (botKeyboardView != null) { + botKeyboardView.setVisibility(GONE); + } + if (sizeNotifierLayout != null) { + if (show == 0) { + emojiPadding = 0; + } + sizeNotifierLayout.requestLayout(); + onWindowSizeChanged(); + } + updateBotButton(); + } + } + + public void hidePopup() { + if (isPopupShowing()) { + showPopup(0, 0); + } + } + + private void openKeyboardInternal() { + showPopup(AndroidUtilities.usingHardwareInput || isPaused ? 0 : 2, 0); + messageEditText.requestFocus(); + AndroidUtilities.showKeyboard(messageEditText); + if (isPaused) { + showKeyboardOnResume = true; + } else if (!AndroidUtilities.usingHardwareInput && !keyboardVisible) { + waitingForKeyboardOpen = true; + AndroidUtilities.cancelRunOnUIThread(openKeyboardRunnable); + AndroidUtilities.runOnUIThread(openKeyboardRunnable, 100); + } + } + + public void openKeyboard() { + AndroidUtilities.showKeyboard(messageEditText); + } + + public boolean isPopupShowing() { + return emojiView != null && emojiView.getVisibility() == VISIBLE || botKeyboardView != null && botKeyboardView.getVisibility() == VISIBLE; } @Override @@ -1267,37 +1334,60 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat } } - if (emojiPopup != null && emojiPopup.isShowing()) { + if (isPopupShowing()) { int newHeight = isWidthGreater ? keyboardHeightLand : keyboardHeight; - final WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) emojiPopup.getContentView().getLayoutParams(); - FileLog.e("tmessages", "update emoji height to = " + newHeight); + if (currentPopupContentType == 1 && !botKeyboardView.isFullSize()) { + newHeight = Math.min(botKeyboardView.getKeyboardHeight(), newHeight); + } + + View currentView = null; + if (currentPopupContentType == 0) { + currentView = emojiView; + } else if (currentPopupContentType == 1) { + currentView = botKeyboardView; + } + if (botKeyboardView != null) { + botKeyboardView.setPanelHeight(newHeight); + } + + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) currentView.getLayoutParams(); if (layoutParams.width != AndroidUtilities.displaySize.x || layoutParams.height != newHeight) { layoutParams.width = AndroidUtilities.displaySize.x; layoutParams.height = newHeight; - WindowManager wm = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); - if (wm != null) { - wm.updateViewLayout(emojiPopup.getContentView(), layoutParams); - if (!keyboardVisible) { - if (sizeNotifierLayout != null) { - sizeNotifierLayout.setPadding(0, 0, 0, layoutParams.height); - sizeNotifierLayout.requestLayout(); - onWindowSizeChanged(sizeNotifierLayout.getHeight() - sizeNotifierLayout.getPaddingBottom()); - } - } + currentView.setLayoutParams(layoutParams); + if (sizeNotifierLayout != null) { + emojiPadding = layoutParams.height; + sizeNotifierLayout.requestLayout(); + onWindowSizeChanged(); } } } + if (lastSizeChangeValue1 == height && lastSizeChangeValue2 == isWidthGreater) { + onWindowSizeChanged(); + return; + } + lastSizeChangeValue1 = height; + lastSizeChangeValue2 = isWidthGreater; + boolean oldValue = keyboardVisible; keyboardVisible = height > 0; - if (keyboardVisible && (sizeNotifierLayout.getPaddingBottom() > 0 || keyboardTransitionState == 1)) { - setKeyboardTransitionState(1); - } else if (keyboardTransitionState != 2 && !keyboardVisible && keyboardVisible != oldValue && emojiPopup != null && emojiPopup.isShowing()) { - showEmojiPopup(false, true); + if (keyboardVisible && isPopupShowing()) { + showPopup(0, currentPopupContentType); } - if (keyboardTransitionState == 0) { - onWindowSizeChanged(sizeNotifierLayout.getHeight() - sizeNotifierLayout.getPaddingBottom()); + if (emojiPadding != 0 && !keyboardVisible && keyboardVisible != oldValue && !isPopupShowing()) { + emojiPadding = 0; + sizeNotifierLayout.requestLayout(); } + if (keyboardVisible && waitingForKeyboardOpen) { + waitingForKeyboardOpen = false; + AndroidUtilities.cancelRunOnUIThread(openKeyboardRunnable); + } + onWindowSizeChanged(); + } + + public int getEmojiPadding() { + return emojiPadding; } public int getEmojiHeight() { @@ -1314,6 +1404,9 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat if (emojiView != null) { emojiView.invalidateViews(); } + if (botKeyboardView != null) { + botKeyboardView.invalidateViews(); + } } else if (id == NotificationCenter.recordProgressChanged) { Long time = (Long) args[0] / 1000; String str = String.format("%02d:%02d", time / 60, time % 60); @@ -1344,8 +1437,6 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat if (delegate != null) { delegate.onMessageSend(null); } - } else if (id == NotificationCenter.hideEmojiKeyboard) { - hideEmojiPopup(); } else if (id == NotificationCenter.audioRouteChanged) { if (parentActivity != null) { boolean frontSpeaker = (Boolean) args[0]; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachView.java new file mode 100644 index 000000000..461e32f9b --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachView.java @@ -0,0 +1,227 @@ +/* + * This is the source code of Telegram for Android v. 2.x.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.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.content.Context; +import android.os.Build; +import android.text.TextUtils; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.MotionEvent; +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.android.MediaController; +import org.telegram.android.support.widget.LinearLayoutManager; +import org.telegram.messenger.R; +import org.telegram.ui.Adapters.PhotoAttachAdapter; +import org.telegram.ui.ChatActivity; + +import java.util.HashMap; + +public class ChatAttachView extends FrameLayout { + + public interface ChatAttachViewDelegate { + void didPressedButton(int button); + } + + private LinearLayoutManager attachPhotoLayoutManager; + private PhotoAttachAdapter photoAttachAdapter; + private ChatActivity baseFragment; + private AttachButton sendPhotosButton; + private AttachButton buttons[] = new AttachButton[8]; + + private ChatAttachViewDelegate delegate; + + private static class AttachButton extends FrameLayout { + + private TextView textView; + private ImageView imageView; + + public AttachButton(Context context) { + super(context); + + imageView = new ImageView(context); + imageView.setScaleType(ImageView.ScaleType.CENTER); + //imageView.setColorFilter(0x33000000); + addView(imageView, LayoutHelper.createFrame(64, 64, Gravity.CENTER_HORIZONTAL | Gravity.TOP)); + + textView = new TextView(context); + textView.setLines(1); + textView.setSingleLine(true); + textView.setGravity(Gravity.CENTER_HORIZONTAL); + textView.setEllipsize(TextUtils.TruncateAt.END); + textView.setTextColor(0xff757575); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12); + addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 0, 64, 0, 0)); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(85), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(90), MeasureSpec.EXACTLY)); + } + + public void setTextAndIcon(CharSequence text, int icon) { + textView.setText(text); + imageView.setBackgroundResource(icon); + } + } + + public ChatAttachView(Context context) { + super(context); + + RecyclerListView attachPhotoRecyclerView = new RecyclerListView(context); + if (photoAttachAdapter != null) { + photoAttachAdapter.onDestroy(); + } + attachPhotoRecyclerView.setVerticalScrollBarEnabled(true); + attachPhotoRecyclerView.setAdapter(photoAttachAdapter = new PhotoAttachAdapter(context)); + attachPhotoRecyclerView.setClipToPadding(false); + attachPhotoRecyclerView.setPadding(AndroidUtilities.dp(8), 0, AndroidUtilities.dp(8), 0); + attachPhotoRecyclerView.setItemAnimator(null); + attachPhotoRecyclerView.setLayoutAnimation(null); + if (Build.VERSION.SDK_INT >= 9) { + attachPhotoRecyclerView.setOverScrollMode(RecyclerListView.OVER_SCROLL_NEVER); + } + addView(attachPhotoRecyclerView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 80)); + attachPhotoLayoutManager = new LinearLayoutManager(context) { + @Override + public boolean supportsPredictiveItemAnimations() { + return false; + } + }; + attachPhotoLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); + attachPhotoRecyclerView.setLayoutManager(attachPhotoLayoutManager); + photoAttachAdapter.setDelegate(new PhotoAttachAdapter.PhotoAttachAdapterDelegate() { + @Override + public void selectedPhotosChanged() { + updatePhotosButton(); + } + }); + + View lineView = new View(getContext()); + lineView.setBackgroundColor(0xffd2d2d2); + FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1, Gravity.TOP | Gravity.LEFT); + layoutParams.topMargin = AndroidUtilities.dp(88); + addView(lineView, layoutParams); + CharSequence[] items = new CharSequence[]{ + LocaleController.getString("ChatCamera", R.string.ChatCamera), + LocaleController.getString("ChatGallery", R.string.ChatGallery), + LocaleController.getString("ChatVideo", R.string.ChatVideo), + LocaleController.getString("AttachAudio", R.string.AttachAudio), + LocaleController.getString("ChatDocument", R.string.ChatDocument), + LocaleController.getString("AttachContact", R.string.AttachContact), + LocaleController.getString("ChatLocation", R.string.ChatLocation), + "" + }; + int itemIcons[] = new int[] { + R.drawable.ic_attach_photo_big, + R.drawable.ic_attach_gallery_big, + R.drawable.ic_attach_video_big, + R.drawable.ic_attach_music_big, + R.drawable.ic_attach_file_big, + R.drawable.ic_attach_contact_big, + R.drawable.ic_attach_location_big, + R.drawable.ic_attach_hide_big, + }; + for (int a = 0; a < 8; a++) { + AttachButton attachButton = new AttachButton(context); + attachButton.setTextAndIcon(items[a], itemIcons[a]); + int y = 97 + 95 * (a / 4); + int x = 10 + (a % 4) * 85; + addView(attachButton, LayoutHelper.createFrame(85, 90, Gravity.LEFT | Gravity.TOP, x, y, 0, 0)); + attachButton.setTag(a); + buttons[a] = attachButton; + if (a == 7) { + sendPhotosButton = attachButton; + sendPhotosButton.imageView.setPadding(0, AndroidUtilities.dp(4), 0, 0); + } + attachButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (delegate != null) { + delegate.didPressedButton((Integer) v.getTag()); + } + } + }); + } + setOnTouchListener(new OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + } + + @Override + protected void onMeasure(int widthSpec, int heightSpec) { + super.onMeasure(widthSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(278), MeasureSpec.EXACTLY)); + } + + public void updatePhotosButton() { + int count = photoAttachAdapter.getSelectedPhotos().size(); + if (count == 0) { + sendPhotosButton.imageView.setPadding(0, AndroidUtilities.dp(4), 0, 0); + sendPhotosButton.imageView.setBackgroundResource(R.drawable.ic_attach_hide_big); + sendPhotosButton.imageView.setImageResource(R.drawable.ic_attach_hide_big_icon); + sendPhotosButton.textView.setText(""); + } else { + sendPhotosButton.imageView.setPadding(AndroidUtilities.dp(2), 0, 0, 0); + sendPhotosButton.imageView.setBackgroundResource(R.drawable.ic_attach_send_big); + sendPhotosButton.imageView.setImageResource(R.drawable.ic_attach_send_big_icon); + sendPhotosButton.textView.setText(LocaleController.formatString("SendItems", R.string.SendItems, String.format("(%d)", count))); + } + } + + public void setDelegate(ChatAttachViewDelegate chatAttachViewDelegate) { + delegate = chatAttachViewDelegate; + } + + public void startAnimations(boolean up) { + for (int a = 0; a < 4; a++) { + //buttons[a].setTranslationY(AndroidUtilities.dp(up ? 20 : -20)); + //buttons[a + 4].setTranslationY(AndroidUtilities.dp(up ? 20 : -20)); + buttons[a].setScaleX(0.8f); + buttons[a].setScaleY(0.8f); + buttons[a + 4].setScaleX(0.8f); + buttons[a + 4].setScaleY(0.8f); + AnimatorSet animatorSet = new AnimatorSet(); + animatorSet.playTogether(ObjectAnimator.ofFloat(buttons[a], "scaleX", 1), + ObjectAnimator.ofFloat(buttons[a + 4], "scaleX", 1), + ObjectAnimator.ofFloat(buttons[a], "scaleY", 1), + ObjectAnimator.ofFloat(buttons[a + 4], "scaleY", 1)); + animatorSet.setDuration(150); + animatorSet.setStartDelay((3 - a) * 40); + animatorSet.start(); + } + } + + public void init(ChatActivity parentFragment) { + attachPhotoLayoutManager.scrollToPositionWithOffset(0, 1000000); + photoAttachAdapter.clearSelectedPhotos(); + baseFragment = parentFragment; + updatePhotosButton(); + } + + public HashMap getSelectedPhotos() { + return photoAttachAdapter.getSelectedPhotos(); + } + + public void onDestroy() { + photoAttachAdapter.onDestroy(); + baseFragment = null; + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiView.java index 260b398c1..076a91869 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/EmojiView.java @@ -12,14 +12,17 @@ import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.database.DataSetObserver; +import android.os.Build; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.text.TextUtils; +import android.util.TypedValue; import android.view.Gravity; import android.view.HapticFeedbackConstants; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.widget.AbsListView; import android.widget.BaseAdapter; import android.widget.FrameLayout; import android.widget.GridView; @@ -28,6 +31,7 @@ import android.widget.LinearLayout; import android.widget.TextView; import org.telegram.android.AndroidUtilities; +import org.telegram.android.AnimationCompat.ViewProxy; import org.telegram.android.Emoji; import org.telegram.android.LocaleController; import org.telegram.android.NotificationCenter; @@ -35,6 +39,7 @@ import org.telegram.android.query.StickersQuery; import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; +import org.telegram.ui.Cells.EmptyCell; import org.telegram.ui.Cells.StickerEmojiCell; import java.util.ArrayList; @@ -42,7 +47,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -public class EmojiView extends LinearLayout implements NotificationCenter.NotificationCenterDelegate { +public class EmojiView extends FrameLayout implements NotificationCenter.NotificationCenterDelegate { public interface Listener { boolean onBackspace(); @@ -51,9 +56,9 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi } private ArrayList adapters = new ArrayList<>(); - private StickersGridAdapter stickersGridAdapter; private HashMap stickersUseHistory = new HashMap<>(); - private ArrayList stickers; + private ArrayList recentStickers = new ArrayList<>(); + private ArrayList stickerSets = new ArrayList<>(); private int[] icons = { R.drawable.ic_emoji_recent, @@ -67,9 +72,15 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi private Listener listener; private ViewPager pager; private FrameLayout recentsWrap; - private FrameLayout emojiWrap; + private FrameLayout stickersWrap; private ArrayList views = new ArrayList<>(); private ImageView backspaceButton; + private StickersGridAdapter stickersGridAdapter; + private LinearLayout pagerSlidingTabStripContainer; + private ScrollSlidingTabStrip scrollSlidingTabStrip; + + private int oldWidth; + private int lastNotifyWidth; private boolean backspacePressed; private boolean backspaceOnce; @@ -80,7 +91,6 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi showStickers = needStickers; - setOrientation(LinearLayout.VERTICAL); for (int i = 0; i < Emoji.data.length; i++) { GridView gridView = new GridView(context); if (AndroidUtilities.isTablet()) { @@ -99,7 +109,6 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi if (showStickers) { StickersQuery.checkStickers(); - stickers = StickersQuery.getStickers(); GridView gridView = new GridView(context); gridView.setColumnWidth(AndroidUtilities.dp(72)); gridView.setNumColumns(-1); @@ -109,29 +118,180 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi stickersGridAdapter = new StickersGridAdapter(context); gridView.setAdapter(stickersGridAdapter); AndroidUtilities.setListViewEdgeEffectColor(gridView, 0xfff5f6f7); + + stickersWrap = new FrameLayout(context); + stickersWrap.addView(gridView); + + TextView textView = new TextView(context); + textView.setText(LocaleController.getString("NoStickers", R.string.NoStickers)); + textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + textView.setTextColor(0xff888888); + stickersWrap.addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER)); + gridView.setEmptyView(textView); + + scrollSlidingTabStrip = new ScrollSlidingTabStrip(context) { + + boolean startedScroll; + float lastX; + float lastTranslateX; + boolean first = true; + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + if (getParent() != null) { + getParent().requestDisallowInterceptTouchEvent(true); + } + return super.onInterceptTouchEvent(ev); + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + if (Build.VERSION.SDK_INT >= 11) { + if (first) { + first = false; + lastX = ev.getX(); + } + float newTranslationX = ViewProxy.getTranslationX(scrollSlidingTabStrip); + if (scrollSlidingTabStrip.getScrollX() == 0 && newTranslationX == 0) { + if (!startedScroll && lastX - ev.getX() < 0) { + if (pager.beginFakeDrag()) { + startedScroll = true; + lastTranslateX = ViewProxy.getTranslationX(scrollSlidingTabStrip); + } + } else if (startedScroll && lastX - ev.getX() > 0) { + if (pager.isFakeDragging()) { + pager.endFakeDrag(); + startedScroll = false; + } + } + } + if (startedScroll) { + int dx = (int) (ev.getX() - lastX + newTranslationX - lastTranslateX); + try { + pager.fakeDragBy(dx); + lastTranslateX = newTranslationX; + } catch (Exception e) { + try { + pager.endFakeDrag(); + } catch (Exception e2) { + //don't promt + } + startedScroll = false; + FileLog.e("tmessages", e); + } + } + lastX = ev.getX(); + if (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP) { + first = true; + if (startedScroll) { + pager.endFakeDrag(); + startedScroll = false; + } + } + return startedScroll || super.onTouchEvent(ev); + } + return super.onTouchEvent(ev); + } + }; + scrollSlidingTabStrip.setUnderlineHeight(AndroidUtilities.dp(1)); + scrollSlidingTabStrip.setIndicatorColor(0xffe2e5e7); + scrollSlidingTabStrip.setUnderlineColor(0xffe2e5e7); + addView(scrollSlidingTabStrip, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.TOP)); + ViewProxy.setTranslationX(scrollSlidingTabStrip, AndroidUtilities.displaySize.x); + updateStickerTabs(); + scrollSlidingTabStrip.setDelegate(new ScrollSlidingTabStrip.ScrollSlidingTabStripDelegate() { + @Override + public void onPageSelected(int page) { + if (page == 0) { + pager.setCurrentItem(0); + return; + } else if (page == 1 && !recentStickers.isEmpty()) { + views.get(6).setSelection(0); + return; + } + int index = page - (recentStickers.isEmpty() ? 1 : 2); + if (index >= stickerSets.size()) { + index = stickerSets.size() - 1; + } + views.get(6).setSelection(stickersGridAdapter.getPositionForPack(stickerSets.get(index))); + } + }); + + gridView.setOnScrollListener(new AbsListView.OnScrollListener() { + @Override + public void onScrollStateChanged(AbsListView view, int scrollState) { + + } + + @Override + public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { + int count = view.getChildCount(); + for (int a = 0; a < count; a++) { + View child = view.getChildAt(a); + if (child.getHeight() + child.getTop() < AndroidUtilities.dp(5)) { + firstVisibleItem++; + } else { + break; + } + } + scrollSlidingTabStrip.onPageScrolled(stickersGridAdapter.getTabForPosition(firstVisibleItem) + 1, 0); + } + }); } setBackgroundColor(0xfff5f6f7); - pager = new ViewPager(context); + pager = new ViewPager(context) { + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + if (getParent() != null) { + getParent().requestDisallowInterceptTouchEvent(true); + } + return super.onInterceptTouchEvent(ev); + } + }; pager.setAdapter(new EmojiPagesAdapter()); - LinearLayout linearLayout = new LinearLayout(context); - linearLayout.setOrientation(LinearLayout.HORIZONTAL); - linearLayout.setBackgroundColor(0xfff5f6f7); - addView(linearLayout, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, AndroidUtilities.dp(48))); + pagerSlidingTabStripContainer = new LinearLayout(context) { + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + if (getParent() != null) { + getParent().requestDisallowInterceptTouchEvent(true); + } + return super.onInterceptTouchEvent(ev); + } + }; + pagerSlidingTabStripContainer.setOrientation(LinearLayout.HORIZONTAL); + pagerSlidingTabStripContainer.setBackgroundColor(0xfff5f6f7); + addView(pagerSlidingTabStripContainer, LayoutHelper.createFrame(LayoutParams.MATCH_PARENT, 48)); - PagerSlidingTabStrip tabs = new PagerSlidingTabStrip(context); - tabs.setViewPager(pager); - tabs.setShouldExpand(true); - tabs.setIndicatorHeight(AndroidUtilities.dp(2)); - tabs.setUnderlineHeight(AndroidUtilities.dp(1)); - tabs.setIndicatorColor(0xff2b96e2); - tabs.setUnderlineColor(0xffe2e5e7); - linearLayout.addView(tabs, new LinearLayout.LayoutParams(0, AndroidUtilities.dp(48), 1.0f)); + PagerSlidingTabStrip pagerSlidingTabStrip = new PagerSlidingTabStrip(context); + pagerSlidingTabStrip.setViewPager(pager); + pagerSlidingTabStrip.setShouldExpand(true); + pagerSlidingTabStrip.setIndicatorHeight(AndroidUtilities.dp(2)); + pagerSlidingTabStrip.setUnderlineHeight(AndroidUtilities.dp(1)); + pagerSlidingTabStrip.setIndicatorColor(0xff2b96e2); + pagerSlidingTabStrip.setUnderlineColor(0xffe2e5e7); + pagerSlidingTabStripContainer.addView(pagerSlidingTabStrip, LayoutHelper.createLinear(0, 48, 1.0f)); + pagerSlidingTabStrip.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + EmojiView.this.onPageScrolled(position, getMeasuredWidth(), positionOffsetPixels); + } + + @Override + public void onPageSelected(int position) { + + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); FrameLayout frameLayout = new FrameLayout(context); - linearLayout.addView(frameLayout, new LinearLayout.LayoutParams(AndroidUtilities.dp(52), AndroidUtilities.dp(48))); + pagerSlidingTabStripContainer.addView(frameLayout, LayoutHelper.createLinear(52, 48)); backspaceButton = new ImageView(context) { @Override @@ -155,11 +315,11 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi backspaceButton.setImageResource(R.drawable.ic_smiles_backspace); backspaceButton.setBackgroundResource(R.drawable.ic_emoji_backspace); backspaceButton.setScaleType(ImageView.ScaleType.CENTER); - frameLayout.addView(backspaceButton, new FrameLayout.LayoutParams(AndroidUtilities.dp(52), AndroidUtilities.dp(48))); + frameLayout.addView(backspaceButton, LayoutHelper.createFrame(52, 48)); View view = new View(context); view.setBackgroundColor(0xffe2e5e7); - frameLayout.addView(view, new FrameLayout.LayoutParams(AndroidUtilities.dp(52), AndroidUtilities.dp(1), Gravity.LEFT | Gravity.BOTTOM)); + frameLayout.addView(view, LayoutHelper.createFrame(52, 1, Gravity.LEFT | Gravity.BOTTOM)); recentsWrap = new FrameLayout(context); recentsWrap.addView(views.get(0)); @@ -172,20 +332,7 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi recentsWrap.addView(textView); views.get(0).setEmptyView(textView); - if (views.size() > 6) { - emojiWrap = new FrameLayout(context); - emojiWrap.addView(views.get(6)); - - textView = new TextView(context); - textView.setText(LocaleController.getString("NoStickers", R.string.NoStickers)); - textView.setTextSize(18); - textView.setTextColor(0xff888888); - textView.setGravity(Gravity.CENTER); - emojiWrap.addView(textView); - views.get(6).setEmptyView(textView); - } - - addView(pager); + addView(pager, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 0, 48, 0, 0)); loadRecents(); @@ -194,6 +341,39 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi } } + private void onPageScrolled(int position, int width, int positionOffsetPixels) { + if (scrollSlidingTabStrip == null) { + return; + } + + if (width == 0) { + width = AndroidUtilities.displaySize.x; + } + + int margin = 0; + if (position == 5) { + margin = -positionOffsetPixels; + } else if (position == 6) { + margin = -width; + } + + if (ViewProxy.getTranslationX(pagerSlidingTabStripContainer) != margin) { + ViewProxy.setTranslationX(pagerSlidingTabStripContainer, margin); + ViewProxy.setTranslationX(scrollSlidingTabStrip, width + margin); + if (Build.VERSION.SDK_INT < 11) { + if (margin <= -width) { + pagerSlidingTabStripContainer.clearAnimation(); + pagerSlidingTabStripContainer.setVisibility(GONE); + } else { + pagerSlidingTabStripContainer.setVisibility(VISIBLE); + } + } + } else if (Build.VERSION.SDK_INT < 11 && pagerSlidingTabStripContainer.getVisibility() == GONE) { + pagerSlidingTabStripContainer.clearAnimation(); + pagerSlidingTabStripContainer.setVisibility(GONE); + } + } + private void postBackspaceRunnable(final int time) { AndroidUtilities.runOnUIThread(new Runnable() { @Override @@ -273,12 +453,17 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi } private void sortStickers() { + if (StickersQuery.getStickerSets().isEmpty()) { + recentStickers.clear(); + return; + } + recentStickers.clear(); HashMap hashMap = new HashMap<>(); - for (TLRPC.Document document : stickers) { - Integer count = stickersUseHistory.get(document.id); - if (count != null) { - hashMap.put(document.id, count); - stickersUseHistory.remove(document.id); + for (HashMap.Entry entry : stickersUseHistory.entrySet()) { + TLRPC.Document sticker = StickersQuery.getStickerById(entry.getKey()); + if (sticker != null) { + recentStickers.add(sticker); + hashMap.put(sticker.id, entry.getValue()); } } if (!stickersUseHistory.isEmpty()) { @@ -287,7 +472,7 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi } else { stickersUseHistory = hashMap; } - Collections.sort(stickers, new Comparator() { + Collections.sort(recentStickers, new Comparator() { @Override public int compare(TLRPC.Document lhs, TLRPC.Document rhs) { Integer count1 = stickersUseHistory.get(lhs.id); @@ -306,6 +491,28 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi return 0; } }); + while (recentStickers.size() > 20) { + recentStickers.remove(recentStickers.size() - 1); + } + } + + private void updateStickerTabs() { + scrollSlidingTabStrip.removeTabs(); + scrollSlidingTabStrip.addIconTab(R.drawable.ic_emoji_smile); + if (!recentStickers.isEmpty()) { + scrollSlidingTabStrip.addIconTab(R.drawable.ic_smiles_recent); + } + stickerSets.clear(); + ArrayList packs = StickersQuery.getStickerSets(); + for (int a = 0; a < packs.size(); a++) { + TLRPC.TL_messages_stickerSet pack = packs.get(a); + if ((pack.set.flags & 2) != 0 || pack.documents == null || pack.documents.isEmpty()) { + continue; + } + stickerSets.add(pack); + scrollSlidingTabStrip.addStickerTab(pack.documents.get(0)); + } + scrollSlidingTabStrip.updateTabStyles(); } public void loadRecents() { @@ -344,14 +551,42 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi } } sortStickers(); + updateStickerTabs(); } catch (Exception e) { FileLog.e("tmessages", e); } } } + @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(View.MeasureSpec.makeMeasureSpec(View.MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(View.MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.EXACTLY)); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) pagerSlidingTabStripContainer.getLayoutParams(); + FrameLayout.LayoutParams layoutParams1 = null; + layoutParams.width = View.MeasureSpec.getSize(widthMeasureSpec); + if (scrollSlidingTabStrip != null) { + layoutParams1 = (FrameLayout.LayoutParams) scrollSlidingTabStrip.getLayoutParams(); + layoutParams1.width = layoutParams.width; + } + if (layoutParams.width != oldWidth) { + if (scrollSlidingTabStrip != null) { + onPageScrolled(pager.getCurrentItem(), layoutParams.width, 0); + scrollSlidingTabStrip.setLayoutParams(layoutParams1); + } + pagerSlidingTabStripContainer.setLayoutParams(layoutParams); + oldWidth = layoutParams.width; + } + super.onMeasure(View.MeasureSpec.makeMeasureSpec(layoutParams.width, MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(View.MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.EXACTLY)); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + if (lastNotifyWidth != right - left) { + lastNotifyWidth = right - left; + if (stickersGridAdapter != null) { + stickersGridAdapter.notifyDataSetChanged(); + } + } + super.onLayout(changed, left, top, right, bottom); } public void setListener(Listener value) { @@ -371,8 +606,16 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi super.onAttachedToWindow(); if (stickersGridAdapter != null) { NotificationCenter.getInstance().addObserver(this, NotificationCenter.stickersDidLoaded); - stickers = StickersQuery.getStickers(); + } + } + + @Override + public void setVisibility(int visibility) { + super.setVisibility(visibility); + if (visibility != GONE && stickersGridAdapter != null) { + NotificationCenter.getInstance().addObserver(this, NotificationCenter.stickersDidLoaded); sortStickers(); + updateStickerTabs(); stickersGridAdapter.notifyDataSetChanged(); } } @@ -388,57 +631,173 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi @Override public void didReceivedNotification(int id, Object... args) { if (id == NotificationCenter.stickersDidLoaded) { + updateStickerTabs(); stickersGridAdapter.notifyDataSetChanged(); } } private class StickersGridAdapter extends BaseAdapter { - Context context; + private Context context; + private int stickersPerRow; + private HashMap rowStartPack = new HashMap<>(); + private HashMap packStartRow = new HashMap<>(); + private HashMap cache = new HashMap<>(); + private int totalItems; public StickersGridAdapter(Context context) { this.context = context; } public int getCount() { - return stickers.size(); + return totalItems != 0 ? totalItems + 1 : 0; } public Object getItem(int i) { - return stickers.get(i); + return cache.get(i); } public long getItemId(int i) { - return stickers.get(i).id; + return NO_ID; + } + + public int getPositionForPack(TLRPC.TL_messages_stickerSet stickerSet) { + return packStartRow.get(stickerSet) * stickersPerRow; + } + + @Override + public boolean areAllItemsEnabled() { + return false; + } + + @Override + public boolean isEnabled(int position) { + return cache.get(position) != null; + } + + @Override + public int getItemViewType(int position) { + if (cache.get(position) != null) { + return 0; + } + return 1; + } + + @Override + public int getViewTypeCount() { + return 2; + } + + public int getTabForPosition(int position) { + if (stickersPerRow == 0) { + int width = getMeasuredWidth(); + if (width == 0) { + width = AndroidUtilities.displaySize.x; + } + stickersPerRow = width / AndroidUtilities.dp(72); + } + int row = position / stickersPerRow; + TLRPC.TL_messages_stickerSet pack = rowStartPack.get(row); + if (pack == null) { + return 0; + } + return stickerSets.indexOf(pack) + (recentStickers.isEmpty() ? 0 : 1); } public View getView(int i, View view, ViewGroup viewGroup) { - if (view == null) { - view = new StickerEmojiCell(context) { - public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(82), MeasureSpec.EXACTLY)); - } - }; - view.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - if (listener != null) { - TLRPC.Document document = ((StickerEmojiCell) v).getSticker(); - Integer count = stickersUseHistory.get(document.id); - if (count == null) { - count = 0; - } - stickersUseHistory.put(document.id, ++count); - saveRecentStickers(); - listener.onStickerSelected(document); + TLRPC.Document sticker = cache.get(i); + if (sticker != null) { + if (view == null) { + view = new StickerEmojiCell(context) { + public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(82), MeasureSpec.EXACTLY)); } + }; + view.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (listener != null) { + TLRPC.Document document = ((StickerEmojiCell) v).getSticker(); + Integer count = stickersUseHistory.get(document.id); + if (count == null) { + count = 0; + } + if (count == 0 && stickersUseHistory.size() > 19) { + for (int a = recentStickers.size() - 1; a >= 0; a--) { + TLRPC.Document sticker = recentStickers.get(a); + stickersUseHistory.remove(sticker.id); + recentStickers.remove(a); + if (stickersUseHistory.size() <= 19) { + break; + } + } + } + stickersUseHistory.put(document.id, ++count); + saveRecentStickers(); + listener.onStickerSelected(document); + } + } + }); + } + ((StickerEmojiCell) view).setSticker(sticker, false); + } else { + if (view == null) { + view = new EmptyCell(context); + } + if (i == totalItems) { + int row = (i - 1) / stickersPerRow; + TLRPC.TL_messages_stickerSet pack = rowStartPack.get(row); + if (pack == null) { + ((EmptyCell) view).setHeight(1); + } else { + int height = pager.getHeight() - (int) Math.ceil(pack.documents.size() / (float) stickersPerRow) * AndroidUtilities.dp(82); + ((EmptyCell) view).setHeight(height > 0 ? height : 1); } - }); + } else { + ((EmptyCell) view).setHeight(AndroidUtilities.dp(82)); + } } - ((StickerEmojiCell) view).setSticker(stickers.get(i), false); return view; } + @Override + public void notifyDataSetChanged() { + int width = getMeasuredWidth(); + if (width == 0) { + width = AndroidUtilities.displaySize.x; + } + stickersPerRow = width / AndroidUtilities.dp(72); + rowStartPack.clear(); + packStartRow.clear(); + cache.clear(); + totalItems = 0; + ArrayList packs = stickerSets; + for (int a = -1; a < packs.size(); a++) { + ArrayList documents; + TLRPC.TL_messages_stickerSet pack = null; + int startRow = totalItems / stickersPerRow; + if (a == -1) { + documents = recentStickers; + } else { + pack = packs.get(a); + documents = pack.documents; + packStartRow.put(pack, startRow); + } + if (documents.isEmpty()) { + continue; + } + int count = (int) Math.ceil(documents.size() / (float) stickersPerRow); + for (int b = 0; b < documents.size(); b++) { + cache.put(b + totalItems, documents.get(b)); + } + totalItems += count * stickersPerRow; + for (int b = 0; b < count; b++) { + rowStartPack.put(startRow + b, pack); + } + } + super.notifyDataSetChanged(); + } + @Override public void unregisterDataSetObserver(DataSetObserver observer) { if (observer != null) { @@ -500,16 +859,16 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi private class EmojiPagesAdapter extends PagerAdapter implements PagerSlidingTabStrip.IconTabProvider { - public void destroyItem(ViewGroup paramViewGroup, int paramInt, Object paramObject) { - View localObject; - if (paramInt == 0) { - localObject = recentsWrap; - } else if (paramInt == 6) { - localObject = emojiWrap; + public void destroyItem(ViewGroup viewGroup, int position, Object object) { + View view; + if (position == 0) { + view = recentsWrap; + } else if (position == 6) { + view = stickersWrap; } else { - localObject = views.get(paramInt); + view = views.get(position); } - paramViewGroup.removeView(localObject); + viewGroup.removeView(view); } public int getCount() { @@ -520,21 +879,21 @@ public class EmojiView extends LinearLayout implements NotificationCenter.Notifi return icons[paramInt]; } - public Object instantiateItem(ViewGroup paramViewGroup, int paramInt) { - View localObject; - if (paramInt == 0) { - localObject = recentsWrap; - } else if (paramInt == 6) { - localObject = emojiWrap; + public Object instantiateItem(ViewGroup viewGroup, int position) { + View view; + if (position == 0) { + view = recentsWrap; + } else if (position == 6) { + view = stickersWrap; } else { - localObject = views.get(paramInt); + view = views.get(position); } - paramViewGroup.addView(localObject); - return localObject; + viewGroup.addView(view); + return view; } - public boolean isViewFromObject(View paramView, Object paramObject) { - return paramView == paramObject; + public boolean isViewFromObject(View view, Object object) { + return view == object; } @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/LinkPath.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/LinkPath.java new file mode 100644 index 000000000..c597ccafe --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/LinkPath.java @@ -0,0 +1,47 @@ +/* + * This is the source code of Telegram for Android v. 2.x.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.graphics.Path; +import android.text.StaticLayout; + +public class LinkPath extends Path { + + private StaticLayout currentLayout; + private int currentLine; + private float lastTop = -1; + + public void setCurrentLayout(StaticLayout layout, int start) { + currentLayout = layout; + currentLine = layout.getLineForOffset(start); + lastTop = -1; + } + + @Override + public void addRect(float left, float top, float right, float bottom, Direction dir) { + if (lastTop == -1) { + lastTop = top; + } else if (lastTop != top) { + lastTop = top; + currentLine++; + } + float lineRight = currentLayout.getLineRight(currentLine); + float lineLeft = currentLayout.getLineLeft(currentLine); + if (left >= lineRight) { + return; + } + if (right > lineRight) { + right = lineRight; + } + if (left < lineLeft) { + left = lineLeft; + } + super.addRect(left, top, right, bottom, dir); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoViewerCaptionEnterView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoViewerCaptionEnterView.java index 0bf595a75..fcff6ef23 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoViewerCaptionEnterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PhotoViewerCaptionEnterView.java @@ -8,26 +8,20 @@ package org.telegram.ui.Components; -import android.app.Activity; import android.content.Context; import android.text.Editable; import android.text.InputFilter; -import android.text.InputType; import android.text.TextWatcher; import android.text.style.ImageSpan; import android.util.TypedValue; import android.view.Gravity; import android.view.KeyEvent; -import android.view.MotionEvent; import android.view.View; -import android.view.ViewTreeObserver; -import android.view.WindowManager; import android.view.inputmethod.EditorInfo; import android.widget.EditText; +import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.PopupWindow; -import android.widget.RelativeLayout; import android.widget.TextView; import org.telegram.android.AndroidUtilities; @@ -41,25 +35,18 @@ import org.telegram.messenger.TLRPC; import org.telegram.android.AnimationCompat.AnimatorSetProxy; import org.telegram.android.AnimationCompat.ObjectAnimatorProxy; -public class PhotoViewerCaptionEnterView extends FrameLayoutFixed implements NotificationCenter.NotificationCenterDelegate, SizeNotifierRelativeLayoutPhoto.SizeNotifierRelativeLayoutPhotoDelegate { +public class PhotoViewerCaptionEnterView extends FrameLayoutFixed implements NotificationCenter.NotificationCenterDelegate, SizeNotifierFrameLayoutPhoto.SizeNotifierFrameLayoutPhotoDelegate { public interface PhotoViewerCaptionEnterViewDelegate { void onCaptionEnter(); - void onTextChanged(CharSequence text, boolean bigChange); + void onTextChanged(CharSequence text); void onWindowSizeChanged(int size); } private EditText messageEditText; - private PopupWindow emojiPopup; private ImageView emojiButton; private EmojiView emojiView; - private SizeNotifierRelativeLayoutPhoto sizeNotifierFrameLayout; - - private int framesDroped; - - private int keyboardTransitionState; - private boolean showKeyboardOnEmojiButton; - private ViewTreeObserver.OnPreDrawListener onPreDrawListener; + private SizeNotifierFrameLayoutPhoto sizeNotifierLayout; private AnimatorSetProxy runningAnimation; private AnimatorSetProxy runningAnimation2; @@ -67,22 +54,23 @@ public class PhotoViewerCaptionEnterView extends FrameLayoutFixed implements Not private int runningAnimationType; private int audioInterfaceState; + private int lastSizeChangeValue1; + private boolean lastSizeChangeValue2; + private int keyboardHeight; private int keyboardHeightLand; private boolean keyboardVisible; + private int emojiPadding; - private View window; private PhotoViewerCaptionEnterViewDelegate delegate; - private boolean wasFocus; - public PhotoViewerCaptionEnterView(Context context, View windowView, SizeNotifierRelativeLayoutPhoto parent) { + public PhotoViewerCaptionEnterView(Context context, SizeNotifierFrameLayoutPhoto parent) { super(context); setBackgroundColor(0x7f000000); setFocusable(true); setFocusableInTouchMode(true); - window = windowView; - sizeNotifierFrameLayout = parent; + sizeNotifierLayout = parent; LinearLayout textFieldContainer = new LinearLayout(context); textFieldContainer.setOrientation(LinearLayout.HORIZONTAL); @@ -99,23 +87,10 @@ public class PhotoViewerCaptionEnterView extends FrameLayoutFixed implements Not emojiButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - if (showKeyboardOnEmojiButton) { - setKeyboardTransitionState(1); - showEmojiPopup(false, false); - int selection = messageEditText.getSelectionStart(); - MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0); - messageEditText.onTouchEvent(event); - event.recycle(); - messageEditText.setSelection(selection); + if (!isPopupShowing()) { + showPopup(1); } else { - boolean show = emojiPopup == null || !emojiPopup.isShowing(); - if (show) { - setKeyboardTransitionState(5); - showEmojiPopup(show, true); - } else { - showEmojiPopup(show, true); - setKeyboardTransitionState(1); - } + openKeyboardInternal(); } } }); @@ -123,9 +98,9 @@ public class PhotoViewerCaptionEnterView extends FrameLayoutFixed implements Not messageEditText = new EditText(context); messageEditText.setHint(LocaleController.getString("AddCaption", R.string.AddCaption)); messageEditText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_DONE); - messageEditText.setInputType(EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); - messageEditText.setSingleLine(false); + messageEditText.setInputType(EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES | EditorInfo.TYPE_CLASS_TEXT); messageEditText.setMaxLines(4); + messageEditText.setHorizontallyScrolling(false); messageEditText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); messageEditText.setGravity(Gravity.BOTTOM); messageEditText.setPadding(0, AndroidUtilities.dp(11), 0, AndroidUtilities.dp(12)); @@ -140,9 +115,9 @@ public class PhotoViewerCaptionEnterView extends FrameLayoutFixed implements Not messageEditText.setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(View view, int i, KeyEvent keyEvent) { - if (i == 4 && !keyboardVisible && emojiPopup != null && emojiPopup.isShowing()) { + if (i == KeyEvent.KEYCODE_BACK && !keyboardVisible && isPopupShowing()) { if (keyEvent.getAction() == 1) { - showEmojiPopup(false, true); + showPopup(0); } return true; } else if (i == KeyEvent.KEYCODE_ENTER && keyEvent.getAction() == KeyEvent.ACTION_DOWN) { @@ -152,30 +127,18 @@ public class PhotoViewerCaptionEnterView extends FrameLayoutFixed implements Not return false; } }); - messageEditText.setOnFocusChangeListener(new OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - if (!wasFocus) { - setKeyboardTransitionState(3); - } - wasFocus = hasFocus; - } - }); messageEditText.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { - if (emojiPopup != null && emojiPopup.isShowing()) { - setKeyboardTransitionState(1); - showEmojiPopup(false, false); - } else { - setKeyboardTransitionState(3); + if (isPopupShowing()) { + showPopup(AndroidUtilities.usingHardwareInput ? 0 : 2); } } }); messageEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { - if (i == EditorInfo.IME_ACTION_DONE) { + if (i == EditorInfo.IME_ACTION_DONE || i == EditorInfo.IME_ACTION_NEXT) { delegate.onCaptionEnter(); return true; } else if (keyEvent != null && i == EditorInfo.IME_NULL && keyEvent.getAction() == KeyEvent.ACTION_DOWN) { @@ -193,10 +156,8 @@ public class PhotoViewerCaptionEnterView extends FrameLayoutFixed implements Not @Override public void onTextChanged(CharSequence charSequence, int start, int before, int count) { - String message = getTrimmedString(charSequence.toString()); - if (delegate != null) { - delegate.onTextChanged(charSequence, before > count || count > 2); + delegate.onTextChanged(charSequence); } } @@ -217,48 +178,11 @@ public class PhotoViewerCaptionEnterView extends FrameLayoutFixed implements Not }); } - private void setKeyboardTransitionState(int state) { - if (AndroidUtilities.usingHardwareInput) { - if (state == 1) { - showEmojiPopup(false, false); - RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams(); - layoutParams.bottomMargin = 0;//AndroidUtilities.dp(48); - setLayoutParams(layoutParams); - keyboardTransitionState = 0; - } else if (state == 2) { - int currentHeight = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y ? keyboardHeightLand : keyboardHeight; - sizeNotifierFrameLayout.setPadding(0, 0, 0, currentHeight); - keyboardTransitionState = 0; - } else if (state == 3) { - RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams(); - layoutParams.bottomMargin = 0;//AndroidUtilities.dp(48); - setLayoutParams(layoutParams); - keyboardTransitionState = 0; - } else if (state == 4) { - RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams(); - layoutParams.bottomMargin = -AndroidUtilities.dp(400); - setLayoutParams(layoutParams); - keyboardTransitionState = 0; - } else if (state == 5) { - RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams(); - layoutParams.bottomMargin = 0; - setLayoutParams(layoutParams); - keyboardTransitionState = 0; - } - } else { - framesDroped = 0; - keyboardTransitionState = state; - if (state == 1) { - sizeNotifierFrameLayout.setPadding(0, 0, 0, 0); - } + private void onWindowSizeChanged() { + int size = sizeNotifierLayout.getHeight(); + if (!keyboardVisible) { + size -= emojiPadding; } - } - - public int getKeyboardTransitionState() { - return keyboardTransitionState; - } - - private void onWindowSizeChanged(int size) { if (delegate != null) { delegate.onWindowSizeChanged(size); } @@ -266,202 +190,21 @@ public class PhotoViewerCaptionEnterView extends FrameLayoutFixed implements Not public void onCreate() { NotificationCenter.getInstance().addObserver(this, NotificationCenter.emojiDidLoaded); - NotificationCenter.getInstance().addObserver(this, NotificationCenter.hideEmojiKeyboard); - sizeNotifierFrameLayout.getViewTreeObserver().addOnPreDrawListener(onPreDrawListener = new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { - if (keyboardTransitionState == 1) { - if (keyboardVisible || framesDroped >= 60) { - showEmojiPopup(false, false); - keyboardTransitionState = 0; - } else { - if (messageEditText != null) { - messageEditText.requestFocus(); - AndroidUtilities.showKeyboard(messageEditText); - } - } - framesDroped++; - return false; - } else if (keyboardTransitionState == 2) { - if (!keyboardVisible || framesDroped >= 60) { - int currentHeight = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y ? keyboardHeightLand : keyboardHeight; - sizeNotifierFrameLayout.setPadding(0, 0, 0, currentHeight); - keyboardTransitionState = 0; - } - framesDroped++; - return false; - } else if (keyboardTransitionState == 3) { - if (keyboardVisible) { - RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams(); - layoutParams.bottomMargin = 0;//AndroidUtilities.usingHardwareInput ? AndroidUtilities.dp(48) : 0; - setLayoutParams(layoutParams); - keyboardTransitionState = 0; - } - } else if (keyboardTransitionState == 4) { - if (!keyboardVisible && (emojiPopup == null || !emojiPopup.isShowing())) { - RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams(); - layoutParams.bottomMargin = -AndroidUtilities.dp(400); - setLayoutParams(layoutParams); - keyboardTransitionState = 0; - } - } else if (keyboardTransitionState == 5) { - if (emojiPopup != null && emojiPopup.isShowing()) { - RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams(); - layoutParams.bottomMargin = 0; - setLayoutParams(layoutParams); - keyboardTransitionState = 0; - } - } - return true; - } - }); - sizeNotifierFrameLayout.setDelegate(this); + sizeNotifierLayout.setDelegate(this); } public void onDestroy() { - if (isEmojiPopupShowing()) { - hideEmojiPopup(); - } + hidePopup(); if (isKeyboardVisible()) { closeKeyboard(); } keyboardVisible = false; NotificationCenter.getInstance().removeObserver(this, NotificationCenter.emojiDidLoaded); - NotificationCenter.getInstance().removeObserver(this, NotificationCenter.hideEmojiKeyboard); - if (sizeNotifierFrameLayout != null) { - sizeNotifierFrameLayout.getViewTreeObserver().removeOnPreDrawListener(onPreDrawListener); - sizeNotifierFrameLayout.setDelegate(null); + if (sizeNotifierLayout != null) { + sizeNotifierLayout.setDelegate(null); } } - private String getTrimmedString(String src) { - String result = src.trim(); - if (result.length() == 0) { - return result; - } - while (src.startsWith("\n")) { - src = src.substring(1); - } - while (src.endsWith("\n")) { - src = src.substring(0, src.length() - 1); - } - return src; - } - - private void showEmojiPopup(boolean show, boolean post) { - if (show) { - if (emojiPopup == null) { - emojiView = new EmojiView(false, getContext()); - emojiView.setListener(new EmojiView.Listener() { - public boolean onBackspace() { - if (messageEditText.length() == 0) { - return false; - } - messageEditText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL)); - return true; - } - - public void onEmojiSelected(String symbol) { - int i = messageEditText.getSelectionEnd(); - if (i < 0) { - i = 0; - } - try { - CharSequence localCharSequence = Emoji.replaceEmoji(symbol, messageEditText.getPaint().getFontMetricsInt(), AndroidUtilities.dp(20)); - messageEditText.setText(messageEditText.getText().insert(i, localCharSequence)); - int j = i + localCharSequence.length(); - messageEditText.setSelection(j, j); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } - - public void onStickerSelected(TLRPC.Document sticker) { - - } - }); - emojiPopup = new PopupWindow(emojiView); - } - - if (keyboardHeight <= 0) { - keyboardHeight = ApplicationLoader.applicationContext.getSharedPreferences("emoji", 0).getInt("kbd_height", AndroidUtilities.dp(200)); - } - if (keyboardHeightLand <= 0) { - keyboardHeightLand = ApplicationLoader.applicationContext.getSharedPreferences("emoji", 0).getInt("kbd_height_land3", AndroidUtilities.dp(200)); - } - int currentHeight = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y ? keyboardHeightLand : keyboardHeight; - FileLog.e("tmessages", "show emoji with height = " + currentHeight); - emojiPopup.setHeight(View.MeasureSpec.makeMeasureSpec(currentHeight, View.MeasureSpec.EXACTLY)); - if (sizeNotifierFrameLayout != null) { - emojiPopup.setWidth(View.MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.x, View.MeasureSpec.EXACTLY)); - } - - emojiPopup.showAtLocation(window, Gravity.BOTTOM | Gravity.LEFT, 0, 0); - - if (!keyboardVisible) { - if (sizeNotifierFrameLayout != null) { - sizeNotifierFrameLayout.setPadding(0, 0, 0, currentHeight); - emojiButton.setImageResource(R.drawable.arrow_down_w); - showKeyboardOnEmojiButton = false; - onWindowSizeChanged(sizeNotifierFrameLayout.getHeight() - sizeNotifierFrameLayout.getPaddingBottom()); - } - return; - } else { - setKeyboardTransitionState(2); - AndroidUtilities.hideKeyboard(messageEditText); - } - emojiButton.setImageResource(R.drawable.ic_keyboard_w); - showKeyboardOnEmojiButton = true; - return; - } - if (emojiButton != null) { - showKeyboardOnEmojiButton = false; - emojiButton.setImageResource(R.drawable.ic_smile_w); - } - if (emojiPopup != null) { - try { - emojiPopup.dismiss(); - } catch (Exception e) { - //don't promt - } - } - if (keyboardTransitionState == 0) { - if (sizeNotifierFrameLayout != null) { - if (post) { - sizeNotifierFrameLayout.post(new Runnable() { - public void run() { - if (sizeNotifierFrameLayout != null) { - sizeNotifierFrameLayout.setPadding(0, 0, 0, 0); - onWindowSizeChanged(sizeNotifierFrameLayout.getHeight()); - } - } - }); - } else { - sizeNotifierFrameLayout.setPadding(0, 0, 0, 0); - onWindowSizeChanged(sizeNotifierFrameLayout.getHeight()); - } - } - } - } - - public void hideEmojiPopup() { - if (emojiPopup != null && emojiPopup.isShowing()) { - showEmojiPopup(false, true); - } - setKeyboardTransitionState(4); - } - - public void openKeyboard() { - setKeyboardTransitionState(3); - messageEditText.requestFocus(); - AndroidUtilities.showKeyboard(messageEditText); - } - - public void closeKeyboard() { - setKeyboardTransitionState(4); - AndroidUtilities.hideKeyboard(messageEditText); - } - public void setDelegate(PhotoViewerCaptionEnterViewDelegate delegate) { this.delegate = delegate; } @@ -473,7 +216,7 @@ public class PhotoViewerCaptionEnterView extends FrameLayoutFixed implements Not messageEditText.setText(text); messageEditText.setSelection(messageEditText.getText().length()); if (delegate != null) { - delegate.onTextChanged(messageEditText.getText(), true); + delegate.onTextChanged(messageEditText.getText()); } } @@ -525,27 +268,122 @@ public class PhotoViewerCaptionEnterView extends FrameLayoutFixed implements Not } } - public boolean hasText() { - return messageEditText != null && messageEditText.length() > 0; - } - - public String getFieldText() { - if (messageEditText != null && messageEditText.length() > 0) { - return getTrimmedString(messageEditText.getText().toString()); - } - return null; - } - public CharSequence getFieldCharSequence() { return messageEditText.getText(); } - public boolean isEmojiPopupShowing() { - return emojiPopup != null && emojiPopup.isShowing(); + public int getEmojiPadding() { + return emojiPadding; + } + + public boolean isPopupView(View view) { + return view == emojiView; + } + + private void showPopup(int show) { + if (show == 1) { + if (emojiView == null) { + emojiView = new EmojiView(false, getContext()); + emojiView.setListener(new EmojiView.Listener() { + public boolean onBackspace() { + if (messageEditText.length() == 0) { + return false; + } + messageEditText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL)); + return true; + } + + public void onEmojiSelected(String symbol) { + int i = messageEditText.getSelectionEnd(); + if (i < 0) { + i = 0; + } + try { + CharSequence localCharSequence = Emoji.replaceEmoji(symbol, messageEditText.getPaint().getFontMetricsInt(), AndroidUtilities.dp(20)); + messageEditText.setText(messageEditText.getText().insert(i, localCharSequence)); + int j = i + localCharSequence.length(); + messageEditText.setSelection(j, j); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + + public void onStickerSelected(TLRPC.Document sticker) { + + } + }); + sizeNotifierLayout.addView(emojiView); + } + + emojiView.setVisibility(VISIBLE); + + if (keyboardHeight <= 0) { + keyboardHeight = ApplicationLoader.applicationContext.getSharedPreferences("emoji", 0).getInt("kbd_height", AndroidUtilities.dp(200)); + } + if (keyboardHeightLand <= 0) { + keyboardHeightLand = ApplicationLoader.applicationContext.getSharedPreferences("emoji", 0).getInt("kbd_height_land3", AndroidUtilities.dp(200)); + } + int currentHeight = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y ? keyboardHeightLand : keyboardHeight; + + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) emojiView.getLayoutParams(); + layoutParams.width = AndroidUtilities.displaySize.x; + layoutParams.height = currentHeight; + emojiView.setLayoutParams(layoutParams); + AndroidUtilities.hideKeyboard(messageEditText); + if (sizeNotifierLayout != null) { + emojiPadding = currentHeight; + sizeNotifierLayout.requestLayout(); + emojiButton.setImageResource(R.drawable.ic_keyboard_w); + onWindowSizeChanged(); + } + } else { + if (emojiButton != null) { + emojiButton.setImageResource(R.drawable.ic_smile_w); + } + if (emojiView != null) { + emojiView.setVisibility(GONE); + } + if (sizeNotifierLayout != null) { + if (show == 0) { + emojiPadding = 0; + } + sizeNotifierLayout.requestLayout(); + onWindowSizeChanged(); + } + } + } + + public void hidePopup() { + if (isPopupShowing()) { + showPopup(0); + } + } + + private void openKeyboardInternal() { + showPopup(AndroidUtilities.usingHardwareInput ? 0 : 2); + /*int selection = messageEditText.getSelectionStart(); + MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0); + messageEditText.onTouchEvent(event); + event.recycle(); + messageEditText.setSelection(selection);*/ + AndroidUtilities.showKeyboard(messageEditText); + } + + public void openKeyboard() { + messageEditText.requestFocus(); + AndroidUtilities.showKeyboard(messageEditText); + } + + public boolean isPopupShowing() { + return emojiView != null && emojiView.getVisibility() == VISIBLE; + } + + public void closeKeyboard() { + AndroidUtilities.hideKeyboard(messageEditText); } public boolean isKeyboardVisible() { - return AndroidUtilities.usingHardwareInput && getLayoutParams() != null && ((RelativeLayout.LayoutParams) getLayoutParams()).bottomMargin == 0 || keyboardVisible; + return AndroidUtilities.usingHardwareInput && getLayoutParams() != null && ((FrameLayout.LayoutParams) getLayoutParams()).bottomMargin == 0 || keyboardVisible; } @Override @@ -560,41 +398,44 @@ public class PhotoViewerCaptionEnterView extends FrameLayoutFixed implements Not } } - if (emojiPopup != null && emojiPopup.isShowing()) { - int newHeight = 0; + if (isPopupShowing()) { + int newHeight; if (isWidthGreater) { newHeight = keyboardHeightLand; } else { newHeight = keyboardHeight; } - WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) emojiPopup.getContentView().getLayoutParams(); + + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) emojiView.getLayoutParams(); if (layoutParams.width != AndroidUtilities.displaySize.x || layoutParams.height != newHeight) { layoutParams.width = AndroidUtilities.displaySize.x; layoutParams.height = newHeight; - WindowManager wm = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); - if (wm != null) { - wm.updateViewLayout(emojiPopup.getContentView(), layoutParams); - if (!keyboardVisible) { - if (sizeNotifierFrameLayout != null) { - sizeNotifierFrameLayout.setPadding(0, 0, 0, layoutParams.height); - sizeNotifierFrameLayout.requestLayout(); - onWindowSizeChanged(sizeNotifierFrameLayout.getHeight() - sizeNotifierFrameLayout.getPaddingBottom()); - } - } + emojiView.setLayoutParams(layoutParams); + if (sizeNotifierLayout != null) { + emojiPadding = layoutParams.height; + sizeNotifierLayout.requestLayout(); + onWindowSizeChanged(); } } } + if (lastSizeChangeValue1 == height && lastSizeChangeValue2 == isWidthGreater) { + onWindowSizeChanged(); + return; + } + lastSizeChangeValue1 = height; + lastSizeChangeValue2 = isWidthGreater; + boolean oldValue = keyboardVisible; keyboardVisible = height > 0; - if (keyboardVisible && (sizeNotifierFrameLayout.getPaddingBottom() > 0 || keyboardTransitionState == 1)) { - setKeyboardTransitionState(1); - } else if (keyboardTransitionState != 2 && !keyboardVisible && keyboardVisible != oldValue && emojiPopup != null && emojiPopup.isShowing()) { - showEmojiPopup(false, true); + if (keyboardVisible && isPopupShowing()) { + showPopup(0); } - if (keyboardTransitionState == 0) { - onWindowSizeChanged(sizeNotifierFrameLayout.getHeight() - sizeNotifierFrameLayout.getPaddingBottom()); + if (emojiPadding != 0 && !keyboardVisible && keyboardVisible != oldValue && !isPopupShowing()) { + emojiPadding = 0; + sizeNotifierLayout.requestLayout(); } + onWindowSizeChanged(); } @Override @@ -603,8 +444,6 @@ public class PhotoViewerCaptionEnterView extends FrameLayoutFixed implements Not if (emojiView != null) { emojiView.invalidateViews(); } - } else if (id == NotificationCenter.hideEmojiKeyboard) { - hideEmojiPopup(); } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/RecyclerListView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/RecyclerListView.java index 55a75b2f3..b356c7196 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/RecyclerListView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/RecyclerListView.java @@ -290,7 +290,7 @@ public class RecyclerListView extends RecyclerView { return; } boolean emptyViewVisible = getAdapter().getItemCount() == 0; - emptyView.setVisibility(emptyViewVisible ? VISIBLE : INVISIBLE); + emptyView.setVisibility(emptyViewVisible ? VISIBLE : GONE); setVisibility(emptyViewVisible ? INVISIBLE : VISIBLE); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ScrollSlidingTabStrip.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ScrollSlidingTabStrip.java new file mode 100644 index 000000000..a5b56b4d3 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ScrollSlidingTabStrip.java @@ -0,0 +1,210 @@ +/* + * This is the source code of Telegram for Android v. 2.x.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2015. + */ + +package org.telegram.ui.Components; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Paint.Style; +import android.util.DisplayMetrics; +import android.view.Gravity; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.HorizontalScrollView; +import android.widget.ImageView; +import android.widget.LinearLayout; + +import org.telegram.android.AndroidUtilities; +import org.telegram.messenger.TLRPC; + +public class ScrollSlidingTabStrip extends HorizontalScrollView { + + public interface ScrollSlidingTabStripDelegate { + void onPageSelected(int page); + } + + private LinearLayout.LayoutParams defaultTabLayoutParams; + private LinearLayout tabsContainer; + private ScrollSlidingTabStripDelegate delegate; + + private int tabCount; + + private int currentPosition = 0; + + private Paint rectPaint; + + private int indicatorColor = 0xff666666; + private int underlineColor = 0x1a000000; + + private int scrollOffset = AndroidUtilities.dp(52); + private int underlineHeight = AndroidUtilities.dp(2); + private int dividerPadding = AndroidUtilities.dp(12); + private int tabPadding = AndroidUtilities.dp(24); + + private int lastScrollX = 0; + + public ScrollSlidingTabStrip(Context context) { + super(context); + + setFillViewport(true); + setWillNotDraw(false); + + setHorizontalScrollBarEnabled(false); + tabsContainer = new LinearLayout(context); + tabsContainer.setOrientation(LinearLayout.HORIZONTAL); + tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); + addView(tabsContainer); + + DisplayMetrics dm = getResources().getDisplayMetrics(); + + rectPaint = new Paint(); + rectPaint.setAntiAlias(true); + rectPaint.setStyle(Style.FILL); + + defaultTabLayoutParams = new LinearLayout.LayoutParams(AndroidUtilities.dp(52), LayoutHelper.MATCH_PARENT); + } + + public void setDelegate(ScrollSlidingTabStripDelegate scrollSlidingTabStripDelegate) { + delegate = scrollSlidingTabStripDelegate; + } + + public void removeTabs() { + tabsContainer.removeAllViews(); + tabCount = 0; + currentPosition = 0; + } + + public void addIconTab(int resId) { + final int position = tabCount++; + ImageView tab = new ImageView(getContext()); + tab.setFocusable(true); + tab.setImageResource(resId); + tab.setScaleType(ImageView.ScaleType.CENTER); + tab.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + delegate.onPageSelected(position); + } + }); + tabsContainer.addView(tab); + tab.setSelected(position == currentPosition); + } + + public void addStickerTab(TLRPC.Document sticker) { + final int position = tabCount++; + FrameLayout tab = new FrameLayout(getContext()); + tab.setFocusable(true); + tab.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + delegate.onPageSelected(position); + } + }); + tabsContainer.addView(tab); + tab.setSelected(position == currentPosition); + BackupImageView imageView = new BackupImageView(getContext()); + if (sticker != null && sticker.thumb != null) { + imageView.setImage(sticker.thumb.location, null, "webp", null); + } + imageView.setAspectFit(true); + tab.addView(imageView, LayoutHelper.createFrame(30, 30, Gravity.CENTER)); + } + + public void updateTabStyles() { + for (int i = 0; i < tabCount; i++) { + View v = tabsContainer.getChildAt(i); + v.setLayoutParams(defaultTabLayoutParams); + } + } + + private void scrollToChild(int position) { + if (tabCount == 0) { + return; + } + int newScrollX = tabsContainer.getChildAt(position).getLeft(); + if (position > 0) { + newScrollX -= scrollOffset; + } + int currentScrollX = getScrollX(); + if (newScrollX != lastScrollX) { + if (newScrollX < currentScrollX) { + lastScrollX = newScrollX; + smoothScrollTo(lastScrollX, 0); + } else if (newScrollX + scrollOffset > currentScrollX + getWidth() - scrollOffset * 2) { + lastScrollX = newScrollX - getWidth() + scrollOffset * 3; + smoothScrollTo(lastScrollX, 0); + } + } + } + + @Override + protected void onScrollChanged(int l, int t, int oldl, int oldt) { + super.onScrollChanged(l, t, oldl, oldt); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + if (isInEditMode() || tabCount == 0) { + return; + } + + final int height = getHeight(); + + rectPaint.setColor(underlineColor); + canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint); + + View currentTab = tabsContainer.getChildAt(currentPosition); + float lineLeft = 0; + float lineRight = 0; + if (currentTab != null) { + lineLeft = currentTab.getLeft(); + lineRight = currentTab.getRight(); + } + + rectPaint.setColor(indicatorColor); + canvas.drawRect(lineLeft, 0, lineRight, height, rectPaint); + } + + public void onPageScrolled(int position, int positionOffsetPixels) { + if (currentPosition == position) { + return; + } + currentPosition = position; + if (position >= tabsContainer.getChildCount()) { + return; + } + for (int a = 0; a < tabsContainer.getChildCount(); a++) { + tabsContainer.getChildAt(a).setSelected(a == position); + } + scrollToChild(position); + invalidate(); + } + + public void setIndicatorColor(int indicatorColor) { + this.indicatorColor = indicatorColor; + invalidate(); + } + + public void setUnderlineColor(int underlineColor) { + this.underlineColor = underlineColor; + invalidate(); + } + + public void setUnderlineColorResource(int resId) { + this.underlineColor = getResources().getColor(resId); + invalidate(); + } + + public void setUnderlineHeight(int underlineHeightPx) { + this.underlineHeight = underlineHeightPx; + invalidate(); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayout.java index 864e9e1ea..031f887ba 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayout.java @@ -8,7 +8,6 @@ package org.telegram.ui.Components; -import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; @@ -25,23 +24,18 @@ public class SizeNotifierFrameLayout extends FrameLayout { private Rect rect = new Rect(); private Drawable backgroundDrawable; private int keyboardHeight; - private SizeNotifierRelativeLayout.SizeNotifierRelativeLayoutDelegate delegate; + private int bottomClip; + private SizeNotifierFrameLayoutDelegate delegate; + + public interface SizeNotifierFrameLayoutDelegate { + void onSizeChanged(int keyboardHeight, boolean isWidthGreater); + } public SizeNotifierFrameLayout(Context context) { super(context); setWillNotDraw(false); } - public SizeNotifierFrameLayout(Context context, android.util.AttributeSet attrs) { - super(context, attrs); - setWillNotDraw(false); - } - - public SizeNotifierFrameLayout(Context context, android.util.AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - setWillNotDraw(false); - } - public void setBackgroundImage(int resourceId) { try { backgroundDrawable = getResources().getDrawable(resourceId); @@ -58,23 +52,26 @@ public class SizeNotifierFrameLayout extends FrameLayout { return backgroundDrawable; } - public void setDelegate(SizeNotifierRelativeLayout.SizeNotifierRelativeLayoutDelegate delegate) { + public void setDelegate(SizeNotifierFrameLayoutDelegate delegate) { this.delegate = delegate; } - @SuppressLint("DrawAllocation") @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); notifyHeightChanged(); } + public int getKeyboardHeight() { + View rootView = getRootView(); + getWindowVisibleDisplayFrame(rect); + int usableViewHeight = rootView.getHeight() - (rect.top != 0 ? AndroidUtilities.statusBarHeight : 0) - AndroidUtilities.getViewInset(rootView); + return usableViewHeight - (rect.bottom - rect.top); + } + public void notifyHeightChanged() { if (delegate != null) { - View rootView = this.getRootView(); - int usableViewHeight = rootView.getHeight() - AndroidUtilities.statusBarHeight - AndroidUtilities.getViewInset(rootView); - this.getWindowVisibleDisplayFrame(rect); - keyboardHeight = usableViewHeight - (rect.bottom - rect.top); + keyboardHeight = getKeyboardHeight(); final boolean isWidthGreater = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y; post(new Runnable() { @Override @@ -87,12 +84,23 @@ public class SizeNotifierFrameLayout extends FrameLayout { } } + public void setBottomClip(int value) { + bottomClip = value; + } + @Override protected void onDraw(Canvas canvas) { if (backgroundDrawable != null) { if (backgroundDrawable instanceof ColorDrawable) { + if (bottomClip != 0) { + canvas.save(); + canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight() - bottomClip); + } backgroundDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight()); backgroundDrawable.draw(canvas); + if (bottomClip != 0) { + canvas.restore(); + } } else { float scaleX = (float) getMeasuredWidth() / (float) backgroundDrawable.getIntrinsicWidth(); float scaleY = (float) (getMeasuredHeight() + keyboardHeight) / (float) backgroundDrawable.getIntrinsicHeight(); @@ -101,8 +109,15 @@ public class SizeNotifierFrameLayout extends FrameLayout { int height = (int) Math.ceil(backgroundDrawable.getIntrinsicHeight() * scale); int x = (getMeasuredWidth() - width) / 2; int y = (getMeasuredHeight() - height + keyboardHeight) / 2; + if (bottomClip != 0) { + canvas.save(); + canvas.clipRect(0, 0, width, getMeasuredHeight() - bottomClip); + } backgroundDrawable.setBounds(x, y, x + width, y + height); backgroundDrawable.draw(canvas); + if (bottomClip != 0) { + canvas.restore(); + } } } else { super.onDraw(canvas); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayoutPhoto.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayoutPhoto.java similarity index 61% rename from TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayoutPhoto.java rename to TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayoutPhoto.java index ef2d6055e..8ee9f9611 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayoutPhoto.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierFrameLayoutPhoto.java @@ -8,42 +8,47 @@ package org.telegram.ui.Components; -import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Rect; import android.view.View; -import android.widget.RelativeLayout; +import android.widget.FrameLayout; import org.telegram.android.AndroidUtilities; -public class SizeNotifierRelativeLayoutPhoto extends RelativeLayout { - - public interface SizeNotifierRelativeLayoutPhotoDelegate { - void onSizeChanged(int keyboardHeight, boolean isWidthGreater); - } +public class SizeNotifierFrameLayoutPhoto extends FrameLayout { private Rect rect = new Rect(); private int keyboardHeight; - private SizeNotifierRelativeLayoutPhotoDelegate delegate; + private SizeNotifierFrameLayoutPhotoDelegate delegate; - public SizeNotifierRelativeLayoutPhoto(Context context) { + public interface SizeNotifierFrameLayoutPhotoDelegate { + void onSizeChanged(int keyboardHeight, boolean isWidthGreater); + } + + public SizeNotifierFrameLayoutPhoto(Context context) { super(context); } - public void setDelegate(SizeNotifierRelativeLayoutPhotoDelegate delegate) { + public void setDelegate(SizeNotifierFrameLayoutPhotoDelegate delegate) { this.delegate = delegate; } - @SuppressLint("DrawAllocation") @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); + notifyHeightChanged(); + } + public int getKeyboardHeight() { + View rootView = getRootView(); + int usableViewHeight = rootView.getHeight() - AndroidUtilities.getViewInset(rootView); + getWindowVisibleDisplayFrame(rect); + return (rect.bottom - rect.top) - usableViewHeight; + } + + public void notifyHeightChanged() { if (delegate != null) { - View rootView = this.getRootView(); - int usableViewHeight = rootView.getHeight() - AndroidUtilities.getViewInset(rootView); - this.getWindowVisibleDisplayFrame(rect); - keyboardHeight = (rect.bottom - rect.top) - usableViewHeight; + keyboardHeight = getKeyboardHeight(); final boolean isWidthGreater = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y; post(new Runnable() { @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayout.java deleted file mode 100644 index 8802e8505..000000000 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayout.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * This is the source code of Telegram for Android v. 1.3.2. - * 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. - */ - -package org.telegram.ui.Components; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Rect; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.view.View; -import android.widget.RelativeLayout; - -import org.telegram.android.AndroidUtilities; -import org.telegram.messenger.FileLog; - -public class SizeNotifierRelativeLayout extends RelativeLayout { - - private Rect rect = new Rect(); - private Drawable backgroundDrawable; - private int keyboardHeight; - private SizeNotifierRelativeLayoutDelegate delegate; - - public interface SizeNotifierRelativeLayoutDelegate { - void onSizeChanged(int keyboardHeight, boolean isWidthGreater); - } - - public SizeNotifierRelativeLayout(Context context) { - super(context); - setWillNotDraw(false); - } - - public SizeNotifierRelativeLayout(android.content.Context context, android.util.AttributeSet attrs) { - super(context, attrs); - setWillNotDraw(false); - } - - public SizeNotifierRelativeLayout(android.content.Context context, android.util.AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - setWillNotDraw(false); - } - - public void setBackgroundImage(int resourceId) { - try { - backgroundDrawable = getResources().getDrawable(resourceId); - } catch (Throwable e) { - FileLog.e("tmessages", e); - } - } - - public void setBackgroundImage(Drawable bitmap) { - backgroundDrawable = bitmap; - } - - public Drawable getBackgroundImage() { - return backgroundDrawable; - } - - public void setDelegate(SizeNotifierRelativeLayoutDelegate delegate) { - this.delegate = delegate; - } - - @SuppressLint("DrawAllocation") - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - super.onLayout(changed, l, t, r, b); - - if (delegate != null) { - View rootView = this.getRootView(); - int usableViewHeight = rootView.getHeight() - AndroidUtilities.statusBarHeight - AndroidUtilities.getViewInset(rootView); - this.getWindowVisibleDisplayFrame(rect); - keyboardHeight = usableViewHeight - (rect.bottom - rect.top); - final boolean isWidthGreater = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y; - post(new Runnable() { - @Override - public void run() { - if (delegate != null) { - delegate.onSizeChanged(keyboardHeight, isWidthGreater); - } - } - }); - } - } - - @Override - protected void onDraw(Canvas canvas) { - 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/StickersAlert.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/StickersAlert.java index 49ace5b72..5e2d9d2b2 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/StickersAlert.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/StickersAlert.java @@ -19,9 +19,7 @@ import android.widget.FrameLayout; import android.widget.GridView; import org.telegram.android.AndroidUtilities; -import org.telegram.android.LocaleController; import org.telegram.android.NotificationCenter; -import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.ui.Cells.StickerEmojiCell; @@ -32,9 +30,9 @@ public class StickersAlert extends AlertDialog implements NotificationCenter.Not private ArrayList stickers; private GridView gridView; - public StickersAlert(Context context, TLRPC.TL_stickerSet set, ArrayList arrayList) { + public StickersAlert(Context context, TLRPC.TL_messages_stickerSet set) { super(context); - stickers = arrayList; + stickers = set.documents; FrameLayout container = new FrameLayout(context) { @Override @@ -50,11 +48,7 @@ public class StickersAlert extends AlertDialog implements NotificationCenter.Not gridView.setVerticalScrollBarEnabled(false); container.addView(gridView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); - if (set.id == -1) { - setTitle(LocaleController.getString("GeniusStickerPackName", R.string.GeniusStickerPackName)); - } else { - setTitle(set.title); - } + setTitle(set.set.title); NotificationCenter.getInstance().addObserver(this, NotificationCenter.emojiDidLoaded); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/WebFrameLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/WebFrameLayout.java index 7d597cce6..d794f29db 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/WebFrameLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/WebFrameLayout.java @@ -33,6 +33,7 @@ import android.widget.Toast; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; import org.telegram.messenger.ApplicationLoader; +import org.telegram.messenger.FileLog; import org.telegram.messenger.R; import org.telegram.ui.ActionBar.BottomSheet; @@ -106,13 +107,17 @@ public class WebFrameLayout extends FrameLayout { textView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - if (Build.VERSION.SDK_INT < 11) { - android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); - clipboard.setText(openUrl); - } else { - android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); - android.content.ClipData clip = android.content.ClipData.newPlainText("label", openUrl); - clipboard.setPrimaryClip(clip); + try { + if (Build.VERSION.SDK_INT < 11) { + android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); + clipboard.setText(openUrl); + } else { + android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); + android.content.ClipData clip = android.content.ClipData.newPlainText("label", openUrl); + clipboard.setPrimaryClip(clip); + } + } catch (Exception e) { + FileLog.e("tmessages", e); } Toast.makeText(getContext(), LocaleController.getString("LinkCopied", R.string.LinkCopied), Toast.LENGTH_SHORT).show(); if (dialog != null) { @@ -127,6 +132,7 @@ public class WebFrameLayout extends FrameLayout { webView = new WebView(context); webView.getSettings().setJavaScriptEnabled(true); + webView.getSettings().setDomStorageEnabled(true); String userAgent = webView.getSettings().getUserAgentString(); if (userAgent != null) { userAgent = userAgent.replace("Android", ""); @@ -205,11 +211,20 @@ public class WebFrameLayout extends FrameLayout { }); parentDialog.setDelegate(new BottomSheet.BottomSheetDelegate() { + @Override + public void onOpenAnimationStart() { + + } + @Override public void onOpenAnimationEnd() { HashMap args = new HashMap<>(); args.put("Referer", "http://youtube.com"); - webView.loadUrl(url, args); + try { + webView.loadUrl(url, args); + } catch (Exception e) { + FileLog.e("tmessages", e); + } } }); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java index 99a4b4475..6a6695aeb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java @@ -15,7 +15,9 @@ import android.content.Intent; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.text.Editable; import android.text.InputType; +import android.text.TextWatcher; import android.util.TypedValue; import android.view.Gravity; import android.view.LayoutInflater; @@ -30,17 +32,20 @@ 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.MessagesStorage; import org.telegram.android.SecretChatHelper; +import org.telegram.android.UserObject; import org.telegram.messenger.TLRPC; import org.telegram.android.ContactsController; import org.telegram.messenger.FileLog; import org.telegram.android.MessagesController; import org.telegram.android.NotificationCenter; import org.telegram.messenger.R; +import org.telegram.messenger.Utilities; import org.telegram.ui.Adapters.BaseSectionsAdapter; import org.telegram.ui.Adapters.ContactsAdapter; import org.telegram.ui.Adapters.SearchAdapter; @@ -158,7 +163,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter } @Override - public boolean onSearchCollapse() { + public void onSearchCollapse() { searchListViewAdapter.searchDialogs(null); searching = false; searchWas = false; @@ -170,7 +175,6 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter listView.setFastScrollEnabled(true); listView.setVerticalScrollBarEnabled(false); emptyTextView.setText(LocaleController.getString("NoContacts", R.string.NoContacts)); - return true; } @Override @@ -407,36 +411,87 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter if (getParentActivity() == null) { return; } + if ((user.flags & TLRPC.USER_FLAG_BOT) != 0 && (user.flags & TLRPC.USER_FLAG_BOT_CANT_JOIN_GROUP) != 0) { + try { + Toast.makeText(getParentActivity(), LocaleController.getString("BotCantJoinGroups", R.string.BotCantJoinGroups), Toast.LENGTH_SHORT).show(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + return; + } AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setMessage(LocaleController.formatStringSimple(selectAlertString, ContactsController.formatName(user.first_name, user.last_name))); - final EditText editText = new EditText(getParentActivity()); - if (android.os.Build.VERSION.SDK_INT < 11) { - editText.setBackgroundResource(android.R.drawable.editbox_background_normal); + String message = LocaleController.formatStringSimple(selectAlertString, UserObject.getUserName(user)); + EditText editText = null; + if ((user.flags & TLRPC.USER_FLAG_BOT) == 0) { + message = String.format("%s\n\n%s", message, LocaleController.getString("AddToTheGroupForwardCount", R.string.AddToTheGroupForwardCount)); + editText = new EditText(getParentActivity()); + if (android.os.Build.VERSION.SDK_INT < 11) { + editText.setBackgroundResource(android.R.drawable.editbox_background_normal); + } + editText.setTextSize(18); + editText.setText("50"); + editText.setGravity(Gravity.CENTER); + editText.setInputType(InputType.TYPE_CLASS_NUMBER); + editText.setImeOptions(EditorInfo.IME_ACTION_DONE); + final EditText editTextFinal = editText; + editText.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) { + try { + String str = s.toString(); + if (str.length() != 0) { + int value = Utilities.parseInt(str); + if (value < 0) { + editTextFinal.setText("0"); + editTextFinal.setSelection(editTextFinal.length()); + } else if (value > 300) { + editTextFinal.setText("300"); + editTextFinal.setSelection(editTextFinal.length()); + } else if (!str.equals("" + value)) { + editTextFinal.setText("" + value); + editTextFinal.setSelection(editTextFinal.length()); + } + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + + }); + builder.setView(editText); } - editText.setTextSize(18); - editText.setText("50"); - editText.setGravity(Gravity.CENTER); - editText.setInputType(InputType.TYPE_CLASS_NUMBER); - editText.setImeOptions(EditorInfo.IME_ACTION_DONE); - builder.setView(editText); + builder.setMessage(message); + final EditText finalEditText = editText; builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { - didSelectResult(user, false, editText.getText().toString()); + didSelectResult(user, false, finalEditText != null ? finalEditText.getText().toString() : "0"); } }); builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); showDialog(builder.create()); - ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams)editText.getLayoutParams(); - if (layoutParams != null) { - if (layoutParams instanceof FrameLayout.LayoutParams) { - ((FrameLayout.LayoutParams)layoutParams).gravity = Gravity.CENTER_HORIZONTAL; + if (editText != null) { + ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) editText.getLayoutParams(); + if (layoutParams != null) { + if (layoutParams instanceof FrameLayout.LayoutParams) { + ((FrameLayout.LayoutParams) layoutParams).gravity = Gravity.CENTER_HORIZONTAL; + } + layoutParams.rightMargin = layoutParams.leftMargin = AndroidUtilities.dp(10); + editText.setLayoutParams(layoutParams); } - layoutParams.rightMargin = layoutParams.leftMargin = AndroidUtilities.dp(10); - editText.setLayoutParams(layoutParams); + editText.setSelection(editText.getText().length()); } - editText.setSelection(editText.getText().length()); } else { if (delegate != null) { delegate.didSelectContact(user, param); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java index 4bc604486..3058d6912 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java @@ -84,7 +84,7 @@ public class CountrySelectActivity extends BaseFragment { } @Override - public boolean onSearchCollapse() { + public void onSearchCollapse() { searchListViewAdapter.search(null); searching = false; searchWas = false; @@ -96,8 +96,6 @@ public class CountrySelectActivity extends BaseFragment { listView.setVerticalScrollBarEnabled(false); emptyTextView.setText(LocaleController.getString("ChooseCountry", R.string.ChooseCountry)); - - return true; } @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java index d26744043..2639f756a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java @@ -41,9 +41,9 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.LocaleController; +import org.telegram.android.UserObject; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.TLRPC; -import org.telegram.android.ContactsController; import org.telegram.messenger.FileLog; import org.telegram.android.MessagesController; import org.telegram.android.NotificationCenter; @@ -506,7 +506,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen LayoutInflater lf = (LayoutInflater) ApplicationLoader.applicationContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); View textView = lf.inflate(R.layout.group_create_bubble, null); TextView text = (TextView)textView.findViewById(R.id.bubble_text_view); - String name = ContactsController.formatName(user.first_name, user.last_name); + String name = UserObject.getUserName(user); if (name.length() == 0 && user.phone != null && user.phone.length() != 0) { name = PhoneFormat.getInstance().format("+" + user.phone); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/IdenticonActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/IdenticonActivity.java index 10181960b..fea96db4c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/IdenticonActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/IdenticonActivity.java @@ -97,12 +97,10 @@ public class IdenticonActivity extends BaseFragment { obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { - if (fragmentView != null) { - fragmentView.getViewTreeObserver().removeOnPreDrawListener(this); - } - if (getParentActivity() == null || fragmentView == null) { + if (fragmentView == null) { return true; } + fragmentView.getViewTreeObserver().removeOnPreDrawListener(this); LinearLayout layout = (LinearLayout)fragmentView; WindowManager manager = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE); int rotation = manager.getDefaultDisplay().getRotation(); @@ -114,7 +112,7 @@ public class IdenticonActivity extends BaseFragment { } fragmentView.setPadding(fragmentView.getPaddingLeft(), 0, fragmentView.getPaddingRight(), fragmentView.getPaddingBottom()); - return false; + return true; } }); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java index f7f1bd2d1..96fc7648f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LanguageSelectActivity.java @@ -78,7 +78,7 @@ public class LanguageSelectActivity extends BaseFragment { } @Override - public boolean onSearchCollapse() { + public void onSearchCollapse() { search(null); searching = false; searchWas = false; @@ -86,8 +86,6 @@ public class LanguageSelectActivity extends BaseFragment { emptyTextView.setVisibility(View.GONE); listView.setAdapter(listAdapter); } - - return true; } @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java index 42abf382a..e77c865dc 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java @@ -45,6 +45,7 @@ import org.telegram.android.ContactsController; import org.telegram.android.MessagesController; import org.telegram.android.MessagesStorage; import org.telegram.android.SendMessagesHelper; +import org.telegram.android.UserObject; import org.telegram.android.query.StickersQuery; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; @@ -70,6 +71,7 @@ import java.util.ArrayList; import java.util.Map; public class LaunchActivity extends Activity implements ActionBarLayout.ActionBarLayoutDelegate, NotificationCenter.NotificationCenterDelegate, MessagesActivity.MessagesActivityDelegate { + private boolean finished; private String videoPath; private String sendingText; @@ -414,6 +416,10 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa drawerLayoutContainer.setAllowOpenDrawer(allowOpen, false); } + /*if (BuildVars.DEBUG_VERSION) { + ViewServer.get(this).addWindow(this); + }*/ + handleIntent(getIntent(), false, savedInstanceState != null, false); needLayout(); } @@ -543,7 +549,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa if (name != null && !phones.isEmpty()) { contactsToSend = new ArrayList<>(); for (String phone : phones) { - TLRPC.User user = new TLRPC.TL_userContact(); + TLRPC.User user = new TLRPC.TL_userContact_old2(); user.phone = phone; user.first_name = name; user.last_name = ""; @@ -571,9 +577,6 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa text = subject + "\n" + text; } sendingText = text; - if (sendingText.contains("WhatsApp")) { //who needs this sent from ...? - sendingText = null; - } } else { error = true; } @@ -615,6 +618,11 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa documentsMimeType = type; } } + if (sendingText != null) { + if (sendingText.contains("WhatsApp")) { //who needs this sent from ...? + sendingText = null; + } + } } else if (sendingText == null) { error = true; } @@ -678,6 +686,8 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa String username = null; String group = null; String sticker = null; + String botUser = null; + String botChat = null; String scheme = data.getScheme(); if (scheme != null) { if ((scheme.equals("http") || scheme.equals("https"))) { @@ -691,7 +701,9 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } else if (path.startsWith("addstickers/")) { sticker = path.replace("addstickers/", ""); } else { - username = path; + username = data.getLastPathSegment(); + botUser = data.getQueryParameter("start"); + botChat = data.getQueryParameter("startgroup"); } } } @@ -701,6 +713,8 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa url = url.replace("tg:resolve", "tg://telegram.org").replace("tg://resolve", "tg://telegram.org"); data = Uri.parse(url); username = data.getQueryParameter("domain"); + botUser = data.getQueryParameter("start"); + botChat = data.getQueryParameter("startgroup"); } else if (url.startsWith("tg:join") || url.startsWith("tg://join")) { url = url.replace("tg:join", "tg://telegram.org").replace("tg://join", "tg://telegram.org"); data = Uri.parse(url); @@ -713,7 +727,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } } if (username != null || group != null || sticker != null) { - runLinkRequest(username, group, sticker, 0); + runLinkRequest(username, group, sticker, botUser, botChat, 0); } else { try { Cursor cursor = getContentResolver().query(intent.getData(), null, null, null, null); @@ -865,7 +879,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa return false; } - private void runLinkRequest(final String username, final String group, final String sticker, final int state) { + private void runLinkRequest(final String username, final String group, final String sticker, final String botUser, final String botChat, final int state) { final ProgressDialog progressDialog = new ProgressDialog(this); progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading)); progressDialog.setCanceledOnTouchOutside(false); @@ -888,16 +902,53 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa FileLog.e("tmessages", e); } if (error == null && actionBarLayout != null) { - TLRPC.User user = (TLRPC.User) response; + final 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); + if (botChat != null) { + if ((user.flags & TLRPC.USER_FLAG_BOT) != 0 && (user.flags & TLRPC.USER_FLAG_BOT_CANT_JOIN_GROUP) != 0) { + try { + Toast.makeText(LaunchActivity.this, LocaleController.getString("BotCantJoinGroups", R.string.BotCantJoinGroups), Toast.LENGTH_SHORT).show(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + return; + } + Bundle args = new Bundle(); + args.putBoolean("onlySelect", true); + args.putInt("dialogsType", 2); + args.putString("addToGroupAlertString", LocaleController.formatString("AddToTheGroupTitle", R.string.AddToTheGroupTitle, UserObject.getUserName(user), "%1$s")); + MessagesActivity fragment = new MessagesActivity(args); + fragment.setDelegate(new MessagesActivity.MessagesActivityDelegate() { + @Override + public void didSelectDialog(MessagesActivity fragment, long did, boolean param) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); + MessagesController.getInstance().addUserToChat(-(int) did, user, null, 0, botChat); + Bundle args = new Bundle(); + args.putBoolean("scrollToTopOnResume", true); + args.putInt("chat_id", -(int) did); + actionBarLayout.presentFragment(new ChatActivity(args), true, false, true); + } + }); + presentFragment(fragment); + } else { + Bundle args = new Bundle(); + args.putInt("user_id", user.id); + if (botUser != null) { + args.putString("botUser", botUser); + } + ChatActivity fragment = new ChatActivity(args); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); + actionBarLayout.presentFragment(fragment, false, true, true); + } + } else { + try { + Toast.makeText(LaunchActivity.this, LocaleController.getString("NoUsernameFound", R.string.NoUsernameFound), Toast.LENGTH_SHORT).show(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } } } } @@ -939,7 +990,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { - runLinkRequest(username, group, sticker, 1); + runLinkRequest(username, group, sticker, botUser, botChat, 1); } }); builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); @@ -1107,12 +1158,13 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa SendMessagesHelper.prepareSendingVideo(videoPath, 0, 0, 0, 0, null, dialog_id, null); } } else { + + actionBarLayout.presentFragment(fragment, true); + if (sendingText != null) { SendMessagesHelper.prepareSendingText(sendingText, dialog_id); } - actionBarLayout.presentFragment(fragment, true); - if (photoPathsArray != null) { SendMessagesHelper.prepareSendingPhotos(null, photoPathsArray, dialog_id, null, null); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java index b275de811..9907ecccb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java @@ -24,6 +24,7 @@ import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.view.WindowManager; import android.widget.AbsListView; @@ -47,7 +48,7 @@ import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MarkerOptions; import org.telegram.android.AndroidUtilities; -import org.telegram.android.ContactsController; +import org.telegram.android.UserObject; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLog; import org.telegram.android.LocaleController; @@ -212,7 +213,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter } @Override - public boolean onSearchCollapse() { + public void onSearchCollapse() { searching = false; searchWas = false; searchListView.setEmptyView(null); @@ -221,7 +222,6 @@ public class LocationActivity extends BaseFragment implements NotificationCenter searchListView.setVisibility(View.GONE); emptyTextLayout.setVisibility(View.GONE); searchAdapter.searchDelayed(null, null); - return true; } @Override @@ -618,6 +618,14 @@ public class LocationActivity extends BaseFragment implements NotificationCenter @Override public void onOpenAnimationEnd() { + try { + if (mapView.getParent() instanceof ViewGroup) { + ViewGroup viewGroup = (ViewGroup) mapView.getParent(); + viewGroup.removeView(mapView); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } if (mapViewClip != null) { mapViewClip.addView(mapView, 0, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, overScrollHeight + AndroidUtilities.dp(10), Gravity.TOP | Gravity.LEFT)); updateClipView(listView.getFirstVisiblePosition()); @@ -759,7 +767,7 @@ public class LocationActivity extends BaseFragment implements NotificationCenter photo = user.photo.photo_small; } avatarImageView.setImage(photo, null, new AvatarDrawable(user)); - nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name)); + nameTextView.setText(UserObject.getUserName(user)); } else { avatarImageView.setImageDrawable(null); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java index 2ae84cf47..dfe8b5867 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java @@ -631,7 +631,7 @@ public class LoginActivity extends BaseFragment { }); textView = new TextView(context); - textView.setText(LocaleController.getString("ChangePhoneHelp", R.string.ChangePhoneHelp)); + textView.setText(LocaleController.getString("StartText", R.string.StartText)); textView.setTextColor(0xff757575); textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); textView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); @@ -2137,14 +2137,13 @@ public class LoginActivity extends BaseFragment { needHideProgress(); if (error == null) { final TLRPC.TL_auth_authorization res = (TLRPC.TL_auth_authorization) response; - TLRPC.TL_userSelf user = (TLRPC.TL_userSelf) res.user; UserConfig.clearConfig(); MessagesController.getInstance().cleanUp(); - UserConfig.setCurrentUser(user); + UserConfig.setCurrentUser(res.user); UserConfig.saveConfig(true); MessagesStorage.getInstance().cleanUp(true); ArrayList users = new ArrayList<>(); - users.add(user); + users.add(res.user); MessagesStorage.getInstance().putUsersAndChats(users, null, true, true); //MessagesController.getInstance().uploadAndApplyUserAvatar(avatarPhotoBig); MessagesController.getInstance().putUser(res.user, false); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java index cc14a0e98..fb10c8d0e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java @@ -283,7 +283,7 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No } else if (id == forward) { Bundle args = new Bundle(); args.putBoolean("onlySelect", true); - args.putBoolean("serverOnly", true); + args.putInt("dialogsType", 1); MessagesActivity fragment = new MessagesActivity(args); fragment.setDelegate(new MessagesActivity.MessagesActivityDelegate() { @Override @@ -346,14 +346,12 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No } @Override - public boolean onSearchCollapse() { + public void onSearchCollapse() { dropDownContainer.setVisibility(View.VISIBLE); documentsSearchAdapter.searchDocuments(null); searching = false; searchWas = false; switchToCurrentSelectedMode(); - - return true; } @Override @@ -702,7 +700,7 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No public boolean onPreDraw() { listView.getViewTreeObserver().removeOnPreDrawListener(this); fixLayoutInternal(); - return false; + return true; } }); } @@ -1246,7 +1244,10 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No req.peer.chat_id = -uid; } else { TLRPC.User user = MessagesController.getInstance().getUser(uid); - if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { + if (user == null) { + return; + } + if (user.access_hash != 0) { req.peer = new TLRPC.TL_inputPeerForeign(); req.peer.access_hash = user.access_hash; } else { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java index ed15ce845..53ec757da 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java @@ -37,6 +37,7 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.android.LocaleController; import org.telegram.android.MessageObject; +import org.telegram.android.UserObject; import org.telegram.android.support.widget.LinearLayoutManager; import org.telegram.android.support.widget.RecyclerView; import org.telegram.messenger.FileLog; @@ -86,7 +87,8 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter private String selectAlertString; private String selectAlertStringGroup; - private boolean serverOnly; + private String addToGroupAlertString; + private int dialogsType; private static boolean dialogsLoaded; private boolean searching; @@ -112,9 +114,10 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter if (getArguments() != null) { onlySelect = arguments.getBoolean("onlySelect", false); - serverOnly = arguments.getBoolean("serverOnly", false); + dialogsType = arguments.getInt("dialogsType", 0); selectAlertString = arguments.getString("selectAlertString"); selectAlertStringGroup = arguments.getString("selectAlertStringGroup"); + addToGroupAlertString = arguments.getString("addToGroupAlertString"); } if (searchString == null) { @@ -180,8 +183,8 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter if (listView != null) { if (searchString != null) { listView.setEmptyView(searchEmptyView); - progressView.setVisibility(View.INVISIBLE); - emptyView.setVisibility(View.INVISIBLE); + progressView.setVisibility(View.GONE); + emptyView.setVisibility(View.GONE); } if (!onlySelect) { floatingButton.setVisibility(View.GONE); @@ -191,20 +194,25 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter } @Override - public boolean onSearchCollapse() { + public boolean canCollapseSearch() { if (searchString != null) { finishFragment(); return false; } + return true; + } + + @Override + public void onSearchCollapse() { searching = false; searchWas = false; if (listView != null) { - searchEmptyView.setVisibility(View.INVISIBLE); + searchEmptyView.setVisibility(View.GONE); if (MessagesController.getInstance().loadingDialogs && MessagesController.getInstance().dialogs.isEmpty()) { - emptyView.setVisibility(View.INVISIBLE); + emptyView.setVisibility(View.GONE); listView.setEmptyView(progressView); } else { - progressView.setVisibility(View.INVISIBLE); + progressView.setVisibility(View.GONE); listView.setEmptyView(emptyView); } if (!onlySelect) { @@ -219,10 +227,9 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter } } if (dialogsSearchAdapter != null) { - dialogsSearchAdapter.searchDialogs(null, false); + dialogsSearchAdapter.searchDialogs(null, dialogsType); } updatePasscodeButton(); - return true; } @Override @@ -235,14 +242,14 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter dialogsSearchAdapter.notifyDataSetChanged(); } if (searchEmptyView != null && listView.getEmptyView() != searchEmptyView) { - emptyView.setVisibility(View.INVISIBLE); - progressView.setVisibility(View.INVISIBLE); + emptyView.setVisibility(View.GONE); + progressView.setVisibility(View.GONE); searchEmptyView.showTextView(); listView.setEmptyView(searchEmptyView); } } if (dialogsSearchAdapter != null) { - dialogsSearchAdapter.searchDialogs(text, serverOnly); + dialogsSearchAdapter.searchDialogs(text, dialogsType); } } }); @@ -372,7 +379,7 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter } } if (AndroidUtilities.isTablet()) { - if (openedDialogId == dialog_id) { + if (openedDialogId == dialog_id && adapter != dialogsSearchAdapter) { return; } if (dialogsAdapter != null) { @@ -416,17 +423,11 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter return; } TLRPC.TL_dialog dialog; - if (serverOnly) { - if (position < 0 || position >= MessagesController.getInstance().dialogsServerOnly.size()) { - return; - } - dialog = MessagesController.getInstance().dialogsServerOnly.get(position); - } else { - if (position < 0 || position >= MessagesController.getInstance().dialogs.size()) { - return; - } - dialog = MessagesController.getInstance().dialogs.get(position); + ArrayList dialogs = getDialogsArray(); + if (position < 0 || position >= dialogs.size()) { + return; } + dialog = dialogs.get(position); selectedDialog = dialog.id; /*AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); @@ -487,14 +488,14 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter }); searchEmptyView = new EmptyTextProgressView(context); - searchEmptyView.setVisibility(View.INVISIBLE); + searchEmptyView.setVisibility(View.GONE); searchEmptyView.setShowAtCenter(true); searchEmptyView.setText(LocaleController.getString("NoResult", R.string.NoResult)); frameLayout.addView(searchEmptyView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); emptyView = new LinearLayout(context); emptyView.setOrientation(LinearLayout.VERTICAL); - emptyView.setVisibility(View.INVISIBLE); + emptyView.setVisibility(View.GONE); emptyView.setGravity(Gravity.CENTER); frameLayout.addView(emptyView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); emptyView.setOnTouchListener(new View.OnTouchListener() { @@ -525,7 +526,7 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter emptyView.addView(textView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT)); progressView = new ProgressBar(context); - progressView.setVisibility(View.INVISIBLE); + progressView.setVisibility(View.GONE); frameLayout.addView(progressView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER)); floatingButton = new ImageView(context); @@ -577,7 +578,7 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter return; } if (visibleItemCount > 0) { - if (layoutManager.findLastVisibleItemPosition() == MessagesController.getInstance().dialogs.size() && !serverOnly || layoutManager.findLastVisibleItemPosition() == MessagesController.getInstance().dialogsServerOnly.size() && serverOnly) { + if (layoutManager.findLastVisibleItemPosition() == getDialogsArray().size()) { MessagesController.getInstance().loadDialogs(MessagesController.getInstance().dialogs.size(), MessagesController.getInstance().dialogsServerOnly.size(), 100, true); } } @@ -608,7 +609,7 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter }); if (searchString == null) { - dialogsAdapter = new DialogsAdapter(context, serverOnly); + dialogsAdapter = new DialogsAdapter(context, dialogsType); if (AndroidUtilities.isTablet() && openedDialogId != 0) { dialogsAdapter.setOpenedDialogId(openedDialogId); } @@ -635,12 +636,12 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter }); if (MessagesController.getInstance().loadingDialogs && MessagesController.getInstance().dialogs.isEmpty()) { - searchEmptyView.setVisibility(View.INVISIBLE); - emptyView.setVisibility(View.INVISIBLE); + searchEmptyView.setVisibility(View.GONE); + emptyView.setVisibility(View.GONE); listView.setEmptyView(progressView); } else { - searchEmptyView.setVisibility(View.INVISIBLE); - progressView.setVisibility(View.INVISIBLE); + searchEmptyView.setVisibility(View.GONE); + progressView.setVisibility(View.GONE); listView.setEmptyView(emptyView); } if (searchString != null) { @@ -699,16 +700,16 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter if (listView != null) { try { if (MessagesController.getInstance().loadingDialogs && MessagesController.getInstance().dialogs.isEmpty()) { - searchEmptyView.setVisibility(View.INVISIBLE); - emptyView.setVisibility(View.INVISIBLE); + searchEmptyView.setVisibility(View.GONE); + emptyView.setVisibility(View.GONE); listView.setEmptyView(progressView); } else { - progressView.setVisibility(View.INVISIBLE); + progressView.setVisibility(View.GONE); if (searching && searchWas) { - emptyView.setVisibility(View.INVISIBLE); + emptyView.setVisibility(View.GONE); listView.setEmptyView(searchEmptyView); } else { - searchEmptyView.setVisibility(View.INVISIBLE); + searchEmptyView.setVisibility(View.GONE); listView.setEmptyView(emptyView); } } @@ -729,7 +730,7 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter } else if (id == NotificationCenter.contactsDidLoaded) { updateVisibleRows(0); } else if (id == NotificationCenter.openedChatChanged) { - if (!serverOnly && AndroidUtilities.isTablet()) { + if (dialogsType == 0 && AndroidUtilities.isTablet()) { boolean close = (Boolean) args[1]; long dialog_id = (Long) args[0]; if (close) { @@ -753,6 +754,17 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter } } + private ArrayList getDialogsArray() { + if (dialogsType == 0) { + return MessagesController.getInstance().dialogs; + } else if (dialogsType == 1) { + return MessagesController.getInstance().dialogsServerOnly; + } else if (dialogsType == 2) { + return MessagesController.getInstance().dialogsGroupsOnly; + } + return null; + } + private void updatePasscodeButton() { if (passcodeItem == null) { return; @@ -788,18 +800,20 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter for (int a = 0; a < count; a++) { View child = listView.getChildAt(a); if (child instanceof DialogCell) { - DialogCell cell = (DialogCell) child; - if ((mask & MessagesController.UPDATE_MASK_NEW_MESSAGE) != 0) { - cell.checkCurrentDialogIndex(); - if (!serverOnly && AndroidUtilities.isTablet()) { - cell.setDialogSelected(cell.getDialogId() == openedDialogId); + if (listView.getAdapter() != dialogsSearchAdapter) { + DialogCell cell = (DialogCell) child; + if ((mask & MessagesController.UPDATE_MASK_NEW_MESSAGE) != 0) { + cell.checkCurrentDialogIndex(); + if (dialogsType == 0 && AndroidUtilities.isTablet()) { + cell.setDialogSelected(cell.getDialogId() == openedDialogId); + } + } else if ((mask & MessagesController.UPDATE_MASK_SELECT_DIALOG) != 0) { + if (dialogsType == 0 && AndroidUtilities.isTablet()) { + cell.setDialogSelected(cell.getDialogId() == openedDialogId); + } + } else { + cell.update(mask); } - } else if ((mask & MessagesController.UPDATE_MASK_SELECT_DIALOG) != 0) { - if (!serverOnly && AndroidUtilities.isTablet()) { - cell.setDialogSelected(cell.getDialogId() == openedDialogId); - } - } else { - cell.update(mask); } } else if (child instanceof UserCell) { ((UserCell) child).update(mask); @@ -820,7 +834,7 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter } private void didSelectResult(final long dialog_id, boolean useAlert, final boolean param) { - if (useAlert && selectAlertString != null && selectAlertStringGroup != null) { + if (useAlert && (selectAlertString != null && selectAlertStringGroup != null || addToGroupAlertString != null)) { if (getParentActivity() == null) { return; } @@ -841,13 +855,17 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter if (user == null) { return; } - builder.setMessage(LocaleController.formatStringSimple(selectAlertString, ContactsController.formatName(user.first_name, user.last_name))); + builder.setMessage(LocaleController.formatStringSimple(selectAlertString, UserObject.getUserName(user))); } else if (lower_part < 0) { TLRPC.Chat chat = MessagesController.getInstance().getChat(-lower_part); if (chat == null) { return; } - builder.setMessage(LocaleController.formatStringSimple(selectAlertStringGroup, chat.title)); + if (addToGroupAlertString != null) { + builder.setMessage(LocaleController.formatStringSimple(addToGroupAlertString, chat.title)); + } else { + builder.setMessage(LocaleController.formatStringSimple(selectAlertStringGroup, chat.title)); + } } } } else { @@ -856,7 +874,7 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter if (user == null) { return; } - builder.setMessage(LocaleController.formatStringSimple(selectAlertString, ContactsController.formatName(user.first_name, user.last_name))); + builder.setMessage(LocaleController.formatStringSimple(selectAlertString, UserObject.getUserName(user))); } builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/NotificationsSettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/NotificationsSettingsActivity.java index a6d162c9a..a2ad12143 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/NotificationsSettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/NotificationsSettingsActivity.java @@ -89,6 +89,7 @@ public class NotificationsSettingsActivity extends BaseFragment implements Notif private int otherSectionRow; private int badgeNumberRow; private int pebbleAlertRow; + private int androidAutoAlertRow; private int repeatRow; private int resetSectionRow2; private int resetSectionRow; @@ -141,6 +142,7 @@ public class NotificationsSettingsActivity extends BaseFragment implements Notif otherSectionRow2 = rowCount++; otherSectionRow = rowCount++; badgeNumberRow = rowCount++; + androidAutoAlertRow = -1; pebbleAlertRow = rowCount++; repeatRow = rowCount++; resetSectionRow2 = rowCount++; @@ -325,6 +327,12 @@ public class NotificationsSettingsActivity extends BaseFragment implements Notif enabled = preferences.getBoolean("EnablePebbleNotifications", false); editor.putBoolean("EnablePebbleNotifications", !enabled); editor.commit(); + } else if (i == androidAutoAlertRow) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + enabled = preferences.getBoolean("EnableAutoNotifications", false); + editor.putBoolean("EnableAutoNotifications", !enabled); + editor.commit(); } else if (i == badgeNumberRow) { SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); @@ -702,6 +710,8 @@ public class NotificationsSettingsActivity extends BaseFragment implements Notif checkCell.setTextAndCheck(LocaleController.getString("ContactJoined", R.string.ContactJoined), preferences.getBoolean("EnableContactJoined", true), false); } else if (i == pebbleAlertRow) { checkCell.setTextAndCheck(LocaleController.getString("Pebble", R.string.Pebble), preferences.getBoolean("EnablePebbleNotifications", false), true); + } else if (i == androidAutoAlertRow) { + checkCell.setTextAndCheck("Android Auto", preferences.getBoolean("EnableAutoNotifications", false), true); } else if (i == notificationsServiceRow) { checkCell.setTextAndCheck(LocaleController.getString("NotificationsService", R.string.NotificationsService), preferences.getBoolean("pushService", true), false); } else if (i == badgeNumberRow) { @@ -829,7 +839,7 @@ public class NotificationsSettingsActivity extends BaseFragment implements Notif i == groupPreviewRow || i == inappSoundRow || i == inappVibrateRow || i == inappPreviewRow || i == contactJoinedRow || i == pebbleAlertRow || i == notificationsServiceRow || i == badgeNumberRow || i == inappPriorityRow || - i == inchatSoundRow) { + i == inchatSoundRow || i == androidAutoAlertRow) { return 1; } else if (i == messageLedRow || i == groupLedRow) { return 3; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PasscodeActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PasscodeActivity.java index 49333c45b..677837b97 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PasscodeActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PasscodeActivity.java @@ -456,7 +456,7 @@ public class PasscodeActivity extends BaseFragment implements NotificationCenter public boolean onPreDraw() { listView.getViewTreeObserver().removeOnPreDrawListener(this); fixLayoutInternal(); - return false; + return true; } }); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java index 7b4922103..74b2b80f6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java @@ -417,7 +417,7 @@ public class PhotoAlbumPickerActivity extends BaseFragment implements Notificati if (listView != null) { listView.getViewTreeObserver().removeOnPreDrawListener(this); } - return false; + return true; } }); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java index c737724f6..a9f420e8c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoPickerActivity.java @@ -184,7 +184,7 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen } @Override - public boolean onSearchCollapse() { + public boolean canCollapseSearch() { finishFragment(); return false; } @@ -899,7 +899,7 @@ public class PhotoPickerActivity extends BaseFragment implements NotificationCen if (listView != null) { listView.getViewTreeObserver().removeOnPreDrawListener(this); } - return false; + return true; } }); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java index 270962eda..2816c6257 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java @@ -42,14 +42,13 @@ import android.widget.AdapterView; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ListView; -import android.widget.RelativeLayout; import android.widget.Scroller; import android.widget.TextView; import org.telegram.android.AndroidUtilities; -import org.telegram.android.ContactsController; import org.telegram.android.ImageLoader; import org.telegram.android.MessagesStorage; +import org.telegram.android.UserObject; import org.telegram.android.query.SharedMediaQuery; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; @@ -81,7 +80,7 @@ import org.telegram.ui.Components.PhotoCropView; import org.telegram.ui.Components.PhotoFilterView; import org.telegram.ui.Components.PhotoPickerBottomLayout; import org.telegram.ui.Components.PhotoViewerCaptionEnterView; -import org.telegram.ui.Components.SizeNotifierRelativeLayoutPhoto; +import org.telegram.ui.Components.SizeNotifierFrameLayoutPhoto; import java.io.File; import java.lang.ref.WeakReference; @@ -515,36 +514,114 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } } - private class FrameLayoutDrawer extends SizeNotifierRelativeLayoutPhoto { + private class FrameLayoutDrawer extends SizeNotifierFrameLayoutPhoto { public FrameLayoutDrawer(Context context) { super(context); setWillNotDraw(false); } @Override - protected void onDraw(Canvas canvas) { - getInstance().onDraw(canvas); + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int widthMode = MeasureSpec.getMode(widthMeasureSpec); + int heightMode = MeasureSpec.getMode(heightMeasureSpec); + int widthSize = MeasureSpec.getSize(widthMeasureSpec); + int heightSize = MeasureSpec.getSize(heightMeasureSpec); + + setMeasuredDimension(widthSize, heightSize); + + int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + View child = getChildAt(i); + if (child.getVisibility() == GONE) { + continue; + } + if (captionEditText.isPopupView(child)) { + child.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(child.getLayoutParams().height, MeasureSpec.EXACTLY)); + } else { + measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0); + } + } } @Override - protected boolean drawChild(Canvas canvas, View child, long drawingTime) { - if ((child == captionEditText || child == pickerView || child == captionTextView || child == mentionListView)) { - int state = captionEditText.getKeyboardTransitionState(); - if (!(state == 0 || state == 1 || state == 2)) { - if (child == captionTextView) { - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - if (captionTextView != null) { - captionTextView.invalidate(); - } - } - }, 50); - } - return false; + protected void onLayout(boolean changed, int l, int t, int r, int b) { + final int count = getChildCount(); + + int paddingBottom = getKeyboardHeight() <= AndroidUtilities.dp(20) ? captionEditText.getEmojiPadding() : 0; + + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); + if (child.getVisibility() == GONE) { + continue; } + final LayoutParams lp = (LayoutParams) child.getLayoutParams(); + + final int width = child.getMeasuredWidth(); + final int height = child.getMeasuredHeight(); + + int childLeft; + int childTop; + + int gravity = lp.gravity; + if (gravity == -1) { + gravity = Gravity.TOP | Gravity.LEFT; + } + + final int absoluteGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK; + final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK; + + switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { + case Gravity.CENTER_HORIZONTAL: + childLeft = (r - l - width) / 2 + lp.leftMargin - lp.rightMargin; + break; + case Gravity.RIGHT: + childLeft = r - width - lp.rightMargin; + break; + case Gravity.LEFT: + default: + childLeft = lp.leftMargin; + } + + switch (verticalGravity) { + case Gravity.TOP: + childTop = lp.topMargin; + break; + case Gravity.CENTER_VERTICAL: + childTop = ((b - paddingBottom) - t - height) / 2 + lp.topMargin - lp.bottomMargin; + break; + case Gravity.BOTTOM: + childTop = ((b - paddingBottom) - t) - height - lp.bottomMargin; + break; + default: + childTop = lp.topMargin; + } + + if (child == mentionListView) { + if (!captionEditText.isPopupShowing() && !captionEditText.isKeyboardVisible() && captionEditText.getEmojiPadding() == 0) { + childTop += AndroidUtilities.dp(400); + } else { + childTop -= captionEditText.getMeasuredHeight(); + } + } else if (child == captionEditText) { + if (!captionEditText.isPopupShowing() && !captionEditText.isKeyboardVisible() && captionEditText.getEmojiPadding() == 0) { + childTop += AndroidUtilities.dp(400); + } + } else if (child == pickerView || child == captionTextViewNew || child == captionTextViewOld) { + if (captionEditText.isPopupShowing() || captionEditText.isKeyboardVisible()) { + childTop += AndroidUtilities.dp(400); + } + } else if (captionEditText.isPopupView(child)) { + childTop = captionEditText.getBottom(); + } + child.layout(childLeft, childTop, childLeft + width, childTop + height); } - return super.drawChild(canvas, child, drawingTime); + + notifyHeightChanged(); + } + + @Override + protected void onDraw(Canvas canvas) { + getInstance().onDraw(canvas); } } @@ -787,7 +864,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat @Override public boolean dispatchKeyEventPreIme(KeyEvent event) { if (event != null && event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) { - if (captionEditText.isEmojiPopupShowing() || captionEditText.isKeyboardVisible()) { + if (captionEditText.isPopupShowing() || captionEditText.isKeyboardVisible()) { closeCaptionEnter(false); return false; } @@ -822,13 +899,13 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat actionBar.setItemsBackground(R.drawable.bar_selector_white); actionBar.setBackButtonImage(R.drawable.ic_ab_back); actionBar.setTitle(LocaleController.formatString("Of", R.string.Of, 1, 1)); - containerView.addView(actionBar, LayoutHelper.createRelative(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); + containerView.addView(actionBar, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { @Override public void onItemClick(int id) { if (id == -1) { - if (needCaptionLayout && (captionEditText.isEmojiPopupShowing() || captionEditText.isKeyboardVisible())) { + if (needCaptionLayout && (captionEditText.isPopupShowing() || captionEditText.isKeyboardVisible())) { closeCaptionEnter(false); return; } @@ -991,6 +1068,12 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat checkImageView.setVisibility(View.GONE); captionDoneItem.setVisibility(View.VISIBLE); pickerView.setVisibility(View.GONE); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) captionEditText.getLayoutParams(); + layoutParams.bottomMargin = 0; + captionEditText.setLayoutParams(layoutParams); + layoutParams = (FrameLayout.LayoutParams) mentionListView.getLayoutParams(); + layoutParams.bottomMargin = 0; + mentionListView.setLayoutParams(layoutParams); captionTextView.clearAnimation(); captionTextView.setVisibility(View.INVISIBLE); captionEditText.openKeyboard(); @@ -1032,7 +1115,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat bottomLayout = new FrameLayout(parentActivity); bottomLayout.setBackgroundColor(0x7f000000); - containerView.addView(bottomLayout, LayoutHelper.createRelative(LayoutHelper.MATCH_PARENT, 48, RelativeLayout.ALIGN_PARENT_BOTTOM)); + containerView.addView(bottomLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.BOTTOM | Gravity.LEFT)); captionTextViewOld = new TextView(parentActivity); captionTextViewOld.setMaxLines(10); @@ -1043,7 +1126,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat captionTextViewOld.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT); captionTextViewOld.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); captionTextViewOld.setVisibility(View.INVISIBLE); - containerView.addView(captionTextViewOld, LayoutHelper.createRelative(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 0, 48, RelativeLayout.ALIGN_PARENT_BOTTOM)); + containerView.addView(captionTextViewOld, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM | Gravity.LEFT, 0, 0, 0, 48)); captionTextView = captionTextViewNew = new TextView(parentActivity); captionTextViewNew.setMaxLines(10); @@ -1054,7 +1137,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat captionTextViewNew.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT); captionTextViewNew.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); captionTextViewNew.setVisibility(View.INVISIBLE); - containerView.addView(captionTextViewNew, LayoutHelper.createRelative(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 0, 48, RelativeLayout.ALIGN_PARENT_BOTTOM)); + containerView.addView(captionTextViewNew, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM | Gravity.LEFT, 0, 0, 0, 48)); radialProgressViews[0] = new RadialProgressView(containerView.getContext(), containerView); radialProgressViews[0].setBackgroundState(0, false); @@ -1128,7 +1211,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat pickerView = new PhotoPickerBottomLayout(parentActivity); pickerView.setBackgroundColor(0x7f000000); - containerView.addView(pickerView, LayoutHelper.createRelative(LayoutHelper.MATCH_PARENT, 48, RelativeLayout.ALIGN_PARENT_BOTTOM)); + containerView.addView(pickerView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.BOTTOM | Gravity.LEFT)); pickerView.cancelButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { @@ -1152,7 +1235,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat editorDoneLayout.setBackgroundColor(0x7f000000); editorDoneLayout.updateSelectedCount(0, false); editorDoneLayout.setVisibility(View.GONE); - containerView.addView(editorDoneLayout, LayoutHelper.createRelative(LayoutHelper.MATCH_PARENT, 48, RelativeLayout.ALIGN_PARENT_BOTTOM)); + containerView.addView(editorDoneLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM)); editorDoneLayout.cancelButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { @@ -1198,7 +1281,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat checkImageView.setCheckOffset(AndroidUtilities.dp(1)); checkImageView.setColor(0xff3ccaef); checkImageView.setVisibility(View.GONE); - containerView.addView(checkImageView, LayoutHelper.createRelative(45, 45, 0, rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90 ? 58 : 68, 10, 0, RelativeLayout.ALIGN_PARENT_RIGHT)); + containerView.addView(checkImageView, LayoutHelper.createFrame(45, 45, Gravity.RIGHT | Gravity.TOP, 0, rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90 ? 58 : 68, 10, 0)); checkImageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -1210,8 +1293,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } }); - captionEditText = new PhotoViewerCaptionEnterView(parentActivity, windowView, containerView); - captionEditText.setId(1000); + captionEditText = new PhotoViewerCaptionEnterView(parentActivity, containerView); captionEditText.setDelegate(new PhotoViewerCaptionEnterView.PhotoViewerCaptionEnterViewDelegate() { @Override public void onCaptionEnter() { @@ -1219,7 +1301,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } @Override - public void onTextChanged(CharSequence text, boolean bigChange) { + public void onTextChanged(CharSequence text) { if (mentionsAdapter != null && captionEditText != null && parentChatActivity != null && text != null) { mentionsAdapter.searchUsernameOrHashtag(text.toString(), captionEditText.getCursorPosition(), parentChatActivity.messages); } @@ -1243,7 +1325,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } } }); - containerView.addView(captionEditText, LayoutHelper.createRelative(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 0, -400, RelativeLayout.ALIGN_PARENT_BOTTOM)); + containerView.addView(captionEditText, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM | Gravity.LEFT, 0, 0, 0, -400)); mentionListView = new ListView(parentActivity); mentionListView.setBackgroundColor(0x7f000000); @@ -1254,13 +1336,13 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (Build.VERSION.SDK_INT > 8) { mentionListView.setOverScrollMode(ListView.OVER_SCROLL_NEVER); } - containerView.addView(mentionListView, LayoutHelper.createRelative(LayoutHelper.MATCH_PARENT, 110, 0, -110, 0, 0, RelativeLayout.ALIGN_TOP, 1000)); + containerView.addView(mentionListView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 110, Gravity.LEFT | Gravity.BOTTOM)); mentionListView.setAdapter(mentionsAdapter = new MentionsAdapter(parentActivity, true, new MentionsAdapter.MentionsAdapterDelegate() { @Override public void needChangePanelVisibility(boolean show) { if (show) { - RelativeLayout.LayoutParams layoutParams3 = (RelativeLayout.LayoutParams) mentionListView.getLayoutParams(); + FrameLayout.LayoutParams layoutParams3 = (FrameLayout.LayoutParams) mentionListView.getLayoutParams(); int height = 36 * Math.min(3, mentionsAdapter.getCount()) + (mentionsAdapter.getCount() > 3 ? 18 : 0); layoutParams3.height = AndroidUtilities.dp(height); layoutParams3.topMargin = -AndroidUtilities.dp(height); @@ -1411,6 +1493,14 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat captionDoneItem.setVisibility(View.GONE); pickerView.setVisibility(View.VISIBLE); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) captionEditText.getLayoutParams(); + layoutParams.bottomMargin = -AndroidUtilities.dp(400); + captionEditText.setLayoutParams(layoutParams); + + layoutParams = (FrameLayout.LayoutParams) mentionListView.getLayoutParams(); + layoutParams.bottomMargin = -AndroidUtilities.dp(400); + mentionListView.setLayoutParams(layoutParams); + if (lastTitle != null) { actionBar.setTitle(lastTitle); lastTitle = null; @@ -1418,8 +1508,8 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat updateCaptionTextForCurrentPhoto(object); setCurrentCaption(captionEditText.getFieldCharSequence()); - if (captionEditText.isEmojiPopupShowing()) { - captionEditText.hideEmojiPopup(); + if (captionEditText.isPopupShowing()) { + captionEditText.hidePopup(); } else { captionEditText.closeKeyboard(); } @@ -1619,7 +1709,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (photoCropView == null) { photoCropView = new PhotoCropView(parentActivity); photoCropView.setVisibility(View.GONE); - containerView.addView(photoCropView, LayoutHelper.createRelative(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, 0, 0, 0, 48)); + containerView.addView(photoCropView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, 0, 0, 0, 48)); photoCropView.setDelegate(new PhotoCropView.PhotoCropViewDelegate() { @Override public void needMoveImageTo(float x, float y, float s, boolean animated) { @@ -1722,7 +1812,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } else if (mode == 2) { if (photoFilterView == null) { photoFilterView = new PhotoFilterView(parentActivity, centerImage.getBitmap(), centerImage.getOrientation()); - containerView.addView(photoFilterView, LayoutHelper.createRelative(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); + containerView.addView(photoFilterView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); photoFilterView.getDoneTextView().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -2236,9 +2326,6 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat captionEditText.setVisibility(cropItem.getVisibility()); needCaptionLayout = captionItem.getVisibility() == View.VISIBLE; if (needCaptionLayout) { - RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) captionEditText.getLayoutParams(); - layoutParams.bottomMargin = -AndroidUtilities.dp(400); - captionEditText.setLayoutParams(layoutParams); captionEditText.onCreate(); } } @@ -2288,7 +2375,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat currentMessageObject = imagesArr.get(currentIndex); TLRPC.User user = MessagesController.getInstance().getUser(currentMessageObject.messageOwner.from_id); if (user != null) { - nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name)); + nameTextView.setText(UserObject.getUserName(user)); } else { nameTextView.setText(""); } @@ -2849,6 +2936,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (containerView == null) { return; } + if (Build.VERSION.SDK_INT >= 18) { + containerView.setLayerType(View.LAYER_TYPE_NONE, null); + } animationInProgress = 0; transitionAnimationStartTime = 0; setImages(); @@ -2892,7 +2982,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat animatorSet.start(); } }); - + if (Build.VERSION.SDK_INT >= 18) { + containerView.setLayerType(View.LAYER_TYPE_HARDWARE, null); + } backgroundDrawable.drawRunnable = new Runnable() { @Override public void run() { @@ -3052,6 +3144,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat animationEndRunnable = new Runnable() { @Override public void run() { + if (Build.VERSION.SDK_INT >= 18) { + containerView.setLayerType(View.LAYER_TYPE_NONE, null); + } animationInProgress = 0; onPhotoClosed(object); } @@ -3078,6 +3173,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } }); transitionAnimationStartTime = System.currentTimeMillis(); + if (Build.VERSION.SDK_INT >= 18) { + containerView.setLayerType(View.LAYER_TYPE_HARDWARE, null); + } animatorSet.start(); } else { AnimatorSetProxy animatorSet = new AnimatorSetProxy(); @@ -3094,6 +3192,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (containerView == null) { return; } + if (Build.VERSION.SDK_INT >= 18) { + containerView.setLayerType(View.LAYER_TYPE_NONE, null); + } animationInProgress = 0; onPhotoClosed(object); ViewProxy.setScaleX(containerView, 1.0f); @@ -3112,6 +3213,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } }); transitionAnimationStartTime = System.currentTimeMillis(); + if (Build.VERSION.SDK_INT >= 18) { + containerView.setLayerType(View.LAYER_TYPE_HARDWARE, null); + } animatorSet.start(); } } @@ -3285,7 +3389,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } } - if (captionEditText.isEmojiPopupShowing() || captionEditText.isKeyboardVisible()) { + if (captionEditText.isPopupShowing() || captionEditText.isKeyboardVisible()) { return true; } @@ -3776,7 +3880,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat checkImageView.post(new Runnable() { @Override public void run() { - RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) checkImageView.getLayoutParams(); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) checkImageView.getLayoutParams(); WindowManager manager = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Activity.WINDOW_SERVICE); int rotation = manager.getDefaultDisplay().getRotation(); layoutParams.topMargin = AndroidUtilities.dp(rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90 ? 58 : 68); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java index d06f17a6d..f5d4a8828 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java @@ -38,6 +38,7 @@ import org.telegram.android.MediaController; import org.telegram.android.MessagesController; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.NotificationsController; +import org.telegram.android.UserObject; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLoader; @@ -55,7 +56,7 @@ import org.telegram.ui.Components.FrameLayoutFixed; import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.PopupAudioView; import org.telegram.ui.Components.RecordStatusDrawable; -import org.telegram.ui.Components.SizeNotifierRelativeLayout; +import org.telegram.ui.Components.SizeNotifierFrameLayout; import org.telegram.ui.Components.TypingDotsDrawable; import java.io.File; @@ -164,38 +165,112 @@ public class PopupNotificationActivity extends Activity implements NotificationC typingDotsDrawable = new TypingDotsDrawable(); recordStatusDrawable = new RecordStatusDrawable(); - SizeNotifierRelativeLayout contentView = new SizeNotifierRelativeLayout(this); + SizeNotifierFrameLayout contentView = new SizeNotifierFrameLayout(this) { + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int widthMode = MeasureSpec.getMode(widthMeasureSpec); + int heightMode = MeasureSpec.getMode(heightMeasureSpec); + int widthSize = MeasureSpec.getSize(widthMeasureSpec); + int heightSize = MeasureSpec.getSize(heightMeasureSpec); + + setMeasuredDimension(widthSize, heightSize); + + int keyboardSize = getKeyboardHeight(); + + if (keyboardSize <= AndroidUtilities.dp(20)) { + heightSize -= chatActivityEnterView.getEmojiPadding(); + } + + int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + View child = getChildAt(i); + if (child.getVisibility() == GONE) { + continue; + } + if (chatActivityEnterView.isPopupView(child)) { + child.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(child.getLayoutParams().height, MeasureSpec.EXACTLY)); + } else { + child.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(Math.max(AndroidUtilities.dp(10), heightSize + AndroidUtilities.dp(2)), MeasureSpec.EXACTLY)); + } + } + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + final int count = getChildCount(); + + int paddingBottom = getKeyboardHeight() <= AndroidUtilities.dp(20) ? chatActivityEnterView.getEmojiPadding() : 0; + + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); + if (child.getVisibility() == GONE) { + continue; + } + final LayoutParams lp = (LayoutParams) child.getLayoutParams(); + + int width = child.getMeasuredWidth(); + int height = child.getMeasuredHeight(); + + int childLeft; + int childTop; + + int gravity = lp.gravity; + if (gravity == -1) { + gravity = Gravity.TOP | Gravity.LEFT; + } + + final int absoluteGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK; + final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK; + + switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { + case Gravity.CENTER_HORIZONTAL: + childLeft = (r - l - width) / 2 + lp.leftMargin - lp.rightMargin; + break; + case Gravity.RIGHT: + childLeft = r - width - lp.rightMargin; + break; + case Gravity.LEFT: + default: + childLeft = lp.leftMargin; + } + + switch (verticalGravity) { + case Gravity.TOP: + childTop = lp.topMargin; + break; + case Gravity.CENTER_VERTICAL: + childTop = ((b - paddingBottom) - t - height) / 2 + lp.topMargin - lp.bottomMargin; + break; + case Gravity.BOTTOM: + childTop = ((b - paddingBottom) - t) - height - lp.bottomMargin; + break; + default: + childTop = lp.topMargin; + } + if (chatActivityEnterView.isPopupView(child)) { + childTop = paddingBottom != 0 ? getMeasuredHeight() - paddingBottom : getMeasuredHeight(); + } + child.layout(childLeft, childTop, childLeft + width, childTop + height); + } + + notifyHeightChanged(); + } + }; setContentView(contentView); contentView.setBackgroundColor(0x99000000); RelativeLayout relativeLayout = new RelativeLayout(this); - contentView.addView(relativeLayout); - RelativeLayout.LayoutParams layoutParams3 = (RelativeLayout.LayoutParams) relativeLayout.getLayoutParams(); - layoutParams3.width = LayoutHelper.MATCH_PARENT; - layoutParams3.height = LayoutHelper.MATCH_PARENT; - relativeLayout.setLayoutParams(layoutParams3); + contentView.addView(relativeLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); RelativeLayout popupContainer = new RelativeLayout(this); popupContainer.setBackgroundColor(0xffffffff); - relativeLayout.addView(popupContainer); - layoutParams3 = (RelativeLayout.LayoutParams) popupContainer.getLayoutParams(); - layoutParams3.width = LayoutHelper.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); + relativeLayout.addView(popupContainer, LayoutHelper.createRelative(LayoutHelper.MATCH_PARENT, 240, 12, 0, 12, 0, RelativeLayout.CENTER_IN_PARENT)); if (chatActivityEnterView != null) { chatActivityEnterView.onDestroy(); } chatActivityEnterView = new ChatActivityEnterView(this, contentView, null, false); - popupContainer.addView(chatActivityEnterView); - layoutParams3 = (RelativeLayout.LayoutParams) chatActivityEnterView.getLayoutParams(); - layoutParams3.width = LayoutHelper.MATCH_PARENT; - layoutParams3.height = LayoutHelper.WRAP_CONTENT; - layoutParams3.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); - chatActivityEnterView.setLayoutParams(layoutParams3); + popupContainer.addView(chatActivityEnterView, LayoutHelper.createRelative(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, RelativeLayout.ALIGN_PARENT_BOTTOM)); chatActivityEnterView.setDelegate(new ChatActivityEnterView.ChatActivityEnterViewDelegate() { @Override public void onMessageSend(String message) { @@ -749,7 +824,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC } int padding = (AndroidUtilities.getCurrentActionBarHeight() - AndroidUtilities.dp(48)) / 2; avatarContainer.setPadding(avatarContainer.getPaddingLeft(), padding, avatarContainer.getPaddingRight(), padding); - return false; + return true; } }); } @@ -767,7 +842,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC messageContainer.setLayoutParams(layoutParams); applyViewsLayoutParams(0); } - return false; + return true; } }); } @@ -872,11 +947,11 @@ public class PopupNotificationActivity extends Activity implements NotificationC if (currentChat != null && currentUser != null) { nameTextView.setText(currentChat.title); - onlineTextView.setText(ContactsController.formatName(currentUser.first_name, currentUser.last_name)); + onlineTextView.setText(UserObject.getUserName(currentUser)); nameTextView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); nameTextView.setCompoundDrawablePadding(0); } else if (currentUser != null) { - nameTextView.setText(ContactsController.formatName(currentUser.first_name, currentUser.last_name)); + nameTextView.setText(UserObject.getUserName(currentUser)); if ((int)dialog_id == 0) { nameTextView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_white, 0, 0, 0); nameTextView.setCompoundDrawablePadding(AndroidUtilities.dp(4)); @@ -903,10 +978,10 @@ public class PopupNotificationActivity extends Activity implements NotificationC if (currentUser.phone != null && currentUser.phone.length() != 0) { nameTextView.setText(PhoneFormat.getInstance().format("+" + currentUser.phone)); } else { - nameTextView.setText(ContactsController.formatName(currentUser.first_name, currentUser.last_name)); + nameTextView.setText(UserObject.getUserName(currentUser)); } } else { - nameTextView.setText(ContactsController.formatName(currentUser.first_name, currentUser.last_name)); + nameTextView.setText(UserObject.getUserName(currentUser)); } CharSequence printString = MessagesController.getInstance().printingStrings.get(currentMessageObject.getDialogId()); if (printString == null || printString.length() == 0) { @@ -984,8 +1059,8 @@ public class PopupNotificationActivity extends Activity implements NotificationC @Override public void onBackPressed() { - if (chatActivityEnterView.isEmojiPopupShowing()) { - chatActivityEnterView.hideEmojiPopup(); + if (chatActivityEnterView.isPopupShowing()) { + chatActivityEnterView.hidePopup(); return; } super.onBackPressed(); @@ -1008,7 +1083,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC super.onPause(); overridePendingTransition(0, 0); if (chatActivityEnterView != null) { - chatActivityEnterView.hideEmojiPopup(); + chatActivityEnterView.hidePopup(); chatActivityEnterView.setFieldFocused(false); } ConnectionsManager.getInstance().setAppPaused(true, false); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java index 980c185be..07f415931 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java @@ -17,6 +17,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.res.Configuration; import android.graphics.Bitmap; +import android.graphics.Canvas; import android.graphics.Outline; import android.net.Uri; import android.os.Build; @@ -29,6 +30,8 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.view.ViewTreeObserver; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.DecelerateInterpolator; import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.FrameLayout; @@ -38,10 +41,15 @@ import android.widget.TextView; import org.telegram.android.AndroidUtilities; import org.telegram.PhoneFormat.PhoneFormat; +import org.telegram.android.AnimationCompat.AnimatorListenerAdapterProxy; +import org.telegram.android.AnimationCompat.AnimatorSetProxy; +import org.telegram.android.AnimationCompat.ObjectAnimatorProxy; import org.telegram.android.LocaleController; import org.telegram.android.MessagesStorage; import org.telegram.android.SecretChatHelper; import org.telegram.android.SendMessagesHelper; +import org.telegram.android.UserObject; +import org.telegram.android.query.BotQuery; import org.telegram.android.query.SharedMediaQuery; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ConnectionsManager; @@ -87,7 +95,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. private TextView nameTextView; private TextView onlineTextView; private ImageView writeButton; - + private AnimatorSetProxy writeButtonAnimation; private int user_id; private int chat_id; private long dialog_id; @@ -102,6 +110,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. private TLRPC.EncryptedChat currentEncryptedChat; private TLRPC.Chat currentChat; + private TLRPC.BotInfo botInfo; private int totalMediaCount = -1; @@ -113,6 +122,8 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. private final static int add_member = 6; private final static int leave_group = 7; private final static int edit_name = 8; + private final static int invite_to_group = 9; + private final static int share = 10; private int overscrollRow; private int emptyRow; @@ -126,6 +137,8 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. private int sharedMediaRow; private int startSecretChatRow; private int sectionRow; + private int botSectionRow; + private int botInfoRow; private int membersSectionRow; private int membersEndRow; private int addMemberRow; @@ -144,7 +157,8 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. if (dialog_id != 0) { currentEncryptedChat = MessagesController.getInstance().getEncryptedChat((int) (dialog_id >> 32)); } - if (MessagesController.getInstance().getUser(user_id) == null) { + TLRPC.User user = MessagesController.getInstance().getUser(user_id); + if (user == null) { return false; } NotificationCenter.getInstance().addObserver(this, NotificationCenter.updateInterfaces); @@ -152,8 +166,11 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. NotificationCenter.getInstance().addObserver(this, NotificationCenter.encryptedChatCreated); NotificationCenter.getInstance().addObserver(this, NotificationCenter.encryptedChatUpdated); NotificationCenter.getInstance().addObserver(this, NotificationCenter.blockedUsersDidLoaded); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.botInfoDidLoaded); userBlocked = MessagesController.getInstance().blockedUsers.contains(user_id); - + if ((user.flags & TLRPC.USER_FLAG_BOT) != 0) { + BotQuery.loadBotInfo(user.id, true, classGuid); + } MessagesController.getInstance().loadFullUser(MessagesController.getInstance().getUser(user_id), classGuid); } else if (chat_id != 0) { currentChat = MessagesController.getInstance().getChat(chat_id); @@ -219,6 +236,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. NotificationCenter.getInstance().removeObserver(this, NotificationCenter.encryptedChatCreated); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.encryptedChatUpdated); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.blockedUsersDidLoaded); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.botInfoDidLoaded); MessagesController.getInstance().cancelLoadFullUser(user_id); } else if (chat_id != 0) { NotificationCenter.getInstance().removeObserver(this, NotificationCenter.chatInfoDidLoaded); @@ -271,7 +289,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } else if (id == share_contact) { Bundle args = new Bundle(); args.putBoolean("onlySelect", true); - args.putBoolean("serverOnly", true); + args.putInt("dialogsType", 1); MessagesActivity fragment = new MessagesActivity(args); fragment.setDelegate(ProfileActivity.this); presentFragment(fragment); @@ -315,6 +333,47 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. Bundle args = new Bundle(); args.putInt("chat_id", chat_id); presentFragment(new ChangeChatNameActivity(args)); + } else if (id == invite_to_group) { + final TLRPC.User user = MessagesController.getInstance().getUser(user_id); + if (user == null) { + return; + } + Bundle args = new Bundle(); + args.putBoolean("onlySelect", true); + args.putInt("dialogsType", 2); + args.putString("addToGroupAlertString", LocaleController.formatString("AddToTheGroupTitle", R.string.AddToTheGroupTitle, UserObject.getUserName(user), "%1$s")); + MessagesActivity fragment = new MessagesActivity(args); + fragment.setDelegate(new MessagesActivity.MessagesActivityDelegate() { + @Override + public void didSelectDialog(MessagesActivity fragment, long did, boolean param) { + NotificationCenter.getInstance().removeObserver(ProfileActivity.this, NotificationCenter.closeChats); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); + MessagesController.getInstance().addUserToChat(-(int) did, user, null, 0, null); + Bundle args = new Bundle(); + args.putBoolean("scrollToTopOnResume", true); + args.putInt("chat_id", -(int) did); + presentFragment(new ChatActivity(args), true); + removeSelfFromStack(); + } + }); + presentFragment(fragment); + } else if (id == share) { + try { + TLRPC.User user = MessagesController.getInstance().getUser(user_id); + if (user == null) { + return; + } + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + if (botInfo != null && botInfo.share_text != null && botInfo.share_text.length() > 0) { + intent.putExtra(Intent.EXTRA_TEXT, String.format("%s https://telegram.me/%s", botInfo.share_text, user.username)); + } else { + intent.putExtra(Intent.EXTRA_TEXT, String.format("https://telegram.me/%s", user.username)); + } + startActivityForResult(Intent.createChooser(intent, LocaleController.getString("BotShare", R.string.BotShare)), 500); + } catch (Exception e) { + FileLog.e("tmessages", e); + } } } }); @@ -323,7 +382,34 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. listAdapter = new ListAdapter(context); - fragmentView = new FrameLayout(context); + fragmentView = new FrameLayout(context) { + @Override + protected boolean drawChild(Canvas canvas, View child, long drawingTime) { + if (child == listView) { + boolean result = super.drawChild(canvas, child, drawingTime); + if (parentLayout != null) { + int actionBarHeight = 0; + int childCount = getChildCount(); + for (int a = 0; a < childCount; a++) { + View view = getChildAt(a); + if (view == child) { + continue; + } + if (view instanceof ActionBar && view.getVisibility() == VISIBLE) { + if (((ActionBar) view).getCastShadows()) { + actionBarHeight = view.getMeasuredHeight(); + } + break; + } + } + parentLayout.drawHeaderShadow(canvas, actionBarHeight); + } + return result; + } else { + return super.drawChild(canvas, child, drawingTime); + } + } + }; FrameLayout frameLayout = (FrameLayout) fragmentView; avatarImage = new BackupImageView(context); @@ -469,13 +555,17 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. FileLog.e("tmessages", e); } } else if (i == 1) { - if (Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB) { - android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); - clipboard.setText("+" + user.phone); - } else { - android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); - android.content.ClipData clip = android.content.ClipData.newPlainText("label", "+" + user.phone); - clipboard.setPrimaryClip(clip); + try { + if (Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB) { + android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); + clipboard.setText("+" + user.phone); + } else { + android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); + android.content.ClipData clip = android.content.ClipData.newPlainText("label", "+" + user.phone); + clipboard.setPrimaryClip(clip); + } + } catch (Exception e) { + FileLog.e("tmessages", e); } } } @@ -661,18 +751,18 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. args.putBoolean("onlyUsers", true); args.putBoolean("destroyAfterSelect", true); args.putBoolean("returnAsResult", true); - if (info != null && info.admin_id == UserConfig.getClientUserId()) { - args.putInt("chat_id", currentChat.id); - } //args.putBoolean("allowUsernameSearch", false); if (chat_id > 0) { + if (info != null && info.admin_id == UserConfig.getClientUserId()) { + args.putInt("chat_id", currentChat.id); + } args.putString("selectAlertString", LocaleController.getString("AddToTheGroup", R.string.AddToTheGroup)); } ContactsActivity fragment = new ContactsActivity(args); fragment.setDelegate(new ContactsActivity.ContactsActivityDelegate() { @Override public void didSelectContact(TLRPC.User user, String param) { - MessagesController.getInstance().addUserToChat(chat_id, user, info, param != null ? Utilities.parseInt(param) : 0); + MessagesController.getInstance().addUserToChat(chat_id, user, info, param != null ? Utilities.parseInt(param) : 0, null); } }); if (info != null) { @@ -727,10 +817,53 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. layoutParams = (FrameLayout.LayoutParams) writeButton.getLayoutParams(); layoutParams.topMargin = (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0) + AndroidUtilities.getCurrentActionBarHeight() + actionBar.getExtraHeight() - AndroidUtilities.dp(29.5f); writeButton.setLayoutParams(layoutParams); - ViewProxy.setAlpha(writeButton, diff); + /*ViewProxy.setAlpha(writeButton, diff); writeButton.setVisibility(diff <= 0.02 ? View.GONE : View.VISIBLE); if (writeButton.getVisibility() == View.GONE) { writeButton.clearAnimation(); + }*/ + final boolean setVisible = diff > 0.2f; + boolean currentVisible = writeButton.getTag() == null; + if (setVisible != currentVisible) { + if (setVisible) { + writeButton.setTag(null); + writeButton.setVisibility(View.VISIBLE); + } else { + writeButton.setTag(0); + } + if (writeButtonAnimation != null) { + AnimatorSetProxy old = writeButtonAnimation; + writeButtonAnimation = null; + old.cancel(); + } + writeButtonAnimation = new AnimatorSetProxy(); + if (setVisible) { + writeButtonAnimation.setInterpolator(new DecelerateInterpolator()); + writeButtonAnimation.playTogether( + ObjectAnimatorProxy.ofFloat(writeButton, "scaleX", 1.0f), + ObjectAnimatorProxy.ofFloat(writeButton, "scaleY", 1.0f), + ObjectAnimatorProxy.ofFloat(writeButton, "alpha", 1.0f) + ); + } else { + writeButtonAnimation.setInterpolator(new AccelerateInterpolator()); + writeButtonAnimation.playTogether( + ObjectAnimatorProxy.ofFloat(writeButton, "scaleX", 0.2f), + ObjectAnimatorProxy.ofFloat(writeButton, "scaleY", 0.2f), + ObjectAnimatorProxy.ofFloat(writeButton, "alpha", 0.0f) + ); + } + writeButtonAnimation.setDuration(150); + writeButtonAnimation.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + if (writeButtonAnimation != null && writeButtonAnimation.equals(animation)) { + writeButton.clearAnimation(); + writeButton.setVisibility(setVisible ? View.VISIBLE : View.GONE); + writeButtonAnimation = null; + } + } + }); + writeButtonAnimation.start(); } } @@ -772,7 +905,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. needLayout(); fragmentView.getViewTreeObserver().removeOnPreDrawListener(this); } - return false; + return true; } }); } @@ -881,6 +1014,12 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } } else if (id == NotificationCenter.closeChats) { removeSelfFromStack(); + } else if (id == NotificationCenter.botInfoDidLoaded) { + TLRPC.BotInfo info = (TLRPC.BotInfo) args[0]; + if (info.user_id == user_id) { + botInfo = info; + updateRowsIds(); + } } } @@ -1058,14 +1197,22 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. rowCount = 0; overscrollRow = rowCount++; if (user_id != 0) { - emptyRow = rowCount++; - phoneRow = rowCount++; TLRPC.User user = MessagesController.getInstance().getUser(user_id); + emptyRow = rowCount++; + if (user != null && (user.flags & TLRPC.USER_FLAG_BOT) != 0) { + phoneRow = -1; + } else { + phoneRow = rowCount++; + } if (user != null && user.username != null && user.username.length() > 0) { usernameRow = rowCount++; } else { usernameRow = -1; } + if (botInfo != null && botInfo.share_text != null && botInfo.share_text.length() > 0) { + botSectionRow = rowCount++; + botInfoRow = rowCount++; + } sectionRow = rowCount++; settingsNotificationsRow = rowCount++; sharedMediaRow = rowCount++; @@ -1076,7 +1223,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. settingsTimerRow = -1; settingsKeyRow = -1; } - if (currentEncryptedChat == null) { + if (user != null && (user.flags & TLRPC.USER_FLAG_BOT) == 0 && currentEncryptedChat == null) { startSecretChatRow = rowCount++; } else { startSecretChatRow = -1; @@ -1119,12 +1266,12 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. AvatarDrawable avatarDrawable = new AvatarDrawable(user); avatarImage.setImage(photo, "50_50", avatarDrawable); - if (user instanceof TLRPC.TL_userDeleted) { - nameTextView.setText(LocaleController.getString("HiddenName", R.string.HiddenName)); + nameTextView.setText(UserObject.getUserName(user)); + if ((user.flags & TLRPC.USER_FLAG_BOT) != 0) { + onlineTextView.setText(LocaleController.getString("Bot", R.string.Bot)); } else { - nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name)); + onlineTextView.setText(LocaleController.formatUserStatus(user)); } - onlineTextView.setText(LocaleController.formatUserStatus(user)); avatarImage.getImageReceiver().setVisible(!PhotoViewer.getInstance().isShowingImage(photoBig), false); } else if (chat_id != 0) { @@ -1170,6 +1317,12 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. return; } ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_other); + if ((user.flags & TLRPC.USER_FLAG_BOT) != 0) { + if ((user.flags & TLRPC.USER_FLAG_BOT_CANT_JOIN_GROUP) == 0) { + item.addSubItem(invite_to_group, LocaleController.getString("BotInvite", R.string.BotInvite), 0); + } + item.addSubItem(share, LocaleController.getString("BotShare", R.string.BotShare), 0); + } if (user.phone != null && user.phone.length() != 0) { item.addSubItem(add_contact, LocaleController.getString("AddContact", R.string.AddContact), 0); item.addSubItem(share_contact, LocaleController.getString("ShareContact", R.string.ShareContact), 0); @@ -1327,6 +1480,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } else { value = String.format("%d", totalMediaCount); } + textCell.setMultiline(false); textCell.setTextAndValue(LocaleController.getString("SharedMedia", R.string.SharedMedia), value); } else if (i == settingsTimerRow) { TLRPC.EncryptedChat encryptedChat = MessagesController.getInstance().getEncryptedChat((int)(dialog_id >> 32)); @@ -1336,17 +1490,24 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } else { value = AndroidUtilities.formatTTLString(encryptedChat.ttl); } + textCell.setMultiline(false); textCell.setTextAndValue(LocaleController.getString("MessageLifetime", R.string.MessageLifetime), value); } else if (i == settingsNotificationsRow) { + textCell.setMultiline(false); textCell.setTextAndIcon(LocaleController.getString("NotificationsAndSounds", R.string.NotificationsAndSounds), R.drawable.profile_list); } else if (i == startSecretChatRow) { + textCell.setMultiline(false); textCell.setText(LocaleController.getString("StartEncryptedChat", R.string.StartEncryptedChat)); textCell.setTextColor(0xff37a919); } else if (i == settingsKeyRow) { IdenticonDrawable identiconDrawable = new IdenticonDrawable(); TLRPC.EncryptedChat encryptedChat = MessagesController.getInstance().getEncryptedChat((int)(dialog_id >> 32)); identiconDrawable.setEncryptedChat(encryptedChat); + textCell.setMultiline(false); textCell.setTextAndValueDrawable(LocaleController.getString("EncryptionKey", R.string.EncryptionKey), identiconDrawable); + } else if (i == botInfoRow) { + textCell.setMultiline(true); + textCell.setTextAndIcon(botInfo.share_text, R.drawable.bot_info); } } else if (type == 4) { if (view == null) { @@ -1362,6 +1523,11 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } else if (type == 6) { if (view == null) { view = new AddMemberCell(mContext); + if (chat_id > 0) { + ((AddMemberCell) view).setText(LocaleController.getString("AddMember", R.string.AddMember)); + } else { + ((AddMemberCell) view).setText(LocaleController.getString("AddRecipient", R.string.AddRecipient)); + } } } return view; @@ -1371,11 +1537,11 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. public int getItemViewType(int i) { if (i == emptyRow || i == overscrollRow || i == emptyRowChat || i == emptyRowChat2) { return 0; - } else if (i == sectionRow) { + } else if (i == sectionRow || i == botSectionRow) { return 1; } else if (i == phoneRow || i == usernameRow) { return 2; - } else if (i == sharedMediaRow || i == settingsTimerRow || i == settingsNotificationsRow || i == startSecretChatRow || i == settingsKeyRow) { + } else if (i == sharedMediaRow || i == settingsTimerRow || i == settingsNotificationsRow || i == startSecretChatRow || i == settingsKeyRow || i == botInfoRow) { return 3; } else if (i > emptyRowChat2 && i < membersEndRow) { return 4; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java index a5bdf3b00..9c0be40e4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java @@ -21,6 +21,7 @@ import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.res.Configuration; import android.graphics.Bitmap; +import android.graphics.Canvas; import android.graphics.Outline; import android.net.Uri; import android.os.Build; @@ -38,6 +39,8 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.view.ViewTreeObserver; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.DecelerateInterpolator; import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.FrameLayout; @@ -46,9 +49,12 @@ import android.widget.ListView; import android.widget.TextView; import org.telegram.android.AndroidUtilities; -import org.telegram.android.ContactsController; +import org.telegram.android.AnimationCompat.AnimatorListenerAdapterProxy; +import org.telegram.android.AnimationCompat.AnimatorSetProxy; +import org.telegram.android.AnimationCompat.ObjectAnimatorProxy; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.android.MediaController; +import org.telegram.android.UserObject; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.BuildVars; import org.telegram.android.LocaleController; @@ -96,6 +102,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter private TextView nameTextView; private TextView onlineTextView; private ImageView writeButton; + private AnimatorSetProxy writeButtonAnimation; private AvatarUpdater avatarUpdater = new AvatarUpdater(); private int overscrollRow; @@ -311,7 +318,34 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter listAdapter = new ListAdapter(context); - fragmentView = new FrameLayout(context); + fragmentView = new FrameLayout(context) { + @Override + protected boolean drawChild(Canvas canvas, View child, long drawingTime) { + if (child == listView) { + boolean result = super.drawChild(canvas, child, drawingTime); + if (parentLayout != null) { + int actionBarHeight = 0; + int childCount = getChildCount(); + for (int a = 0; a < childCount; a++) { + View view = getChildAt(a); + if (view == child) { + continue; + } + if (view instanceof ActionBar && view.getVisibility() == VISIBLE) { + if (((ActionBar) view).getCastShadows()) { + actionBarHeight = view.getMeasuredHeight(); + } + break; + } + } + parentLayout.drawHeaderShadow(canvas, actionBarHeight); + } + return result; + } else { + return super.drawChild(canvas, child, drawingTime); + } + } + }; FrameLayout frameLayout = (FrameLayout) fragmentView; avatarImage = new BackupImageView(context); @@ -882,10 +916,52 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter layoutParams = (FrameLayout.LayoutParams) writeButton.getLayoutParams(); layoutParams.topMargin = (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0) + AndroidUtilities.getCurrentActionBarHeight() + actionBar.getExtraHeight() - AndroidUtilities.dp(29.5f); writeButton.setLayoutParams(layoutParams); - ViewProxy.setAlpha(writeButton, diff); - writeButton.setVisibility(diff <= 0.02 ? View.GONE : View.VISIBLE); - if (writeButton.getVisibility() == View.GONE) { - writeButton.clearAnimation(); + + //ViewProxy.setScaleX(writeButton, diff > 0.2f ? 1.0f : diff / 0.2f); + //ViewProxy.setScaleY(writeButton, diff > 0.2f ? 1.0f : diff / 0.2f); + //ViewProxy.setAlpha(writeButton, diff > 0.2f ? 1.0f : diff / 0.2f); + final boolean setVisible = diff > 0.2f; + boolean currentVisible = writeButton.getTag() == null; + if (setVisible != currentVisible) { + if (setVisible) { + writeButton.setTag(null); + writeButton.setVisibility(View.VISIBLE); + } else { + writeButton.setTag(0); + } + if (writeButtonAnimation != null) { + AnimatorSetProxy old = writeButtonAnimation; + writeButtonAnimation = null; + old.cancel(); + } + writeButtonAnimation = new AnimatorSetProxy(); + if (setVisible) { + writeButtonAnimation.setInterpolator(new DecelerateInterpolator()); + writeButtonAnimation.playTogether( + ObjectAnimatorProxy.ofFloat(writeButton, "scaleX", 1.0f), + ObjectAnimatorProxy.ofFloat(writeButton, "scaleY", 1.0f), + ObjectAnimatorProxy.ofFloat(writeButton, "alpha", 1.0f) + ); + } else { + writeButtonAnimation.setInterpolator(new AccelerateInterpolator()); + writeButtonAnimation.playTogether( + ObjectAnimatorProxy.ofFloat(writeButton, "scaleX", 0.2f), + ObjectAnimatorProxy.ofFloat(writeButton, "scaleY", 0.2f), + ObjectAnimatorProxy.ofFloat(writeButton, "alpha", 0.0f) + ); + } + writeButtonAnimation.setDuration(150); + writeButtonAnimation.addListener(new AnimatorListenerAdapterProxy() { + @Override + public void onAnimationEnd(Object animation) { + if (writeButtonAnimation != null && writeButtonAnimation.equals(animation)) { + writeButton.clearAnimation(); + writeButton.setVisibility(setVisible ? View.VISIBLE : View.GONE); + writeButtonAnimation = null; + } + } + }); + writeButtonAnimation.start(); } avatarImage.setRoundRadius(AndroidUtilities.dp(avatarSize / 2)); @@ -926,7 +1002,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter needLayout(); fragmentView.getViewTreeObserver().removeOnPreDrawListener(this); } - return false; + return true; } }); } @@ -945,7 +1021,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter avatarImage.setImage(photo, "50_50", avatarDrawable); avatarImage.getImageReceiver().setVisible(!PhotoViewer.getInstance().isShowingImage(photoBig), false); - nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name)); + nameTextView.setText(UserObject.getUserName(user)); onlineTextView.setText(LocaleController.getString("Online", R.string.Online)); avatarImage.getImageReceiver().setVisible(!PhotoViewer.getInstance().isShowingImage(photoBig), false); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/StickersActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/StickersActivity.java index ce76b2d02..0fd9958b1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/StickersActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/StickersActivity.java @@ -99,18 +99,18 @@ public class StickersActivity extends BaseFragment implements NotificationCenter @Override public void onItemClick(AdapterView adapterView, View view, final int i, long l) { if (i >= stickersStartRow && i < stickersEndRow && getParentActivity() != null) { - final TLRPC.TL_stickerSet stickerSet = StickersQuery.getStickerSets().get(i); - ArrayList stickers = StickersQuery.getStickersForSet(stickerSet.id); - if (stickers == null) { + final TLRPC.TL_messages_stickerSet stickerSet = StickersQuery.getStickerSets().get(i); + ArrayList stickers = stickerSet.documents; + if (stickers == null || stickers.isEmpty()) { return; } - StickersAlert alert = new StickersAlert(getParentActivity(), stickerSet, stickers); + StickersAlert alert = new StickersAlert(getParentActivity(), stickerSet); alert.setButton(AlertDialog.BUTTON_NEGATIVE, LocaleController.getString("Close", R.string.Close), (Message) null); - if (stickerSet.id != -1) { + if ((stickerSet.set.flags & 4) == 0) { alert.setButton(AlertDialog.BUTTON_NEUTRAL, LocaleController.getString("StickersRemove", R.string.StickersRemove), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - StickersQuery.removeStickersSet(getParentActivity(), stickerSet); + StickersQuery.removeStickersSet(getParentActivity(), stickerSet.set, 0); } }); } @@ -132,7 +132,7 @@ public class StickersActivity extends BaseFragment implements NotificationCenter private void updateRows() { rowCount = 0; - ArrayList stickerSets = StickersQuery.getStickerSets(); + ArrayList stickerSets = StickersQuery.getStickerSets(); if (!stickerSets.isEmpty()) { stickersStartRow = 0; stickersEndRow = stickerSets.size(); @@ -192,6 +192,37 @@ public class StickersActivity extends BaseFragment implements NotificationCenter return false; } + private void processSelectionOption(int which, TLRPC.TL_messages_stickerSet stickerSet) { + if (which == 0) { + StickersQuery.removeStickersSet(getParentActivity(), stickerSet.set, (stickerSet.set.flags & 2) == 0 ? 1 : 2); + } else if (which == 1) { + StickersQuery.removeStickersSet(getParentActivity(), stickerSet.set, 0); + } else if (which == 2) { + try { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + intent.putExtra(Intent.EXTRA_TEXT, String.format(Locale.US, "https://telegram.me/addstickers/%s", stickerSet.set.short_name)); + getParentActivity().startActivityForResult(Intent.createChooser(intent, LocaleController.getString("StickersShare", R.string.StickersShare)), 500); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } else if (which == 3) { + try { + if (Build.VERSION.SDK_INT < 11) { + android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); + clipboard.setText(String.format(Locale.US, "https://telegram.me/addstickers/%s", stickerSet.set.short_name)); + } else { + android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); + android.content.ClipData clip = android.content.ClipData.newPlainText("label", String.format(Locale.US, "https://telegram.me/addstickers/%s", stickerSet.set.short_name)); + clipboard.setPrimaryClip(clip); + } + Toast.makeText(getParentActivity(), LocaleController.getString("LinkCopied", R.string.LinkCopied), Toast.LENGTH_SHORT).show(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + } + @Override public View getView(int i, View view, ViewGroup viewGroup) { int type = getItemViewType(i); @@ -203,17 +234,22 @@ public class StickersActivity extends BaseFragment implements NotificationCenter @Override public void onClick(View v) { StickerSetCell cell = (StickerSetCell) v.getParent(); - final TLRPC.TL_stickerSet stickerSet = cell.getStickersSet(); + final TLRPC.TL_messages_stickerSet stickerSet = cell.getStickersSet(); AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setTitle(stickerSet.set.title); CharSequence[] items; - if (stickerSet.id == -1) { - builder.setTitle(LocaleController.getString("GeniusStickerPackName", R.string.GeniusStickerPackName)); + final int[] options; + if ((stickerSet.set.flags & 4) != 0) { + options = new int[]{0, 2, 3}; items = new CharSequence[]{ - StickersQuery.getHideMainStickersPack() ? LocaleController.getString("StickersShow", R.string.StickersShow) : LocaleController.getString("StickersHide", R.string.StickersHide) + (stickerSet.set.flags & 2) == 0 ? LocaleController.getString("StickersHide", R.string.StickersHide) : LocaleController.getString("StickersShow", R.string.StickersShow), + LocaleController.getString("StickersShare", R.string.StickersShare), + LocaleController.getString("StickersCopy", R.string.StickersCopy), }; } else { - builder.setTitle(stickerSet.title); + options = new int[]{0, 1, 2, 3}; items = new CharSequence[]{ + (stickerSet.set.flags & 2) == 0 ? LocaleController.getString("StickersHide", R.string.StickersHide) : LocaleController.getString("StickersShow", R.string.StickersShow), LocaleController.getString("StickersRemove", R.string.StickersRemove), LocaleController.getString("StickersShare", R.string.StickersShare), LocaleController.getString("StickersCopy", R.string.StickersCopy), @@ -222,46 +258,14 @@ public class StickersActivity extends BaseFragment implements NotificationCenter builder.setItems(items, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - if (which == 0) { - if (stickerSet.id == -1) { - StickersQuery.setHideMainStickersPack(!StickersQuery.getHideMainStickersPack()); - listAdapter.notifyDataSetChanged(); - StickersQuery.loadStickers(true, false); - } else { - StickersQuery.removeStickersSet(getParentActivity(), stickerSet); - } - } else if (which == 1) { - try { - Intent intent = new Intent(Intent.ACTION_SEND); - intent.setType("text/plain"); - intent.putExtra(Intent.EXTRA_TEXT, String.format(Locale.US, "https://telegram.me/addstickers/%s", stickerSet.short_name)); - getParentActivity().startActivityForResult(Intent.createChooser(intent, LocaleController.getString("StickersShare", R.string.StickersShare)), 500); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } else if (which == 2) { - try { - if (Build.VERSION.SDK_INT < 11) { - android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); - clipboard.setText(String.format(Locale.US, "https://telegram.me/addstickers/%s", stickerSet.short_name)); - } else { - android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); - android.content.ClipData clip = android.content.ClipData.newPlainText("label", String.format(Locale.US, "https://telegram.me/addstickers/%s", stickerSet.short_name)); - clipboard.setPrimaryClip(clip); - } - Toast.makeText(getParentActivity(), LocaleController.getString("LinkCopied", R.string.LinkCopied), Toast.LENGTH_SHORT).show(); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } + processSelectionOption(options[which], stickerSet); } }); - //builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); showDialog(builder.create()); } }); } - ArrayList arrayList = StickersQuery.getStickerSets(); + ArrayList arrayList = StickersQuery.getStickerSets(); ((StickerSetCell) view).setStickersSet(arrayList.get(i), i != arrayList.size() - 1); } else if (type == 1) { if (view == null) { diff --git a/TMessagesProj/src/main/res/drawable-hdpi/arrow_down_w.png b/TMessagesProj/src/main/res/drawable-hdpi/arrow_down_w.png deleted file mode 100755 index deca1e6e9..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/arrow_down_w.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/bot_info.png b/TMessagesProj/src/main/res/drawable-hdpi/bot_info.png new file mode 100644 index 000000000..51f0232d2 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/bot_info.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/bot_keyboard.png b/TMessagesProj/src/main/res/drawable-hdpi/bot_keyboard.png new file mode 100644 index 000000000..e045972d8 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/bot_keyboard.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/bot_keyboard2.png b/TMessagesProj/src/main/res/drawable-hdpi/bot_keyboard2.png new file mode 100755 index 000000000..d43df46ce Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/bot_keyboard2.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/bot_keyboard_button.9.png b/TMessagesProj/src/main/res/drawable-hdpi/bot_keyboard_button.9.png new file mode 100644 index 000000000..55777ab32 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/bot_keyboard_button.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/bot_keyboard_button_pressed.9.png b/TMessagesProj/src/main/res/drawable-hdpi/bot_keyboard_button_pressed.9.png new file mode 100644 index 000000000..15a03df75 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/bot_keyboard_button_pressed.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_contact.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_contact.png new file mode 100755 index 000000000..671f56f99 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_contact.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_contact_big.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_contact_big.png new file mode 100755 index 000000000..147f8b75e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_contact_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_file_big.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_file_big.png new file mode 100755 index 000000000..26abdde73 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_file_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_gallery_big.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_gallery_big.png new file mode 100755 index 000000000..e207259c6 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_gallery_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_hide_big.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_hide_big.png new file mode 100755 index 000000000..20940dec1 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_hide_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_hide_big_icon.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_hide_big_icon.png new file mode 100755 index 000000000..e50515231 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_hide_big_icon.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_location_big.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_location_big.png new file mode 100755 index 000000000..8e76cff4f Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_location_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_music.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_music.png new file mode 100755 index 000000000..5a8f5cf4e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_music.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_music_big.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_music_big.png new file mode 100755 index 000000000..a5c7a37ca Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_music_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_photo_big.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_photo_big.png new file mode 100755 index 000000000..1c38eae49 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_photo_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_photobig.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_photobig.png new file mode 100755 index 000000000..ca397177e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_photobig.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_send_big.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_send_big.png new file mode 100755 index 000000000..b5e897664 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_send_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_send_big_icon.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_send_big_icon.png new file mode 100755 index 000000000..92f8b2dd4 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_send_big_icon.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_video_big.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_video_big.png new file mode 100755 index 000000000..7bb7aca4f Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/ic_attach_video_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/ic_msg_panel_hide.png b/TMessagesProj/src/main/res/drawable-hdpi/ic_msg_panel_hide.png deleted file mode 100755 index 40977e866..000000000 Binary files a/TMessagesProj/src/main/res/drawable-hdpi/ic_msg_panel_hide.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/search_down.png b/TMessagesProj/src/main/res/drawable-hdpi/search_down.png new file mode 100755 index 000000000..f7831fa7a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/search_down.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/search_up.png b/TMessagesProj/src/main/res/drawable-hdpi/search_up.png new file mode 100755 index 000000000..41839a16b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/search_up.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/arrow_down_w.png b/TMessagesProj/src/main/res/drawable-mdpi/arrow_down_w.png deleted file mode 100755 index 02ad9766d..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/arrow_down_w.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/bot_info.png b/TMessagesProj/src/main/res/drawable-mdpi/bot_info.png new file mode 100644 index 000000000..0939e7282 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/bot_info.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/bot_keyboard.png b/TMessagesProj/src/main/res/drawable-mdpi/bot_keyboard.png new file mode 100644 index 000000000..0e9f59a4c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/bot_keyboard.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/bot_keyboard2.png b/TMessagesProj/src/main/res/drawable-mdpi/bot_keyboard2.png new file mode 100755 index 000000000..200acbe00 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/bot_keyboard2.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/bot_keyboard_button.9.png b/TMessagesProj/src/main/res/drawable-mdpi/bot_keyboard_button.9.png new file mode 100644 index 000000000..d84e51881 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/bot_keyboard_button.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/bot_keyboard_button_pressed.9.png b/TMessagesProj/src/main/res/drawable-mdpi/bot_keyboard_button_pressed.9.png new file mode 100644 index 000000000..094720870 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/bot_keyboard_button_pressed.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_contact.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_contact.png new file mode 100755 index 000000000..b7ca453f5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_contact.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_contact_big.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_contact_big.png new file mode 100755 index 000000000..6d32ff13c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_contact_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_file_big.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_file_big.png new file mode 100755 index 000000000..3fad1cebb Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_file_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_gallery_big.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_gallery_big.png new file mode 100755 index 000000000..d70963a25 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_gallery_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_hide_big.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_hide_big.png new file mode 100755 index 000000000..cb21c7882 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_hide_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_hide_big_icon.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_hide_big_icon.png new file mode 100755 index 000000000..1bc52abd5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_hide_big_icon.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_location_big.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_location_big.png new file mode 100755 index 000000000..cc02b3201 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_location_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_music.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_music.png new file mode 100755 index 000000000..3440214d1 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_music.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_music_big.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_music_big.png new file mode 100755 index 000000000..6c576c5b7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_music_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_photo_big.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_photo_big.png new file mode 100755 index 000000000..cf44d89e4 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_photo_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_photobig.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_photobig.png new file mode 100755 index 000000000..f4a9297d4 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_photobig.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_send_big.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_send_big.png new file mode 100755 index 000000000..afcfb0aad Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_send_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_send_big_icon.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_send_big_icon.png new file mode 100755 index 000000000..a8e54f409 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_send_big_icon.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_video_big.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_video_big.png new file mode 100755 index 000000000..67ac2e3c7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/ic_attach_video_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/ic_msg_panel_hide.png b/TMessagesProj/src/main/res/drawable-mdpi/ic_msg_panel_hide.png deleted file mode 100755 index d926efa47..000000000 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/ic_msg_panel_hide.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/search_down.png b/TMessagesProj/src/main/res/drawable-mdpi/search_down.png new file mode 100755 index 000000000..143e47d83 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/search_down.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/search_up.png b/TMessagesProj/src/main/res/drawable-mdpi/search_up.png new file mode 100755 index 000000000..9c3d94a2b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/search_up.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/arrow_down_w.png b/TMessagesProj/src/main/res/drawable-xhdpi/arrow_down_w.png deleted file mode 100755 index a94e1d57b..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/arrow_down_w.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/bot_info.png b/TMessagesProj/src/main/res/drawable-xhdpi/bot_info.png new file mode 100644 index 000000000..2fb49d276 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/bot_info.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/bot_keyboard.png b/TMessagesProj/src/main/res/drawable-xhdpi/bot_keyboard.png new file mode 100644 index 000000000..af078978d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/bot_keyboard.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/bot_keyboard2.png b/TMessagesProj/src/main/res/drawable-xhdpi/bot_keyboard2.png new file mode 100755 index 000000000..6a672a795 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/bot_keyboard2.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/bot_keyboard_button.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/bot_keyboard_button.9.png new file mode 100644 index 000000000..7f5fd2a7a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/bot_keyboard_button.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/bot_keyboard_button_pressed.9.png b/TMessagesProj/src/main/res/drawable-xhdpi/bot_keyboard_button_pressed.9.png new file mode 100644 index 000000000..66fe8b30e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/bot_keyboard_button_pressed.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_contact.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_contact.png new file mode 100755 index 000000000..6fdc58b0b Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_contact.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_contact_big.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_contact_big.png new file mode 100755 index 000000000..b81f418de Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_contact_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_file_big.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_file_big.png new file mode 100755 index 000000000..ef152d004 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_file_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_gallery_big.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_gallery_big.png new file mode 100755 index 000000000..8c2fe6748 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_gallery_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_hide_big.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_hide_big.png new file mode 100755 index 000000000..1c0ab496f Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_hide_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_hide_big_icon.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_hide_big_icon.png new file mode 100755 index 000000000..ef92c839c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_hide_big_icon.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_location_big.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_location_big.png new file mode 100755 index 000000000..0294c218f Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_location_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_music.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_music.png new file mode 100755 index 000000000..12336bf80 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_music.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_music_big.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_music_big.png new file mode 100755 index 000000000..eec779844 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_music_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_photo_big.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_photo_big.png new file mode 100755 index 000000000..8a2056eca Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_photo_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_photobig.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_photobig.png new file mode 100755 index 000000000..67a9bf2ea Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_photobig.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_send_big.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_send_big.png new file mode 100755 index 000000000..69742eb45 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_send_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_send_big_icon.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_send_big_icon.png new file mode 100755 index 000000000..be41c7288 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_send_big_icon.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_video_big.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_video_big.png new file mode 100755 index 000000000..5dfd67b6c Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_video_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/ic_msg_panel_hide.png b/TMessagesProj/src/main/res/drawable-xhdpi/ic_msg_panel_hide.png deleted file mode 100755 index b09776f75..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/ic_msg_panel_hide.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/search_down.png b/TMessagesProj/src/main/res/drawable-xhdpi/search_down.png new file mode 100755 index 000000000..2b8bd80cc Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/search_down.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/search_up.png b/TMessagesProj/src/main/res/drawable-xhdpi/search_up.png new file mode 100755 index 000000000..a212e27c0 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/search_up.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/arrow_down_w.png b/TMessagesProj/src/main/res/drawable-xxhdpi/arrow_down_w.png deleted file mode 100755 index e7710ef9a..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/arrow_down_w.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/bot_info.png b/TMessagesProj/src/main/res/drawable-xxhdpi/bot_info.png new file mode 100644 index 000000000..278975633 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/bot_info.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/bot_keyboard.png b/TMessagesProj/src/main/res/drawable-xxhdpi/bot_keyboard.png new file mode 100644 index 000000000..67b0fa4de Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/bot_keyboard.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/bot_keyboard2.png b/TMessagesProj/src/main/res/drawable-xxhdpi/bot_keyboard2.png new file mode 100755 index 000000000..b75abe5c3 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/bot_keyboard2.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/bot_keyboard_button.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/bot_keyboard_button.9.png new file mode 100644 index 000000000..58fccc6e9 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/bot_keyboard_button.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/bot_keyboard_button_pressed.9.png b/TMessagesProj/src/main/res/drawable-xxhdpi/bot_keyboard_button_pressed.9.png new file mode 100644 index 000000000..dba2a36bc Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/bot_keyboard_button_pressed.9.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_contact.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_contact.png new file mode 100755 index 000000000..cf1a4bbd6 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_contact.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_contact_big.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_contact_big.png new file mode 100755 index 000000000..71f9be5bc Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_contact_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_file_big.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_file_big.png new file mode 100755 index 000000000..50294ed72 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_file_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_gallery_big.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_gallery_big.png new file mode 100755 index 000000000..7aaa8baa6 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_gallery_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_hide_big.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_hide_big.png new file mode 100755 index 000000000..a00c94dba Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_hide_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_hide_big_icon.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_hide_big_icon.png new file mode 100755 index 000000000..28b2e4b14 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_hide_big_icon.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_location_big.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_location_big.png new file mode 100755 index 000000000..13ba2eaa7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_location_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_music.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_music.png new file mode 100755 index 000000000..7317d7295 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_music.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_music_big.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_music_big.png new file mode 100755 index 000000000..e6383e095 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_music_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_photo_big.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_photo_big.png new file mode 100755 index 000000000..824b9f6ef Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_photo_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_photobig.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_photobig.png new file mode 100755 index 000000000..db8c53ae1 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_photobig.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_send_big.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_send_big.png new file mode 100755 index 000000000..91ebc55d6 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_send_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_send_big_icon.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_send_big_icon.png new file mode 100755 index 000000000..d7f0a3d01 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_send_big_icon.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_video_big.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_video_big.png new file mode 100755 index 000000000..fd4e0ce8e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_video_big.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_msg_panel_hide.png b/TMessagesProj/src/main/res/drawable-xxhdpi/ic_msg_panel_hide.png deleted file mode 100755 index 2c9359e25..000000000 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/ic_msg_panel_hide.png and /dev/null differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/search_down.png b/TMessagesProj/src/main/res/drawable-xxhdpi/search_down.png new file mode 100755 index 000000000..55352cb7d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/search_down.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/search_up.png b/TMessagesProj/src/main/res/drawable-xxhdpi/search_up.png new file mode 100755 index 000000000..35730561d Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/search_up.png differ diff --git a/TMessagesProj/src/main/res/drawable/bot_keyboard_states.xml b/TMessagesProj/src/main/res/drawable/bot_keyboard_states.xml new file mode 100644 index 000000000..15083a9e1 --- /dev/null +++ b/TMessagesProj/src/main/res/drawable/bot_keyboard_states.xml @@ -0,0 +1,15 @@ + + + + + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/chat_loading_layout.xml b/TMessagesProj/src/main/res/layout/chat_loading_layout.xml deleted file mode 100644 index 7d15e8b0d..000000000 --- a/TMessagesProj/src/main/res/layout/chat_loading_layout.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - diff --git a/TMessagesProj/src/main/res/layout/chat_unread_layout.xml b/TMessagesProj/src/main/res/layout/chat_unread_layout.xml deleted file mode 100644 index 13832bbf5..000000000 --- a/TMessagesProj/src/main/res/layout/chat_unread_layout.xml +++ /dev/null @@ -1,33 +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 b3877943f..8cbb7ef3a 100644 --- a/TMessagesProj/src/main/res/values-ar/strings.xml +++ b/TMessagesProj/src/main/res/values-ar/strings.xml @@ -99,6 +99,7 @@ موقع مقطع مرئي ملف + الكاميرا ...لا توجد رسائل بعد الرسالة المعاد توجيهها من @@ -128,6 +129,7 @@ جاري جلب معلومات الرابط... فتح في المتصفح انسخ الرابط + أرسل %1$s %1$s قام بتعيين عداد التدمير الذاتي إلى to %2$s لقد قمت بتعيين التدمير الذاتي إلى %1$s @@ -245,7 +247,6 @@ حدث خطأ. ملصقات - العقول العظيمة الرسامون مرحب بهم ليصنعوا حزم ملصقات عن طريق مراسلة @stickers .\n\nيمكن إضافة هذه الحزم بالضغط مرتين على الملصق واختيار \"معلومات\" — \"إضافة الملصقات\". إضافة ملصق إضافة إلى الملصقات @@ -294,7 +295,7 @@ اشترك صديق في تيليجرام PEBBLE اللغة - نرجو الأخذ بالعلم أن الدعم الفني في تيليجرام يقوم به مجموعة من المتطوعين. نحاول الرد بسرعة قدر المستطاع، لكن ربما نستغرق القليل من الوقت.
]]>يرجى الإطلاع على الأسئلة الشائعة عن تيليجرام]]>: يوجد بها حلول للمشاكل وإجابات لمعظم الأسئلة.
+ نرجو الأخذ بالعلم أن الدعم الفني في تيليجرام يقوم به مجموعة من المتطوعين. نحن نحاول الرد بسرعة قدر المستطاع، لكن ربما نستغرق القليل من الوقت.
]]> صفحة الأسئلة الأكثر شيوعًا]]>: يوجد بها حلول للمشاكل وإجابات لمعظم الأسئلة.
اسأل أحد المتطوعين الأسئلة الشائعة عن تيليجرام https://telegram.org/faq/ar @@ -528,6 +529,16 @@ تم تحرير الفيديو جارٍ إرسال المقطع المرئي... اضغط المقطع المرئي + + البوت + مشاركة + إضافة إلى المجموعة + الإعدادات + مساعدة + يستطيع الوصول للرسائل + لا يستطيع الوصول للرسائل + ماذا يستطيع هذا البوت عمله؟ + إبدأ التالي رجوع @@ -570,7 +581,7 @@ un1 قام بإضافتك un1 عاد إلى المجموعة لقد عدت إلى المجموعة - نسخة تيليجرام الموجودة لديك لا تدعم هذه الرسالة. الرجاء التحديث لأحدث نسخة: http://telegram.org/update + نسخة تيليجرام الموجودة لديك لا تدعم هذه الرسالة. الرجاء التحديث لأحدث نسخة لاستعراضها: https://telegram.org/update صورة مقطع مرئي موقع @@ -595,13 +606,16 @@ لا يوجد لديك تطبيق يمكنه فتح \'%1$s\'، يرجى تنزيل تطبيق مناسب للإستمرار هذا المستخدم ليس لديه تيليجرام بعد ، هل ترغب في دعوته الآن؟ هل أنت متأكد؟ - هل ترغب في إضافة %1$s للمجموعة؟\n\nعدد الرسائل الحديثة المراد إعادة تحويلها: + هل ترغب في إضافة %1$s للمجموعة %2$s؟ + عدد الرسائل الحديثة المراد إعادة تحويلها: + إضافة %1$s للمجموعة؟ + هذا المستخدم عضو مسبق في هذه المجموعة ؟%1$s هل تريد إعادة توجيه الرسائل إلى هل ترغب في إرسال رسالة إلى %1$s؟ نرجو الأخذ بالعلم أنه يمكنك استخدام تيليجرام على أجهزتك المتعددة بسهولة تامة وفي وقت واحد.\n\nوتذكر، تسجيل الخروج يحذف كافة محادثاتك السرية. هل أنت متأكد من تسجيل الخروج من جميع الأجهزة الأخرى باستثناء هذا الجهاز؟ هل أنت متأكد من أنك تريد حذف المجموعة والخروج منها؟ - هل أنت متأكد من رغبتك في حذف المجموعة؟ + هل أنت متأكد من رغبتك في حذف المحادثة؟ هل أنت متأكد من أنك تريد مشاركة معلومات جهة الاتصال الخاصة بك؟ هل أنت متأكد من رغبتك في حظر جهة الاتصال هذه؟ هل أنت متأكد من رغبتك في إزالة الحظر عن جهة الاتصال هذه؟ @@ -613,6 +627,8 @@ هل ترغب في إرسال رسالة إلى %1$s؟ ؟%1$s هل تريد إعادة توجيه الرسائل إلى .Sorry, this feature is currently not available in your country + لا يوجد حساب تيليجرام بهذا الاسم. + هذا البوت لا يستطيع الدخول للمجموعات. تيليجرام سريع @@ -738,6 +754,12 @@ %1$d ملصقات %1$d ملصق %1$d ملصق + %1$d صور + %1$d صورة + %1$d صور + %1$d صور + %1$d صور + %1$d صور %1$d رسالة معاد توجيهها الرسالة المعاد توجيهها @@ -805,6 +827,6 @@ h:mm a %1$s الساعة %2$s - تيليجرام نسخة الـ Android تم تحديثه. الجديد في نسخة ٢.٩:\n\n- تنصيب ومشاركة الملصقات كهذه: https://telegram.me/addstickers/Animals\n- إذا كنت رسام، قم بصنع حزمة ملصقات عن طريق مراسلة @stickers .\n\n - استخدم تيليجرام مع أندرويد أوتو. - 536 + تيليجرام نسخة الأندرويد تم تحديثه. الجديد في نسخة ٣.٠:\n\n- أقسام مخصصة خاصة ومرتبة لكل لحزم الملصقات. يمكنك إضافة حزم الملصقات كهذه https://telegram.me/addstickers/Animals\n- واجهة برمجية خاصة جديدة بالبوت، مجانًا للجميع. إذا كنت مبرمج، اصنع البوت الخاص بك مثل @quiz_bot و @hot_or_bot باستخدام حساب @botfather. للإستزادة، فضلًا اطلع على https://telegram.org/blog/bot-revolution + 551 \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-de/strings.xml b/TMessagesProj/src/main/res/values-de/strings.xml index a044f7818..df5390eb6 100644 --- a/TMessagesProj/src/main/res/values-de/strings.xml +++ b/TMessagesProj/src/main/res/values-de/strings.xml @@ -57,7 +57,7 @@ Stumm für %1$s Stumm aus In %1$s - Stumm aus + Dauerhaft Stumm HASHTAGS Neue Broadcast Liste @@ -99,6 +99,7 @@ Standort Video Datei + Kamera Noch keine Nachrichten… Weitergeleitete Nachricht Von @@ -128,6 +129,7 @@ Lade Linkvorschau... Im Browser öffnen URL kopieren + %1$s senden %1$s hat den Selbstzerstörungs-Timer auf %2$s gesetzt Du hast den Selbstzerstörungs-Timer auf %1$s gesetzt @@ -245,8 +247,7 @@ Es ist ein Fehler aufgetreten. Sticker - Große Denker - Künstler können eigene Sticker-Pakete über unseren Sticker Bot (@stickers) einstellen.\n\nNutzer fügen neue Sticker durch doppeltes Antippen (\"Doppelklick\") eines Stickers und dann \"Info\" — \"Sticker hinzufügen\" hinzu. + Künstler können eigene Sticker-Pakete über unseren Sticker Bot (@stickers) einstellen.\n\nNutzer fügen neue Sticker durch Antippen eines Stickers und dann \"Hinzufügen\" hinzu. Sticker hinzufügen Sticker hinzufügen Sticker nicht gefunden @@ -294,7 +295,7 @@ Kontakt ist Telegram beigetreten PEBBLE Sprache - Bedenke bitte, dass der Telegram Support von einem ehrenamtlichen Team betreut wird. Wir versuchen so schnell wie möglich zu antworten, dies kann jedoch manchmal ein bisschen dauern.
]]>Bitte schau auch in den Fragen und Antworten ]]> nach. Dort findest du Antworten auf die meisten Fragen und wichtige Tipps zur Problembehandlung]]>.
+ Bedenke bitte, dass der Telegram Support von ehrenamtlichen Helfern betreut wird. Wir versuchen so schnell wie möglich zu antworten, dies kann jedoch manchmal ein bisschen dauern.
]]>Bitte schau auch in den Fragen und Antworten ]]> nach. Dort findest du Antworten auf die meisten Fragen und wichtige Tipps zur Problembehandlung]]>.
Eine Frage stellen Fragen und Antworten https://telegram.org/faq/de @@ -378,7 +379,7 @@ Ungültiger Pincode Pincode falsch Auto-Sperre - Benötigt Pincode wenn lange inaktiv. + Sperrt App bei Inaktivität automatisch. in %1$s Deaktiviert @@ -528,6 +529,16 @@ Bearbeitetes Video Sende Video... Video komprimieren + + Bot + Teilen + Zu einer Gruppe hinzufügen + Einstellungen + Hilfe + Zugriff auf Nachrichten + kein Zugriff auf Nachrichten + Was kann dieser Bot? + STARTEN Weiter Zurück @@ -570,7 +581,7 @@ un1 hat dich hinzugefügt un1 ist in die Gruppe zurückgekehrt Du bist 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 + Diese Nachricht wird von deiner Telegram-Version nicht unterstützt. Bitte aktualisiere Telegram um sie zu sehen: https://telegram.org/update Foto Video Standort @@ -595,7 +606,10 @@ Du hast keine Applikationen, die den Dateityp \'%1$s\' öffnen könnten. Bitte installiere eine entsprechende Anwendung um fortzufahren. Dieser Benutzer hat noch kein Telegram. Möchtest du ihn einladen? Bist du sicher? - %1$s zur Gruppe hinzufügen?\n\nAnzahl der letzten Nachrichten für die Weiterleitung: + %1$s zur Gruppe %2$s hinzufügen? + Wieviele der letzten Nachrichten willst du weiterleiten? + %1$s zur Gruppe hinzufügen? + Nutzer befindet sich schon in der Gruppe Nachrichten an %1$s weiterleiten? Nachricht an %1$s senden? Wirklich abmelden?\n\nDu kannst Telegram von all deinen Geräten gleichzeitig nutzen.\n\nWichtig: Abmelden löscht deine Geheimen Chats. @@ -613,6 +627,8 @@ Nachricht an %1$s senden? Weiterleiten an %1$s? Verzeihung, diese Funktion ist derzeit in deinem Land nicht verfügbar. + Kein Konto mit diesem Benutzernamen + Keine Gruppen mit diesem Bot möglich Telegram Schnell @@ -738,6 +754,12 @@ %1$d Sticker %1$d Sticker %1$d Sticker + %1$d Bilder + %1$d Bild + %1$d Bilder + %1$d Bilder + %1$d Bilder + %1$d Bilder %1$d angehängten Nachrichten Angehängte Nachricht @@ -805,6 +827,6 @@ h:mm a %1$s um %2$s - Telegram für Android wurde aktualisiert. Neu in Version 2.9:\n\n- Installiere und teile benutzerdefinierte Sticker-Pakete, wie z.B. dieses: https://telegram.me/addstickers/Animals\n- Künstler können eigene Sticker-Pakete über unseren Sticker Bot (@stickers) einstellen.\n\n- Benutze Telegram mit Android Auto (siehe android.com/auto) - 536 + Telegram für Android wurde aktualisiert. Neu in Version 3.0:\n\n- Neue Tabs im Sticker Panel für alle deine eigenen Sticker-Pakete. Füge neue Sticker wie beispielsweise https://telegram.me/addstickers/Animals hinzu.\n- Neue Bot API, für alle kostenlos verfügbar. Kannst du programmieren? Erstelle deine eigenen Bots für Spiele, Dienste oder Integrationen. Mehr dazu unter https://telegram.org/blog/bot-revolution + 551 \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-es/strings.xml b/TMessagesProj/src/main/res/values-es/strings.xml index 02eb45317..8cc0c49f4 100644 --- a/TMessagesProj/src/main/res/values-es/strings.xml +++ b/TMessagesProj/src/main/res/values-es/strings.xml @@ -99,6 +99,7 @@ Ubicación Vídeo Archivo + Cámara Aún sin mensajes... Mensaje reenviado De @@ -128,6 +129,7 @@ Obteniendo información... Abrir en el navegador Copiar URL + Enviar %1$s %1$s activó la autodestrucción en %2$s Activaste la autodestrucción en %1$s @@ -161,7 +163,7 @@ %1$s te expulsó del grupo %2$s %1$s dejó el grupo %2$s ¡%1$s se unió a Telegram! - %1$s,\nDetectamos un inicio de sesión en tu cuenta desde un nuevo dispositivo, el %2$s\n\nDispositivo: %3$s\nUbicación: %4$s\n\nSi no eras tú, puedes ir a Ajustes - Privacidad y seguridad - Cerrar todas las otras sesiones.\n\nSi crees que alguien ha iniciado la sesión sin tu consentimiento, puedes activar la verificación en dos pasos, en los ajustes de privacidad y seguridad.\n\nAtentamente,\nEl equipo de Telegram + %1$s,\nDetectamos un inicio de sesión en tu cuenta desde un nuevo dispositivo, el %2$s\n\nDispositivo: %3$s\nUbicación: %4$s\n\nSi no eras tú, puedes ir a Ajustes - Privacidad y seguridad - Sesiones activas y cerrar esa sesión.\n\nSi crees que alguien ha iniciado la sesión sin tu consentimiento, puedes activar la verificación en dos pasos, en los ajustes de privacidad y seguridad.\n\nAtentamente,\nEl equipo de Telegram %1$s actualizó su foto de perfil %1$s se unió al grupo %2$s con un enlace de invitación Responder @@ -245,7 +247,6 @@ Ocurrió un error. Stickers - Grandes personajes Los artistas pueden añadir sus propios packs de stickers usando el bot @stickers.\n\nLos usuarios pueden añadir stickers pulsando y eligiendo \"Añadir stickers\". Añadir stickers Añadir a stickers @@ -294,7 +295,7 @@ Un contacto se unió a Telegram PEBBLE Idioma - Por favor, considera que el soporte de Telegram está hecho por voluntarios. Respondemos lo antes posible, pero puede tomar tiempo.
]]>Si quieres, mira las preguntas frecuentes de Telegram]]>: tienen soluciones a problemas]]>, y respuestas para la mayoría de las preguntas.
+ Por favor, considera que el soporte de Telegram está hecho por voluntarios. Respondemos lo antes posible, pero puede tomar tiempo.
]]>Por favor, mira las preguntas frecuentes de Telegram]]>: tienen respuestas para la mayoría de las preguntas y soluciones a problemas]]>.
Preguntar Preguntas frecuentes https://telegram.org/faq/es @@ -528,6 +529,16 @@ Vídeo editado Enviando vídeo... Comprimir Vídeo + + bot + Compartir + Añadir a un grupo + Ajustes + Ayuda + tiene acceso a los mensajes + no tiene acceso a los mensajes + ¿Qué puede hacer este bot? + INICIAR Siguiente Atrás @@ -570,7 +581,7 @@ un1 te añadió un1 volvió al grupo Volviste al grupo - Este mensaje no lo admite tu versión de Telegram. Actualiza la app para verlo: http://telegram.org/update + Este mensaje no está soportado en tu versión de Telegram. Actualiza la aplicación para verlo: https://telegram.org/update Foto Vídeo Ubicación @@ -595,7 +606,10 @@ No tienes aplicaciones que puedan manejar el tipo de archivo \'%1$s\'. Por favor, instala una para continuar. Este usuario aún no tiene Telegram. ¿Enviarle una invitación? ¿Quieres hacerlo? - ¿Añadir a %1$s al grupo?\n\nNúmero de los últimos mensajes para reenviar: + ¿Añadir a %1$s al grupo %2$s? + Cantidad de últimos mensajes para reenviar: + ¿Añadir a %1$s al grupo? + Este usuario ya está en el grupo ¿Reenviar mensajes a %1$s? ¿Enviar mensajes a %1$s? ¿Quieres cerrar sesión?\n\nConsidera que puedes usar Telegram en todos tus dispositivos a la vez.\n\nRecuerda que, al cerrar sesión, eliminas todos tus chats secretos. @@ -613,6 +627,8 @@ ¿Enviar mensajes a %1$s? ¿Reenviar mensajes a %1$s? Lo siento, esta característica no está disponible en tu país actualmente. + No hay ninguna cuenta de Telegram con este alias. + Este bot no puede unirse a grupos. Telegram Rápida @@ -738,6 +754,12 @@ %1$d stickers %1$d stickers %1$d stickers + %1$d fotos + %1$d foto + %1$d fotos + %1$d fotos + %1$d fotos + %1$d fotos %1$d mensajes adjuntos Mensaje adjunto @@ -805,6 +827,6 @@ h:mm a %1$s a las %2$s - Telegram para Android fue actualizada. Novedades en la versión 2.9:\n\n- Instala y comparte packs de stickers personalizados como este: https://telegram.me/addstickers/Animals\n- Si eres un artista, crea packs de stickers personalizados usando nuestro bot @stickers.\n\n- Usa Telegram con Android Auto. - 536 + Telegram para Android fue actualizada. Novedades en la versión 3.0:\n\n- Pestañas dedicadas para cada uno de tus packs de stickers personalizados en el panel de stickers. Añade stickers personalizados como: https://telegram.me/addstickers/Animals\n- Nueva API para bots, gratis para todos. Si eres un ingeniero, crea tus propios bots para juegos, servicios o integraciones. Conoce más en: https://telegram.org/blog/bot-revolution + 551 \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-it/strings.xml b/TMessagesProj/src/main/res/values-it/strings.xml index 2fd334137..8b5e8022f 100644 --- a/TMessagesProj/src/main/res/values-it/strings.xml +++ b/TMessagesProj/src/main/res/values-it/strings.xml @@ -99,6 +99,7 @@ Posizione Video File + Foto Ancora nessun messaggio qui… Messaggio inoltrato Da @@ -119,7 +120,7 @@ Elimina questo gruppo Elimina questa chat ANNULLA - Salva in download + Salva nei download Condividi Applica traduzione Allegato non supportato @@ -128,6 +129,7 @@ Recupero le info del link... Apri nel Browser Copia URL + Invia %1$s %1$s ha impostato il timer di autodistruzione a %2$s Hai impostato il timer di autodistruzione a %1$s @@ -160,7 +162,7 @@ %1$s ha rimosso %3$s dal gruppo %2$s %1$s ti ha rimosso dal gruppo %2$s %1$s ha lasciato il gruppo %2$s - %1$s ha iniziato a usare Telegram! + %1$s si è unito a Telegram! %1$s,\nAbbiamo rilevato un accesso al tuo account da un nuovo dispositivo il %2$s\n\nDispositivo: %3$s\nPosizione: %4$s\n\nSe non sei stato tu, puoi andare su Impostazioni - Privacy e sicurezza - Sessioni - Termina tutte le sessioni.\n\nSe pensi che qualcuno si sia collegato al tuo account contro il tuo volere, ti raccomandiamo di attivare la verifica in due passaggi nelle impostazioni di Privacy e Sicurezza.\n\nGrazie,\nil team di Telegram %1$s ha aggiornato la foto del profilo %1$s si è unito al gruppo %2$s tramite link di invito @@ -245,8 +247,7 @@ Si è verificato un errore. Sticker - Grandi menti - Gli artisti sono invitati ad aggiungere i loro pacchetti di sticker usando il nostro bot @stickers.\n\nGli utenti possono aggiungere sticker premendo su di loro e scegliendo \"Aggiungi agli sticker\". + Gli artisti sono invitati ad aggiungere i loro set di sticker usando il nostro bot @stickers.\n\nGli utenti possono aggiungere sticker premendo su di loro e scegliendo \"Aggiungi agli sticker\". Aggiungi sticker Aggiungi agli sticker Sticker non trovati @@ -288,13 +289,13 @@ Solo se silenzioso Sfondo chat Messaggi - Spedisci con invio + Spedisci con Invio Termina le altre sessioni Eventi - Un contatto ha iniziato a usare Telegram + Un contatto si è unito a Telegram PEBBLE Lingua - Nota che il supporto di Telegram è fornito da volontari. Proviamo a rispondere non appena possibile, ma potrebbe richiedere del tempo.
]]>Dai un\'occhiata alle FAQ]]>: troverai risposte alla maggior parte delle domande e suggerimenti importanti per l\'individuazione del problema]]>.
+ Nota che il supporto di Telegram è fornito da volontari. Proviamo a rispondere non appena possibile, ma potrebbe volerci un pò.
]]>Dai un\'occhiata alle FAQdi Telegram]]>: troverai risposte alla maggior parte delle domande e suggerimenti importanti per l\'individuazione del problema]]>
Chiedi a un volontario FAQ di Telegram https://telegram.org/faq/it @@ -320,8 +321,8 @@ Predefinito di sistema Impostazioni predefinite Download automatico media - Quando si utilizza la rete dati - Quando si utilizza il Wi-Fi + Quando utilizzi la rete mobile + Quando connesso tramite Wi-Fi In roaming Nessun media Salva nella galleria @@ -528,6 +529,16 @@ Video modificato Inviando il video... Comprimi video + + bot + Condividi + Aggiungi a un gruppo + Impostazioni + Aiuto + ha accesso ai messaggi + non ha accesso ai messaggi + Cosa può fare questo bot? + AVVIA Avanti Indietro @@ -570,7 +581,7 @@ un1 ti ha aggiunto un1 è rientrato nel gruppo Sei rientrato nel gruppo - Questo messaggio non è supportato sulla tua versione di Telegram. Aggiorna l\'applicazione per visualizzarlo: http://telegram.org/update + Questo messaggio non è supportato sulla tua versione di Telegram. Aggiorna l\'applicazione per visualizzarlo: https://telegram.org/update Foto Video Posizione @@ -595,7 +606,10 @@ Non hai nessuna applicazione che può gestire il tipo di file \'%1$s\': installane una per proseguire Questo utente non ha ancora Telegram, vuoi invitarlo? Sei sicuro? - Aggiungere %1$s al gruppo?\n\nNumero di messaggi recenti da inoltrare: + Aggiungere %1$s al gruppo %2$s? + Numero di ultimi messaggi da inoltrare: + Aggiungere %1$s al gruppo? + Questo utente è già membro del gruppo Vuoi inoltrare i messaggi a %1$s? Inviare i messaggi a %1$s? Sei sicuro di volerti disconnettere?\n\nRicorda che puoi usare Telegram su tutti i tuoi device insieme.\n\nRicorda, disconnettersi elimina tutte le Chat Segrete. @@ -613,6 +627,8 @@ Inviare messaggi a %1$s? Inoltra messaggi a %1$s? Ci spiace, questa funzione non è disponibile nel tuo paese. + Non esiste alcun account Telegram con questo username. + Questo bot non può unirsi ai gruppi. Telegram Veloce @@ -625,7 +641,7 @@ Telegram]]> consegna i messaggi più]]>velocemente di qualsiasi altra app. Telegram]]> sarà sempre gratuito.]]>Nessuna pubblicità. Nessun abbonamento. Telegram]]> protegge i tuoi messaggi]]>dagli attacchi degli hacker. - Telegram]]> non ha limiti sulle dimensioni]]>dei tuoi file multimediali e delle chat. + Telegram]]> non ha limiti di dimensione]]>per le tue chat e i file multimediali. Telegram]]> ti consente di accedere]]>ai messaggi da più dispositivi. Telegram]]> cifra in maniera sicura i messaggi]]>e può far sì che si autodistruggano. Inizia a inviare messaggi @@ -738,6 +754,12 @@ %1$d sticker %1$d sticker %1$d sticker + %1$d foto + %1$d foto + %1$d foto + %1$d foto + %1$d foto + %1$d foto %1$d messaggi inoltrati Messaggio inoltrato @@ -805,6 +827,6 @@ h:mm a %1$s alle %2$s - Telegram per Android è stato aggiornato. Nuovo nella versione 2.9:\n\n- Installa e condividi pacchetti di sticker personalizzati come questo: https://telegram.me/addstickers/Animals\n- Se sei un artista, crea pacchetti di sticker utilizzando il nostro bot @stickers.\n\n- Usa Telegram con Android Auto. - 536 + Telegram per Android è stato aggiornato. Nuovo nella versione 3.0:\n\n- Pagine dedicate per ognuno dei tuoi pacchetti sticker nel pannello sticker. Aggiunti sticker personalizzati come https://telegram.me/addstickers/Animals\n- Nuova API per i bot, gratis per tutti. Se sei un ingegnere, crea i tuoi bot per giochi, servizi o integrazioni. Scopri di più su https://telegram.org/blog/bot-revolution + 551 \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-ko/strings.xml b/TMessagesProj/src/main/res/values-ko/strings.xml index e642f9979..f4eec4eeb 100644 --- a/TMessagesProj/src/main/res/values-ko/strings.xml +++ b/TMessagesProj/src/main/res/values-ko/strings.xml @@ -99,6 +99,7 @@ 위치 동영상 파일 + 카메라 메시지가 없습니다... 전달된 메시지 보낸 사람 @@ -128,6 +129,7 @@ 링크 정보를 가져오는 중... 브라우져에서 열기 URL 복사 + %1$s 전송 %1$s님이 자동삭제를 %2$s 후로 설정했습니다 자동삭제를 %1$s 후로 설정했습니다 @@ -245,8 +247,7 @@ 오류가 발생했습니다. 스티커 - Great Minds - \@stickers 봇을 통하여 누구든지 스스로 제작한 스티커를 등록 할 수 있습니다.\n\n스티커는 더블탭하여 \"스티커 추가\" 를 통하여 추가할 수 있습니다. + /@stickers 봇을 통하여 누구든지 스스로 제작한 스티커를 등록 할 수 있습니다.\n\n스티커는 더블탭하여 \"스티커 추가\" 를 통하여 추가할 수 있습니다. 스티커 추가 스티커 추가 스티커를 찾을 수 없음 @@ -294,7 +295,7 @@ 친구의 텔레그램 가입 알림 PEBBLE 스마트워치 지원 언어 - 텔레그램에 관한 질문은 자원봉사자들이 답변해 드립니다. 신속한 답변을 위해 노력하지만 답변이 다소 늦을 수 있습니다.
]]>일반적인 문제와 해결방법]]>에 대해서는 \'자주 묻는 질문]]>\'을 확인해 보세요.
+ 텔레그램에 관한 질문은 자원봉사자들이 답변해 드립니다. 신속한 답변을 위해 노력하지만 답변이 다소 늦을 수 있습니다.
]]>일반적인 문제와 해결방법]]>에 대해서는 \'자주 묻는 질문]]>\'을 확인해 보세요.
질문하기 자주 묻는 질문 https://telegram.org/faq/ko @@ -528,6 +529,16 @@ 편집한 동영상 동영상 보내는 중... 동영상 크기 줄이기 + + + 공유 + 그룹에 추가 + 설정 + 도움말 + 메시지 접근 권한이 있습니다. + 메시지 접근 권한이 없습니다 + 이 봇은 무엇을 할 수 있나요? + 시작 다음 뒤로 @@ -570,7 +581,7 @@ un1님이 그룹에 초대했습니다 un1 님께서 그룹에 돌아오셨습니다 그룹에 돌아오셨습니다. - 이 메시지는 사용 중인 텔레그램의 버전이 낮아 지원하지 않습니다. 앱을 업데이트 하세요: http://telegram.org/update + 이 메시지는 현재 사용 중인 버전의 Telegram에서 지원되지 않습니다. 메시지를 보려면 https://telegram.org/update 에서 앱을 업데이트하세요. 사진 동영상 위치 @@ -595,7 +606,10 @@ \'%1$s\' 파일 형식을 처리할 앱이 없습니다. 계속하려면 앱을 설치해 주세요. 친구가 아직 텔레그램을 사용하지 않네요. 초대해 보세요! 확실합니까? - %1$s님을 그룹에 초대할까요?\n\n전달할 최근 메시지 개수: + %2$s 그룹에 %1$s님을 추가할까요? + 전달할 마지막 대화내용 개수: + %1$s 님을 그룹에 추가할까요? + 이 사용자는 이미 그룹에 추가되었습니다. %1$s님에게 메시지를 전달할까요? %1$s님에게 메시지를 보낼까요? 정말로 로그아웃하시겠습니까?\n\n텔레그램은 여러 기기에서 동시에 사용이 가능합니다.\n\n로그아웃하시면 비밀대화가 삭제되는 점 유의해주세요. @@ -613,6 +627,8 @@ %1$s 그룹에 메시지를 보낼까요? %1$s 그룹에 메시지를 전달할까요? 이 기능은 회원님의 국가에서는 사용할 수 없습니다. + 입력된 아이디와 일치하는 텔레그램 계정이 없습니다. + 이 봇은 그룹에 참여 할 수 없습니다. 텔레그램 눈부신 속도 @@ -738,6 +754,12 @@ 스티커 %1$d개 스티커 %1$d개 스티커 %1$d개 + %1$d 개의 사진 + %1$d 개의 사진 + %1$d 개의 사진 + %1$d 개의 사진 + %1$d 개의 사진 + %1$d 개의 사진 %1$d 개의 전달된 메시지 전달된 메시지 @@ -805,6 +827,6 @@ a h:mm %1$s %2$s - 텔레그램 안드로이드 버전이 업데이트 되었습니다. 새로운 버전은 2.9 입니다:\n\n - 아래와 같은 커스텀 스티커 설치 및 공유 : https://telegram.me/addstickers/Animals\n - 커스텀 스티커를 신규로 생성하여 등록할 수 있는 @stickers 봇 활용\n\n - Android Auto와 텔레그램 호환 - 536 + 텔레그램 안드로이드 버전이 업데이트 되었습니다. 새로운 버전은 3.0 입니다:\n\n- 스티커 패널에 커스텀 스티커별 탭 지원. https://telegram.me/addstickers/Animals 와 같은 커스텀 스티커 추가 기능\n- 신규 봇 API를 무료로 공개합니다. 개발자라면 누구나 게임, 서비스나 통합 봇등 개발이 가능합니다. https://telegram.org/blog/bot-revolution 에서 자세한 사항을 알아보세요. + 551 \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-nl/strings.xml b/TMessagesProj/src/main/res/values-nl/strings.xml index 990c87af5..49562999d 100644 --- a/TMessagesProj/src/main/res/values-nl/strings.xml +++ b/TMessagesProj/src/main/res/values-nl/strings.xml @@ -99,6 +99,7 @@ Locatie Video Bestand + Camera Nog geen berichten Doorgestuurd bericht Van @@ -128,6 +129,7 @@ Link-preview ophalen... Openen in browser Link kopiëren + %1$s versturen %1$s heeft de zelfvernietigingstimer ingesteld op %2$s Je hebt de zelfvernietigingstimer ingesteld op %1$s @@ -245,10 +247,7 @@ Er is een fout opgetreden. Stickers - Grote geesten - Ontwerpers kunnen stickerbundels toevoegen via onze bot: @stickers. - -Gebruikers kunnen met een tik stickers toevoegen via \"Toevoegen aan stickers\". + Ontwerpers kunnen stickerbundels toevoegen via onze bot: @stickers.\n\nGebruikers kunnen met een tik stickers toevoegen via \"Toevoegen aan stickers\". Stickers toevoegen Toevoegen aan stickers Stickers niet gevonden @@ -282,7 +281,7 @@ Gebruikers kunnen met een tik stickers toevoegen via \"Toevoegen aan stickers\". Meldingen resetten Aangepaste meldingsinstellingen wissen voor contacten en groepen. Meldingen en geluiden - Geblokkeerde gebruikers + Geblokkeerd Uitloggen Geen geluid Standaard @@ -296,7 +295,7 @@ Gebruikers kunnen met een tik stickers toevoegen via \"Toevoegen aan stickers\". Contact lid van Telegram PEBBLE Taal - De ondersteuning van Telegram wordt gedaan door vrijwilligers.]]>We doen ons best om zo snel mogelijk te antwoorden.
]]>Bekijk ook de veelgestelde vragen]]>. Hier staan de antwoorden op de meeste vragen en belangrijke tips voor het oplossen van problemen]]>.
+ De ondersteuning van Telegram wordt gedaan door vrijwilligers. We doen ons best om zo snel mogelijk te antwoorden.
]]>Bekijk ook de veelgestelde vragen]]>: Hierhier staan de antwoorden op de meeste vragen en belangrijke tips voor het oplossen van problemen]]>.
Vraag een vrijwilliger Veelgestelde vragen https://telegram.org/faq @@ -530,6 +529,16 @@ Gebruikers kunnen met een tik stickers toevoegen via \"Toevoegen aan stickers\". Bewerkte video Video versturen Video comprimeren + + bot + Delen + Groepslid maken + Instellingen + Help + toegang tot berichten + geen toegang tot berichten + Wat kan deze bot? + BEGIN Volgende Vorige @@ -572,7 +581,7 @@ Gebruikers kunnen met een tik stickers toevoegen via \"Toevoegen aan stickers\". un1 heeft je toegevoegd un1 is terug in de groep Je keerde terug naar de groep - Dit bericht wordt niet ondersteund door jouw versie van Telegram. Werk Telegram bij om dit bericht te bekijken: http://telegram.org/update + Dit bericht wordt niet ondersteund door jouw versie van Telegram. Werk Telegram bij om dit bericht te bekijken: https://telegram.org/update Foto Video Locatie @@ -597,7 +606,10 @@ Gebruikers kunnen met een tik stickers toevoegen via \"Toevoegen aan stickers\". Je hebt geen apps die bestandstype \'%1$s\' kunnen verwerken, gelieve een compatibele app te installeren Deze gebruiker heeft nog geen Telegram. Wil je een uitnodiging sturen? Weet je het zeker? - %1$s toevoegen aan de groep?\n\nAantal recente berichten om door te sturen: + %1$s toevoegen aan de groep %2$s? + Aantal recente berichten om door te sturen: + %1$s toevoegen aan de groep? + Gebruiker neemt al deel aan de groep Berichten doorsturen naar %1$s? Berichten naar %1$s versturen? Weet je zeker dat je wilt uitloggen?\n\nTelegram kun je naadloos op al je apparaten tegelijkertijd gebruiken.\n\nLet op! Als je uitlogt worden al je geheime chats verwijderd. @@ -615,6 +627,8 @@ Gebruikers kunnen met een tik stickers toevoegen via \"Toevoegen aan stickers\". Berichten naar %1$s versturen? Berichten doorsturen naar %1$s? Sorry, deze functie is momenteel niet beschikbaar in jouw land. + Er is geen Telegram-account met deze gebruikersnaam. + Deze bot kan geen groepslid worden. Telegram Snel @@ -740,6 +754,12 @@ Gebruikers kunnen met een tik stickers toevoegen via \"Toevoegen aan stickers\". %1$d stickers %1$d stickers %1$d stickers + %1$d foto\'s + %1$d foto + %1$d foto\'s + %1$d foto\'s + %1$d foto\'s + %1$d foto\'s Bijlage: %1$d berichten Bijlage: 1 bericht @@ -807,6 +827,6 @@ Gebruikers kunnen met een tik stickers toevoegen via \"Toevoegen aan stickers\". h:mm a %1$s om %2$s - Telegram voor Android is geüpdatet. Nieuw in versie 2.9:\n\n- Deel en installeer stickerbundels zoals deze: https://telegram.me/addstickers/Animals\n- Ben je een ontwerper? Maak stickerbundels met onze bot: @stickers.\n\n- Gebruik Telegram met Android Auto. - 536 + Telegram voor Android is geüpdatet. Nieuw in versie 3.0:\n\n- Tabbladen voor al je eigen stickerbundels in het stickerpaneel. Voeg stickerbundels zoals: https://telegram.me/addstickers/Animals toe.\n- Nieuwe bot-API, gratis voor iedereen. Handig met programmeren? Maak dan je eigen bots voor spelletjes, diensten of integraties. Meer weten? kijk op: https://telegram.org/blog/bot-revolution + 551 \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-pt-rBR/strings.xml b/TMessagesProj/src/main/res/values-pt-rBR/strings.xml index ea42ce566..4b4e6d254 100644 --- a/TMessagesProj/src/main/res/values-pt-rBR/strings.xml +++ b/TMessagesProj/src/main/res/values-pt-rBR/strings.xml @@ -57,7 +57,7 @@ Silenciar por %1$s Restaurar Som Em %1$s - Desativado + Desativar HASHTAGS Nova Lista de Transmissão @@ -99,6 +99,7 @@ Localização Vídeo Arquivo + Câmera Ainda não há mensagens aqui... Mensagem encaminhada De @@ -128,6 +129,7 @@ Obtendo informações... Abrir no Navegador Copiar URL + Enviar %1$s %1$s estabeleceu o tempo de autodestruição para %2$s Você estabeleceu o tempo de autodestruição para %1$s @@ -245,7 +247,6 @@ Ocorreu um erro. Stickers - Grandes Mentes Artistas são bem vindos a adicionar seus próprios pacotes de stickers usando o @stickers bot.\n\nUsuários podem adicionar stickers com um clique sobre eles e então escolher \"Adicionar aos Stickers\". Adicionar Stickers Adicionar aos Stickers @@ -294,7 +295,7 @@ Contato entrou para o Telegram PEBBLE Idioma - Por favor compreenda que o Suporte do Telegram é feito por voluntários. Tentamos responder o mais rápido possível, mas pode demorar um pouco.
]]>Por favor acesse o FAQ do Telegram]]>: temos respostas para algumas questões, assim como dicas importantes à resolução de problemas]]>.
+ Por favor entenda que o suporte do Telegram é feito por voluntários. Tentaremos responder o mais rápido possível, mas poderemos demorar um pouco.
]]>Por favor verifique a página de perguntas frequentes do Telegram]]>: há dicas e respostas para a maioria dos problemas]]>.
Pergunte a um voluntário Perguntas frequentes https://telegram.org/faq @@ -341,7 +342,7 @@ O número %1$s já possui uma conta do Telegram. Por favor, exclua esta conta antes de migrar para o novo número. Outro Desativado - Desativar + Desativado Desativado Desativado Sons no Chat @@ -359,7 +360,7 @@ Nenhuma outra sessão ativa Você pode entrar no Telegram a partir de outro celular, tablet ou computador usando o mesmo número de telefone. Todos os seus dados serão sincronizados instantaneamente. Sessões Ativas - Controle suas sessões em outros aparelho. + Controle suas sessões em outros aparelhos. Toque em uma sessão para terminá-la. Encerrar essa sessão? aplicativo não oficial @@ -528,6 +529,16 @@ Vídeo Editado Enviando vídeo... Compactar Vídeo + + bot + Compartilhar + Adicionar Ao Grupo + Configurações + Ajuda + tem acesso as mensagens + não tem acesso as mensagens + O que esse bot pode fazer? + COMEÇAR Próximo Voltar @@ -570,7 +581,7 @@ un1 adicionou você un1 retornou ao grupo Você 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 + Esta mensagem não é suportada na sua versão do Telegram. Para visualiza-la atualize seu aplicativo em https://telegram.org/update Foto Vídeo Localização @@ -595,7 +606,10 @@ Você não possui um aplicativo que suporte o tipo de arquivo \'%1$s\', por favor instale um para continuar Este usuário ainda não possui Telegram, deseja enviar um convite? Você tem certeza? - Adicionar %1$s para o grupo?\n\nNúmero de últimas mensagens para encaminhar: + Adicionar %1$s ao grupo %2$s? + Número de mensagens antigas para encaminhar: + Adicionar %1$s no grupo? + Este usuário já está neste grupo Encaminhar mensagem para %1$s? 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. @@ -613,6 +627,8 @@ Enviar mensagens para %1$s? Encaminhar mensagem para %1$s? Desculpe, esta funcionalidade não está disponível para seu país. + Não há conta do Telegram com esse nome de usuário + Esse bot não pode entrar em grupos. Telegram Rápido @@ -738,6 +754,12 @@ %1$d stickers %1$d stickers %1$d stickers + %1$d fotos + %1$d foto + %1$d fotos + %1$d fotos + %1$d fotos + %1$d fotos %1$d mensagens encaminhadas Mensagem encaminhada @@ -805,6 +827,6 @@ h:mm a %1$s às %2$s - Seu Telegram para Android acaba de ser atualizado. Novidades da versão 2.9:\n\n- Instale e compartilhe pacotes de stickers customizados como esse: https://telegram.me/addstickers/Animals\n- Se você é um artista, crie stickers customizados usando o @stickers bot.\n\n- Use Telegram com Android Auto. - 536 + Seu Telegram para Android acaba de ser atualizado. Novo na versão 3.0:\n\n- Abas dedicadas para cada um dos pacotes customizados de stickers no painel de stickers. Adicione stickers customizados como https://telegram.me/addstickers/Animals\n- Nova API de bots, gratuita para todos. Se você for um engenheiro, crie seus próprios bots como @quiz_bot ou @hot_or_bot usando o @botfather. Leia mais em https://telegram.org/blog/bot-revolution + 551 \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-pt-rPT/strings.xml b/TMessagesProj/src/main/res/values-pt-rPT/strings.xml index 06a50d418..a544d799b 100644 --- a/TMessagesProj/src/main/res/values-pt-rPT/strings.xml +++ b/TMessagesProj/src/main/res/values-pt-rPT/strings.xml @@ -57,7 +57,7 @@ Silenciar por %1$s Restaurar Som Em %1$s - Desativado + Desativar HASHTAGS Nova Lista de Transmissão @@ -99,6 +99,7 @@ Localização Vídeo Arquivo + Câmera Ainda não há mensagens aqui... Mensagem encaminhada De @@ -128,6 +129,7 @@ Obtendo informações... Abrir no Navegador Copiar URL + Enviar %1$s %1$s estabeleceu o tempo de autodestruição para %2$s Você estabeleceu o tempo de autodestruição para %1$s @@ -245,7 +247,6 @@ Ocorreu um erro. Stickers - Grandes Mentes Artistas são bem vindos a adicionar seus próprios pacotes de stickers usando o @stickers bot.\n\nUsuários podem adicionar stickers com um clique sobre eles e então escolher \"Adicionar aos Stickers\". Adicionar Stickers Adicionar aos Stickers @@ -294,7 +295,7 @@ Contato entrou para o Telegram PEBBLE Idioma - Por favor compreenda que o Suporte do Telegram é feito por voluntários. Tentamos responder o mais rápido possível, mas pode demorar um pouco.
]]>Por favor acesse o FAQ do Telegram]]>: temos respostas para algumas questões, assim como dicas importantes à resolução de problemas]]>.
+ Por favor entenda que o suporte do Telegram é feito por voluntários. Tentaremos responder o mais rápido possível, mas poderemos demorar um pouco.
]]>Por favor verifique a página de perguntas frequentes do Telegram]]>: há dicas e respostas para a maioria dos problemas]]>.
Pergunte a um voluntário Perguntas frequentes https://telegram.org/faq @@ -341,7 +342,7 @@ O número %1$s já possui uma conta do Telegram. Por favor, exclua esta conta antes de migrar para o novo número. Outro Desativado - Desativar + Desativado Desativado Desativado Sons no Chat @@ -359,7 +360,7 @@ Nenhuma outra sessão ativa Você pode entrar no Telegram a partir de outro celular, tablet ou computador usando o mesmo número de telefone. Todos os seus dados serão sincronizados instantaneamente. Sessões Ativas - Controle suas sessões em outros aparelho. + Controle suas sessões em outros aparelhos. Toque em uma sessão para terminá-la. Encerrar essa sessão? aplicativo não oficial @@ -528,6 +529,16 @@ Vídeo Editado Enviando vídeo... Compactar Vídeo + + bot + Compartilhar + Adicionar Ao Grupo + Configurações + Ajuda + tem acesso as mensagens + não tem acesso as mensagens + O que esse bot pode fazer? + COMEÇAR Próximo Voltar @@ -570,7 +581,7 @@ un1 adicionou você un1 retornou ao grupo Você 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 + Esta mensagem não é suportada na sua versão do Telegram. Para visualiza-la atualize seu aplicativo em https://telegram.org/update Foto Vídeo Localização @@ -595,7 +606,10 @@ Você não possui um aplicativo que suporte o tipo de arquivo \'%1$s\', por favor instale um para continuar Este usuário ainda não possui Telegram, deseja enviar um convite? Você tem certeza? - Adicionar %1$s para o grupo?\n\nNúmero de últimas mensagens para encaminhar: + Adicionar %1$s ao grupo %2$s? + Número de mensagens antigas para encaminhar: + Adicionar %1$s no grupo? + Este usuário já está neste grupo Encaminhar mensagem para %1$s? 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. @@ -613,6 +627,8 @@ Enviar mensagens para %1$s? Encaminhar mensagem para %1$s? Desculpe, esta funcionalidade não está disponível para seu país. + Não há conta do Telegram com esse nome de usuário + Esse bot não pode entrar em grupos. Telegram Rápido @@ -738,6 +754,12 @@ %1$d stickers %1$d stickers %1$d stickers + %1$d fotos + %1$d foto + %1$d fotos + %1$d fotos + %1$d fotos + %1$d fotos %1$d mensagens encaminhadas Mensagem encaminhada @@ -805,6 +827,6 @@ h:mm a %1$s às %2$s - Seu Telegram para Android acaba de ser atualizado. Novidades da versão 2.9:\n\n- Instale e compartilhe pacotes de stickers customizados como esse: https://telegram.me/addstickers/Animals\n- Se você é um artista, crie stickers customizados usando o @stickers bot.\n\n- Use Telegram com Android Auto. - 536 + Seu Telegram para Android acaba de ser atualizado. Novo na versão 3.0:\n\n- Abas dedicadas para cada um dos pacotes customizados de stickers no painel de stickers. Adicione stickers customizados como https://telegram.me/addstickers/Animals\n- Nova API de bots, gratuita para todos. Se você for um engenheiro, crie seus próprios bots como @quiz_bot ou @hot_or_bot usando o @botfather. Leia mais em https://telegram.org/blog/bot-revolution + 551 \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-v21/styles.xml b/TMessagesProj/src/main/res/values-v21/styles.xml index b02410741..5f8d4a200 100644 --- a/TMessagesProj/src/main/res/values-v21/styles.xml +++ b/TMessagesProj/src/main/res/values-v21/styles.xml @@ -88,4 +88,11 @@ #000000 + + + + diff --git a/TMessagesProj/src/main/res/values/strings.xml b/TMessagesProj/src/main/res/values/strings.xml index 85ef4036e..903c5d2cd 100644 --- a/TMessagesProj/src/main/res/values/strings.xml +++ b/TMessagesProj/src/main/res/values/strings.xml @@ -1,7 +1,6 @@ - Telegram English @@ -99,6 +98,7 @@ Location Video File + Camera No messages here yet... Forwarded message From @@ -128,6 +128,7 @@ Getting Link Info... Open in Browser Copy URL + Send %1$s %1$s set the self-destruct timer to %2$s You set the self-destruct timer to %1$s @@ -245,7 +246,6 @@ An error occurred. Stickers - Great Minds Artists are welcome to add their own sticker packs using our @stickers bot.\n\nUsers can add stickers by tapping on them and choosing \"Add to Stickers\". Add Stickers Add to Stickers @@ -294,7 +294,7 @@ Contact joined Telegram PEBBLE Language - Please note that Telegram Support is done by volunteers. We try to respond as quickly as possible, but it may take a while.
]]>Please take a look at the Telegram FAQ]]>: it has answers to most questions and important tips for troubleshooting]]>.
+ Please note that Telegram Support is done by volunteers. We try to respond as quickly as possible, but it may take a while.
]]>Please take a look at the Telegram FAQ]]>: it has answers to most questions and important tips for troubleshooting]]>.
Ask a volunteer Telegram FAQ https://telegram.org/faq @@ -528,6 +528,16 @@ Edited Video Sending video... Compress Video + + bot + Share + Add to group + Settings + Help + has access to messages + has no access to messages + What can this bot do? + START Next Back @@ -570,7 +580,7 @@ un1 added you un1 returned to the group You returned to the group - This message is not supported on your version of Telegram. Update the app to view: http://telegram.org/update + This message is not supported on your version of Telegram. Update the app to view: https://telegram.org/update Photo Video Location @@ -595,7 +605,10 @@ You don\'t have applications that can handle the file type \'%1$s\', please install one to continue This user does not have Telegram yet, send an invitation? Are you sure? - Add %1$s to the group?\n\nNumber of last messages to forward: + Add %1$s to the group %2$s? + Number of last messages to forward: + Add %1$s to the group? + This user is already in this group Forward messages to %1$s? Send messages to %1$s? Are you sure you want to log out?\n\nNote that you can seamlessly use Telegram on all your devices at once.\n\nRemember, logging out kills all your Secret Chats. @@ -613,6 +626,8 @@ Send messages to %1$s? Forward messages to %1$s? Sorry, this feature is currently not available in your country. + There is no Telegram account with this username. + This bot can\'t join groups. Telegram Fast @@ -738,6 +753,12 @@ %1$d stickers %1$d stickers %1$d stickers + %1$d photos + %1$d photo + %1$d photos + %1$d photos + %1$d photos + %1$d photos %1$d forwarded messages Forwarded message @@ -805,6 +826,6 @@ h:mm a %1$s at %2$s - Telegram for Android has been updated. New in version 2.9:\n\n- Install and share custom sticker sets like this one: https://telegram.me/addstickers/Animals\n- If you\'re an artist, create custom sticker sets using our @stickers bot.\n\n- Use Telegram with Android Auto. - 536 + Telegram for Android has been updated. New in version 3.0:\n\n- Dedicated tabs for each one of your custom sticker sets in the sticker panel. Add custom stickers like https://telegram.me/addstickers/Animals\n- New bot API, free for everyone. If you\'re an engineer, create your own bots for games, services or integrations. Learn more at https://telegram.org/blog/bot-revolution + 551
\ No newline at end of file diff --git a/TMessagesProj/src/main/res/values/styles.xml b/TMessagesProj/src/main/res/values/styles.xml index 9884ff93b..56449ed43 100644 --- a/TMessagesProj/src/main/res/values/styles.xml +++ b/TMessagesProj/src/main/res/values/styles.xml @@ -70,4 +70,11 @@ #000000 + + + + diff --git a/build.gradle b/build.gradle index 495c5038e..712b03d91 100644 --- a/build.gradle +++ b/build.gradle @@ -1 +1,9 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath 'com.android.tools.build:gradle:1.2.3' + } +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 5b258a3d9..27fd29715 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Nov 27 03:55:06 MSK 2014 +#Tue Jun 16 02:56:07 KRAT 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip