From a93d2994842ef694442a7ddf4e9be29e31ff0080 Mon Sep 17 00:00:00 2001 From: DrKLO Date: Mon, 29 Jun 2015 20:12:11 +0300 Subject: [PATCH] Update to 3.0.1 --- TMessagesProj/build.gradle | 14 +- TMessagesProj/jni/image.c | 6 +- .../libs/armeabi-v7a/libtmessages.8.so | Bin 1577868 -> 1577828 bytes TMessagesProj/libs/armeabi/libtmessages.8.so | Bin 1119076 -> 1119032 bytes TMessagesProj/libs/x86/libtmessages.8.so | Bin 1886124 -> 1865604 bytes .../SQLite/SQLitePreparedStatement.java | 16 + .../telegram/android/AndroidUtilities.java | 44 +- .../AnimationCompat/AnimatorSetProxy.java | 9 + .../telegram/android/ContactsController.java | 32 +- .../main/java/org/telegram/android/Emoji.java | 29 +- .../org/telegram/android/ImageLoader.java | 97 +- .../telegram/android/LocaleController.java | 2 +- .../org/telegram/android/MediaController.java | 82 +- .../org/telegram/android/MessageObject.java | 59 +- .../telegram/android/MessagesController.java | 187 ++- .../org/telegram/android/MessagesStorage.java | 133 +- .../telegram/android/NotificationCenter.java | 6 +- .../telegram/android/NotificationDelay.java | 29 - .../android/NotificationsController.java | 250 +-- .../telegram/android/SendMessagesHelper.java | 73 +- .../java/org/telegram/android/UserObject.java | 45 + .../org/telegram/android/query/BotQuery.java | 205 +++ .../android/query/MessagesSearchQuery.java | 137 ++ .../android/query/SharedMediaQuery.java | 10 +- .../telegram/android/query/StickersQuery.java | 366 +++-- .../android/support/widget/RecyclerView.java | 16 +- .../org/telegram/messenger/BuildVars.java | 2 +- .../messenger/ConnectionsManager.java | 147 +- .../telegram/messenger/HandshakeAction.java | 3 + .../java/org/telegram/messenger/TLRPC.java | 1037 ++++++++++--- .../org/telegram/messenger/UserConfig.java | 6 +- .../org/telegram/messenger/Utilities.java | 2 +- .../ui/ActionBar/ActionBarLayout.java | 58 +- .../ui/ActionBar/ActionBarMenuItem.java | 195 ++- .../ui/ActionBar/ActionBarPopupWindow.java | 238 ++- .../telegram/ui/ActionBar/BaseFragment.java | 45 +- .../telegram/ui/ActionBar/BottomSheet.java | 333 +++- .../ui/ActionBar/DrawerLayoutContainer.java | 15 +- .../telegram/ui/Adapters/DialogsAdapter.java | 51 +- .../ui/Adapters/DialogsSearchAdapter.java | 94 +- .../ui/Adapters/DrawerLayoutAdapter.java | 3 +- .../telegram/ui/Adapters/MentionsAdapter.java | 74 +- .../ui/Adapters/PhotoAttachAdapter.java | 123 ++ .../telegram/ui/Adapters/StickersAdapter.java | 2 +- .../org/telegram/ui/Cells/AddMemberCell.java | 9 +- .../java/org/telegram/ui/Cells/BaseCell.java | 5 + .../org/telegram/ui/Cells/BotHelpCell.java | 196 +++ .../org/telegram/ui/Cells/ChatAudioCell.java | 21 +- .../org/telegram/ui/Cells/ChatBaseCell.java | 53 +- .../telegram/ui/Cells/ChatLoadingCell.java | 51 + .../org/telegram/ui/Cells/ChatMediaCell.java | 6 +- .../telegram/ui/Cells/ChatMessageCell.java | 8 +- .../org/telegram/ui/Cells/ChatUnreadCell.java | 53 + .../org/telegram/ui/Cells/DialogCell.java | 53 +- .../telegram/ui/Cells/DrawerProfileCell.java | 4 +- .../org/telegram/ui/Cells/MentionCell.java | 23 +- .../ui/Cells/PhotoAttachCameraCell.java | 35 + .../ui/Cells/PhotoAttachPhotoCell.java | 85 ++ .../telegram/ui/Cells/ProfileSearchCell.java | 17 +- .../telegram/ui/Cells/SharedDocumentCell.java | 2 +- .../ui/Cells/SharedPhotoVideoCell.java | 2 +- .../org/telegram/ui/Cells/StickerSetCell.java | 32 +- .../java/org/telegram/ui/Cells/TextCell.java | 20 +- .../java/org/telegram/ui/Cells/UserCell.java | 25 +- .../org/telegram/ui/ChangePhoneActivity.java | 2 +- .../java/org/telegram/ui/ChatActivity.java | 1351 ++++++++++++----- .../telegram/ui/Components/AlertsCreator.java | 80 + .../ui/Components/BotKeyboardView.java | 126 ++ .../ui/Components/ChatActivityEnterView.java | 751 +++++---- .../ui/Components/ChatAttachView.java | 227 +++ .../org/telegram/ui/Components/EmojiView.java | 533 +++++-- .../org/telegram/ui/Components/LinkPath.java | 47 + .../PhotoViewerCaptionEnterView.java | 483 ++---- .../ui/Components/RecyclerListView.java | 2 +- .../ui/Components/ScrollSlidingTabStrip.java | 210 +++ .../Components/SizeNotifierFrameLayout.java | 51 +- ...java => SizeNotifierFrameLayoutPhoto.java} | 35 +- .../SizeNotifierRelativeLayout.java | 112 -- .../telegram/ui/Components/StickersAlert.java | 12 +- .../ui/Components/WebFrameLayout.java | 31 +- .../org/telegram/ui/ContactsActivity.java | 95 +- .../telegram/ui/CountrySelectActivity.java | 4 +- .../org/telegram/ui/GroupCreateActivity.java | 4 +- .../org/telegram/ui/IdenticonActivity.java | 8 +- .../telegram/ui/LanguageSelectActivity.java | 4 +- .../java/org/telegram/ui/LaunchActivity.java | 84 +- .../org/telegram/ui/LocationActivity.java | 16 +- .../java/org/telegram/ui/LoginActivity.java | 7 +- .../java/org/telegram/ui/MediaActivity.java | 13 +- .../org/telegram/ui/MessagesActivity.java | 126 +- .../ui/NotificationsSettingsActivity.java | 12 +- .../org/telegram/ui/PasscodeActivity.java | 2 +- .../telegram/ui/PhotoAlbumPickerActivity.java | 2 +- .../org/telegram/ui/PhotoPickerActivity.java | 4 +- .../java/org/telegram/ui/PhotoViewer.java | 200 ++- .../ui/PopupNotificationActivity.java | 135 +- .../java/org/telegram/ui/ProfileActivity.java | 220 ++- .../org/telegram/ui/SettingsActivity.java | 92 +- .../org/telegram/ui/StickersActivity.java | 96 +- .../main/res/drawable-hdpi/arrow_down_w.png | Bin 1362 -> 0 bytes .../src/main/res/drawable-hdpi/bot_info.png | Bin 0 -> 1666 bytes .../main/res/drawable-hdpi/bot_keyboard.png | Bin 0 -> 2441 bytes .../main/res/drawable-hdpi/bot_keyboard2.png | Bin 0 -> 1474 bytes .../drawable-hdpi/bot_keyboard_button.9.png | Bin 0 -> 198 bytes .../bot_keyboard_button_pressed.9.png | Bin 0 -> 201 bytes .../res/drawable-hdpi/ic_attach_contact.png | Bin 0 -> 1255 bytes .../drawable-hdpi/ic_attach_contact_big.png | Bin 0 -> 2861 bytes .../res/drawable-hdpi/ic_attach_file_big.png | Bin 0 -> 2685 bytes .../drawable-hdpi/ic_attach_gallery_big.png | Bin 0 -> 2726 bytes .../res/drawable-hdpi/ic_attach_hide_big.png | Bin 0 -> 2270 bytes .../drawable-hdpi/ic_attach_hide_big_icon.png | Bin 0 -> 1124 bytes .../drawable-hdpi/ic_attach_location_big.png | Bin 0 -> 3111 bytes .../res/drawable-hdpi/ic_attach_music.png | Bin 0 -> 1206 bytes .../res/drawable-hdpi/ic_attach_music_big.png | Bin 0 -> 3054 bytes .../res/drawable-hdpi/ic_attach_photo_big.png | Bin 0 -> 5454 bytes .../res/drawable-hdpi/ic_attach_photobig.png | Bin 0 -> 1696 bytes .../res/drawable-hdpi/ic_attach_send_big.png | Bin 0 -> 2285 bytes .../drawable-hdpi/ic_attach_send_big_icon.png | Bin 0 -> 1545 bytes .../res/drawable-hdpi/ic_attach_video_big.png | Bin 0 -> 2366 bytes .../res/drawable-hdpi/ic_msg_panel_hide.png | Bin 1351 -> 0 bytes .../main/res/drawable-hdpi/search_down.png | Bin 0 -> 1139 bytes .../src/main/res/drawable-hdpi/search_up.png | Bin 0 -> 1123 bytes .../main/res/drawable-mdpi/arrow_down_w.png | Bin 1182 -> 0 bytes .../src/main/res/drawable-mdpi/bot_info.png | Bin 0 -> 1369 bytes .../main/res/drawable-mdpi/bot_keyboard.png | Bin 0 -> 1836 bytes .../main/res/drawable-mdpi/bot_keyboard2.png | Bin 0 -> 1334 bytes .../drawable-mdpi/bot_keyboard_button.9.png | Bin 0 -> 218 bytes .../bot_keyboard_button_pressed.9.png | Bin 0 -> 214 bytes .../res/drawable-mdpi/ic_attach_contact.png | Bin 0 -> 1162 bytes .../drawable-mdpi/ic_attach_contact_big.png | Bin 0 -> 2293 bytes .../res/drawable-mdpi/ic_attach_file_big.png | Bin 0 -> 2125 bytes .../drawable-mdpi/ic_attach_gallery_big.png | Bin 0 -> 2238 bytes .../res/drawable-mdpi/ic_attach_hide_big.png | Bin 0 -> 1844 bytes .../drawable-mdpi/ic_attach_hide_big_icon.png | Bin 0 -> 1055 bytes .../drawable-mdpi/ic_attach_location_big.png | Bin 0 -> 2447 bytes .../res/drawable-mdpi/ic_attach_music.png | Bin 0 -> 1102 bytes .../res/drawable-mdpi/ic_attach_music_big.png | Bin 0 -> 2368 bytes .../res/drawable-mdpi/ic_attach_photo_big.png | Bin 0 -> 4069 bytes .../res/drawable-mdpi/ic_attach_photobig.png | Bin 0 -> 1376 bytes .../res/drawable-mdpi/ic_attach_send_big.png | Bin 0 -> 1844 bytes .../drawable-mdpi/ic_attach_send_big_icon.png | Bin 0 -> 1183 bytes .../res/drawable-mdpi/ic_attach_video_big.png | Bin 0 -> 1964 bytes .../res/drawable-mdpi/ic_msg_panel_hide.png | Bin 1165 -> 0 bytes .../main/res/drawable-mdpi/search_down.png | Bin 0 -> 982 bytes .../src/main/res/drawable-mdpi/search_up.png | Bin 0 -> 976 bytes .../main/res/drawable-xhdpi/arrow_down_w.png | Bin 1415 -> 0 bytes .../src/main/res/drawable-xhdpi/bot_info.png | Bin 0 -> 2005 bytes .../main/res/drawable-xhdpi/bot_keyboard.png | Bin 0 -> 3012 bytes .../main/res/drawable-xhdpi/bot_keyboard2.png | Bin 0 -> 1758 bytes .../drawable-xhdpi/bot_keyboard_button.9.png | Bin 0 -> 318 bytes .../bot_keyboard_button_pressed.9.png | Bin 0 -> 315 bytes .../res/drawable-xhdpi/ic_attach_contact.png | Bin 0 -> 1399 bytes .../drawable-xhdpi/ic_attach_contact_big.png | Bin 0 -> 3537 bytes .../res/drawable-xhdpi/ic_attach_file_big.png | Bin 0 -> 3074 bytes .../drawable-xhdpi/ic_attach_gallery_big.png | Bin 0 -> 3406 bytes .../res/drawable-xhdpi/ic_attach_hide_big.png | Bin 0 -> 2828 bytes .../ic_attach_hide_big_icon.png | Bin 0 -> 1173 bytes .../drawable-xhdpi/ic_attach_location_big.png | Bin 0 -> 3939 bytes .../res/drawable-xhdpi/ic_attach_music.png | Bin 0 -> 1272 bytes .../drawable-xhdpi/ic_attach_music_big.png | Bin 0 -> 3822 bytes .../drawable-xhdpi/ic_attach_photo_big.png | Bin 0 -> 4910 bytes .../res/drawable-xhdpi/ic_attach_photobig.png | Bin 0 -> 1921 bytes .../res/drawable-xhdpi/ic_attach_send_big.png | Bin 0 -> 2808 bytes .../ic_attach_send_big_icon.png | Bin 0 -> 1764 bytes .../drawable-xhdpi/ic_attach_video_big.png | Bin 0 -> 2867 bytes .../res/drawable-xhdpi/ic_msg_panel_hide.png | Bin 1439 -> 0 bytes .../main/res/drawable-xhdpi/search_down.png | Bin 0 -> 1054 bytes .../src/main/res/drawable-xhdpi/search_up.png | Bin 0 -> 1058 bytes .../main/res/drawable-xxhdpi/arrow_down_w.png | Bin 1774 -> 0 bytes .../src/main/res/drawable-xxhdpi/bot_info.png | Bin 0 -> 2366 bytes .../main/res/drawable-xxhdpi/bot_keyboard.png | Bin 0 -> 2644 bytes .../res/drawable-xxhdpi/bot_keyboard2.png | Bin 0 -> 2074 bytes .../drawable-xxhdpi/bot_keyboard_button.9.png | Bin 0 -> 315 bytes .../bot_keyboard_button_pressed.9.png | Bin 0 -> 321 bytes .../res/drawable-xxhdpi/ic_attach_contact.png | Bin 0 -> 1648 bytes .../drawable-xxhdpi/ic_attach_contact_big.png | Bin 0 -> 4898 bytes .../drawable-xxhdpi/ic_attach_file_big.png | Bin 0 -> 4297 bytes .../drawable-xxhdpi/ic_attach_gallery_big.png | Bin 0 -> 4425 bytes .../drawable-xxhdpi/ic_attach_hide_big.png | Bin 0 -> 3655 bytes .../ic_attach_hide_big_icon.png | Bin 0 -> 1301 bytes .../ic_attach_location_big.png | Bin 0 -> 5425 bytes .../res/drawable-xxhdpi/ic_attach_music.png | Bin 0 -> 1496 bytes .../drawable-xxhdpi/ic_attach_music_big.png | Bin 0 -> 5187 bytes .../drawable-xxhdpi/ic_attach_photo_big.png | Bin 0 -> 6368 bytes .../drawable-xxhdpi/ic_attach_photobig.png | Bin 0 -> 2487 bytes .../drawable-xxhdpi/ic_attach_send_big.png | Bin 0 -> 3664 bytes .../ic_attach_send_big_icon.png | Bin 0 -> 2009 bytes .../drawable-xxhdpi/ic_attach_video_big.png | Bin 0 -> 3909 bytes .../res/drawable-xxhdpi/ic_msg_panel_hide.png | Bin 1784 -> 0 bytes .../main/res/drawable-xxhdpi/search_down.png | Bin 0 -> 1136 bytes .../main/res/drawable-xxhdpi/search_up.png | Bin 0 -> 1125 bytes .../main/res/drawable/bot_keyboard_states.xml | 15 + .../main/res/layout/chat_loading_layout.xml | 27 - .../main/res/layout/chat_unread_layout.xml | 33 - .../src/main/res/values-ar/strings.xml | 36 +- .../src/main/res/values-de/strings.xml | 40 +- .../src/main/res/values-es/strings.xml | 36 +- .../src/main/res/values-it/strings.xml | 50 +- .../src/main/res/values-ko/strings.xml | 36 +- .../src/main/res/values-nl/strings.xml | 40 +- .../src/main/res/values-pt-rBR/strings.xml | 40 +- .../src/main/res/values-pt-rPT/strings.xml | 40 +- .../src/main/res/values-v21/styles.xml | 7 + TMessagesProj/src/main/res/values/strings.xml | 35 +- TMessagesProj/src/main/res/values/styles.xml | 7 + build.gradle | 8 + gradle/wrapper/gradle-wrapper.properties | 4 +- 207 files changed, 7675 insertions(+), 2931 deletions(-) delete mode 100644 TMessagesProj/src/main/java/org/telegram/android/NotificationDelay.java create mode 100644 TMessagesProj/src/main/java/org/telegram/android/UserObject.java create mode 100644 TMessagesProj/src/main/java/org/telegram/android/query/BotQuery.java create mode 100644 TMessagesProj/src/main/java/org/telegram/android/query/MessagesSearchQuery.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Adapters/PhotoAttachAdapter.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Cells/BotHelpCell.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatLoadingCell.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatUnreadCell.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoAttachCameraCell.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Cells/PhotoAttachPhotoCell.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/BotKeyboardView.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachView.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/LinkPath.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/ScrollSlidingTabStrip.java rename TMessagesProj/src/main/java/org/telegram/ui/Components/{SizeNotifierRelativeLayoutPhoto.java => SizeNotifierFrameLayoutPhoto.java} (61%) delete mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Components/SizeNotifierRelativeLayout.java delete mode 100755 TMessagesProj/src/main/res/drawable-hdpi/arrow_down_w.png create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/bot_info.png create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/bot_keyboard.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/bot_keyboard2.png create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/bot_keyboard_button.9.png create mode 100644 TMessagesProj/src/main/res/drawable-hdpi/bot_keyboard_button_pressed.9.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/ic_attach_contact.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/ic_attach_contact_big.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/ic_attach_file_big.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/ic_attach_gallery_big.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/ic_attach_hide_big.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/ic_attach_hide_big_icon.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/ic_attach_location_big.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/ic_attach_music.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/ic_attach_music_big.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/ic_attach_photo_big.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/ic_attach_photobig.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/ic_attach_send_big.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/ic_attach_send_big_icon.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/ic_attach_video_big.png delete mode 100755 TMessagesProj/src/main/res/drawable-hdpi/ic_msg_panel_hide.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/search_down.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/search_up.png delete mode 100755 TMessagesProj/src/main/res/drawable-mdpi/arrow_down_w.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/bot_info.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/bot_keyboard.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/bot_keyboard2.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/bot_keyboard_button.9.png create mode 100644 TMessagesProj/src/main/res/drawable-mdpi/bot_keyboard_button_pressed.9.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/ic_attach_contact.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/ic_attach_contact_big.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/ic_attach_file_big.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/ic_attach_gallery_big.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/ic_attach_hide_big.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/ic_attach_hide_big_icon.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/ic_attach_location_big.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/ic_attach_music.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/ic_attach_music_big.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/ic_attach_photo_big.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/ic_attach_photobig.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/ic_attach_send_big.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/ic_attach_send_big_icon.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/ic_attach_video_big.png delete mode 100755 TMessagesProj/src/main/res/drawable-mdpi/ic_msg_panel_hide.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/search_down.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/search_up.png delete mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/arrow_down_w.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/bot_info.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/bot_keyboard.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/bot_keyboard2.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/bot_keyboard_button.9.png create mode 100644 TMessagesProj/src/main/res/drawable-xhdpi/bot_keyboard_button_pressed.9.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_contact.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_contact_big.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_file_big.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_gallery_big.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_hide_big.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_hide_big_icon.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_location_big.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_music.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_music_big.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_photo_big.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_photobig.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_send_big.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_send_big_icon.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/ic_attach_video_big.png delete mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/ic_msg_panel_hide.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/search_down.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/search_up.png delete mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/arrow_down_w.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/bot_info.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/bot_keyboard.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/bot_keyboard2.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/bot_keyboard_button.9.png create mode 100644 TMessagesProj/src/main/res/drawable-xxhdpi/bot_keyboard_button_pressed.9.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_contact.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_contact_big.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_file_big.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_gallery_big.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_hide_big.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_hide_big_icon.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_location_big.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_music.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_music_big.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_photo_big.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_photobig.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_send_big.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_send_big_icon.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/ic_attach_video_big.png delete mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/ic_msg_panel_hide.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/search_down.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/search_up.png create mode 100644 TMessagesProj/src/main/res/drawable/bot_keyboard_states.xml delete mode 100644 TMessagesProj/src/main/res/layout/chat_loading_layout.xml delete mode 100644 TMessagesProj/src/main/res/layout/chat_unread_layout.xml 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 b73f401f35c8c469d5a1f408484f7aba4be7c688..ebbd6bff2bce9ac3270badf2050282985f259515 100755 GIT binary patch delta 9893 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

`T-!2bZyc>?1A delta 9966 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 diff --git a/TMessagesProj/libs/armeabi/libtmessages.8.so b/TMessagesProj/libs/armeabi/libtmessages.8.so index b720a57b42ff730e5a4d7795539888d849408515..fdd6919ec8db759572a2a2ce9114bbfd6d0a808b 100755 GIT binary patch delta 10193 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 a&GVv~WO(Q$Yp+)45!F4W$`LQ9i2omvc9`w} delta 10273 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 ZKCdn`z0}BF_|>^p9p-~PxVpFI{{hZ}jxGQI diff --git a/TMessagesProj/libs/x86/libtmessages.8.so b/TMessagesProj/libs/x86/libtmessages.8.so index 0b3e8df013ea2735a5ccd60cca6d8157d12548ae..22a2929199c233c10a6d7c9be49544a880b2d99c 100755 GIT binary patch delta 245035 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 o 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 SJ()Z|6@JUx{-gf}^M3&UsGQya delta 267038 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 z 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¨585X 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®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 z 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 deca1e6e91ed1fb154fc2dedb12d378ac2a309c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1362 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d43df46ce8f4352a2d31d67250cbb747bf5d3a20 GIT binary patch literal 1474 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbBBuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFe_z-M3hAM`dB6B=jtVb)aX^@765fKFxc2v6eK2Rr0UTq__OB&@Hb09I0xZL0)vRD^GUf^&XRs)DJWv2L<~p`n7AnVzAE zshOFfj)IYap^?4;5Si&3npl~dSs9rtK!Fm_wxX0Ys~{IQs9ivwtx`rwNr9EVetCJh zUb(Seeo?xx^|#0uTKVr7^KE~&-IMVSR9nfZANAQKal@=Hr> zm4GgVcpgi&u1T;Y}Gc(1?%+1-%!qmmm(9*@w(9qS?(!$Nn$;`~j#Kg_Q z)YaS>rq?AuximL5uLPzy1)HJXpQLXaYqimw9&k|$;>{7)p$WvApujG{dLgLJ4`<-gOie66~ zSvRc6+&HhPC~;Zz&&8n^j=t6AVsc#(J7ZzS7mfce#d8aH^OQ*Z$;v)zTV*p->uhn> z)(H#QE^b`>=lZ&g>ysA>ot~Y#+-?HXd8Vi(fAx+}TIXt=^+9{>*AEB#pE)dCs?U@b z+ZXyH=(MVknGsL+5y$!?4{fiw$G?hSXrHa|bb`kj&yToSNO_R~e5j^|fysW_{Jt9png9Cdfro^$k-%S96l zb1BhgjqKQMGXM65&A2}E%mnv>2lW@$@6G(V<$ICX?c;&mm0v2fe#{g96P_)W=JT2{ zS4gCRai3mc@r9xVuJeB1?fl5e(`0M#*15NXD{OMdnP1`V5vxAt77I45$}ElHDENIt nuJWPWitCf+Wrn*~2qrM>zdK#o|J&YMpiCO|9!pD&iwmFRq_F$$w&BJ>|fB>p)h?N&|wUou6{1-oD!MWdEuNj(ss7;68ir|3;mcW;7@baVm!5N{@kW1?f{{@BPxgxU7mo9C ze0}F(|KYI1w~d*GH_pWO*II5^zg~=6Y=(+jk#oSw--|=<0^P>o>FVdQ&MBb@02QB0 A$N&HU literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..671f56f99c2bd5fbb52f75faf549c0b1c44ccfc6 GIT binary patch literal 1255 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbBBuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFe_z-M3hAM`dB6B=jtVb)aX^@765fKFxc2v6eK2Rr0UTq__OB&@Hb09I0xZL0)vRD^GUf^&XRs)DJWv2L<~p`n7AnVzAE zshOFfj)IYap^?4;5Si&3npl~dSs9rtK!Fm_wxX0Ys~{IQs9ivwtx`rwNr9EVetCJh zUb(Seeo?xx^|#0uTKVr7^KE~&-IMVSR9nfZANAQKal@=Hr> zm4GgVcpgi&u1T;Y}Gc(1?&B@8o(!j{fz`)$h(9qS?(%8bx&Dhn@+`_=j z(ACHVrq?AuximL5uLPzy1)j23ho_mR$Ergh!BJd8Q{*C#X8h*b>uUC)L!zf zS4v| zcN_V3x+P^a$;5FU>29o07dRcD&8s@;p+pM9rP(fLUG~oBdRc0JRfdIU?*5R13-YU$ zDkdEIYoBylQBB6ytEzGO5ep5`l?xVcO%A%qD(QZ_-A&d-k%7a2VK0Z@A{)CD9Z=EZ M>FVdQ&MBb@0Ea7{FaQ7m literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..147f8b75e283de2c73ee45464cb81a1db772a79a GIT binary patch literal 2861 zcmaJ@c{r4N8=grs$U2c_h%t&r#*ASG!yL;X(lD0nGQ$jpW@%3^~4xq#Anbcsq3!O?6>}#W&0RSR! zhMOnfle7yT$Y$zM*D!ifOpcHZ0GOFaaj1b|bUrMA9?W17;Ip-N;4lV_0QbO>&?F9# z9>TDT=F(lG9o+(>!valcaPvQ4W>I*d0F%zA!lIaaSv-6c0sdVVFPyJ!qu{Xb5Plc| z{*Nh75*bEhbLlXwo&hott*;Nm;q>$ku{fN*E)0X#$Dq){8;8_4#A9)Ij1la|1s6u+ z(t_|V*0w)l30DMo2%pcvqfn8Nk$RB^dTeemO5eo9WK9EuK?)H_o`A)tMj=@|&7TU^ zbY38r!QnI5EZCYNHGmz?C%}bH|4D(#`6bKZ{WvD!fuW+P9F)EudM%}&KoaTyLz&E9 zXdd5%{;%KvDa>;daOfx(I*%RB4HOnGNOLU|2T$bEseCrqjm_Ts^AyP;Y(AS8!sft; zt~l5>4+e|Ij^rV}<4GjEJ&VVuvI6P$)&#gvL65NC)b)C7|x`#_&>R{f4Nq_<*u~?lOv35P3JNq=rmg{n+f}#GM@2! zFUG&s`@yCC-iyg^xhSC-)LLQxtI$8Ugx#|?{nfU@#jnPvvxMEw6}B~JZbkzD5Y4l< zwseacnDLut%kNfQ>DcSw;1hyiLh=i`-~qa)J;W@Tf|Qe}LjVPP00|AeXsemEEEAWs zF)?XNvXa|eVv_j!%DSB}C2N=)=t+PBL{Rz6`}VdnVGjUQD9*tN290khNyppz=Lh$EkLCPgC?d>VJ6Q?K5HDMU*xi!KwY`+)PaOT#v!tU1-? ztOpM_-iuouJqN$ADyv#Br#Xrl7b#PSb@&TeA~jn2)o703+!%eW%wM~?%2-WG3HWZ^ zt$2`HN%*EC=mXl#s)}H@xGRkUeK*2|?V*mSd*wjHsP^a?N|0pLNpONsQwJsVx^k+7 z8o)m}@t%&yiKRrrjethGIZ;li>Vnd)P5YqZ;Ua1vnM51;KPmGv@qzWBfRqMNRonR# z>cs`$8LSA`riW?VYJMoionPW1Ioesa8FMFD$>PQlUb3R(vetDdF(H14cU0QnRvYD^gta7bPx^~}DZDrgC2zD{0>nCXySE@$ZQmGcE z_L)E}3EjE2*Q_VxX$Fei-h3SRcRj5!TMGMldT^pEpYarM>_L~--8lE+z?P7-lOVs{ znD?E&bcoU_xq%pkyZVLX0wx1W!~*D zG#Shn_W~1g7+rT|RMYB~{#2yiD@8VS=_aY4TUS_EFhNt|^mfQPL1|qT#E!1fXv0fh zdzE;dvKNoXp`QKGx8KC#ewHsu5sQ&r?mw2AF}mH~eNsXhrm{kL)oy0c^3o3CGj)4t zD!(X$+UP`kyKSs5v#}eZRd3ck@ld->u2xHW=f#ejLmxj0?te)>zQa!f@0s&_lBVOi z`xTG$^;;llxaM--lcipZ+U=OayrV0Qf6cw|O;>nbG^iik#7Te1-5m1`XsUP?qpqN* z^S+1eb*rVOhFD93HV(#qq8~<^caT|eL@K3t(ayj^7vHC0ddhxkA+j*&hFsPs`kikE zLlqPipYzLr#k8BoM5xRDsncATWSw_;cZ42g$tq`dk9$u|e6we4mtr-2ih^v}QwPnz z1;X|DsmM-QCsC3%vN>mn(0YxTtvjjv4~#WU-|Sp!{mf}OQMs}4i{`Vi;#pu=`IC9? z%&Tc7J<%hHkk&d3*hsomen%(d$od-M1afNpLGH_}2u&jJ-;`Q#& zPeVhTi}JVXEw+6!jBg#0l&Z4*08lQ5If8b`k-uKTZ~@BTxptF1&EDx2V}Bnp9{HF6 zJPIy%2d$n4jQPv&W2VldUEg~&IebL5+*nq<)sJzloykEDKVU$k@Y1d3$gv39*F@6c zhO{eZ|QyfXlUD5_p6q>*)vBc1|aI)AI!XhV_Tud z?Go0i1KH6@Dwi}y5}Z=QU0klm-NmbYz4u132CLdSq)^wfmHl>dykxJm&q1-UY!wtg z#*Aa?6)ee#tU7aC@l{zJvbn0GL$OFHwcfJ#D)d6-JlqM z=9#L!QYZCRue&0BM`Ct7G8XAwVFQ7H&<&TmbZLnwr94t8|$J00i8bVIi@o$CDl`1N~U&+~k~-|y@Fet)j7*YoU%2oE-& zvtSMk1~X@c&^dY=Kl_*<_3x2A3bNif$QjY{C@4v;;7LJP03S*K(JT=!8RURGerDPY zkP3q#03kP89?cG;BtjxAZx(~i5J~iG7>w$lA>k#i2j%DlFj*+30prb=0kn`$16F&p zz1WfM*{@RVhW<-80}vCR3C z0v(hkN`(@+5E7$j6?q9zx|{~+BmFxCk>souFwCm@^s|Dht$ zXS7Vt0so2je+tXEnGz7k0cB9SG*REUBBD3Y$e*}$C^20GishfU{C~IsU*yh?f=HtGOb4aH4IrN>g+%BNDN}@Bj>YGT zdLOy`FULauA{VC*1~=Q-|7!H7BmMNuE zU~KI)#QkRe+oT7=`bBlI%O2PXkF;4wxfj=}dO{+L+)C!=hY;BeBK9!m^gFFTtia68 z)T+YHx!)jkf_oWJKf1#tl>_8LuuZZKz`7Fk!svQJpDosCm5d z^s8+E2FqN}O{A5M)ivhbNWs1QKDtvx?A?b#_!_q$iUD;IyZ~=eX5P0aIZ=?^z6xvo4I@7~nSxcMxz_VM$g3iA+SpUqCn80?s{%4pbly{38qr6rs`?UOe zha%^!vo@INVq8{_Z#Z6Qe6_K?a~>9!w?1F+`+c!yptfXkff#vrAZ4X+t)=2j*)E07 zgqT4tHlFIlc3vr5S}>Ggm+4sFQc~6)QQvRX5Kx$>ZvDCCHehlw5C87h6X*SZyjV;A z_B+Gh7}Odag2A-#t|g)&0l`>E7TLpSoa})Zc!!G51Br zvtOnTzf+^yQB!p^Sy#>CqeCm=&zo-30Q7*kW1c(v;4-d-&++ozRSi>bgNhj|M-M(KlT;dKA`h6a|`ngGK{lh{pyo?+@B6#9{OBW?#6rD7QO$j{6MbLX? zo7!#bXRPfp?je1-346-CU-pjEdZPEpFFF;^t*Z>{2y3!0-^ypga5mga8A3tyt##g5 zak%9cUf{5iYgkifUL(2vR>L(zyZ6|=$kOIotNA}158^jWIkTH6j}E+gVk}I(xg}I z2@c4(Q9A^IlXH%rrA-aR*lpZ)<@sbiqHl%Z{_n6TaHr9{i>?M5`=olfg__g&NDua^lRE)S1+f!Y^F2J^L}DOqWQ%#X&A4gl_XO1Z zZpzUhDzdVNu$Os?q*?d8&8vFNAA$vWH@vi#Ck_bZdRu*`he!eEcOOb8st^Q}pr2CC zJcdH3T`Rt}O~b2M_mpMr-D!)A4s~1n`9u45*e~J}^*rK@r>4ta3TWmBA`ijYM_2HV z5})V@x4?7J9BOzwuwxuU|7;tlJn)U=`Zsq$?os3oR;mF-Zq?w$(n))5-nD4268 z>KXLDyLs50)5>zOnxGc!zx$1Y#!Nn~Y)-pWY-2;6iHYYImekCHMq1XNyLBKzWu-HB zL{C^u72cTv7Q%-KGtO6$+g*j{@4N=Mj)TsrB!hcfELDBaztV&Y&fM>`w267~hRm=y zIzhQ*;@QSQXvr58`}<~kd%J6|N)cO3vt9qqv@HA%VNPSr!a?sP~PL zlu(1#^Z1`%Szlh8ExT-kieGr3Z8{*Bihg%Wo2|R~$QCg_+reO5MJv5F;$%0B@q7S6 z>W9x>L5NpNYo^|?FK`|;xJi$~N2R6}6PeaKx{`UrShcEB49gET%2d#PR5iU-$NAa6 zuqasg3tfy?wwztmr7XlqTYnnR2-W+6)}mzt&b;f$RQ07Tr-~jt1$3E#ImoHgPwivQ zBdWHYvM*?qZOh*}DxcKt%GPq~=i$!Hm>8(9jb;^~l2`nm6%gJLswFlIwc8J*A?Z$x zr2eTxs?oNg$K#b9)8Wg9cB*6RR3(E-nf6Gt&oZg4!8U3aK03_@`*nHtlB~1Yy{)ll z(j3cd{!_BhZueKRM_`pt#B-GES#6RR4*R4(XNJ&4mL?+@tAEoyE#&a7wf&JAWIJdw z=-eiHfh|~<+;QbudSh!_jbtY0N}Ml=Q)#w#(4_a3v7qU)^&S1^1#u1@YamjRR$ldc b#|ZU`7n=QAN>1~-TaxN+#AOdlql5xegma|;9l zL$ZDSL4V42VlbCuNngTP#&CFYHUzT8E`~=B4rhWu5Hpk=NkYDCmLLH(gM{2|O~Fuj zj!YKYHIC2R8RzL692XvJ%Rt&~1-8Tx#JmndH^9ix%JX9yTh zLjL2FKgA1hoQlv9`9hOBy&FN{&DYVk1F%3@TD!`c=V+ zDG27Xc_5n`2`nkngSb&32`TsVpAa~_Z?chsFKLn|3>`z~p|O^jrI5Y?DU|;Y<#4{C z1)vY}Uw{9nu)sH#$3*)u1>7ipu)J^~rc0)HL`Oc84s!XvTyDhIEPAoHAXmWR@&L!3 z1i*YZJCebT7Fc}7Qz%5YNC8NX3}(7Hk&to)OE#N9Bs*iBY+Nu{3?6TV#X4I%xY!bG zZEys#eAsLvTYu#`af72c%t-Jnm+>zb_g(H%D{y#n%T7!_dq0!m!sl{;&mj}p-}A-U z#pSztU$~6#`-1r{7cF-Ny;Ru$D)iSQdG{FQ@F#Uogs&fBp?TR}_crnN70RfJ%YMO-^xVUU@{JX_(oAf|WwR2q0-^T`9d%i} zz402jF-FHtQ?*QM=h?oil_-uuMtv%HbE^IiuyhVIT0Ar+u5S=qMK3g;L4WW$b$@Vr z=;h||LBUji(qN>G>qHvOA`x$I0GOzY;I0$N-S%kSn3Nizda5{Qjfe2EhwvBwtb^K3 z`fhtr8clHh)WF2RbVElCgcR`tRK(c0MlqNn7Tzcn0b`enjkVKw?*eTN;9Q9rGcZzsR86QGn=K790~IM1z_RR zgLwV?#A_SAvCk+?Ry{o1U!qnziejv2g5zb=3U!D*f8_F-6nP`e(*OX{dp{- z@7pi{2Ph9k)bse-LC%<=(OEr#eJP93T zkGe5V^{erK8q=X#`_K~wcYhW2gkWi~tIAEC4qUZ{^aB|-*PzD$Rnc-9Ni_RGx-BaV zl3tt^sQS2lZ_fcwd;wIW2Mkbpe3#ghxgXIEiPJyXnZIGX&}pBnBa3z;Ps*q@&TVf| zN-41)Q#@_Ux1orq|2q2X1FPKDM}v@+cDrVDclQqp6GqMOrQUz6pGaAG=-l0d4i7^i zV+(n&WCEW#{j+6eH7p-Rx&uDKfBBt+ix-p%Dt|ug*Hb&NcDQ8aA+pFU%@+kdHOHQ) z&c3)Jhzy!Ot6iy9<)@(G`dUwsk{3%op)G7WbH8eA>UDLtdNQinNKHvF zdUz^C@Aw$8^y0nt_z!S~!pS6yDecpl5uRYQ`PG~Ptcvoit6cit5DhJzAl7IKII6UrMr`)A&zf-Y)9a=FB zJ{c)=$BJexir^7>>V}dlX%B^`eRfE$B)3B@bxc^)d%u{p(e`d;Woy^!j5=sk#3bE@ z=!rnVDS5(V^*UQjX}F*{#0$?7vVrayce%QT}9TIOeQF-8pF`K)kfYoWZ&xi z(^Dq-Ej+ChC%LOkf6GI3UwBUyl{nkcs#|5|f1C7KXKyt<$>T zX>3$5GcUnO^j>((jUOEEdP(Z`u@(=%oNK;QGOBmJ7~ac6@B(Tk7Vqy%s$(;{Lfh@4 z?RVFOp9@U0ZTH8>#*r=0yd$zmNOM#)IQ`n0Y-KeP?oY zMD=uW)pn&pl|JFj(X*D9J;*yuUb>U&XdKnzcQy@Z3O1xj}Dra``gN zYPQbXS@Q-~YdH1I)5+pDHKjw|c4|5U1WL`^n+h*G%Xh81-oGwB`l0%!o4@YrTM2(v zt!jDIXI0QL*wV&^aHgFp>W^%E-Q5$q9e++1|1$kNbE_XYsE15&oz2Ls?AI)WDh$;& zPOqCeL@)PIJAd#~nH@Y3`f@~#u&HnxXk(v>VAV4$o1sCibJ#A|jyKmxEmYEhft4_; z><`xnH-@w^RP`&Iq!$r}iP!IkOk6VV5fjVA<`nnBAlkB~{7Kml$1mm1Yc3vKf2K}# z1T&T(5qsmFi{5QxPUtjhq(Whc+^=R2_ zhFF>LcsgMCN#(66K>hb!AA{TBN1l*1+&?|l4D+sOg5Fv-ux>njRpudW>rF;d#Z9_D zdRdq^l+LyrT0_#HctQ5b+Q)sa^9K85mZpf|$=;-BzhOIqro?%0LkH^+Mo?X{_G726 z?wKi6YMoesZY|F$Dt6fA?=`Qok9(p>Pkom~-j=M5V$p2sNO7M>dxdH2pr5@Z~8H;da>fMmeGT0g&5f^Zk73%UOTC>!Nnm{u}@EQEcyM}HFd(ECrR_( zf2D}`LU+`lScM(~13l83s}>D-t?*>s@z!OoF4a9N^7lULarye1J30IK`5qKQtkBM7i? zD<`FH4I56b9-g5Ww}s{u-Z-Gk07^nI6w7myC*ELWYcV7kH%@o;XCQ^-e-_~uL+pCI9G==ETX8NeIJ;!6RyR~bdn`fO!xeTG`T+9JrBrIXphJVy X2N}ldA8(sn`g3%1_H?Rtpe6kcH~)ue literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..20940dec1499bc2713933b8f8c7e5021b92f97aa GIT binary patch literal 2270 zcmaJ@Yg7|w8XgD)2sd%%Vig#|Vv(B51c)I8LPEktO`wQ^7AzqdND7mQ$zTGy7(x}$ z3SJO#7lES79)yxsT)Z!!LKUqFimpfz(P9v*+@$J)c4Ecuk7eh~e3$n;&+}fs_k3rH zVnvbmq>o4d0N6)I@#FA0#q?Pd@o}(R!@{S9m>>~bjizB5u?hybQZy9?qY-gB90!Y~ z*&8pz!2m!Y%i|NVMBys71VyM~6NaiqlsFpzf;n2HSdsx_U@Dw0SA>wCpJ^e3a%l)T zAy7ycD#Kx!JSs;8ug($0OL8(KK~gd&6b#m~aRCIz#Gn?*RH)h75b`@+Hoi8QX=Lyn z1j`5^{~lDLFcu6)RWKMx^`}Va5Ck%rR45>j$%K}H3_8T1(eal_fdbfpOg3XV`2Hc| z-c-^wb{s$Ay)S$hLY85el1-y&G#aYLpNgu|X;4s5kV%8Vpx_9KI$ME>wG@TgdscxD zt0gMA5|g6}(4;6%MYFIFG9KygDIm%ZvI_P4GT{ZIX~jw!M5UWjngt4l{~wAVAJA$n z4*nzF|0%4F&sM^;I9QElsU-NprFolNDcRvFSd5{ncofZ?tzxVU#Za{jRf6HGnV@fi zTp>j@>ZR}SLLoa^p~l1t2^`H2A>#^Exm?Qjr}KDBKE$O5;3Fgmb58?(0 z7!Yfg%SRFGI;g&+g~thZ+wZR6kp;8R~zP)=eZ5OItZdc3PzB+`xH+ zi$EU7ZD`WmHN()pzP0<<5q?;McPlK-w{1H$U`KbXuqd|jZ|fRZ{+-oyE9bthq%CrK zBJ`!mj&3zS%O}yg5wKmwA6C+L9^`e=T5hgtT6mVwFP$nfYtiJl4=hpIvsO&JxXIEN ze%iWWl%zF3>oE00)&f2cwYt~F{;tn*%<2=3`+;cq`J={VOrlhGrcE?T|8*ocuQSwo zlWy}##U5sLg=cZkw9dZ!LN4ddx4}Dzt1J!r^tL{r?a)H8+V!g^Y3~0 zTx5i_JWbnIJ3Qw1HQ(h1f^Gg+F8iIXZtlr{#q|dZ3KXm3C!uWxw}QBkZo~HE+t~?U z0k8UooVfG>>ywG?jyq5NQoMUentY?ZH^VvjT8Tfitjs57vjVtS)!EekJ+yqln`N~m zc;d7z+i&n~Ipq0ba-r@_RlnO3!GAoXc>7*dVqD+C&_&HhQ(Af^3CRJ`;R&}MZ?eez z)7aahq}v_mtXqGIsd{D{`K;ME6NBYv7wSDukgMY^zNK|EMZER~G@OGywMklUHwe?) z@VPC|tbON?3B4SXevWWG9(}yWu)mI4SWs!$Uow);Bd(tgbowdQ&}i+uV2qOIvekLy zsh%WQeZ|*_FuiT*kK4BptKVK9dh>(tz`;IE->3Cz|BW4=$3VLF^^$xyS>=G5w#A4j>6(*Xnld%eSYMxDIK~P@;+p; z(Ckf3jNPc~^DMW~wb=1p32Zy#Ja^}U4yU!Rj!bZzwz zkJTaV?8C{Lad+g=@dcSh)h{W1&1(<23N^#jb+uogD?6+wD)vnoH+?cwdYd0tqY_$N zG(2cNt9dx67<$`nEOZ!Nx~5~{7h*zBHs!>F`p>s%_vrp&Q(?7z_-gpkku9V8dzRVz z&0?yCWfP>{Ug(nHSe?Q->5hm-n#{4)t2=`m9b`5ND=+(C6-dg>27PWNJ!G+g;cXLX#j-v>GtZ^a%ygyAH%+aaEv_lRmcxGW?n*C# P>5n5?AmTUjQuMz8WEYfU literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..e50515231c683488ca329a28a5fb1d1748c287cb GIT binary patch literal 1124 zcmaJ=TWHfz7|u|qOzLI&;1uMLA>P)c>DF`&t)pw&SunG9g;h~7OU~A8CMPCmwkv|7 zbKXF_yeK|-87jKri%h&A^Fi=IaKc1oUJ>+3nK;)sJ(=tD!5WgB3*Yzs|M~y#98EMg zxhj@dP!#2gZxoYcTuHvldFAB4>6`JA3{^Oq#x1BFXJrdgVHLGO5ZC1nn1r(0v->d& zQq(M3OQmsI+9W7QXJiM%@@ zHk)O#wG6U4SS}C->OEa;C4B#lrZKxZEXp-sgBk1Og ztYJ@=i4=^@$tKG&9_L6!pd|ets_Qdo8zS5 zb$&0$MSYF_u)jVU<@~k0FVg6*D{@7obnDQ-MXvgXTVImvSV1>QWD#209;n7Fq=Ts= z3tH)1d?od!xoYWL_>x?fB*Qw5{j1T%E#e+$I%8Y1m@z&yh}$h<>)4lbt>j9)h>PJ= z?$wRaaK%H22G z7o8gK99cXuJaJmUjq88rkG%Oj)U;~s;^fcli47|w*DAkUTKeHfU)7!D-fh9YJFd)| zWiK+Gara2oMBjr2I}+y$dqsA#*YzryA3O7@xpQdfifiBY{`wWJ_m$gwAMJE8v6h>& zTQ3C89>4x{?b(CZ6ANw(uinDc3~#+Udrx7oeBB|t5I)fPZW$BP=U2a7F)*^^Wy85A ell|;i)BZB**yUu|=y!ImbMNEPW^u4_=Ye0a$bFaq literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..8e76cff4fb9b09bbf79504f8bc66aace94dd7b58 GIT binary patch literal 3111 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..a5c7a37caccc5508e9b31dec930f2fb66f74b832 GIT binary patch literal 3054 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..1c38eae491e80e370b6f9c029c57a6ca280f2e82 GIT binary patch literal 5454 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..92f8b2dd4c011f3aff080c55d47846b38c4657ab GIT binary patch literal 1545 zcmeAS@N?(olHy`uVBq!ia0vp^NXlw^r(L`iUdT1k0gQ7VIDN`6wR zf@f}GdTLN=VoGJ<$y6H#2IjQPkcg59UmvUF{9L_6kQ%*;+ybC(1_m4Zih{)C?9>v4 zq}24xJX@vryZ0+8WTx0Eg`4^s_!c;)W@LI)6{QAO`Gq7`WhYyvDB0U7*i={n4aiL` zNmQuF&B-gas<2f8n`;GRgM{^!6u?SKvTcwn`GuBNuFf>#!Gt)CP zF*P$Y)KM@pFf`IP03tJ8LlY}gGb`4?pZBPB7%B|o_|H#M)s)5TT^D5IB>nPO$`>S*BT zWaegKY+&MQYG`O-Vrl7WX>Md@kOD7AMUeCPZlEl2^RG7V)KzpHj9r5b5axO|uEXgkl$G8yO;GeeeCv{0lv$RV;#QQOs{jsPt4u8Rn**JW-`^0uDddEi zKF~4xpu~ZcSYSfH6bNF%lRl6G&pfGlz#LNq%o??Ue8CJ1OqQN5jv*Dd&dl)j2z3-W z{ygiaql(wBP5iuq;;#N2tcnGSTXb%Tv}kIo#nNZQswf{=AO8?#{z|*5Cg=KQqVpdGBUV}0%s`vP~TecXE7T4J?`A@+Ps zYn8B|qhe?qQ^~_xS-*p)S6DBaq%*U3?P1#rhS}S;JqwZyjHqVXoB2=HO=uE_rKxiP zcinESFs<(qYu2j@sl|l*ie{Fb>n|$%WEZ}iae1or_gpSL$K-V`KjbtgecR-7aI=M9 i&z`?UZQtS>7#X6Svdk|Xxmgb?oIPFrT-G@yGywovhbm$K literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..7bb7aca4f4a35d5e326596ac02f2da330b65e7fb GIT binary patch literal 2366 zcmaJ@dpy&7AOFo|ltwN|OWIk4$}TQrYhxH~J%$N6j>_2B&g^2FV-q#>M5T*vdeG%i z#MzN@>#{PPh-fr~QbyM&mpI)N)w6ZddH#5Mey`u}_xXOmulM`?x&HCp6&kz_G9Nl0 z000PuObXN5Slwp~*8WG1rFv=25^+G3cmqE{oJtom0bd3`jtQf1>50rRCY>QoZe!vB zKp)Nyj}k{wgK+VDE`qMZAS7IYmJI-SABlh-&tZyTam++Ej{tvpr4bHeGYIgF9#j-n z;Ll{S$!S97hP2@D_%u#DmI3$ihT$bRtpJxPro$xMB%TN-A;7=r; z2^k5vFjC-GU)mi3&Jv3SI3zMPH5HNShTsbmk!UOytJ83Gb!g**pe6Rpk5yPo?50Jdv2ri)T_u1h`fK!DcgXfdQ^)te-y$xuaCGq1^xJ;gSj?4I)i~cTGHws*V)-#DIWdFis1Pb|F*q4-X?C-|n z7w}!ZuUy7=WAO|8E*Gf{2B~Z8e>HmUNIN~c<+ribZoUmZlc$|_p?0j@#%)Fc!0-Zv zY_i6PfgICv$ zuP*G++gMvBPqPUsg(%@^$Bgoicbn3O zIPgvoAcnE zN42HGfHzVmcL(>#US<(AH#K<+Oh9j(*DBjJGsT#55Y`h_^4ipD>5H+3?y=D6 zMG`>XId%586W#r7?6=otm`S6_Cwh?1pCpfaHZ$}Cv)!qKX8VvDTej^*vq6)6&V`^u z%14?ayP!z6Bz-|~jFo;__E4q?J}r(Y#WqXZ>p&sdj!l7&mP4`pnm>OguIOA-4&Cl6 z9n~xPGeK!@cbPz+HF`2-{0zGo-1SGb|G_gQ0BZ!lUzH8IqI_SLeymd(vZK;|G;8O* zzS=3T#tunoS$s&2NFTP1&}n_MU{Kbm#G-~b_EEcdi$1IJqz&EPz?tn1-kZb5U!F27 zR7{+ncYW{kx?$;|m*s^&YUWebT~?5?P5O5$rp*l47rc9+GIhwgiEa6XJ9gMys(<=0 zC6Lnh0RJM*S(eQI&gJenbL^ioS3YQqKam z7M>cU5kXgD1O0m#imRC5DB)yO+dfoykh6w-K~36s6?ML-HK!g5yh-E5$dK{UY6YwJUbZK@+mU z=1>=}O@31$|EL8lz+Jbn^XcP={OJe9&l+FF0>AbdZ1vybk~!Td+Pu{P5$O`M%8B&Z zbANNW!sU>BT-}sfo8Rp>S)4O+@{!_rfr6E?{>)>k$ZBsDc)Npi*@gd8}`b489L4@KnW_ z<^Eu)pp|wzJwy*&d;W6RJ(Tzc6I?X)K(^3I>W_S%Sg5(G*K4|XPvdjDlOnh7R(9(e zQ-oO}MLj!_5-;i@WB$3WDf3l-?$-S^zk7T> zNx&*kN6dRIUx`<}O|-O4yw4HtR-AMUI{wJKtbi<*Wta3Hul9q4>h}Ogh+1PcFzf>Y Y1N~cQ4u}%M65Wl45)e$P@{7&-54QH)#{d8T literal 0 HcmV?d00001 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 40977e86641616174678864b07c9267115ce79c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1351 zcmeAS@N?(olHy`uVBq!ia0vp^3P3E#!3HGv#H{-Rq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~;1Ffc1+hD4M^`1)8S=jZArg4F0$^BXQ!4Z zB&DWj=GiK}-@RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT6rXh3di zNuokUZcbjYRfVk**jy_h8zii+qySb@l5ML5aa4qFfP!;=QL2Kep0RGSfuW&-nVFuU ziK&^Hp^k!)fuWJU0T7w#8k$&{npqi{D?ot~(6*wKG^-#NH>h1eo~=?wNlAf~zJ7Um zxn8-kUVc%!zM-Y1CCCgTBVC{h-Qvo;lEez#ykcdT2`;I{$wiq3C7Jno3Lp~`lk!VT zY?Xj6g?J&i0B&qvF*KNf0j6J(SfFpHX8`gNOrftYexnUy@&(kzb(T9Bihb5uTZsl3!k| z30CjxYvq|&T#}fVoa*Ufs{}MbFEca6%GuD-z|zFo(#+M-(a_M<#KO$b&B@5pz{t|o z(!$ux0;bm`Ke;qFHLnDwHwB^B5vN{IQpha;+U$~Alv$RV;#QQOs{r=0RVHq?nBz1L zsy79MRlu}e|wy$c3R8fvW`znnG5;6dmIJLC za~?`__88b4P@g9@>m1KZ>5K;734+~|A4svd3&<_G-g3d{OpXTE{si_VE)&^fnm*Vc zI{f7Whwf3GxtSUpFFdR3;68g+R(hkLT;lrZjKZ`n)=jT2&S0osaCE2e62~)66+O0o z=c2#(l!&jgW7}0JZDLv8pknc;bpOKy-=Hg|FQ>k{x`1s)>Or;@+`3$TM<$H9DOr(o0OElooc+U)U9{#Pe;a6NB&1LXg~1I`1NMTqj%pvR0Xf8 z-?ZG|%$?MtVB60>_ONcg^5yc~54ZHQ><>t3%r*=YE8AxFrO|xh&)tXOE%j%chKlWf z%f;+vd(F$HNIQ&YYA^FLu4#^e8LnBOtJCymyT37yV11qx{O^Y0FX04+KW$-hIh7Jx PprXyw)z4*}Q$iB}S*_&* 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 0000000000000000000000000000000000000000..f7831fa7a71569ca5c3a1ca36a9e6d036a389624 GIT binary patch literal 1139 zcmeAS@N?(olHy`uVBq!ia0vp^qCm{Y!3HD`u!WxkQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS=07?=ezLn2Bde0{8v^Kf6`()~Xj@TAnpKdC8`Lf!&sHg;q@=(~U%$M( zT(8_%FTW^V-_X+15@d#vkuFe$ZgFK^Nn(X=Ua>OF1ees}t-3#_`hBq$Z(46Le)Ln;eW^@CE2 z^Gl18f$@>14ATq@JNy=b6armi<&vLVnwy$e;^|_m1QgLr$xN|wv2Zptc5$^ZbaHhy zG;}q!GGjMjE=kNwPKD{sMCdigtJli8C^fMpzbGU>KL-|j z0U7xv`NbLe1q#l=W(wh%c`5nj#h`$Nx-+#Xvn(~mttdZN0UR<`nMk%fx*A(Jnz))9 zm|7T_8M#`Rn;TfT8Ms(DI$N4Kx;U9BLG`2{`Iev_eW2y~plC#jR+tblt$>*DL<;1< zlX+?$Fl`qB6EWL4oi<Uv^ zaM!*ycHZKio)V6ER_A257;{Pb81b+ zIW5yiz2~O&iriY_!j~g^Nca27H9?CQ_{0?7KF{5}?sP1px}wd;eWmBhV?J<{9GLmq r`1-~5iqoeEHHle#lG?=<$Hc=hVT0I?&*%0}0~G_Fu6{1-oD!M?Dp2${^B%?`=T z8D~zqvrBKuL%MCD=u2rqQS%h~AT5LzYQbOx5lT^15J3sC3YLn9zSN@eOuC!qLFzCw z=bWGK`~K@WqmCTt?AX;oQB-H{pj;s9^W=Nx$#(KzZXdf%mYrBB;Zan^Rn3J|#y}Gg zn)+eaVM zz%-KdSS-)x9SK&A1{C{i-U*Bpk6u#9B|d2OIQT!4?l_)oM~tT~V=Ko8BhI_XEb zzeOgsd%U9nNTLyCq|aE;#yL4j6HCM}4N(>ZNr@^lH>@Zer^FJ`Xf}}$_-s^)WjUE^ zadWnZHCu-*uK9>7J(epIH>u#tB{XC^WJz zvcN`VM01Pxj4}|~!W9h-wN`2d>H`Ll2d-wGH`6Iv7d2X#MJ>4i@?JoBA zEiLSR?X>dc0U&(V{q_rL4XaNLEcKkbGX}2pzcv5s`***{aLH0bJL=Uy{ W?!`O$u}d!p*FL9=$R7@m&;1K;M|6$= literal 0 HcmV?d00001 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 02ad9766d504a94ccddd41c510951bb05f12a99d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1182 zcmeAS@N?(olHy`uVBq!ia0vp^qCm{e!3HEJoIX|yq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~;1Ffc1+hD4M^`1)8S=jZArg4F0$^BXQ!4Z zB&DWj=GiK}-@RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT6rXh3di zNuokUZcbjYRfVk**jy_h8zii+qySb@l5ML5aa4qFfP!;=QL2Kep0RGSfuW&-nVFuU ziK&^Hp^k!)fuWJU0T7w#8k$&{npqi{D?ot~(6*wKG^-#NH>h1eo~=?wNlAf~zJ7Um zxn8-kUVc%!zM-Y1CCCgTBVC{h-Qvo;lEez#ykcdT2`;I{$wiq3C7Jno3Lp~`lk!VT zY?Xj6g?J&i0B&qvF*KNf0j6J(SfFpHX8`gNOrftYexnUy@&(kzb(T9Bihb5uTZsl3!k| z30CjxYvq|&T#}fVoa*Ufs{}MbFEca6%GKD?)Y#d~+||X^(a_M<#KO?cz}3mX+|Pr&;PYClfI`;J7nN2em z_jSIt_bcdk_KAIA$Zxu2gM;v4Tc-1c?H2oDrg4|*_XW7Jd2ji+(fI-EDT@O<{Xh7e z?|Lj~GQPV0g*%H_;HA$Tyg$}O@S3iDp}78+tn8XPk;A5Xq5Kyv@#O|*SiIz7y*j@l zaDVLmya|_gn}4a(-DPMZ!`iyr^;pF*T|d!F!7pxgaG7pB7#v;mwRYuOzJIf}=w2x) u5M}*kH6idxkL>?xJiB(~|NZCQz{udQcD&g*ZPN@;iQ(z$=d#Wzp$Pz25SJ7H 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 0000000000000000000000000000000000000000..0939e72829c9490a59ab278d33118dc7265d325a GIT binary patch literal 1369 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE;=WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2v2cX64L~h>{3jAFJg2T)jk)8oi3#0-$aN1{?c|g2d$P)DnfH z)bz|eTc!8A_bVx6rr0WloBA5~7C5J7WO`H;r3P2|g(O#HCtIc{+1n}DR9FEG$W1Lt zRH(?!$t$+1uvG$^YXxM3g!Ppaz)DK8ZIvL7itr6kaLzAERWQ{v)lD`qG*K|O)H5_S zG_f$$Q7|$vG}bpT);BcPH8ip^u(UEXRe%B|plwAdX;wilZcw{`JX@uVl9B=|ef{$C za=mh6z5JqdeM3u2OML?)eIp}XpbFjM%Dj@q3f;V7Wta&rsl~}fnFS@8`FRQ;6BCp2 zOG|8(fG&l2A-4c-Y+f-mn1BJMUy)d#Z>VPg@)As;uP=V3xw&xF#U(+h2=`(&xHzP; zAXPsowK%`DC>a=WY04n03ap%qQWHz^i$e1Ab6}wukda@KU!0L&py2GRpy8XCoS6sW zYl1cS`dWGB6_+IDC8v72*eU^y(96tBu`)6-HgR+{cQG(DH!?JIHMMkdF|q)LyP1Wt zqqBvJ2~4j`esXDUYF-IUZwf-MD^9(jw2)f>wAm%KD6=dz#jPkmR{`v2t4!Q(al&aH zRBsAyw>aa}s}FRHJ}739Vj3m{Og#Fn5J?ko$zn}NHe*5=1#cv~Y(ss_^=V`PPVBxL#&!Trw z(4#p>Y2uFwFLrcvUa-BvlIVM8k^cK_62=*7vzs(G@Xk75I)hDi!K@B>R`VXupSIn*;9-*6eHgyrI+P-V0QIv>_|WvwsfL|5d*C&t8#i zll?aHM(fvd>*vNAOt8Q8Rd%@t3A4-FFR<>`} zy!N@@IAmwI(vJ03_mppZ`%pUjVX;3;`9bZBf@iY{<3EL$P&T2{73N;;`s?D>sL=QbRAZY1$| zu7>aL12fVt@VYtdo@LN+R!eaI>4#odpI3e_tqHv8Zot0rOu6|tz6{30MJE)NuYLL> iZ-$|y@z2->Mh4Rz`KQkviv9yC>^xolT-G@yGywp%jqeWt literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..0e9f59a4cb4150439774758039329a5152d86a6c GIT binary patch literal 1836 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d84e518813f0e3e527fe236656647a4f2b24dcb7 GIT binary patch literal 218 zcmV<0044v4P)99TA>r}zFefX4CdA2hKTqc9moW}rkiBNMBraeR?o5WBPq2{VjddE~;>7*|NF(^9)ADlE9 UsYKJ0!vFvP07*qoM6N<$g1D+$zW@LL literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..094720870164ac35bffccf334114e14093a41112 GIT binary patch literal 214 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0y_xt=bLAr-fh6AtkGTby|3!JVzy zpVIYXV=JFsnkt^I7x%NjNk6udWy$k7J1c`(PA05a)*XH?Im6*_x_(@3!LxUavsRIWw5yFeKfnKXu=fC zVo}6-yX@V+zrSTPP6|v>a+t{7r9Qzvz~Dlq!t4dJBqo^tQx`O5VEFCvrQcI#f*R1F N44$rjF6*2UngE2CQ|15w literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..b7ca453f54146194ce665a11a3e9c5564bfd9fe1 GIT binary patch literal 1162 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gjk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+n3Xa^B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxSU1_g&``n5OwZ87 z)XdCKN5ROz&`93^h|F{iO{`4Ktc=VRpg;*|TTx1yRgjAt)Gi>;Rw<*Tq`*pFzr4I$ zuiRKKzbIYb(9+TpWQLKEE>MMTab;dfVufyAu`f(~1RD^r68eAMwS&*t9 zlvv ztM~P_^2{qPNz6-5^>ndS0-B(gnVDkc>TKz1;cRGPU|?=$Xy|I{Xk=z$X=GvSYGz?+ z>1g2y)9aF-T$-DjR|3v4~Pj*wm=R%;iu*SQ+p9GS+A>kPy);n|2$nBLn>}1 z{rUgjo>`Ysn7NnntZstivnf-iurRHZbkK2IR=K{>V(aqd>B@TY0ZA4d9ZVl}Y8+ME zS_1@?)%ofe3dICIGaA|pJZJdmKj|?8zXns=>k^fJAqh2xOfOGf@pARv(4o65%_vnR zs3(UzX=BIHU}L_jg^BwlUKLGv7<*+)gRIoT$(pB5vM{U&sbNm-4$$V?=UBWBasU7T literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..6d32ff13c69dc9725ca0fd1af2fbfd4a369a1cdc GIT binary patch literal 2293 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 F{|570MGpV~ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d70963a25fda663ca0f9d2eae15eae1376482885 GIT binary patch literal 2238 zcmbVOc~ld39-jn)93mhTgJ>B8*#MSY) zRHUF-1YzlFQB<%3!YW&jrGnZ%Z>dnLs00s07R63f-2KDXeQ)Q@%2$6#(O{UhsGYJT9b$RIAvP~g? zZy`vAfbh<#gs50B6xKr^lN=bJpweg{i$$g}m@F3UGmuWD(J55)W(Cj~JSK}rXM^uA z0%}dKOy$LiB=2pZD*-`;AUYm}Vl*1b#y~QxPovPdT&_ifP7gp40frncA~ywS4c;>f zBFLc7t96JP)`AvA`C2#&5fD&M--V#jMMZrO)*9X?3QZZsB-c@BWGY3YvBdQjZ9w9n z|G4o{v_Y1mgD7#30nXAZ(DO+3o*|>T`(r~EAnFY-Mz2N>MV={w6EH*Pl!Vq$2xDi?dBG)RQ8M|uK?t3ox54pThJtRk9y$pskXDT381tYLQ1?#|2 zDGT(CS8J89(cot}o_EoTAiX*pQcCo&27H@ep86y9|99N)xXS-0XB5;KilsRIt5{~X z&|;6a^S5@M>&W=T zODOaY*EAd%bX`gG4M%$5{9;*FzD#)4?drY)>&*Lgvi@RR%O(P`yRM)Z1aWio?dvfi zlV_}JI3+``iWQHp)?~zdxyUQ+USI2-Rzv;%?KK@$C(=eYjCM>d_(iw-l7~mdJ-iEe z3y0SnEs&n#M>k_U^Y-jX#`sWi$$-8*cowNJ@h-e7#o^^_r8r}0TL3@Bb}P2BFr$Z0 zjek1XnBtLu-Bl<&X-l=cX`{t8dNz^b$HMw??uA=~ zJ%x1vk#;RE8vys-e`N$x=iI~uS+gHB^~;BSiWjC}OM`o|BCcCcV;v5=9wj9M_~3cH zxUn)H_}7a)=0*P~EQ-S5-!Mz<9q<=-<5q{&c10D>vK^w7O{$2GgbVOATxa!gMS@yH?vm!qNv=;-y|$dXS7H4 zzWjU45B+SM)NcuCCtbpwo#;H`DBXEE>?@*nB;E0B&|bS~AFLnOsr$Zx|0aakd|`2o zP@0;WzVQ43p4V3kzm3nS2z{`?B#g~=OgJ?EQtHMRhqKqPVo5hzmO(C`#cpe%FSw4Q zCZy$;0y!1D1R@c*_eNG-^Y6`N$@0rBf)tmAPw!o@rIK*C-QM2aTix8iFv+HKe!kt- z9+;rd5i@q$`HO-BUCp(=-b+Jv+PtLZju(|pcV5|{Yr`+wG$(NWL&qY&e%FzSsr?%} zhVyPm9b17p8i#yDOPR}&Yzp+zC*L%J)PapD#_P`wNdcJY!VMCH_+LUCPEV=ot zc}w#J!En~()a&3kw+Eg|+JIwp?9HF9>3=%$r>9xgcgmi8w@1Ic?^r%Xd(FG~^J;|B z%RKE491bLr_yc#16HCq|-nwR<7=4kV{L#r~wOj4YpO3oppUA;@4Q#v0!Sd->mgKi% zZ6A^PsuJz66FIf%RJVt?4dh$eP)uq6M7tGfr_4@vS-x1zi!u=K({!?`pY9t zR&DrBC%npk>;$9MNObVLSe8AlOJ37!6<%L=&}L0izbSghUF1Z1)t36p!y@;e?aLm| zUa;~|MW3^DE+{E7BjT+#JrTQv-}=AbkRDO0i#Ec`M1eW zn5P VH$r}G`YOvGMT9t7bSNaH;CCsHZm$3U literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..cb21c788201906b1b152bccc1af826eed4dd444e GIT binary patch literal 1844 zcmaJ?X;2eq7~Vi2BwVG4Qc+xj7mT?{ASvNYI1R>-3JNlWWFavoyCe$<-~lLADk_RI zAXGr7R-XgBC?A5Ikze*0CEE?2po&-F?6Bo9B7nb7#xNNwKb^ z*(3k}T;t;e63j-}9w$faeMFV}8)m*hg{f#VoQ)b}ItYkVz*!I&uaV_I5=f>f$nAqd z0l=QDlBS}mqNO}Jtf9(m7^+c&U~B*g4L2e(xf(*jEGS2%<&(!d&XGZtf=^Cii|8UG z8d9p_3UyF&VUko{sFrgTis7b1dv{?Qz57d z)`B)gSr(j!^2u1FA5zdDQ?gq9$1-6BqZwrgjX|Z`Qkn#cME?)fXr|D5R04g9_dkX8 z(gFmcNgzF(r;}ri%l5aqLU_?SNQS~XDGaZjtfE*6qp)5HBVcqg2V9(@(kftsKHxoG zB;v(u^{7lMhvEf%GNwRPsT4dGSI7=#vV-VB907wNWOG?;CYL1?L<)mrLg-P^lUxBT z&(lC!bdsz1#AQ#*wT*%X!8{8fohlzv#OPoR_&#NxYWi51)9QWXDyENxH7%Eh1w*qn z_Fs*jJi?~OwwxMUY%?|ZkQSSE9X8ep>CTbZ*U}U(h?E+CeU>JQ+Y{+se+ $ogxS z+sa=WM*IS|HoD!;uD-=-PMqoFFwmW-slJpb7O#FPp4;k{_oDLWzO1t|1pR)CM-A+< zRn-ZSH{AJ}>z7}X>Y6%O_g{}*yK>4s)P;QiO6T>?7cZ`Lc_tjXN$#y#V7KD{5IHMz z#~^7eKY!M(V&%>H9uin`Fw^z4Te>UNG10m)+;k!{-0JqsAvwlqa;b40!@u6t(VfsY z?rHYdF`Efb8Pd~gA-MedHaUjX}M{u zi2W{qmb6q9j1rp0s?2IjW64BDw7SD=Ds{!wGxbyaisN~dh z96}R}TppZJJdw6Mbiicn3A8ZYv{GokrVAIl9ct%3-7s*{d71H19l>N>lV5bNV$qdD zUHf;kyNp0!#^wjyh6kwQF=CpT=$}z!64_TYqBdW4G;-e3YH$u!h`WocCLL!@0!Gd#xgzS0{M*Dejn~&$1eVZ_0C^ zBCPDvCg0e+GN9~+m!&j!rF&DG$yzRMUjdN>W&Ev2oWwc1fINvBcoeSjiVn6?gJ5jg<2w$V#4?s*i{6bYG4|icnYhKWZT}7Xh zr7sHS2;q(JegMXdY(H?8>s-uY-8-~k3A1bCkq|H~$l6cFwSUz!MBRoTk$5y-++7*c zce0mgGAKu9I`uQ|tQKk_3Hv&>_Thj*>dLB)uUae~tdssISWPsM`}u>oq4`wz#{}y zD1_b=91|fN{X8kKqoKu~(p7!t*kFcqWVi@7yFA&PV3`y0yX;Jt6 z-(2MEnbF@tsd=92*Fx-aJ-GaQ`Sfp>UsAXD@z*wgVsitRrZFH8~~kIF3l2Rrk> AbN~PV literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..1bc52abd566af9995053aaa4ad603ed5a5ee2a1c GIT binary patch literal 1055 zcmaJ=TTIhX7;eN6_=(Q07SbCcFF`KTm9I!Dv# zblRS7wnHO9vtF;)(r`Fz7-2KB8WJ-$&1}dk2*8vKMMnzMNJ~+S!y)9OaHcy)Q1ybW zX6}{=7mUt`I?dV{>qvQEDD;1*sus{D3WL3T|0!%nvpS%|z=T7Fgd5l2V1?2--T)$k zMij!qd=-0>5J58ub&`*`$rF8wCd0IOGKUX^xS(btQIkMW@KIR7t|&6cJ6l}5(ClTL z9tXtq@ zcrKozdb?b?crGnPxin6Owi^3aqw`zXJ=U~fTf8V3A86R^2DbHD5|crpJ(^jc z`m|JjizzGpTC)%t+jv^{ld7MsUw@wZFxA+luHN}Q`@P~_Ephqd_!@J6OPTpx^KE{4 z^nke(89VfN+P5$>S24P;jV8xE6$aCe;)jHRVQfDNS0q4l7BOhKKn$^AFjtyf%;ClXAR-co<_oFF(UvwOg3qHO zLy2rGTTBOH_&zBTAUMT8gqsq_CG(IpH-xL40tpBJkb{s5;)PO*oQnLYOM&K#+ZZI` zBLs}2B0o75#tuNxMG^o(L_0Zhu{a!pL_*^TL=p-24FZqF;W1d~COP5=6e5X&cSd}^ zkdQSAFNzYx@cL{ET2YZPASk9_Ffy48EptMPB+(cgnM_{Pz~dbugrhWB2y*0(LaE)7 z0t1k8C44c+7YPxIikwJMB1lC-o_-2JAZD|_2n(g369uIVBj<=QI5ZX`5G=;^5iJFS zfd9DhRkSoDSqxx;0I4WZ!iCNw%5I4a@`XH+Op01Oo=?#-00}<{;CV?z0>sDsQutr7|G(q@#O3`zIm1BCU>1wx zzlvpP3#!1y>6g-n7GIhN5JDXzfm-ACwB=qHOt+22@CcEsUx)MKLw2rqqwn^88TrOD zyc~p|t`96@lm!OW_eALETv(>GG}A|)v@B&C`uH3@bIG{N{UFDzw{QI}YwP^gM5b<5 zrV@xj{fEzohFxop+-$hu6+rKXwbX3i{lWQM%4`&)iqs!85BG!3j{1Lbr z*6}!fyDe6BG+VNE%*DsSwqX-&*y5SwkxoaQy;fH3%bS6RU_)te>@8ky^IF%}NK=1n zbGX=znbrF6T(o{m>v6Y+uJxwoQuw; zdE1FuJ2l29Hk8gZO#kvoQ~f3und;p-`=jgoy@!j;(HyS>=J1#gu9^0;RYX+GruOqs zn%BIk9qO)&mUS8oyOs4Gp;c7*_d4|gfm1%lCk)R={fnXUJUORvtXM)pMIkJg)w%AC-?dNfXWX>gP693`tf>Yb;5~*PfXpI@vCp{ z$%dJzXLlNHJJu>JUR7(^97y!eR_N&;YZz!ppKI#O#Z7H<5?aTYOO=+*&zo*_I-WJ%byokz!RYo7_ukkf8zDQU6TAKduIHg(r z(7jIEu4qJASmY7+G|$k~m`J=Qu*y1SVbp%+5i#8yr8|>YIiN9EsdwY@IN%(sh(!gT z{UuXzqq*%;bjfekvbL)C>}%J;LA^_-yYIXd_)jLxuUuXCb4J{-y?*U0V>XC&?Qv8qIh()e*dW3M0os! zU~<&UaOww*vC2UDpgYgz$J(&I7dKA!clENvecK2>&BP8Jv4zJP3C^3C3%1UuV6AP2 zl&5apSNC%=o99P*w7n0*@^bhubn-8aQQY$;J3q9^`o~}T9ckAaF6g2b&`Hn`>1 z9hwVHD*MwpCD*{^PO5zxKJIj;KrzdhO9u|9o# z>wZ@Dp4&$V;I!&>WN_mt2Y3}qtaHDxFS$`rQCUd`?G&u*3IkDZePL&^n|*@~skk?p zm1?!C=%?)cSTQ(NSAHH6qdKs^a>Xy{s696JS{z8mZWLAV?`g{JvE>y zHk~{KV`^Qgqq6DC^W(g_5_%f)5_7<1zXoX8JU57d8?6IGPMrxOX|#}Lw|s{H3FdGd za;*E*Xrqt%&2;aLkc=TfRwMJ{)JIk4Nm(s{HCU-~GAi*0XOn=~<5I%xzV{ Y)>6BVf9Q{NS^Py}G5r}eo)H=U218r+;s5{u literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..3440214d1790323c77be51ff46462ae611d4ecc9 GIT binary patch literal 1102 zcmaJ=TSyd97@lplqBOSjq02*uG3Y`&m%WVc;AZR0rVFjC>qcr&&CVR%QD@FHb8JT+ z?PW~@@gWGJ+e6t)4?z$FNl}DP712w*2!%v1B}GJpc1B(8p>3F%bK(2G|3Cl#o$*XZ zTkV$JTPTXEO|{EeGVb)g%^S&ot{DGGhFv(>jk{1EE-E&p5*o@wkTR5hn1zZqa&8tj zQ5ctC&#PK1PBd-wTBVtq#Lychdp-D7b>l3r`vDH{)6{iarTO!LA zi$$gwW{};_^08RV(+Guv1QB#bOsu#;(`hIx$k0)3-NHIDfv2eC(J+qFB-5267}lDs z>8zHC6pVEhi{%;4J5m{#PX8Zj7;9(;XW@Fj{}gs|BNk+{&_TntN*dSK;Dxe8$%YC> zb`GJTauqWLgppG~7Ld9GaNwkFYN+TOT*jx4$zsj;&?IiRiLLMV`1g}5@iZkTa_+nQ z@1>;{f6!OwzvSD>j89EX9R*Q;>3MtPTQqRz$M^3;`#$>ZnoYh=a4mT}Fy0vm<*P1~ z0@OxdL+|9`i#@ZT`eFU+eN*GUXHBK~S)A#yHkE=mpA1M7O{MDFSL-rAI(vW4)$~?{ zJKt{zM;=EXTqtaR^>*Rtulm3#YN2)D)Qy^FZPQmSp6;3y&+JeWhXOP7o3FXCL{;!* zoIYwPE4eY`yV>3O5DcXH3X>-#W?PEb`lsfp{M#Zmk@=H2jAvO~VtdUos&v>IYw literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..6c576c5b772f327c084a12ca48fd03f30c53f468 GIT binary patch literal 2368 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 A&;S4c literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..f4a9297d44b0c06454fd7f44af3dccace580149e GIT binary patch literal 1376 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbBBuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFe_z-M3hAM`dB6B=jtVb)aX^@765fKFxc2v6eK2Rr0UTq__OB&@Hb09I0xZL0)vRD^GUf^&XRs)DJWv2L<~p`n7AnVzAE zshOFfj)IYap^?4;5Si&3npl~dSs9rtK!Fm_wxX0Ys~{IQs9ivwtx`rwNr9EVetCJh zUb(Seeo?xx^|#0uTKVr7^KE~&-IMVSR9nfZANAQKal@=Hr> zm4GgVcpgi&u1T;Y}Gc(1?)WFcy#l^zHz`)$X(9qS?(#6%q+04<{)Wpod z&A`wArq?AuximL5uLPzy1)k$J3;}uUA$B>F! zZ)W&H02tnq?c%+?jt*rZri zE~u5f@#tHe1#^41@m=ZSbQPNq2X-EwIrI9?=gDsF9D>qn(%rl>|8hHeFJL>Oe`1E~ z?WVK?swc9Jq-mDjdckM3($updJ26kxU}d%Z*9M!7JXVMH?Y*@3QC-t1r5f#G-o8ui zRtaWL4!vr!EMLggwaVLSow3}3^}Cr$FDyTGi|M3&eBepN*z6{u84>}SpKd5t819&t z9`yQ#ZNycLhp7eWS|?1}qY{`+GUhTLSMYzWWx?9N#ji1X!-Cn)%luayNh&{ZyinC`dl?Jm z6U1#U{$e1-sUOCUU)RO8>G#&j_I~L zymiS%9_E>;tG2FudG*D{(^Iqf$}mFztwr!gv%=RH%x#qEHcOr5hFOkJ6pp{l4#==Xu_9XE%xy=R4SW z*x_(Ehxj<51X~4`hir|#52>u3h)kst_q{P z4@xEy1JSS!0ytDwkb=%&09-DW!RBzej6i@%XE14W?B)hB*nAF`&kP1WTolZk4qU;P z2xC9^!cJinC5j?^8Z9p`kDAA#!n!OPBP1lmqQPVaVTd4oz7~}mg0y z!g^^w0?{Op9?sDzu*R+MvbaL{(K<+u!a6Aot0$@`R>CN(SHcJoox%lt7pt@&oTvAD zhZl+X@mf79*D9cRVHgEdpsG|LpB_wS#W0v0Iy;!lV8n1Dg}mS>MsQ>ZJt{U*7!ollAQH@ihat#zwr;wdDg5BbCpq#&~&`91cqSoWb1yfqI8T+GC8@ z&QKS!Wn!DTaQQMB!5gHCtpbT|#AC&jx3`n}W_Q{)+gvX`;OtBr!wvEjAY&*KTWG+TGjN?rPlc!iI|_ zZOog?s|hLn>u->G+UlVaO?baQf&NAwzGkK^>)t0m(hVi0D@kmRC!y`qKC^_BG3>YK z*(;tYpj7OiR_5!zZHsZGePvSJJU zwl0wGm7Y&1KIrCRURGwba&r;SixzZ85jH{OU74PEA0~-ZtIS{%tOJKnL_8o(JLfdm z6GiwLBEQb?#6Jhg29+oNX~=XVi*>W^*C5?l{ee&*m20?7Av|k1(00Vlx${tzpu)#5 zyJYouUdHF0?mf`v)n3%^`q=|&n%XqD z16O6|icja{R;f)FPVj|X!iLf=`6@8_u{8E{P)>}lEl^syfv=gG_>1o^!S+NKNcU8C~S<%DESAa CvbH7w literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..a8e54f409f672e8a93acf1b3e78b4858700c1677 GIT binary patch literal 1183 zcmeAS@N?(olHy`uVBq!ia0vp^Vn8gx!3HG%?c?8U}fi7AzZCsS=07?_nZLn2Bde0{8v^Kf6`()~Xj@TAnpKdC8`Lf!&sHg;q@=(~U%$M( zT(8_%FTW^V-_X+15@d#vkuFe$ZgFK^Nn(X=Ua>OF1ees}+T7#d8#0MoBXEYLU9GXQxBrqI_HztY@Xxa#7Ppj3o=u^L<)Qdy9y zACy|0Us{w5jJPyqkW~d%&PAz-CHX}m`T04pPz=b(FUc>?$S+WE4mMNJ2+zz*$uBR~ z1grP;werj>E=kNwPW5!LRRWrzmzkMjSShU;^t=IXl!6< zVQ6M#3DfJ6pIn-onpXnTn}X15iBm5qDdZLaZFWg5$}CGwaVyHtRRDY0DigO`%y60q z)tiFbE#^4&>H{644~kf%h=vIPQxAvAA5fFiS5GdooF?((HdHyMCiZ*NhX) zf<_L1UfX9rkQ1mDG@2pZ5&u`6KZYqOJBF?K!^;0t8l4^1bf10TqEN?mi?yC9*24;qi4d-fKiQj1k6&aqcelF{r5}E*v(SlO| literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..67ac2e3c76effa5301ff32dd9d951f0d826b67b7 GIT binary patch literal 1964 zcmbVNdsI_(9KT}<10fI-MU8X0fMCiVmu<4O>Bcs2%H*|@(qykYxWRVkc4-@+@(?W-fjF-n84*&qXq|3yK#3*n+6j$P1hpzjX82oWbGMLO`ibnTjML zN{w~hX@my=WGyOB#*<~STs5YnDxEe|i_Sox0f4vEVo<8n5gb$@si>Y04IOQPKvctr zRr9o<0ddXOPLB5$jD)6GfzqW>Few3@V+b(>ddsur}d|$Ukm8 z*V-hv8W36{V!|?wYT`V!L6cx2cP|!l8WP@czV;wXuDlH++;k(j{}(j_pR$z(DZ5>_O^6)B0P z)0rH4G#ni{iIwV2xKgi1CUsFl_bHa~LM&HgM3gvYlw(-NWCg^hVK`<=!wjG(i4BIW zLiHNVY+B$vo+r_Y5hMC8qKP(QI&dPtT=Y5m{~h-etmgmZj7B&^a~8+Hie++(s6glR zS?LptXU&7?iHx!>D3O$hn= z&3+p#+4O#3U~n>izSQf;wldJyPu2Csx#~idB!V3beO`9%kLvRIjWd`RZPQdap+ijT zZZ!4YdPnEwF>UjW4%vy<9D7V>IgZpbUV9T4Bz#vf-(#MH{PGdf@?##eO9IY(>aw@` z*HKpPl)-|`{^bV$$XSc7ZyY0Sm^x-ZtnjXAY$flrlj3RZb5~6bixHugxIKP(tNW+dPYL2I26m>rKN!%&JG;WVw22&jtMg5Y zVALxuV6Kg)TrfgWU#ytntr)o8zvu)zvn8#sFqHSGlWfZgKl%;YK117mf!@YV;Q{$K zZPvD#d>GOJ4 zSOHa0d09j0p3D&8R*FbFQxo##qg)nbsomwCHz2Wz6*$R7LB6fk*-u>STLQf280Z@Zc#&3C*`6(4cAL3;buS&+Ou>Vx8G;c@u|^(9qq zHg(-;)Z2d7+(7LP6f{9q9@N#s-fOG&|KZ&?4vSfw&&ucY`)XSx1B?3GI5l6x3uA1I zk6!0{er+QC`Tb>84M{aSyRCS~C*Dm3`?`DwhN4F2(@tH*Bg3k$k{0Z@l+i7T|w1WVh?^{=D|2ZE|wkNYr4^ZJ2YQ^`iDdyC5Q9+h;yWaBc_X zL%XBs+i~rd+r{mt+7GqfDr?vN=)QjqE5+8_TlYqB77WbIyVv)-$9{t~?7huNDQ>kx zu`EIJ9DCu)hUmz>cQ@>LC2Vxe*R!&RD0{7VRPN}ar3T`zq)#OS9=_f2OIncEBD1D zHC}0W+|?rvu3Wd{-ME@-m#(_RbOD9>+>I`t0ALFWaycnTaQ;7~l9l2EQHuP(0a0rI ANB{r; literal 0 HcmV?d00001 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 d926efa47c16e3965891d7d75b238f10d44143f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1165 zcmeAS@N?(olHy`uVBq!ia0vp^qCm{e!3HEJoIX|yq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~;1Ffc1+hD4M^`1)8S=jZArg4F0$^BXQ!4Z zB&DWj=GiK}-@RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT6rXh3di zNuokUZcbjYRfVk**jy_h8zii+qySb@l5ML5aa4qFfP!;=QL2Kep0RGSfuW&-nVFuU ziK&^Hp^k!)fuWJU0T7w#8k$&{npqi{D?ot~(6*wKG^-#NH>h1eo~=?wNlAf~zJ7Um zxn8-kUVc%!zM-Y1CCCgTBVC{h-Qvo;lEez#ykcdT2`;I{$wiq3C7Jno3Lp~`lk!VT zY?Xj6g?J&i0B&qvF*KNf0j6J(SfFpHX8`gNOrftYexnUy@&(kzb(T9Bihb5uTZsl3!k| z30CjxYvq|&T#}fVoa*Ufs{}MbFEca6%Guo1$iTwTz|7Ur(a_M<#L~jl%*oN*%+STq z(bUDl5T@59Ke;qFHLnDwHwB^B5T{;HQpha;+U$~Alv$RV;#QQOs{r=0RVGfi7`Wmz z52`l>r&|o%aO%|uIz}H9u}BdO69T3l5EGtkfgE_kPt60S_99@ip7+zVi-CcW(bL5- zq~g|`OSajE0z{5|oc)^HBg}ojySO@g`wlUui-BBven-z9y{Z>0BeTh)kV|Zi_jA6# zJWlQhmrm}!^1s!6N7e^b@w!)r&uxwfH=FooADdwr_aXPweD*z$PJWuSpwHi=n9a=e zeUXs(t%LkdI)e8lC9?HG{EoM-yLdqSRE7KdV+ZE_Iz6l0GJAD*eaDAJCN+sTPMKBf z7wq(~JXYl!ZIgBUUC)QM2P!%jzAInte73Eft=edVvv~5=+A{$`u|apkZNvVb?84txp?_S-!ec9&Z^)@{9@l$*DKIbyMH#xTQ e|Ag*z{R0e*=9U?n7Ej-U3J6bEKbLh*2~7YdRFO9T 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 0000000000000000000000000000000000000000..143e47d83fc4a1de66ba1ea0a79d5fb79e229e98 GIT binary patch literal 982 zcmah|&rj1(9B&jANDzq^Br!gVN7r9lyRKnEw{~vo#vDu7!GooJux7NcwhvbDVpI;I z2V>&F_z##EJsP41B_7m+Cru1$jNZI)Fd-a_@pWv#!C=$&z4y)M^ZEXKx5}lneZ51y z6h-wF@>+$ghsoE|eUSY36_49wIfnHbo6WfS_K}&TK?{N#X?iQDTCohW$cI2=;xUus zc_2v)pAaR9KMe$q7g&zGQjAY1qNE5((0*v*&9|nNik55pBBwN6$JkR?w%Kel%{YVn z8J16_Qjvxr#0Vl5EV$SRV{S0qQP5yu`nHE{ERBU)NXG_5s*ZqXvmy%poq7%0 zzlzXor+ei(!YHUC4`e4KFloCMY6ekZ+i^nQo`+V>M-FIJMzME!SM|88CiEmH%7P^5 zax%%uIZl(+Y)VqKj6}CN)~;;-%VCLgHfrOpwsuTpR-*0pkdnjpm_wJ$woit5H9wXi z7vNGsQ>)?Uo8{ZR)XDD0=>7WJmHyH3tFH!1hxRufKGL=2d-t7B1BJCG&)(c!O7?u% z7~K3b_Tx)7U%&YC&d`$adiK;xX1;4B`TYClfwf;BA8f3iJ9=XLch?{Vzg|1v|84n3 ObkhoYNqd^PeElzEk2sS6 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..9c3d94a2b322c52eb9fc514fe85def330825514c GIT binary patch literal 976 zcmah|&ui0A91jk34mak_IR=kR5y9qHo3ss!BTX__G^1;a_Gp&8wxLU2OkQm^uneaM z#e*jWK@sLrJc=Nwh=O{W2QU5w-o%S@H($DT+d*bX^4|OM`Fy@V-<{IJh0&3dBNRoA z7U%UcS;xqCboem&A2O$0vP@v3hAXI!J5~rO)j>-T6g{f}%g}OGu6>3x6g4#NR%^Is zUXpF(F;;?MVlN$fy;9fiIknw%MEu<6dPhOn}_P_8pO{%1^dPvU&^tlZ%o5O02!Y6?Q#Qx*K#~|f zBT5o~4hS4CupD`%6rYhrNfxr8|Iox+=+x!1KG*j}P72+`IFMPk)9EmsG=sth%jfg? zL_-i#1d)nXd~C%jKbjsW=rFQFH^46PL853ap*B`%66sC~USOKL!hX~*6e$@STLH^6 z9P4>WUOjY#%WyA@f1;!6N&wk1j8HqYNk8h-12U=I!HyCjiAL6u-S(i5i@HJ+3*)$s zZ18G9Omk_zU>H1ahLIDWt_`VqE#8xFYc9#=S!D{CRNFbb;(Ef2a^ zY9frHCJKO7k-!z#cTguv3fqqphVFIf%!SAUy~@b$KJTiL&Z!wA%ZWKb5{z6n%jM=c zJ*R4UN!1Gy-RC&_vi&cICC=HTjr-ah($ literal 0 HcmV?d00001 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 a94e1d57b239fbebd694179043d8697cd3dcf65a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1415 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 MuyexyV&fb8Cv}@7yZ`_I literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..6a672a795af73b26ed674fa32c6ace58db5ae59c GIT binary patch literal 1758 zcmaJ?c~BE)99>Q=3V4A*5qB09q2we9WRXH71OfyZj&gVmAz2_|vN2gCM6n>1O99&g zDsm`-*a}uT$1);eqz+b4ppB&o_jW^zbK(WXL3Ssame3?5E zBlc3skwBGSkWdvXWQicxFTh<&7#ENrm;h8t4oMZT(gm8=h4Hy|n+$>T5G>XO`s7q7 z-yd{GuDivfhNmM$6$)wtYGzyhQrr-~gNTtIJCQNe#7cL05CKpA)0UYjv zEqvty#bB5WCX?gi<4N%jBvc+vrm|Qptp<%o#1TYAf)o=diBg62q5=m|2<2iKCPt;8 zR#6a%#$hfH?&+rxB(f!0sbV2bc*4j^fs9NgQM4f~0{Q&^he{+%XayF4{NwL`3M+yV zWC%F`QJ`^hAzrvBYpp36>@G(H7%C4!(L;+_^p8O?R1t&9K=(i1w;CjyQFFysb9Hr6=>>hgOcUB5Gz>W3s@m#5FgqP?aWY#+LkKXCC8K9!2AWwi z!s%r4U}KIoKk=)lv7LyQBYZxrkn14l5A|^rZFd0>2&5ZitbLghx(s+u5vv_^f<8Lrdh`MF;+=XU)`JZ zq|a6i@UqbAOwpcN^WIiT-;dwB4*GBWZJOI)_cI@;Pg514SFLmi$VUW7F#R(jC-L#N zq@02oQ_|=UBaJ(BR;R>gcHUPcw5S~~O>Q~zwyi$+sNPTe{ldsiYRE))C4T?zoAI(a zHP-}{-Rcg!vUh0nHBW%obf#+f^DDdx8+uclO8=ryMdLnAaCgJxNbMH;r(n@kzTZY) zuZkLzI93+g!3W-){a})1`Z};9gmC+PL9Q~r_bOLaJX+-2&kifc3Z|0blPx!*Vv&ya zq3qX0r)Pruo@E0*^^x9|4$5|`yb4Q$iEz7D4o*pdUE_3viPdxKjD`vxws3pGG+)xX z=K5YRDAtT7y(z-B;@ZBv`^EVhpvU+IDX2cIHSxg_y}J!H`A>HDz_Fw|D~2b=3Z8kr zG_+`n%PM4Aj1D-QzGlAl*eNm%HY>^B)KzrxyKll|{dQKBbu&B9&5RAkw!f+CEn}8V zCLi2e-b`Mndh$zj>*1(Mb@#|xC+nt_&x4-Y5cJQg3)rWWSq$T9?!A5KrJL(AXXm=R ztn2%^kB>hH=LXxRcXwD4*Ui-2GmCvY&fGsokD266*tu$I=1!E~={*)FpC&c~slvt) T3+T+K_K(B!@Z((H9dY7smFus3 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..7f5fd2a7a1b2af8e298541db25fdae7658cd3a46 GIT binary patch literal 318 zcmV-E0m1%>P)q#Z2tFNjsyG6%w*v^_3oxEj4c*!U2Tdtjb{@OFg) znUgwYpe9$iO`aef67mQAK|cZ_=#wvj;1Cd$S|Aw(d{kE%2=yBZln61-i4XPb{pDt` zDHs+VkNWio5k~;%mwryr@u*)Pl~@qs{F0%5O%oSydMd@nKYHT)Zt1`wH(l8X^`pwq Q&j0`b07*qoM6N<$f-f3_;s5{u literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..66fe8b30ee65180eb90838426d79b8702ed5abf5 GIT binary patch literal 315 zcmV-B0mS}^P)IAOq`to)7lqdb7Yl7CX?D%MT^jY(z*Eo=M@YLR8uHl+STYJ2%mNB~xn}|8q9JE_Uo3ZT$CI()pxTuXy^!&_1YBA?+?bGo zPt&wt3sMluH(dbbKorOEpaQy8Vhd7K##bef>Pg4fWlBV0qJgmS_8}?^7Ecga!^^m=PAgs@%Nq>$1UMFl3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|81#=KlDb#X~hD#E>34K5C;EJ)Q4 zN-fSWElLJPT$(b-ssbzLqSVBa{GyQj{2W*)24v)y> zv$Sx5>2=9ZF3nBND}m`vLFhHbsTY(KatnYqyQCInmZhe+73JqDfW2&$iQ6qkIL(9V zO~LIJW1M>RfsWA!MJ!T8!-RmT2gHOYTObFX@Kf`Esl5o8tm_^KcQPu+45_&F zW~Q$RE)|FyaPT6_9wFYV~|OOMo8Js98WEm(bR z`l?lZk5u^%DLg33W1YYl=zDqInK?CSr!`dTS%2B)Jt-G35)RDfI4Y^KK7dc!@0r7l zivj%Bf&vLD3;gvKo2}t6JE-zPb=d*4A4R2-r3vQ~_)`AY)_Kb`1REUL$lj%P^8Z$L z1O9!MTpkfB@f)i*oDOuj)b?J{oiWmJ-zKTG*N^4?V6)_k5P9-?R>M=P=rSgqLXiv3 zvqLT@{S>}%wp56}S$c!()8_dzmIXc9HFNidj-W-Cgtc32gtvcRxQ|i0QT&73d-ekg zFP>;U5MFXnatBL)sFq*tQ%PpyglQkDbrsy(r;Gg9@Zl=!T|rK(O?nNc29LhUXk5}- zy!}O;?8$KBzcX#SHhLMx3Qk}b^u1i>u=1i}gM_`qePyMtkLlA27!ChCaNVq~e6(k$ zqJnBcs1KKT!?Y^Vse32ic)NY#%2l_nc$*%Xymi7%QHiHB%as%kdmPv)%ouodN6d#? zUz!T;Ze!Rb$l3TfDpsT7hK%O1w?602oK(+$wUj~Af$PJSI#vmWrnZvwW9EhjKt-Xa LtDnm{r-UW|iFNQ8 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..b81f418debf46c58aa2e3e8b7b62661f8ac8cb08 GIT binary patch literal 3537 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 lO;tzVH9OXRURRy!~etrS(bx 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..8c2fe67480506d2f99b577f296e6d6a7c9969027 GIT binary patch literal 3406 zcmaJ^2{=@1A3wv8u}jF>7=^|%2E&*zwh=dk41Kn1jKN@*W(GrKP{^9J+{jhwCdN{h zB+5vea*3iWF@=bV5~d>Gxc7GN_k7RScb;?3yF9<&@Be?__xHT#Jx4t~cFRbrNdf>M zidzYVYGPW&Oh+(?ig1plSQBsNv=*dFrk7mnH+|(N28t0P*$cU=H^Hw z5{E)NqH$IZ!X8IQoV}TY^LMTjjTlQIQCZ))VgGQ=e#qUh0);M&>_lRa<49r73>pRc z$B;4PALnB7L%qMaVL#3V`9m&3m<(cLVgF;Hzjq1Uvr+xqw!+5W#wSsQZf6K>ZSer% z3jmPYu1@wo?BTaT(RBQPQgGqn!yy5knH!liJ9DY1y%S1(r~!Ge?TToSK@&V{`M0)sB^bW!su2P>iZo9BeWL{X68zh zwmoAJ^UP^Ta&SC=TJ?DJm|bC)m%zsU5C$I&ng=rY)CFJQ7zW;)? zB=%C}`w6qE_X$RvO1|@g{lhu}xpq#3u86kzS&WyCF6mOQ{oOC{Trg*RvIvmmVbdNt z3=c*WskhZK%F?b#opZu3_d(&&NJ*dh2vt?B0qd?S{a9(!Q7eF|ypG$gSK*)o{CX%z z?3+VUlEXr^Zg1>~BRF97bqY8bcFSE|C4C*7GIIl9Kh3GwlcH<;`_`C-lP895h;zZb zqcVFZSG|+Y>|-v}_Z7qqjim`)3VAVa3DDUrd`rS&6UD}Imqf}AoI6r z*EqE^z=%Msy;!7OBd-0YZ{Tp=wL?5*(1LiL$F6A18~&m4l8moBro32jJ>K)${*eC9)4yvuss!2g z41>azC-3YmC%{%@mg*e(JM zO%e3ZF>}&A&$KzryR|)bd%);@Z)c@@ltGi0J&(0H2SWWKOnfteds#uH9cWFFtp;(i z;uSOUoS2okO*jk~T7n(5uapHzIApnj>H6EG`xhzOlD~QFT4F7?1m^uB3)&{t8E+?}}8&ldm;f)^vaUa;v8D^tI&Cmr?jz1KPlJwZgpX z`i0(%VdJRh{iwGQBivn=o31{?fg0!J?OOLJM~)_D`C7LiYLXNCUV|yYLtkE4$hq^r zG{Y*BQ}WL{W&&!ZM^lU-!`ELyWn{OL-_0q^=4-XPhD{F|QZA)_n>=v*_P3`E8l8R# z2Ao@h5P0F-{Gvv&otfvFzuD3b@q*78%=-8Xx$WfLmhWDSP8|o9=j3@>b6lCSx|G%< zvhf!Zr9|5{3m9JlROVu@2Nz<-W7W8&Pw{K8w_wv2V)TNc_%3Y7!rzfwdYnM5u zT+&f5Ep&=H_JHvz>L|c8sG#fkM-%giL2LBL$vdK!bhI8T`czU;Y zddUT8DsVnjQktgR${GYt#mR?cr>vT$-_^XO&i^6D*HxwL-AJ7V9_ZRC|=* zohS72E?n5$s%*Y!ZjR6yxmjz5LJ&+}0A-JsJ6pz7cwQk|khD9S+t%X4zrGCoxg2+* zL((VpRC9`#vD^b!z*B3lLc8H13F$iCrh}r2oZE^g^h%r!9h>WI#Edw~{p{8z{&j)k z^O$sCYcC@{C@ECBwWDHPNEwSZ~iKaU}>iu_O7=xbka( zP4UNFbgsZfo!vC=fZaCJ44@5PRGIpuwrA}exhLEoi7JAChw1MoGmv|CU#N+;D^=08 z-f6oilhZ-MXjL=jO2}$*Op{A<0HNS#af**4tDDgb!`CdD~s>n|Caa# zAI9~rAh33}d*5D%bF>$_l(Aylq{!6AHM93(8(*K38OhI?ZU}(ek9}GfNqF>Y(57cE zarla#>Ss7I>S89~v8hBkfg&B!(z3#NvV41P-F(OzJrO+l5=pLu(-9bneV;iy61SWzesSKm-&Ag0S@3X*| zM6gV-DHaTyY*w JwGJU^{{|Gk!2|#R literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..1c0ab496f1b99a511800d782142e0baf23ab3460 GIT binary patch literal 2828 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..ef92c839c740025d00198eb01799e0669c194aae GIT binary patch literal 1173 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 M<93)wW@oSb599IPfB*mh literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..12336bf80a1d477ece58bbe7780b80aef69090bf GIT binary patch literal 1272 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%u1Od5hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|81#=KlDb#X~hD#E>34K5C;EJ)Q4 zN-fSWElLJPT$(b-ssbzLqSVBa{GyQj{2W*)24v)ylsbTTkB zvote@>2=9ZF3nBND}m`vLFjeDsTY(KatnYqyQCInmZhe+73JqDfW2&$iQ6p}IL(9V zO~LIJOPqT3fsWA!MJ!T8!-RmT2gHOYTObFX@Kf`Esl5o8tP3?y-C|&1%<*(_45_&F zW~OfzlcPXu`jOuHCsJ_^1&bSRvVRo1$$osk^pO(+MS=%+h?(cbJYi6rF5r0mvGkgT zElQHXex=!>HZJZP_q|(Xp8N86;hUW@mghePFuXhw|7oEC&*};ZC&rMSMSam3d|wx7 z{4&%3l{tIHq8Up|XG9=ibHaOa~|NTQF!fF{G9%wte8Azd+M> zvd2@c?c153aV50Y>=nKr!T-n2$9i46C2If!>khx3g=`@TrVIVUbG9(=m0qvwaqazq zA1gi*voCY|+W=@7tIY^f(M2GrXw$?U;RSW7DtyYztl%%#}%<9C%ZuZ<^1t`iPhg zg(#U|)?%aOdMRvSKW>&v%iiEA{30$q$#>Q=m8k)@B6H3e%}>`<)SUmEQQ$-6J-Hq2 ihvzV99B_QYBEc~6PMF;W7p7uRS>);J=d#Wzp$P!SaJSe1 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..eec779844d9ec34724fbeb0af328d9b0936ad198 GIT binary patch literal 3822 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 SFZq4%57f@e9#d!GpZY&p%4c5y literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..8a2056eca3b0def270474fdc86de9c56f84bab9b GIT binary patch literal 4910 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 W>5cBpT(^Gy!7?$h)Nj!Bi2W~@NP=Mi literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..67a9bf2eabe6b3802f0c8fd7dae2f93bc7b82ea5 GIT binary patch literal 1921 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 ND2MIEI^`0+?Z1LRrt<&* literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..be41c728814e666481cf0fb6a91590a8d9b8b58e GIT binary patch literal 1764 zcmeAS@N?(olHy`uVBq!ia0vp^dO&Qe6%V8Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS=07?{&CLn2Bde0{8v^Kf6`()~Xj@TAnpKdC8`Lf!&sHg;q@=(~U%$M( zT(8_%FTW^V-_X+15@d#vkuFe$ZgFK^Nn(X=Ua>OF1ees}t-3#_`hBq$Z(46Le)Ln;eW^@CE2 z^Gl18f$@>14ATq@JNy=b6armiiZIxhOTUB)=#mKR*YS0s=DfOY(~| z@(UE4gUu8)!ZY(y^2>`gLD2*8txIZAW?5>ATTyO0Qv}Ky^SDj`bDW5$i(^Q|tt+#9JwgISj=%2- z`;vGhC#J^qCx~hTvj(NaCKar^>A5kch@O9ai<_h4*}M#6U8nrTC{@W?iD8$ zLjw=vOHKQ97Hx65bp5}<^FvQR)_hL8w_E-_zx}=98Iu3LpWFF-UiCc5^Pi0tDfln( zh)lD$U`bnc%rdRUR)S49f#VHxq(V$vTD4rn8RK~NyoS6DXTJti%76GJ^?}8PMLX7H z-oY*BkCmD{v7P)!TZUae*2wSr`USgARR3?_Ua<6pLvJfrrpBRa&Brp#%?}h-_;eSp zl)Atc*A%<0cfa=I&AbozUa&~#NXqwpl%0LB_yXUnSiY$TT=~8=*x;bAD-_oZuJL<2~_Vuua3VAn%Sf`ph>1<~c8)?z}SPvB@XS?$Tgo z{d;_IXD0SuUUxn9rcEaI`~$asx`dhZPoCCjn;?5#_J~e*^N-V0Us!%nKJz2QP=kHr zo$~p{CJlmi2V&SB2llpW9&e5~ct!hq6fbiH@3!XcyKb?ICa7<>Uh&rOq{_mytocW5 z>p}~&nZ@wQja&u3*%y}BPu2Wdx9(u;FAf=2+f9>~ZW6R%xNlp2g>~Dn z!-0PnOYvBx?2v!6Y+23)t03o8(c?>V124Zc*}?a(H8kthv*h3{2j{R)Kk!~db=ei6 z)4P+q&qxGjC$F?R+_qA^au;>mryX5rH#bC-NHJa>5QzeD#!A8$Dv z%beb_@VIVa@8whbbh-Ss*nIMs3VZBDTiepM_rBdG^Vl}$$HudV+@5{h$g%vV`GUxd z49V%%kGZ>M{9`%y>5;T}--=1++Z}%$O?~G2@Ididg~z7*u4ja;FAz?1vCuO5$5_Mo zdFR_wry1|>OxtR)^1v+?yW^V1xf16)ru;1zc)6c}nW3`I*votOsXS1<vd$@? F2>_R2s|Nr8 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..5dfd67b6c7dca3dc573a025e106725a52c403ebc GIT binary patch literal 2867 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 GGywqlxgRb7 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 0000000000000000000000000000000000000000..2b8bd80cca5893fa2fdde1e046fe91a575f54110 GIT binary patch literal 1054 zcmah|TWHfz7>=k@rVghdDhh|FC~9+So3?SCq)FQ@j-E-fkdjT*4nfA&J7FH`X3y4#uz{k+ zPqzwfxGlR@GLX&a0fs5tE@4wt!^*O&8(k2CcGzh-N&54x+cdDuB;6X#a#>e_MXRaT zgDt(y1*5miNSO4>M$k}}h=2{T4$Afx$Ct`UdPG+u`@qc7U<87@lJxJO+Oj#IAP<5l z6Al?1&jV3p_()U~`Q*TE%Rbp5QGS?rPL}n#23|Qq_f4K5L zxsu{R9V4%R(3WcVaz%uZUqmiYT13!lIVLLkL18O#LeJU;&9sMXFj5)G8slBo!f`pG z#kgo(5CttBi*fNZr^aO^Aq$?bAOt$~!u*5kVv~f&Zt0pol!FF^=$zgQNp+jcd zBSSp%)q{oP0$j+ba-sa{>frj?onUIs<`rjNH{~`-c-^u!%AUdD$9E?`8%o9p>-#06LPhUBIt#e9aW4JDYWzf3e2X+2tUGKU} t0%0| zok}e`w%nyck&-cPqdpEwjq;-E*f$)(vN}dWiqMV>VbS9 zQ6tJo8#1AVlX8qEmY{CvqRho5L6JjTTv0eq;iU*GNJ^NM1U}I&M};ysX}MUnG+5>u zf4SVMTruH56(c8u(BX3Ty7LGlH;-(P=n=qv!_rZ~^$WYC6FSCGsJA=F1f|M|#){~Y z(j1Xmh(taT5<*HO9A+c!tQ?UNQ9+X9MDZd=Uy<#9ISdKT_-$O#*0PDrioabRQgT=x zb7+y-cE}K)D)#;&7vO4AmNMS!8*{xiC&2o3^9vJ|bKK`^pQ_*Q?f7c{xV5QTDdyVV z^sV{$vkrfkXZe$7o>flXmDs|_^u+h$H=FA23p08U}fi7AzZCsS=07?_nZLn2Bde0{8v^Kf6`()~Xj@TAnpKdC8`Lf!&sHg;q@=(~U%$M( zT(8_%FTW^V-_X+15@d#vkuFe$ZgFK^Nn(X=Ua>OF1ees}+T7#d8#0MoBXEYLU9GXQxBrqI_HztY@Xxa#7Ppj3o=u^L<)Qdy9y zACy|0Us{w5jJPyqkW~d%&PAz-CHX}m`T04pPz=b(FUc>?$S+WE4mMNJ2+zz*$uBR~ z1grP;werj>E=kNwPW5!LRRWrzmzkMjWngLO>||kR;_Bk+WN7GWVqxlP>}q0eVQ%VZ z>SSVM2-EA5pIn-onpXnTn}X15ic>ErDdZLaZFWg5$}CGwaVyHtRRDY0DigO`jBuI< z)tiFbEyg(Y>H{644~kf%h=vIPQxAvZDQC*|8vDcS3@=v6g^Vvz*eR z=^7J0s4{&#%Fg-mAiHPP1TIdMo(Xy$PfM5o@BDvahvnz9>x|ROUp33`c)dOS`S1BR zi~l{JJtH;plwkLP$PZ$B0{(|xX?nXr)W@28TQcVkma^u*39J=NYdXZ`n2$Ti#!qjU z{owli`cHfpj+!;D)s%n7^!=cZOZR#9bcfJWzu!9=|5(Nv(QUu3xm2(DOQV>9;KoPY z2V4W*eflq05X!xv`@S-dna9LqNIqdePBtkV&XKe|@$ zzOwuIZ_XD!PWLPjbZ}R-;ODYo+mk~~0f*ya1-xrSKJ7YayZk(#=9XIj24<&w;c?$5ET3e@ zazSzD(a2=RyvC0cy5f1HY9+P{zT=pGB>LoXhPdagS1R1+|FwPa$ot3N+bw${=f8iw zeM%d{N_DsOKTb&gkO}yhUBSLi{8OB@e^nw!!hg2&jkQkq#LwMmXBFE&(|DKHiE7q& z%XYJ+DmCoon$OVQvPb?wTmR;^=r>H$4;m@HSFMg@%O1veH@ogF@;M=&_Hl8eoR*V-!$!@8wg>nW^G_7s`_OfvYEmL+!tZZv zPw!3rD!s65>0uEE&F}m6+~@ea)8z)!jdd4)rX0)PqRs5T%!ebvU3a#Gq2l?Z;-e=v zdroH3Ff$a&dS~pJ?z4I2rQBCdKHLj#oXL2i^s=YWEclmioR1kxKu(s)#*+(g*kq;| qyZ+?|YB3jz5std)VkoztRf54p`)|9kl&BY|2J&?Eb6Mw<&;$U5HLDi@ 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 0000000000000000000000000000000000000000..278975633e9c9410eedf33aef5436540e4f0fad2 GIT binary patch literal 2366 zcmaJ@XIN8N8m3n%Dxwr22Fy}I8a06cfxwC}fFx2xku)Gca$^!qKtNz{0mW5Rngtn0 zWDumgU?(CdML zoSc@=HgW)DT~>ZI6=)?a4+X8lmH3vIAR7&%8TWT2vQ>avn~PJuN23=#fE zQo&Szm?t3Q!0b`>HY^O*4(5nQVePSYPFN%ihr!ySF}7%|tqm4Oz~Bj3d)Su`4n-5P zBM1Rx?=P_+j|h(vivUN>@pv=_hsNP-AcT!5o-bxdZTKRyRRuCf z#1e7^VlKdkttc{>K%AHehcf-61fJllEMN4cO;E$oQicGHMPXJ-S_M+6e-GvHzM@6q z0M4KJ{-v;p9xvda12`fePRN2TF2Zajlz`wVpqQ3J}0NJz*A9 z28+vI@hv|Ss8oUvUnFMmSsWiS5e`Y9xLh^?XJ>0i@^Zvuu#Pw^*2^C6LB=^jeRpuO zC3!lL?N+&DfECB%@WrcK_McqRH@Pdbz!N}`$s8f~0Eg`@1bDE|H50hs&c*SYdSAHg zZ|CClO)eTr2EB5#|98`?N6`4JY`@Me=C- zSo$tK;^z2t_Z-9OV_DnRP(OOD@ekNuo@}wWWvho&DLZFiQ*`$Ei>9sj!6eAJ$Blw&lgEk<&V)#2 zL|sEm=PbE=z61VVVztU1^+0v&rhqM2go~oKhF{ukutgm9q_0o^3a!rgC{nfIJ0saM za581SUkx}tZ-Qu=Y4V-bUC1ccZZ#&BYAAGT{E{_H$44wnj***=o#lvXg1*l293rQDig98&s!r~s}1Vjr&DB_GF0KY zG>n3YigS}Gt{$`!lm^!#kIg@5#JT_0sF@!IA3bTR0i3+*`XZ#Tv;&$O5a^xyXeHoC47gaY2@pr>9G76wh_TZrIUeqLyPkrXQuL zy1%A}-m?oo-X!`8w6tVi@ZBL_o*70 zYj-(zrG7{Of}h*T+O@_tBK+rerwsfAjw)0(8+UwA&2&|JJUXs6gg%u!)_Ux+v^tb2 zbwj=rO%?dX-fF>-rXD`2?bWbt;f$Yh$eBvXjp3zz2+1pYq-;=wlgL zVFTmpLzU(;X7Utz%`Y3;T9=Qgg`QFd=q7@JnmCHyjoNpOdWhv7P`wEF?_PI`cSe>; zy=zr!X!lWr+u#9*4!tV>@ES(2&%dIXCm9RhJEt+n`+D>4R9ynCI`WTL-PxI3RjY22 zSq+k?n9>Oi%H*VBZ{FaGt;vDORmF#|oqQOTZd398_EUt^;xXm5 zeI@Zz@n^wWHO;<7S8v(woP#0h%0X6lFJy)ERgA9HuV~eGkUfL!F20K8!X;si>yhm_ zYq6PSG}H$gM(4zi#XYa`Mz5$vj~(b_UicZEnxvQb_@u>Tb}_hjw@2!Zw`lb28@eIy zlmdzVvT&j*Fvx9K*+hwgr?n^aZQ3&7%3kNJT?U>=`bP+++~`7#DN1AK#)^)qEmKa- zrGnSLuw~@(ynw=}rzIC0vU)X=r4IPK`Pq`rfn@2xo04K?^>p<9NVngbZtPo9M-=(< zncss+vv1*g9oVJHxvFx%(&+6Q5^&$C*`9UQkgM~v@ zI^fzS=3o|>F+8?>zCCXGO#Q-W^QSh8CRHSQxNC`Y>Z~Z2fn2)0^cC?}LFC5k z^3MQnb5^$3jACBx5lzgGQknU`ttj zSN=Ntcb8M*zhgSOSHv~gp1(4B;#KPd#pk&c@~`DSlf8kFjjv8`Q}}enWx{}>lsnn_ zK5QW>Nt!v*?9%mM^E`12p<7#g^o7omjoD`k?=i~EEph|$Laf`ChIMB^K|<$PYuR)G z3UU8x0{i#S)2+nGh1(wen{rA@tvjiOdc)V*HBFKq-D5D#Ee)4+_A-Dj@$1xabDi|7 z`IpT06-(xd2a|9O1&QjuUDXx|=am#`cwM|@UPVq@o#PALN6HC@&ruuN7x&t%--~E8 zU;oqEGWwdEiwTvV3LVVl74Y3}4z>KMT~*|0d#J?-11+qSISH!uzMH}txdNImf)brs QxALO#@$w~CdW5I_4>!)~QUCw| literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..67b0fa4debf08caea789433ebb64ff8335ba25f3 GIT binary patch literal 2644 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 N002ovPDHLkV1ns;hyDNn literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..dba2a36bc01a9473ae0cc225626322b56df3c631 GIT binary patch literal 321 zcmV-H0lxl;P)oTZ`mKJt2dJeVB9=Wz^wRyaaTqGW0o*t4k%)-1M@i1YL&ne zSOQC62`qtufx-U7p^rV72SwPUHSA>s_WA~W;e{O$Ko3=*$57CNJET#k2UGS0vw3Qn TV9wjW00000NkvXXu0mjf#xajW literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..cf1a4bbd650a2b13fe3f89ff2a545d7a57553bf0 GIT binary patch literal 1648 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@ZgvM!k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+n3Xa^B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxSU1_g&``n5OwZ87 z)XdCKN5ROz&`93^h|F{iO{`4Ktc=VRpg;*|TTx1yRgjAt)Gi>;Rw<*Tq`*pFzr4I$ zuiRKKzbIYb(9+TpWQLKEE>MMTab;dfVufyAu`f(~1RD^r68eAMwS&*t9 zlvv ztM~P_^2{qPNz6-5^>ndS0-B(gnVDkcVr*`1VrJ%KU|?=$Xy|HcY35{MVc=?EY-a9i zV&LQm)9aF-T$-DjR|3v4~Pj*wm=R%;iu*SQ+p9GS#R5LQHOzn>4~R{V@SoV zH*>5rL;^+H-go_Qc&i)J!r`P8^@A%*k!z7-fIx1H>k&0GEu*>DHqKPjE{~zc@v+%J9B*I?&o)`JvBXr z(l6Si&14czY4VxCY2>JOf<@FMExoc>#I^Y2CEjn%d>ahZuis>Feqi*X|M8B8)d?rJ zPimWE6!)%Ss-=I|^#$CM>^eCgomr_l!B}qn0V|JRs;2Cv+LN3&a>-1cvqYQg`F-X| zO;#dYQHq)wjZTiA*Ya(03f!--%JAK%mYZzP7_>B}H8ww}Tc?%zP=c*}=e}RY_Y6aR zmNjuN*y|zrr9pqsvyb#Ud(%* zdsSy%1LN7Ib!!9wjl1=HezlAkRonM(FuFLei`$BhMc%AlQl}W|YI{IGb`&n(6rET(8KTjyu_S-V` zwd32ENdAJ~1{MoBbT-d8<#XOrkyEPwZI5VIB@Z|Ne|i2=ui)R;@Lu@UyrT)4Gr~Q)Vho z7CNajNhGB7p^K@D<9(-%%{srb_RcU}{cG0MX+9SMMIza5>MnB#aDKS8--}BsOe4c1 z=z?f#lb$D+)oPvYxTfNyrhu83b`?&~k9y{C&TsyHvol|G+ZgS4l%#%G;{E-Ud$CIE zxvAHB`WpRWPN&~z_Wt(1a19?gY0Xps2h-8}kG3-~GaOEzXWz$cFAu5%JYD@<);T3K F0RSR_ZG`{; literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..71f9be5bcf9379f388bae6127969c69fd8229641 GIT binary patch literal 4898 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..50294ed725761b343eabea29148f70e4e4728257 GIT binary patch literal 4297 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 J2D{*-{{WKrFm?a{ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..7aaa8baa647db5a48e553229ce6f139fa483de03 GIT binary patch literal 4425 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..a00c94dba5f3c41e62017f4839d9f8285e2b4243 GIT binary patch literal 3655 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 KAk`4*$^Qge!4A>@ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..28b2e4b14592ecffab8f03518fcfc609148e8f6a GIT binary patch literal 1301 zcmeAS@N?(olHy`uVBq!ia0vp^HbAVx!3HF+Rz|h}DajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_)*%u1Od5hW46K32*3xq68pHF_1f1wh?E1MMpc5|gu2OB9k) z(=+pImEP~(ucVNfVyhHx>TBRz;GCL~=}}db8eHWUl3bOYY?-2DZ>L~WVFffGH?<^D zp&~aYuh^=>Rtapb6_5=Q)>l#hD=EpgRf0Gw!Z$#{Ilm}X!Bo#!H`&0@P{GVh&(Orw z%*;?n!N|bSNZ$a6%ybP+tW3?UjLa3FKnZADQA(Oskc%7CE+EfVDWjyMz)D}gyu4hm z+*mKaC|%#s($W%ShLMpjP=#)BWnM{Qg>GK4GRy>*)Z*l#%z~24{5%DaiHS-1r6smX zK$k+ikXryZHm?{OOuzusuShJ=H`Fr#c?qV_*B8Ii++4Wo;*y|LgnO|XTpUtakg6Y) zTAW{6lnjixG-Z%g1y;^Qsfi`|MIrh5Ij~R+$jC3rFV4s>P;d@5Q_u*{%uC5HFV+OB z_w}{%%quQQ%u7!7bg@+enxL1NnPTPa;$muHY;Is+Vs2z;=xSgsH4XkudS zyn>bnwy$e0@Is<&})cOFDNPG765H_NiE7OOHFYr%Fk5*d)X=zr(4WiaheC! zn}X9VW^Oq3>H{644~kf%h=vIPQxAv^d122BQl)g82r!M*(F}>;B!E0@H?Y)cIH?WJZyYxc9tYcY%_u}9U%^6zTM6B4W#cW^Q zx+L<`L61W>vGv8dLS%AaE(ZWv~Jr}mh6SD8!shfZm|es)@cnpnANy5!*q?> zjIOYwSid!_NS?d-qTT`79^eA7%oso?}BIegR3)vfz Ppn}TN)z4*}Q$iB}C|cD8 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..13ba2eaa72db5c2442b0e158fe4c8fc5fcd8b98a GIT binary patch literal 5425 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 Dm|7&O literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..e6383e095a0e86de3822b6f595b5cbec8f5a032b GIT binary patch literal 5187 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..824b9f6efd8313f87fef0fead8206c0e3ee28a5f GIT binary patch literal 6368 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 S_TJzB983%?4XX59qW%Y?Qd;x? literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..db8c53ae17e8f8520ccdbbac56c3749618df996e GIT binary patch literal 2487 zcmaJ@c{r47A08)UjifA-8pBLFn2njtWUMnXg=Cbim@)GX6SFik_O>&1j_o5!XhA9> zlWcV;k)<3_QBkRU6eD{f64f`;N$30H>wB;F_dd&Y-}mo+p67Qx*PH0+u|-qOPz?kE zX;NHCUa~e^9xBSR?=hCoeOY55BKwM{JeDYmE&xD|OkOYmp>XISfEPe##_VeaY(b!9 zP`0Z2Z~ze<63q$c3JK9f=r>)0tS_HNLLuKEqA()# zZ&SYRo)BlA0Dxc-R+bDD8V$kW5NK;G4u`gYU{Gib5+!?amS}4N7DvErf_#6VvTOn- zi{M3a`JPKQB0@t&B0d3$jEagvL|Gwtf)FGckH^b3Fc?c2!crK+715(Dxk8gA1ri`+ z2-tiPo5zL773sme2oVt~bNcrZIQ$>7T;ca^l5H3=n$Aa}5h(eRmVoZ={~yZX{6Gsu zUcf(o|EI9fJBAM+y#OIELcow69Lq$WicfGB0CW*g;LYQOFYTgdC{M%_hVu9jXDSY2 z=ELSPc~QcR-|+741PWIuqH`Glg+zqP6cB7SlVF8H98 zlM|V2<>Z22;*xlb2oAs%EpeIuaBY6dm6rmCFUw2<1nfwF=_259Am5fuVE^0;_NRK^ zxy+w?!Tpqrl$k-w5B9$fdTB~lJ@W34vXu>f6h6R}Rl7h|)(;kg*MLCE<`j~ncXZF# zo&erXvTk6@*4ihKXL{>AS3TaPh)jqoLYIf;@9uHcxQP5P)u)bLiT$F)fWB)yQW)5w z19N<{r}%t-z8Sp8^w&(a#QgV4V2HOWxi}2Cy2_CHu-z_%H9K~z9y$NWIxdeWly0`F z?3Q3F&8bwX;=ppfd{u}(r~#y+EDr~iEXvr~Ew+tk)tXKG;ff{8d@%NmK)o`zjiXdc zu(;rMLA%zeKbfAh!O{i) zva)MvpLAL~oMqd#AKqyE2`?=S{o|bLYx*%vP|CC5lP)76b*c>svDuT&HVt2w9~!Nl z-M3C@)f*bD@>opV5<6;6&~UPts}|2Eh1rM0q!w4JDGqKQ zH(18^YE^AuxSqW(?qv1r29YV!@mHz$j98_t+$w(QmR}?Z19v6stF%j=m-~u=y~hJt z)stqhg*%un7Gloz>X0*x^2={&+-ud76x)(D&4inF4n(f05Hplpp&sdP^w|HcmhXD1-}3B3nSNy}n=Ut5 zAAO|8`ZT4!aZLGN_z^9f*N~Gsj$7S(+A+rs__Bl50M~e0Y2y@H zdZ#uZw#DGDL|UP31J&Tk@X`KHV;FT-l2r=J^HLC4BFt9`+qB!BiGEl!vFCzjcTI=b z67|Hf5#g*bS{ZQQ%2#LVbEOmb@WlSyafQ+88~vZgGv41_)R#1SG)4Foe8oEuSNP9J zA4tIF$_?G%(zZukj}=DV>z-rs>+&cPF!-?r1ttVPlThH(GILq@3UJ;>n$N2S_w-I^PuB3cu=H zab_K}ZY)%P40^LGcY}U*@&9-raS>lPV%Hr)3$LH_Lj;B|m-O_fqPWT#b zyzV`|FXv^8*J9trteMe&29{B zg;Q%!UlCo20kE$fw|JM;WXRkIkV?es|@cO zB%a)SfdTJi9_n5^3Pzwk!)6mI!wVN09>s?1j#f#Ew5HmflN^#)9IN=ftEHs4 zNA%$3>JCGTD%#G!@P_FvAC+rbd3tknPao8c=|?ItcE}xT`$js+%Pra?(F?F#m~r}t zfhel;aQmmKw3*?it*u~5;raW8>hVXeQ5P?Xvs}u~gEpkE(bU!uE1*?yiG@?Cl?WxU zb6ji-I!in*Z_BndM4ltwYPy{AxYm9Qd~c$!1v68+;;H!6?Zr$renvDiZKr`Brm`pL z%w0(q*~{;6jstk}>M+fMXPa`mwNCWq)_$1`tGafA?it(NYrTH&0P#V3foVuxn?iuj z>N-V3{m&A{uNnIKc~7U)e0wuiL>uZTe7}5AAhDw?6y)}_H4f9{0a837i)FR_K?=&C W4#phIk76eOlLAr59;8wyn)pA&K@Rr- literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..91ebc55d62a69f90f97d7b094ca75ca649945ed5 GIT binary patch literal 3664 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 SAFj;?xWm-Y%AicoHR_*xYPW3w literal 0 HcmV?d00001 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 2c9359e25d4da43a1a3bdf1a331463145310b3de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1784 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 be?~Tj7qN;7o;%!IKpEfD)z4*}Q$iB}P2PKa literal 0 HcmV?d00001 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